Skip to content

Commit

Permalink
feat: Support negative tolerance for euclidean + chi2 tests (#4000)
Browse files Browse the repository at this point in the history
  • Loading branch information
paulgessinger authored Dec 19, 2024
1 parent 72145fc commit 8e430f8
Show file tree
Hide file tree
Showing 6 changed files with 597 additions and 156 deletions.
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

0 comments on commit 8e430f8

Please sign in to comment.