From ab41e0be41686aa3c176def855a9f2062794d325 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Mon, 5 Feb 2024 14:26:02 +0100 Subject: [PATCH] feat: Closest forward intersection (#2923) Implements closest forward order and renames `forwardOrder` to `pathLengthOrder` --- Core/include/Acts/Utilities/Intersection.hpp | 41 +++++++++++++++---- Core/src/Digitization/PlanarModuleStepper.cpp | 4 +- .../Geometry/GenericApproachDescriptor.cpp | 2 +- Core/src/Geometry/Layer.cpp | 2 +- Core/src/Geometry/TrackingVolume.cpp | 4 +- Fatras/src/Digitization/PlanarSurfaceMask.cpp | 2 +- .../Core/Geometry/BVHDataTestCase.hpp | 2 +- .../Core/Utilities/IntersectionTests.cpp | 16 ++++---- 8 files changed, 49 insertions(+), 24 deletions(-) diff --git a/Core/include/Acts/Utilities/Intersection.hpp b/Core/include/Acts/Utilities/Intersection.hpp index 7d276b3375d..d76c50a78b8 100644 --- a/Core/include/Acts/Utilities/Intersection.hpp +++ b/Core/include/Acts/Utilities/Intersection.hpp @@ -72,10 +72,10 @@ class Intersection { constexpr static Intersection invalid() { return Intersection(); } - /// Comparison function for forward order i.e. intersection closest to -inf - /// will be first. - constexpr static bool forwardOrder(const Intersection& aIntersection, - const Intersection& bIntersection) { + /// Comparison function for path length order i.e. intersection closest to + /// -inf will be first. + constexpr static bool pathLengthOrder(const Intersection& aIntersection, + const Intersection& bIntersection) { auto a = aIntersection.pathLength(); auto b = bIntersection.pathLength(); return a < b; @@ -99,6 +99,16 @@ class Intersection { return std::abs(a) < std::abs(b); } + /// Comparison function for closest forward order i.e. intersection closest to + /// 0 with positive path length will be first. + constexpr static bool closestForwardOrder(const Intersection& aIntersection, + const Intersection& bIntersection) { + auto a = aIntersection.pathLength(); + auto b = bIntersection.pathLength(); + return std::signbit(a) == std::signbit(b) ? std::abs(a) < std::abs(b) + : a > b; + } + private: /// Position of the intersection Position m_position = Position::Zero(); @@ -157,10 +167,11 @@ class ObjectIntersection { constexpr static ObjectIntersection invalid() { return ObjectIntersection(); } - constexpr static bool forwardOrder(const ObjectIntersection& aIntersection, - const ObjectIntersection& bIntersection) { - return Intersection3D::forwardOrder(aIntersection.intersection(), - bIntersection.intersection()); + constexpr static bool pathLengthOrder( + const ObjectIntersection& aIntersection, + const ObjectIntersection& bIntersection) { + return Intersection3D::pathLengthOrder(aIntersection.intersection(), + bIntersection.intersection()); } constexpr static bool closestOrder(const ObjectIntersection& aIntersection, @@ -169,6 +180,13 @@ class ObjectIntersection { bIntersection.intersection()); } + constexpr static bool closestForwardOrder( + const ObjectIntersection& aIntersection, + const ObjectIntersection& bIntersection) { + return Intersection3D::closestForwardOrder(aIntersection.intersection(), + bIntersection.intersection()); + } + private: /// The intersection itself Intersection3D m_intersection = Intersection3D::invalid(); @@ -218,6 +236,13 @@ class ObjectMultiIntersection { ObjectIntersection::closestOrder); } + constexpr ObjectIntersection closestForward() const { + auto splitIntersections = split(); + return *std::min_element(splitIntersections.begin(), + splitIntersections.end(), + ObjectIntersection::closestForwardOrder); + } + private: /// The intersections MultiIntersection3D m_intersections; diff --git a/Core/src/Digitization/PlanarModuleStepper.cpp b/Core/src/Digitization/PlanarModuleStepper.cpp index 696a6dddfa6..514c5119011 100644 --- a/Core/src/Digitization/PlanarModuleStepper.cpp +++ b/Core/src/Digitization/PlanarModuleStepper.cpp @@ -63,7 +63,7 @@ std::vector Acts::PlanarModuleStepper::cellSteps( Intersection3D(endPoint, (startPoint - endPoint).norm(), Intersection3D::Status::reachable)); std::sort(stepIntersections.begin(), stepIntersections.end(), - Intersection3D::forwardOrder); + Intersection3D::pathLengthOrder); Vector3 lastPosition = startPoint; // reserve the right amount @@ -121,7 +121,7 @@ std::vector Acts::PlanarModuleStepper::cellSteps( "More than 2 Boundary Surfaces intersected, this is an edge " "case, resolving ... "); std::sort(boundaryIntersections.begin(), boundaryIntersections.end(), - Intersection3D::forwardOrder); + Intersection3D::pathLengthOrder); } // if for some reason the intersection does not work if (boundaryIntersections.empty()) { diff --git a/Core/src/Geometry/GenericApproachDescriptor.cpp b/Core/src/Geometry/GenericApproachDescriptor.cpp index a6f5eca3ade..b24db6dd3c2 100644 --- a/Core/src/Geometry/GenericApproachDescriptor.cpp +++ b/Core/src/Geometry/GenericApproachDescriptor.cpp @@ -43,7 +43,7 @@ Acts::SurfaceIntersection Acts::GenericApproachDescriptor::approachSurface( return SurfaceIntersection::invalid(); } return *std::min_element(sIntersections.begin(), sIntersections.end(), - SurfaceIntersection::forwardOrder); + SurfaceIntersection::pathLengthOrder); } const std::vector& diff --git a/Core/src/Geometry/Layer.cpp b/Core/src/Geometry/Layer.cpp index 9da0f186edf..deeeaed5677 100644 --- a/Core/src/Geometry/Layer.cpp +++ b/Core/src/Geometry/Layer.cpp @@ -252,7 +252,7 @@ Acts::Layer::compatibleSurfaces( // sort according to the path length std::sort(sIntersections.begin(), sIntersections.end(), - SurfaceIntersection::forwardOrder); + SurfaceIntersection::pathLengthOrder); return sIntersections; } diff --git a/Core/src/Geometry/TrackingVolume.cpp b/Core/src/Geometry/TrackingVolume.cpp index 1fd2187c159..bd20cf8ebeb 100644 --- a/Core/src/Geometry/TrackingVolume.cpp +++ b/Core/src/Geometry/TrackingVolume.cpp @@ -626,7 +626,7 @@ Acts::TrackingVolume::compatibleLayers( } std::sort(lIntersections.begin(), lIntersections.end(), [](const LayerIntersection& a, const LayerIntersection& b) { - return SurfaceIntersection::forwardOrder(a.first, b.first); + return SurfaceIntersection::pathLengthOrder(a.first, b.first); }); } // and return @@ -709,7 +709,7 @@ Acts::TrackingVolume::compatibleSurfacesFromHierarchy( // Sort according to the path length std::sort(sIntersections.begin(), sIntersections.end(), - SurfaceIntersection::forwardOrder); + SurfaceIntersection::pathLengthOrder); return sIntersections; } diff --git a/Fatras/src/Digitization/PlanarSurfaceMask.cpp b/Fatras/src/Digitization/PlanarSurfaceMask.cpp index 0b7d2416ef1..8c1047ca7ea 100644 --- a/Fatras/src/Digitization/PlanarSurfaceMask.cpp +++ b/Fatras/src/Digitization/PlanarSurfaceMask.cpp @@ -58,7 +58,7 @@ Acts::Result maskAndReturn( std::vector& intersections, const ActsFatras::PlanarSurfaceMask::Segment2D& segment, bool firstInside) { std::sort(intersections.begin(), intersections.end(), - Acts::Intersection2D::forwardOrder); + Acts::Intersection2D::pathLengthOrder); if (intersections.size() >= 2) { return ActsFatras::PlanarSurfaceMask::Segment2D{ intersections[0].position(), intersections[1].position()}; diff --git a/Tests/UnitTests/Core/Geometry/BVHDataTestCase.hpp b/Tests/UnitTests/Core/Geometry/BVHDataTestCase.hpp index fcca6493307..59d3186e67f 100644 --- a/Tests/UnitTests/Core/Geometry/BVHDataTestCase.hpp +++ b/Tests/UnitTests/Core/Geometry/BVHDataTestCase.hpp @@ -71,7 +71,7 @@ BOOST_DATA_TEST_CASE( } // sort by path length - std::sort(hits.begin(), hits.end(), SurfaceIntersection::forwardOrder); + std::sort(hits.begin(), hits.end(), SurfaceIntersection::pathLengthOrder); std::vector expHits; expHits.reserve(hits.size()); for (const auto& hit : hits) { diff --git a/Tests/UnitTests/Core/Utilities/IntersectionTests.cpp b/Tests/UnitTests/Core/Utilities/IntersectionTests.cpp index e21c3200e59..7d149307d26 100644 --- a/Tests/UnitTests/Core/Utilities/IntersectionTests.cpp +++ b/Tests/UnitTests/Core/Utilities/IntersectionTests.cpp @@ -52,7 +52,7 @@ BOOST_AUTO_TEST_CASE(IntersectionTest) { // let's sort the tsf intersection, it should give fst std::sort(tsfpIntersections.begin(), tsfpIntersections.end(), - Intersection3D::forwardOrder); + Intersection3D::pathLengthOrder); BOOST_CHECK_EQUAL(fstpIntersections[0].pathLength(), tsfpIntersections[0].pathLength()); BOOST_CHECK_EQUAL(fstpIntersections[1].pathLength(), @@ -67,7 +67,7 @@ BOOST_AUTO_TEST_CASE(IntersectionTest) { // shuffle the intersections std::sort(ntfspIntersections.begin(), ntfspIntersections.end(), - Intersection3D::forwardOrder); + Intersection3D::pathLengthOrder); BOOST_CHECK_EQUAL(fstpIntersections[0].pathLength(), ntfspIntersections[0].pathLength()); BOOST_CHECK_EQUAL(fstpIntersections[1].pathLength(), @@ -76,7 +76,7 @@ BOOST_AUTO_TEST_CASE(IntersectionTest) { ntfspIntersections[2].pathLength()); std::sort(tfnsnpIntersections.begin(), tfnsnpIntersections.end(), - Intersection3D::forwardOrder); + Intersection3D::pathLengthOrder); BOOST_CHECK_EQUAL(fstpIntersections[0].pathLength(), tfnsnpIntersections[0].pathLength()); BOOST_CHECK_EQUAL(fstpIntersections[1].pathLength(), @@ -97,7 +97,7 @@ BOOST_AUTO_TEST_CASE(IntersectionTest) { // this time around, sort the f-s-t-n to match the t-s-f-n std::sort(fstnIntersections.begin(), fstnIntersections.end(), - Intersection3D::forwardOrder); + Intersection3D::pathLengthOrder); BOOST_CHECK_EQUAL(fstnIntersections[0].pathLength(), tsfnIntersections[0].pathLength()); BOOST_CHECK_EQUAL(fstnIntersections[1].pathLength(), @@ -108,7 +108,7 @@ BOOST_AUTO_TEST_CASE(IntersectionTest) { // shuffle negative and positive solutions std::vector pnsolutions = {tIp, sIn, sIp, fIn, tIn, fIp}; std::sort(pnsolutions.begin(), pnsolutions.end(), - Intersection3D::forwardOrder); + Intersection3D::pathLengthOrder); BOOST_CHECK_EQUAL(pnsolutions[0].pathLength(), -3.); BOOST_CHECK_EQUAL(pnsolutions[1].pathLength(), -2.); @@ -122,7 +122,7 @@ BOOST_AUTO_TEST_CASE(IntersectionTest) { std::vector tszfpIntersections = {tIp, sIp, zI, fIp}; std::sort(tszfpIntersections.begin(), tszfpIntersections.end(), - Intersection3D::forwardOrder); + Intersection3D::pathLengthOrder); BOOST_CHECK_EQUAL(tszfpIntersections[0].pathLength(), 0.); BOOST_CHECK_EQUAL(tszfpIntersections[1].pathLength(), 1.); BOOST_CHECK_EQUAL(tszfpIntersections[2].pathLength(), 2.); @@ -132,7 +132,7 @@ BOOST_AUTO_TEST_CASE(IntersectionTest) { std::vector ztfsnIntersections = {zI, tIn, fIn, sIn}; std::sort(tfsznIntersections.begin(), tfsznIntersections.end(), - Intersection3D::forwardOrder); + Intersection3D::pathLengthOrder); BOOST_CHECK_EQUAL(tfsznIntersections[0].pathLength(), -3.); BOOST_CHECK_EQUAL(tfsznIntersections[1].pathLength(), -2.); BOOST_CHECK_EQUAL(tfsznIntersections[2].pathLength(), -1.); @@ -184,7 +184,7 @@ BOOST_AUTO_TEST_CASE(ObjectIntersectionTest) { // This should give 6 different intersections std::set_union(firstSet.begin(), firstSet.end(), secondSet.begin(), secondSet.end(), std::back_inserter(unionSetStd), - PlaneIntersection::forwardOrder); + PlaneIntersection::pathLengthOrder); BOOST_CHECK_EQUAL(unionSetStd.size(), 6u); }