File indexing completed on 2025-10-31 08:18:00
0001 
0002 
0003 
0004 
0005 
0006 
0007 
0008 
0009 #include <boost/test/unit_test.hpp>
0010 
0011 #include "Acts/Geometry/GeometryContext.hpp"
0012 #include "Acts/Navigation/NavigationState.hpp"
0013 #include "Acts/Navigation/NavigationStateFillers.hpp"
0014 #include "Acts/Navigation/NavigationStateUpdaters.hpp"
0015 #include "Acts/Utilities/AxisDefinitions.hpp"
0016 #include "Acts/Utilities/IAxis.hpp"
0017 
0018 #include <algorithm>
0019 #include <array>
0020 #include <cstddef>
0021 #include <memory>
0022 #include <tuple>
0023 #include <utility>
0024 #include <vector>
0025 
0026 #include "../Surfaces/SurfaceStub.hpp"
0027 
0028 
0029 Acts::GeometryContext tContext;
0030 
0031 namespace Acts {
0032 
0033 namespace Experimental {
0034 
0035 class Detector;
0036 
0037 
0038 class DetectorVolume {
0039  public:
0040   const Detector* d = nullptr;
0041   std::vector<const Surface*> sfs = {};
0042   std::vector<const Portal*> prts = {};
0043   const std::vector<const Surface*> surfaces() const { return sfs; }
0044   const std::vector<const Portal*> portals() const { return prts; }
0045   const Detector* detector() const { return d; };
0046 };
0047 
0048 
0049 class Detector {
0050  public:
0051   std::vector<const DetectorVolume*> vs = {};
0052   const std::vector<const DetectorVolume*> volumes() const { return vs; }
0053 };
0054 
0055 
0056 struct AllPortalsExtractor {
0057   
0058   
0059   
0060   
0061   
0062   inline static const std::vector<const Portal*> extract(
0063       [[maybe_unused]] const GeometryContext& gctx,
0064       const NavigationState& nState,
0065       [[maybe_unused]] const std::vector<std::size_t>& indices = {}) {
0066     return nState.currentVolume->portals();
0067   }
0068 };
0069 
0070 
0071 struct AllSurfacesExtractor {
0072   
0073   
0074   
0075   
0076   
0077   inline static const std::vector<const Surface*> extract(
0078       [[maybe_unused]] const GeometryContext& gctx,
0079       const NavigationState& nState,
0080       [[maybe_unused]] const std::vector<std::size_t>& indices = {}) {
0081     return nState.currentVolume->surfaces();
0082   }
0083 };
0084 
0085 
0086 struct IndexedSurfacesExtractor {
0087   
0088   
0089   
0090   
0091   
0092   inline static const std::vector<const Surface*> extract(
0093       [[maybe_unused]] const GeometryContext& gctx,
0094       const NavigationState& nState, const std::vector<std::size_t>& indices) {
0095     
0096     const auto& surfaces = nState.currentVolume->surfaces();
0097     
0098     std::vector<const Surface*> eSurfaces;
0099     eSurfaces.reserve(indices.size());
0100     std::ranges::for_each(
0101         indices, [&](const auto& i) { eSurfaces.push_back(surfaces[i]); });
0102     return eSurfaces;
0103   }
0104 };
0105 
0106 }  
0107 
0108 class TestAxis : public IAxis {
0109  public:
0110   TestAxis() = default;
0111 
0112   bool isEquidistant() const final { return true; }
0113 
0114   bool isVariable() const final { return false; }
0115 
0116   AxisType getType() const final { return AxisType::Equidistant; }
0117 
0118   AxisBoundaryType getBoundaryType() const final {
0119     return AxisBoundaryType::Closed;
0120   }
0121 
0122   std::vector<double> getBinEdges() const final { return {-1, 1}; }
0123 
0124   double getMin() const final { return -1.; }
0125 
0126   double getMax() const final { return 1.; }
0127 
0128   std::size_t getNBins() const final { return 1; };
0129 
0130   void toStream(std::ostream& os) const final { os << "TextAxis"; }
0131 };
0132 
0133 class MultiGrid1D {
0134  public:
0135   static constexpr std::size_t DIM = 1u;
0136   using point_t = std::array<double, DIM>;
0137 
0138   const std::vector<std::size_t>& atPosition(
0139       const std::array<double, 1u>& ) const {
0140     return e;
0141   }
0142 
0143   std::array<const IAxis*, DIM> axes() const { return {&ta}; }
0144   TestAxis ta = TestAxis();
0145 
0146  private:
0147   std::vector<std::size_t> e = {0u, 1u};
0148 };
0149 
0150 class MultiGrid2D {
0151  public:
0152   static constexpr std::size_t DIM = 2u;
0153   using point_t = std::array<double, DIM>;
0154 
0155   const std::vector<std::size_t>& atPosition(
0156       const std::array<double, 2u>& ) const {
0157     return e;
0158   }
0159 
0160   std::array<const IAxis*, DIM> axes() const { return {&ta, &ta}; };
0161   TestAxis ta = TestAxis();
0162 
0163  private:
0164   std::vector<std::size_t> e = {1u};
0165 };
0166 }  
0167 
0168 using namespace Acts;
0169 
0170 namespace ActsTests {
0171 
0172 using SingleVolumeUpdater =
0173     Experimental::SingleObjectNavigation<Experimental::IExternalNavigation,
0174                                          Experimental::DetectorVolume,
0175                                          Experimental::DetectorVolumeFiller>;
0176 
0177 using AllSurfacesProvider =
0178     Experimental::StaticAccessNavigation<Experimental::IInternalNavigation,
0179                                          Experimental::AllSurfacesExtractor,
0180                                          Experimental::SurfacesFiller>;
0181 
0182 using AllPortalsProvider =
0183     Experimental::StaticAccessNavigation<Experimental::IInternalNavigation,
0184                                          Experimental::AllPortalsExtractor,
0185                                          Experimental::PortalsFiller>;
0186 
0187 auto surfaceA = Surface::makeShared<SurfaceStub>();
0188 auto surfaceB = Surface::makeShared<SurfaceStub>();
0189 auto surfaceC = Surface::makeShared<SurfaceStub>();
0190 
0191 auto pSurfaceA = Surface::makeShared<SurfaceStub>();
0192 auto pSurfaceB = Surface::makeShared<SurfaceStub>();
0193 auto portalA = std::make_shared<Experimental::Portal>(pSurfaceA);
0194 auto portalB = std::make_shared<Experimental::Portal>(pSurfaceB);
0195 
0196 BOOST_AUTO_TEST_SUITE(NavigationSuite)
0197 
0198 BOOST_AUTO_TEST_CASE(SingleExternalNavigationDelegate) {
0199   Experimental::NavigationState nState;
0200 
0201   
0202   auto sVolume = std::make_shared<Experimental::DetectorVolume>();
0203   SingleVolumeUpdater sVolumeUpdater(sVolume.get());
0204 
0205   
0206   sVolumeUpdater.update(tContext, nState);
0207   BOOST_CHECK_EQUAL(nState.currentVolume, sVolume.get());
0208 }
0209 
0210 BOOST_AUTO_TEST_CASE(AllSurfaces) {
0211   
0212   auto dVolume = std::make_shared<Experimental::DetectorVolume>();
0213   (*dVolume).sfs = {surfaceA.get(), surfaceB.get(), surfaceC.get()};
0214   (*dVolume).prts = {portalA.get(), portalB.get()};
0215 
0216   Experimental::NavigationState nState;
0217   nState.currentVolume = dVolume.get();
0218   BOOST_CHECK(nState.surfaceCandidates.empty());
0219   AllSurfacesProvider allSurfaces;
0220   allSurfaces.update(tContext, nState);
0221   BOOST_CHECK_EQUAL(nState.surfaceCandidates.size(), 3u);
0222 }
0223 
0224 BOOST_AUTO_TEST_CASE(AllPortals) {
0225   
0226   auto dVolume = std::make_shared<Experimental::DetectorVolume>();
0227   (*dVolume).sfs = {surfaceA.get(), surfaceB.get(), surfaceC.get()};
0228   (*dVolume).prts = {portalA.get(), portalB.get()};
0229 
0230   Experimental::NavigationState nState;
0231   nState.currentVolume = dVolume.get();
0232   BOOST_CHECK(nState.surfaceCandidates.empty());
0233   AllPortalsProvider allPortals;
0234   allPortals.update(tContext, nState);
0235   BOOST_CHECK_EQUAL(nState.surfaceCandidates.size(), 2u);
0236 }
0237 
0238 BOOST_AUTO_TEST_CASE(AllPortalsAllSurfaces) {
0239   
0240   auto dVolume = std::make_shared<Experimental::DetectorVolume>();
0241   (*dVolume).sfs = {surfaceA.get(), surfaceB.get(), surfaceC.get()};
0242   (*dVolume).prts = {portalA.get(), portalB.get()};
0243 
0244   Experimental::NavigationState nState;
0245   nState.currentVolume = dVolume.get();
0246   BOOST_CHECK(nState.surfaceCandidates.empty());
0247 
0248   AllPortalsProvider allPortals;
0249   AllSurfacesProvider allSurfaces;
0250   auto allPortalsAllSurfaces =
0251       Experimental::ChainedNavigation<Experimental::IInternalNavigation,
0252                                       AllPortalsProvider, AllSurfacesProvider>(
0253           std::tie(allPortals, allSurfaces));
0254 
0255   allPortalsAllSurfaces.update(tContext, nState);
0256   BOOST_CHECK_EQUAL(nState.surfaceCandidates.size(), 5u);
0257 }
0258 
0259 BOOST_AUTO_TEST_CASE(AllPortalsGrid1DSurfaces) {
0260   
0261   auto dVolume = std::make_shared<Experimental::DetectorVolume>();
0262   (*dVolume).sfs = {surfaceA.get(), surfaceB.get(), surfaceC.get()};
0263   (*dVolume).prts = {portalA.get(), portalB.get()};
0264 
0265   Experimental::NavigationState nState;
0266   nState.currentVolume = dVolume.get();
0267   BOOST_CHECK(nState.surfaceCandidates.empty());
0268 
0269   AllPortalsProvider allPortals;
0270   MultiGrid1D grid;
0271   using Grid1DSurfacesProvider = Experimental::IndexedGridNavigation<
0272       Experimental::IInternalNavigation, decltype(grid),
0273       Experimental::IndexedSurfacesExtractor, Experimental::SurfacesFiller>;
0274   auto grid1DSurfaces =
0275       Grid1DSurfacesProvider(std::move(grid), {AxisDirection::AxisR});
0276 
0277   auto allPortalsGrid1DSurfaces =
0278       Experimental::ChainedNavigation<Experimental::IInternalNavigation,
0279                                       AllPortalsProvider,
0280                                       Grid1DSurfacesProvider>(
0281           std::tie(allPortals, grid1DSurfaces));
0282 
0283   allPortalsGrid1DSurfaces.update(tContext, nState);
0284   BOOST_CHECK_EQUAL(nState.surfaceCandidates.size(), 4u);
0285 }
0286 
0287 BOOST_AUTO_TEST_CASE(AllPortalsGrid2DSurfaces) {
0288   
0289   auto dVolume = std::make_shared<Experimental::DetectorVolume>();
0290   (*dVolume).sfs = {surfaceA.get(), surfaceB.get(), surfaceC.get()};
0291   (*dVolume).prts = {portalA.get(), portalB.get()};
0292 
0293   Experimental::NavigationState nState;
0294   nState.currentVolume = dVolume.get();
0295   BOOST_CHECK(nState.surfaceCandidates.empty());
0296 
0297   AllPortalsProvider allPortals;
0298   MultiGrid2D grid;
0299   using Grid2DSurfacesProvider = Experimental::IndexedGridNavigation<
0300       Experimental::IInternalNavigation, decltype(grid),
0301       Experimental::IndexedSurfacesExtractor, Experimental::SurfacesFiller>;
0302   auto grid2DSurfaces = Grid2DSurfacesProvider(
0303       std::move(grid), {AxisDirection::AxisR, AxisDirection::AxisZ});
0304 
0305   auto allPortalsGrid2DSurfaces =
0306       Experimental::ChainedNavigation<Experimental::IInternalNavigation,
0307                                       AllPortalsProvider,
0308                                       Grid2DSurfacesProvider>(
0309           std::tie(allPortals, grid2DSurfaces));
0310 
0311   allPortalsGrid2DSurfaces.update(tContext, nState);
0312   BOOST_CHECK_EQUAL(nState.surfaceCandidates.size(), 3u);
0313 }
0314 
0315 BOOST_AUTO_TEST_SUITE_END()
0316 
0317 }