Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support negative tolerance for euclidean + chi2 tests #4000

Merged
merged 3 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions Core/include/Acts/Surfaces/BoundaryTolerance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,12 @@ class BoundaryTolerance {

AbsoluteBound() = default;
AbsoluteBound(double tolerance0_, double tolerance1_)
: tolerance0(tolerance0_), tolerance1(tolerance1_) {}
: tolerance0(tolerance0_), tolerance1(tolerance1_) {
if (tolerance0 < 0 || tolerance1 < 0) {
throw std::invalid_argument(
"AbsoluteBound: Tolerance must be non-negative");
}
}
};

/// Absolute tolerance in Cartesian coordinates
Expand All @@ -77,7 +82,12 @@ class BoundaryTolerance {

AbsoluteCartesian() = default;
AbsoluteCartesian(double tolerance0_, double tolerance1_)
: tolerance0(tolerance0_), tolerance1(tolerance1_) {}
: tolerance0(tolerance0_), tolerance1(tolerance1_) {
if (tolerance0 < 0 || tolerance1 < 0) {
throw std::invalid_argument(
"AbsoluteCartesian: Tolerance must be non-negative");
}
}
};

/// Absolute tolerance in Euclidean distance
Expand All @@ -98,6 +108,12 @@ class BoundaryTolerance {
: maxChi2(maxChi2_), weight(weight_) {}
};

enum class ToleranceMode {
Extend, // Extend the boundary
None, // No tolerance
Shrink // Shrink the boundary
};

/// Underlying variant type
using Variant = std::variant<Infinite, None, AbsoluteBound, AbsoluteCartesian,
AbsoluteEuclidean, Chi2Bound>;
Expand Down Expand Up @@ -132,7 +148,7 @@ class BoundaryTolerance {
bool hasChi2Bound() const;

/// Check if any tolerance is set.
bool hasTolerance() const;
ToleranceMode toleranceMode() const;

/// Get the tolerance as absolute bound.
AbsoluteBound asAbsoluteBound(bool isCartesian = false) const;
Expand Down
43 changes: 31 additions & 12 deletions Core/include/Acts/Surfaces/detail/BoundaryCheckHelper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,22 @@ inline bool insideAlignedBox(const Vector2& lowerLeft,
const BoundaryTolerance& tolerance,
const Vector2& point,
const std::optional<SquareMatrix2>& jacobianOpt) {
using enum BoundaryTolerance::ToleranceMode;

if (tolerance.isInfinite()) {
return true;
}

if (detail::VerticesHelper::isInsideRectangle(point, lowerLeft, upperRight)) {
return true;
BoundaryTolerance::ToleranceMode mode = tolerance.toleranceMode();
bool insideRectangle =
detail::VerticesHelper::isInsideRectangle(point, lowerLeft, upperRight);

if (mode == None) {
return insideRectangle;
}

if (!tolerance.hasTolerance()) {
return false;
if (mode == Extend && insideRectangle) {
return true;
}

Vector2 closestPoint;
Expand All @@ -64,7 +70,11 @@ inline bool insideAlignedBox(const Vector2& lowerLeft,

Vector2 distance = closestPoint - point;

return tolerance.isTolerated(distance, jacobianOpt);
if (mode == Extend) {
return tolerance.isTolerated(distance, jacobianOpt);
} else {
return tolerance.isTolerated(distance, jacobianOpt) && insideRectangle;
}
}

/// Check if a point is inside a polygon.
Expand All @@ -79,23 +89,27 @@ inline bool insidePolygon(std::span<const Vector2> vertices,
const BoundaryTolerance& tolerance,
const Vector2& point,
const std::optional<SquareMatrix2>& jacobianOpt) {
using enum BoundaryTolerance::ToleranceMode;
if (tolerance.isInfinite()) {
// The null boundary check always succeeds
return true;
}

if (detail::VerticesHelper::isInsidePolygon(point, vertices)) {
// If the point falls inside the polygon, the check always succeeds
return true;
}
BoundaryTolerance::ToleranceMode mode = tolerance.toleranceMode();
bool insidePolygon = detail::VerticesHelper::isInsidePolygon(point, vertices);

if (!tolerance.hasTolerance()) {
if (mode == None) {
// If the point falls inside the polygon, the check always succeeds
// Outside of the polygon, since we've eliminated the case of an absence of
// check above, we know we'll always fail if the tolerance is zero.
//
// This allows us to avoid the expensive computeClosestPointOnPolygon
// computation in this simple case.
return false;
return insidePolygon;
}

if (mode == Extend && insidePolygon) {
return true;
}

// TODO: When tolerance is not 0, we could also avoid this computation in
Expand All @@ -112,7 +126,12 @@ inline bool insidePolygon(std::span<const Vector2> vertices,

Vector2 distance = closestPoint - point;

return tolerance.isTolerated(distance, jacobianOpt);
if (mode == Extend) {
return tolerance.isTolerated(distance, jacobianOpt);
} else {
// @TODO: Check sign
return tolerance.isTolerated(-distance, jacobianOpt) && insidePolygon;
}
}

} // namespace Acts::detail
Loading
Loading