diff --git a/Core/include/Acts/Surfaces/BoundaryTolerance.hpp b/Core/include/Acts/Surfaces/BoundaryTolerance.hpp index 5dfc7ad6552..b0fabd8ec64 100644 --- a/Core/include/Acts/Surfaces/BoundaryTolerance.hpp +++ b/Core/include/Acts/Surfaces/BoundaryTolerance.hpp @@ -54,19 +54,16 @@ namespace Acts { /// class BoundaryTolerance { public: - /// Infinite tolerance i.e. no boundary check - struct Infinite {}; + struct InfiniteParams {}; - /// No tolerance i.e. exact boundary check - struct None {}; + struct NoneParams {}; - /// Absolute tolerance in bound coordinates - struct AbsoluteBound { + struct AbsoluteBoundParams { double tolerance0{}; double tolerance1{}; - AbsoluteBound() = default; - AbsoluteBound(double tolerance0_, double tolerance1_) + AbsoluteBoundParams() = default; + AbsoluteBoundParams(double tolerance0_, double tolerance1_) : tolerance0(tolerance0_), tolerance1(tolerance1_) { if (tolerance0 < 0 || tolerance1 < 0) { throw std::invalid_argument( @@ -75,13 +72,12 @@ class BoundaryTolerance { } }; - /// Absolute tolerance in Cartesian coordinates - struct AbsoluteCartesian { + struct AbsoluteCartesianParams { double tolerance0{}; double tolerance1{}; - AbsoluteCartesian() = default; - AbsoluteCartesian(double tolerance0_, double tolerance1_) + AbsoluteCartesianParams() = default; + AbsoluteCartesianParams(double tolerance0_, double tolerance1_) : tolerance0(tolerance0_), tolerance1(tolerance1_) { if (tolerance0 < 0 || tolerance1 < 0) { throw std::invalid_argument( @@ -94,50 +90,65 @@ class BoundaryTolerance { } }; - /// Absolute tolerance in Euclidean distance - struct AbsoluteEuclidean { + struct AbsoluteEuclideanParams { double tolerance{}; - AbsoluteEuclidean() = default; - explicit AbsoluteEuclidean(double tolerance_) : tolerance(tolerance_) {} + AbsoluteEuclideanParams() = default; + explicit AbsoluteEuclideanParams(double tolerance_) + : tolerance(tolerance_) {} }; - /// Chi2 tolerance in bound coordinates - struct Chi2Bound { + struct Chi2BoundParams { double maxChi2{}; SquareMatrix2 weight = SquareMatrix2::Identity(); - Chi2Bound() = default; - Chi2Bound(const SquareMatrix2& weight_, double maxChi2_) + Chi2BoundParams() = default; + Chi2BoundParams(const SquareMatrix2& weight_, double maxChi2_) : maxChi2(maxChi2_), weight(weight_) {} }; + private: + /// Underlying variant type + using Variant = std::variant; + + /// Construct from variant + explicit BoundaryTolerance(Variant variant); + + public: + /// Infinite tolerance i.e. no boundary check + static auto Infinite() { return BoundaryTolerance{InfiniteParams{}}; } + + /// No tolerance i.e. exact boundary check + static auto None() { return BoundaryTolerance{NoneParams{}}; } + + /// Absolute tolerance in bound coordinates + static auto AbsoluteBound(double tolerance0, double tolerance1) { + return BoundaryTolerance{AbsoluteBoundParams{tolerance0, tolerance1}}; + } + + /// Absolute tolerance in Cartesian coordinates + static auto AbsoluteCartesian(double tolerance0, double tolerance1) { + return BoundaryTolerance{AbsoluteCartesianParams{tolerance0, tolerance1}}; + } + + /// Absolute tolerance in Euclidean distance + static auto AbsoluteEuclidean(double tolerance) { + return BoundaryTolerance{AbsoluteEuclideanParams{tolerance}}; + } + + /// Chi2 tolerance in bound coordinates + static auto Chi2Bound(const SquareMatrix2& weight, double maxChi2) { + return BoundaryTolerance{Chi2BoundParams{weight, maxChi2}}; + } + enum class ToleranceMode { Extend, // Extend the boundary None, // No tolerance Shrink // Shrink the boundary }; - /// Underlying variant type - using Variant = std::variant; - - /// Construct with infinite tolerance. - BoundaryTolerance(const Infinite& infinite); - /// Construct with no tolerance. - BoundaryTolerance(const None& none); - /// Construct with absolute tolerance in bound coordinates. - BoundaryTolerance(const AbsoluteBound& AbsoluteBound); - /// Construct with absolute tolerance in Cartesian coordinates. - BoundaryTolerance(const AbsoluteCartesian& absoluteCartesian); - /// Construct with absolute tolerance in Euclidean distance. - BoundaryTolerance(const AbsoluteEuclidean& absoluteEuclidean); - /// Construct with chi2 tolerance in bound coordinates. - BoundaryTolerance(const Chi2Bound& Chi2Bound); - - /// Construct from variant - BoundaryTolerance(Variant variant); - /// Check if the tolerance is infinite. bool isInfinite() const; /// Check if the is no tolerance. @@ -155,16 +166,16 @@ class BoundaryTolerance { ToleranceMode toleranceMode() const; /// Get the tolerance as absolute bound. - AbsoluteBound asAbsoluteBound(bool isCartesian = false) const; + AbsoluteBoundParams asAbsoluteBound(bool isCartesian = false) const; /// Get the tolerance as absolute Cartesian. - const AbsoluteCartesian& asAbsoluteCartesian() const; + const AbsoluteCartesianParams& asAbsoluteCartesian() const; /// Get the tolerance as absolute Euclidean. - const AbsoluteEuclidean& asAbsoluteEuclidean() const; + const AbsoluteEuclideanParams& asAbsoluteEuclidean() const; /// Get the tolerance as chi2 bound. - const Chi2Bound& asChi2Bound() const; + const Chi2BoundParams& asChi2Bound() const; /// Get the tolerance as absolute bound if possible. - std::optional asAbsoluteBoundOpt( + std::optional asAbsoluteBoundOpt( bool isCartesian = false) const; /// Check if the distance is tolerated. diff --git a/Core/src/Geometry/TrapezoidVolumeBounds.cpp b/Core/src/Geometry/TrapezoidVolumeBounds.cpp index 67b231aa43f..5c96932dc04 100644 --- a/Core/src/Geometry/TrapezoidVolumeBounds.cpp +++ b/Core/src/Geometry/TrapezoidVolumeBounds.cpp @@ -153,7 +153,7 @@ bool TrapezoidVolumeBounds::inside(const Vector3& pos, double tol) const { } Vector2 locp(pos.x(), pos.y()); bool inside(m_faceXYTrapezoidBounds->inside( - locp, BoundaryTolerance::AbsoluteBound{tol, tol})); + locp, BoundaryTolerance::AbsoluteBound(tol, tol))); return inside; } diff --git a/Core/src/Surfaces/BoundaryTolerance.cpp b/Core/src/Surfaces/BoundaryTolerance.cpp index 971a026d7de..3bedc6ab8ff 100644 --- a/Core/src/Surfaces/BoundaryTolerance.cpp +++ b/Core/src/Surfaces/BoundaryTolerance.cpp @@ -15,49 +15,32 @@ namespace Acts { -BoundaryTolerance::BoundaryTolerance(const Infinite& infinite) - : m_variant{infinite} {} - -BoundaryTolerance::BoundaryTolerance(const None& none) : m_variant{none} {} - -BoundaryTolerance::BoundaryTolerance(const AbsoluteBound& absoluteBound) - : m_variant{absoluteBound} {} - -BoundaryTolerance::BoundaryTolerance(const AbsoluteCartesian& absoluteCartesian) - : m_variant{absoluteCartesian} {} - -BoundaryTolerance::BoundaryTolerance(const AbsoluteEuclidean& absoluteEuclidean) - : m_variant{absoluteEuclidean} {} - -BoundaryTolerance::BoundaryTolerance(const Chi2Bound& chi2Bound) - : m_variant{chi2Bound} {} - BoundaryTolerance::BoundaryTolerance(Variant variant) : m_variant{std::move(variant)} {} bool BoundaryTolerance::isInfinite() const { - return holdsVariant(); + return holdsVariant(); } bool BoundaryTolerance::isNone() const { - return holdsVariant(); + return holdsVariant(); } bool BoundaryTolerance::hasAbsoluteBound(bool isCartesian) const { - return holdsVariant() || holdsVariant() || - (isCartesian && holdsVariant()); + return holdsVariant() || holdsVariant() || + (isCartesian && holdsVariant()); } bool BoundaryTolerance::hasAbsoluteCartesian() const { - return holdsVariant(); + return holdsVariant(); } bool BoundaryTolerance::hasAbsoluteEuclidean() const { - return holdsVariant(); + return holdsVariant(); } bool BoundaryTolerance::hasChi2Bound() const { - return holdsVariant(); + return holdsVariant(); } BoundaryTolerance::ToleranceMode BoundaryTolerance::toleranceMode() const { @@ -70,7 +53,7 @@ BoundaryTolerance::ToleranceMode BoundaryTolerance::toleranceMode() const { return None; } - if (const auto* absoluteBound = getVariantPtr(); + if (const auto* absoluteBound = getVariantPtr(); absoluteBound != nullptr) { if (absoluteBound->tolerance0 == 0. && absoluteBound->tolerance1 == 0.) { return None; @@ -79,7 +62,7 @@ BoundaryTolerance::ToleranceMode BoundaryTolerance::toleranceMode() const { return Extend; } - if (const auto* absoluteCartesian = getVariantPtr(); + if (const auto* absoluteCartesian = getVariantPtr(); absoluteCartesian != nullptr) { if (absoluteCartesian->tolerance0 == 0. && absoluteCartesian->tolerance1 == 0.) { @@ -89,7 +72,7 @@ BoundaryTolerance::ToleranceMode BoundaryTolerance::toleranceMode() const { return Extend; } - if (const auto* absoluteEuclidean = getVariantPtr(); + if (const auto* absoluteEuclidean = getVariantPtr(); absoluteEuclidean != nullptr) { if (absoluteEuclidean->tolerance == 0.) { return None; @@ -100,7 +83,7 @@ BoundaryTolerance::ToleranceMode BoundaryTolerance::toleranceMode() const { } } - if (const auto* chi2Bound = getVariantPtr(); + if (const auto* chi2Bound = getVariantPtr(); chi2Bound != nullptr) { if (chi2Bound->maxChi2 == 0.) { return None; @@ -115,35 +98,36 @@ BoundaryTolerance::ToleranceMode BoundaryTolerance::toleranceMode() const { return None; } -BoundaryTolerance::AbsoluteBound BoundaryTolerance::asAbsoluteBound( +BoundaryTolerance::AbsoluteBoundParams BoundaryTolerance::asAbsoluteBound( bool isCartesian) const { if (isNone()) { - return AbsoluteBound{0., 0.}; + return AbsoluteBoundParams{0., 0.}; } if (isCartesian && hasAbsoluteCartesian()) { - const auto& cartesian = getVariant(); - return AbsoluteBound{cartesian.tolerance0, cartesian.tolerance1}; + const auto& cartesian = getVariant(); + return AbsoluteBoundParams{cartesian.tolerance0, cartesian.tolerance1}; } - return getVariant(); + return getVariant(); } -const BoundaryTolerance::AbsoluteCartesian& +const BoundaryTolerance::AbsoluteCartesianParams& BoundaryTolerance::asAbsoluteCartesian() const { - return getVariant(); + return getVariant(); } -const BoundaryTolerance::AbsoluteEuclidean& +const BoundaryTolerance::AbsoluteEuclideanParams& BoundaryTolerance::asAbsoluteEuclidean() const { - return getVariant(); + return getVariant(); } -const BoundaryTolerance::Chi2Bound& BoundaryTolerance::asChi2Bound() const { - return getVariant(); +const BoundaryTolerance::Chi2BoundParams& BoundaryTolerance::asChi2Bound() + const { + return getVariant(); } -std::optional +std::optional BoundaryTolerance::asAbsoluteBoundOpt(bool isCartesian) const { return hasAbsoluteBound(isCartesian) ? std::optional(asAbsoluteBound(isCartesian)) @@ -161,13 +145,13 @@ bool BoundaryTolerance::isTolerated( return distance == Vector2::Zero(); } - if (const auto* absoluteBound = getVariantPtr(); + if (const auto* absoluteBound = getVariantPtr(); absoluteBound != nullptr) { return std::abs(distance[0]) <= absoluteBound->tolerance0 && std::abs(distance[1]) <= absoluteBound->tolerance1; } - if (const auto* chi2Bound = getVariantPtr(); + if (const auto* chi2Bound = getVariantPtr(); chi2Bound != nullptr) { // Mahalanobis distances mean is 2 in 2-dim. cut is 1-d sigma. double chi2 = distance.transpose() * chi2Bound->weight * distance; @@ -187,13 +171,13 @@ bool BoundaryTolerance::isTolerated( cartesianDistance = jacobian * distance; } - if (const auto* absoluteCartesian = getVariantPtr(); + if (const auto* absoluteCartesian = getVariantPtr(); absoluteCartesian != nullptr) { return std::abs(cartesianDistance[0]) <= absoluteCartesian->tolerance0 && std::abs(cartesianDistance[1]) <= absoluteCartesian->tolerance1; } - if (const auto* absoluteEuclidean = getVariantPtr(); + if (const auto* absoluteEuclidean = getVariantPtr(); absoluteEuclidean != nullptr) { if (absoluteEuclidean->tolerance < 0) { return cartesianDistance.norm() > std::abs(absoluteEuclidean->tolerance); @@ -214,7 +198,8 @@ SquareMatrix2 BoundaryTolerance::getMetric( bool isCartesian = !jacobianOpt.has_value(); SquareMatrix2 metric = SquareMatrix2::Identity(); - if (const auto* chi2Bound = getVariantPtr(); + if (const auto* chi2Bound = + getVariantPtr(); chi2Bound != nullptr) { metric = chi2Bound->weight; } else if (!isCartesian) { diff --git a/Examples/Io/Root/src/RootAthenaDumpReader.cpp b/Examples/Io/Root/src/RootAthenaDumpReader.cpp index 421affa36ba..b791dbf2eba 100644 --- a/Examples/Io/Root/src/RootAthenaDumpReader.cpp +++ b/Examples/Io/Root/src/RootAthenaDumpReader.cpp @@ -398,8 +398,8 @@ RootAthenaDumpReader::readMeasurements( bool inside = surface->isOnSurface(gctx, cluster.globalPosition, {}, - Acts::BoundaryTolerance::AbsoluteEuclidean{ - m_cfg.absBoundaryTolerance}, + Acts::BoundaryTolerance::AbsoluteEuclidean( + m_cfg.absBoundaryTolerance), std::numeric_limits::max()); if (!inside) { diff --git a/Tests/Benchmarks/AnnulusBoundsBenchmark.cpp b/Tests/Benchmarks/AnnulusBoundsBenchmark.cpp index 4d89df9bb41..c700c3d08d5 100644 --- a/Tests/Benchmarks/AnnulusBoundsBenchmark.cpp +++ b/Tests/Benchmarks/AnnulusBoundsBenchmark.cpp @@ -56,10 +56,10 @@ int main(int /*argc*/, char** /*argv[]*/) { cov << 1.0, 0, 0, 0.05; BoundaryTolerance bcAbs = BoundaryTolerance::None(); - BoundaryTolerance bcTol0 = BoundaryTolerance::AbsoluteBound{1.0, 0}; - BoundaryTolerance bcTol1 = BoundaryTolerance::AbsoluteBound{0, 0.2}; - BoundaryTolerance bcTol01 = BoundaryTolerance::AbsoluteBound{1.0, 0.2}; - BoundaryTolerance bcCov = BoundaryTolerance::Chi2Bound{cov, 1}; + BoundaryTolerance bcTol0 = BoundaryTolerance::AbsoluteBound(1.0, 0.0); + BoundaryTolerance bcTol1 = BoundaryTolerance::AbsoluteBound(0.0, 0.2); + BoundaryTolerance bcTol01 = BoundaryTolerance::AbsoluteBound(1.0, 0.2); + BoundaryTolerance bcCov = BoundaryTolerance::Chi2Bound(cov, 1.0); // visualization to make sense of things for (std::size_t i = 0; i < 10000; i++) { diff --git a/Tests/UnitTests/Core/Surfaces/BoundaryToleranceTests.cpp b/Tests/UnitTests/Core/Surfaces/BoundaryToleranceTests.cpp index e80035a10a8..47238d51068 100644 --- a/Tests/UnitTests/Core/Surfaces/BoundaryToleranceTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/BoundaryToleranceTests.cpp @@ -39,11 +39,11 @@ BOOST_AUTO_TEST_CASE(BoundaryToleranceConstructors) { { // Valid positive tolerances auto tolerance = BoundaryTolerance::AbsoluteBound(1.0, 2.0); - BOOST_CHECK_EQUAL(tolerance.tolerance0, 1.0); - BOOST_CHECK_EQUAL(tolerance.tolerance1, 2.0); - BOOST_CHECK(BoundaryTolerance{tolerance}.toleranceMode() == Extend); - BOOST_CHECK(BoundaryTolerance{BoundaryTolerance::AbsoluteBound(0.0, 0.0)} - .toleranceMode() == None); + BOOST_CHECK_EQUAL(tolerance.asAbsoluteBound().tolerance0, 1.0); + BOOST_CHECK_EQUAL(tolerance.asAbsoluteBound().tolerance1, 2.0); + BOOST_CHECK(tolerance.toleranceMode() == Extend); + BOOST_CHECK(BoundaryTolerance::AbsoluteBound(0.0, 0.0).toleranceMode() == + None); // Negative tolerances should throw BOOST_CHECK_THROW(BoundaryTolerance::AbsoluteBound(-1.0, 2.0), @@ -56,27 +56,26 @@ BOOST_AUTO_TEST_CASE(BoundaryToleranceConstructors) { { // Valid positive tolerance auto tolerance = BoundaryTolerance::AbsoluteEuclidean(1.0); - BOOST_CHECK_EQUAL(tolerance.tolerance, 1.0); - BOOST_CHECK(BoundaryTolerance{tolerance}.toleranceMode() == Extend); - BOOST_CHECK(BoundaryTolerance{BoundaryTolerance::AbsoluteEuclidean(0.0)} - .toleranceMode() == None); + BOOST_CHECK_EQUAL(tolerance.asAbsoluteEuclidean().tolerance, 1.0); + BOOST_CHECK(tolerance.toleranceMode() == Extend); + BOOST_CHECK(BoundaryTolerance::AbsoluteEuclidean(0.0).toleranceMode() == + None); // Valid negative tolerance tolerance = BoundaryTolerance::AbsoluteEuclidean(-1.0); - BOOST_CHECK_EQUAL(tolerance.tolerance, -1.0); - BOOST_CHECK(BoundaryTolerance{tolerance}.toleranceMode() == Shrink); + BOOST_CHECK_EQUAL(tolerance.asAbsoluteEuclidean().tolerance, -1.0); + BOOST_CHECK(tolerance.toleranceMode() == Shrink); } // Test AbsoluteCartesian constructor { // Valid positive tolerance auto tolerance = BoundaryTolerance::AbsoluteCartesian(1.0, 2.0); - BOOST_CHECK_EQUAL(tolerance.tolerance0, 1.0); - BOOST_CHECK_EQUAL(tolerance.tolerance1, 2.0); - BOOST_CHECK(BoundaryTolerance{tolerance}.toleranceMode() == Extend); + BOOST_CHECK_EQUAL(tolerance.asAbsoluteCartesian().tolerance0, 1.0); + BOOST_CHECK_EQUAL(tolerance.asAbsoluteCartesian().tolerance1, 2.0); + BOOST_CHECK(tolerance.toleranceMode() == Extend); BOOST_CHECK( - BoundaryTolerance{BoundaryTolerance::AbsoluteCartesian(0.0, 0.0)} - .toleranceMode() == None); + BoundaryTolerance::AbsoluteCartesian(0.0, 0.0).toleranceMode() == None); // Negative tolerances should throw BOOST_CHECK_THROW(BoundaryTolerance::AbsoluteCartesian(-1.0, 2.0), @@ -92,15 +91,14 @@ BOOST_AUTO_TEST_CASE(BoundaryToleranceConstructors) { // Valid positive chi2 bound auto tolerance = BoundaryTolerance::Chi2Bound(cov, 3.0); - BOOST_CHECK_EQUAL(tolerance.maxChi2, 3.0); - BOOST_CHECK(BoundaryTolerance{tolerance}.toleranceMode() == Extend); - BOOST_CHECK(BoundaryTolerance{BoundaryTolerance::Chi2Bound(cov, 0.0)} - .toleranceMode() == None); + BOOST_CHECK_EQUAL(tolerance.asChi2Bound().maxChi2, 3.0); + BOOST_CHECK(tolerance.toleranceMode() == Extend); + BOOST_CHECK(BoundaryTolerance::Chi2Bound(cov, 0.0).toleranceMode() == None); // Valid negative chi2 bound tolerance = BoundaryTolerance::Chi2Bound(cov, -3.0); - BOOST_CHECK_EQUAL(tolerance.maxChi2, -3.0); - BOOST_CHECK(BoundaryTolerance{tolerance}.toleranceMode() == Shrink); + BOOST_CHECK_EQUAL(tolerance.asChi2Bound().maxChi2, -3.0); + BOOST_CHECK(tolerance.toleranceMode() == Shrink); } // Test None constructor diff --git a/Tests/UnitTests/Core/Surfaces/TrapezoidBoundsTests.cpp b/Tests/UnitTests/Core/Surfaces/TrapezoidBoundsTests.cpp index 52155fec5fe..76ac35d4bd9 100644 --- a/Tests/UnitTests/Core/Surfaces/TrapezoidBoundsTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/TrapezoidBoundsTests.cpp @@ -189,7 +189,7 @@ BOOST_DATA_TEST_CASE( BoundaryTolerance tolerance = BoundaryTolerance::None(); if (tol != 0.) { - tolerance = BoundaryTolerance::AbsoluteBound{tol, tol}; + tolerance = BoundaryTolerance::AbsoluteBound(tol, tol); } BOOST_CHECK_EQUAL(