Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:11:24

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2023-2024 CERN for the benefit of the Acts project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
0008 
0009 #include <boost/test/unit_test.hpp>
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Geometry/GeometryContext.hpp"
0013 #include "Acts/Navigation/NavigationState.hpp"
0014 #include "Acts/Navigation/NavigationStateFillers.hpp"
0015 #include "Acts/Navigation/NavigationStateUpdaters.hpp"
0016 #include "Acts/Utilities/BinningType.hpp"
0017 #include "Acts/Utilities/IAxis.hpp"
0018 #include "Acts/Utilities/detail/AxisFwd.hpp"
0019 
0020 #include <algorithm>
0021 #include <array>
0022 #include <cstddef>
0023 #include <memory>
0024 #include <tuple>
0025 #include <utility>
0026 #include <vector>
0027 
0028 #include "../Surfaces/SurfaceStub.hpp"
0029 
0030 // A test context
0031 Acts::GeometryContext tContext;
0032 
0033 namespace Acts {
0034 
0035 namespace Experimental {
0036 
0037 class Detector;
0038 
0039 /// A detector volume
0040 class DetectorVolume {
0041  public:
0042   const Detector* d = nullptr;
0043   std::vector<const Surface*> sfs = {};
0044   std::vector<const Portal*> prts = {};
0045   const std::vector<const Surface*> surfaces() const { return sfs; }
0046   const std::vector<const Portal*> portals() const { return prts; }
0047   const Detector* detector() const { return d; };
0048 };
0049 
0050 /// A detector
0051 class Detector {
0052  public:
0053   std::vector<const DetectorVolume*> vs = {};
0054   const std::vector<const DetectorVolume*> volumes() const { return vs; }
0055 };
0056 
0057 /// Helper extractors: all surfaces
0058 struct AllPortalsExtractor {
0059   /// Extract the surfaces from the volume
0060   ///
0061   /// @param gctx the geometry contextfor this extraction call
0062   /// @param nState is the navigation state for the extraction
0063   /// @param indices is an ignored index vector
0064   inline static const std::vector<const Portal*> extract(
0065       [[maybe_unused]] const GeometryContext& gctx,
0066       const NavigationState& nState,
0067       [[maybe_unused]] const std::vector<std::size_t>& indices = {}) {
0068     return nState.currentVolume->portals();
0069   }
0070 };
0071 
0072 /// Helper extractors: all surfaces
0073 struct AllSurfacesExtractor {
0074   /// Extract the surfaces from the volume
0075   ///
0076   /// @param gctx the geometry contextfor this extraction call
0077   /// @param nState is the navigation state for the extraction
0078   /// @param indices is an ignored index vector
0079   inline static const std::vector<const Surface*> extract(
0080       [[maybe_unused]] const GeometryContext& gctx,
0081       const NavigationState& nState,
0082       [[maybe_unused]] const std::vector<std::size_t>& indices = {}) {
0083     return nState.currentVolume->surfaces();
0084   }
0085 };
0086 
0087 /// Helper extractors: indexed surfaces
0088 struct IndexedSurfacesExtractor {
0089   /// Extract the surfaces from the volume
0090   ///
0091   /// @param gctx the geometry contextfor this extraction call
0092   /// @param nState is the navigation state for the extraction
0093   /// @param indices are access indices into the surfaces store
0094   inline static const std::vector<const Surface*> extract(
0095       [[maybe_unused]] const GeometryContext& gctx,
0096       const NavigationState& nState, const std::vector<std::size_t>& indices) {
0097     // Get the surface container
0098     const auto& surfaces = nState.currentVolume->surfaces();
0099     // The extracted surfaces
0100     std::vector<const Surface*> eSurfaces;
0101     eSurfaces.reserve(indices.size());
0102     std::for_each(indices.begin(), indices.end(),
0103                   [&](const auto& i) { eSurfaces.push_back(surfaces[i]); });
0104     return eSurfaces;
0105   }
0106 };
0107 
0108 }  // namespace Experimental
0109 
0110 class TestAxis : public IAxis {
0111  public:
0112   TestAxis() = default;
0113 
0114   bool isEquidistant() const final { return true; }
0115 
0116   bool isVariable() const final { return false; }
0117 
0118   detail::AxisBoundaryType getBoundaryType() const final {
0119     return detail::AxisBoundaryType::Closed;
0120   }
0121 
0122   std::vector<ActsScalar> getBinEdges() const final { return {-1, 1}; }
0123 
0124   ActsScalar getMin() const final { return -1.; }
0125 
0126   ActsScalar getMax() const final { return 1.; }
0127 
0128   std::size_t getNBins() const final { return 1; };
0129 };
0130 
0131 class MultiGrid1D {
0132  public:
0133   static constexpr std::size_t DIM = 1u;
0134   using point_t = std::array<ActsScalar, DIM>;
0135 
0136   const std::vector<std::size_t>& atPosition(
0137       const std::array<ActsScalar, 1u>& /*position*/) const {
0138     return e;
0139   }
0140 
0141   std::array<const IAxis*, DIM> axes() const { return {&ta}; }
0142   TestAxis ta = TestAxis();
0143 
0144  private:
0145   std::vector<std::size_t> e = {0u, 1u};
0146 };
0147 
0148 class MultiGrid2D {
0149  public:
0150   static constexpr std::size_t DIM = 2u;
0151   using point_t = std::array<ActsScalar, DIM>;
0152 
0153   const std::vector<std::size_t>& atPosition(
0154       const std::array<ActsScalar, 2u>& /*position*/) const {
0155     return e;
0156   }
0157 
0158   std::array<const IAxis*, DIM> axes() const { return {&ta, &ta}; };
0159   TestAxis ta = TestAxis();
0160 
0161  private:
0162   std::vector<std::size_t> e = {1u};
0163 };
0164 }  // namespace Acts
0165 
0166 using SingleVolumeUpdater = Acts::Experimental::SingleObjectImpl<
0167     Acts::Experimental::DetectorVolume,
0168     Acts::Experimental::DetectorVolumeFiller>;
0169 
0170 using AllSurfacesProvider = Acts::Experimental::StaticUpdaterImpl<
0171     Acts::Experimental::AllSurfacesExtractor,
0172     Acts::Experimental::SurfacesFiller>;
0173 
0174 using AllPortalsProvider = Acts::Experimental::StaticUpdaterImpl<
0175     Acts::Experimental::AllPortalsExtractor, Acts::Experimental::PortalsFiller>;
0176 
0177 auto surfaceA = Acts::Surface::makeShared<Acts::SurfaceStub>();
0178 auto surfaceB = Acts::Surface::makeShared<Acts::SurfaceStub>();
0179 auto surfaceC = Acts::Surface::makeShared<Acts::SurfaceStub>();
0180 
0181 auto pSurfaceA = Acts::Surface::makeShared<Acts::SurfaceStub>();
0182 auto pSurfaceB = Acts::Surface::makeShared<Acts::SurfaceStub>();
0183 auto portalA = std::make_shared<Acts::Experimental::Portal>(pSurfaceA);
0184 auto portalB = std::make_shared<Acts::Experimental::Portal>(pSurfaceB);
0185 
0186 BOOST_AUTO_TEST_SUITE(Experimental)
0187 
0188 BOOST_AUTO_TEST_CASE(SingleDetectorVolumeUpdater) {
0189   Acts::Experimental::NavigationState nState;
0190 
0191   // Create a single object and a single object updator
0192   auto sVolume = std::make_shared<Acts::Experimental::DetectorVolume>();
0193   SingleVolumeUpdater sVolumeUpdater(sVolume.get());
0194 
0195   // Update the volume and check that it is indeed updated
0196   sVolumeUpdater.update(tContext, nState);
0197   BOOST_CHECK_EQUAL(nState.currentVolume, sVolume.get());
0198 }
0199 
0200 BOOST_AUTO_TEST_CASE(AllSurfaces) {
0201   // Create a single object and a single object updator
0202   auto dVolume = std::make_shared<Acts::Experimental::DetectorVolume>();
0203   (*dVolume).sfs = {surfaceA.get(), surfaceB.get(), surfaceC.get()};
0204   (*dVolume).prts = {portalA.get(), portalB.get()};
0205 
0206   Acts::Experimental::NavigationState nState;
0207   nState.currentVolume = dVolume.get();
0208   BOOST_CHECK(nState.surfaceCandidates.empty());
0209   AllSurfacesProvider allSurfaces;
0210   allSurfaces.update(tContext, nState);
0211   BOOST_CHECK_EQUAL(nState.surfaceCandidates.size(), 3u);
0212 }
0213 
0214 BOOST_AUTO_TEST_CASE(AllPortals) {
0215   // Create a single object and a single object updator
0216   auto dVolume = std::make_shared<Acts::Experimental::DetectorVolume>();
0217   (*dVolume).sfs = {surfaceA.get(), surfaceB.get(), surfaceC.get()};
0218   (*dVolume).prts = {portalA.get(), portalB.get()};
0219 
0220   Acts::Experimental::NavigationState nState;
0221   nState.currentVolume = dVolume.get();
0222   BOOST_CHECK(nState.surfaceCandidates.empty());
0223   AllPortalsProvider allPortals;
0224   allPortals.update(tContext, nState);
0225   BOOST_CHECK_EQUAL(nState.surfaceCandidates.size(), 2u);
0226 }
0227 
0228 BOOST_AUTO_TEST_CASE(AllPortalsAllSurfaces) {
0229   // Create a single object and a single object updator
0230   auto dVolume = std::make_shared<Acts::Experimental::DetectorVolume>();
0231   (*dVolume).sfs = {surfaceA.get(), surfaceB.get(), surfaceC.get()};
0232   (*dVolume).prts = {portalA.get(), portalB.get()};
0233 
0234   Acts::Experimental::NavigationState nState;
0235   nState.currentVolume = dVolume.get();
0236   BOOST_CHECK(nState.surfaceCandidates.empty());
0237 
0238   AllPortalsProvider allPortals;
0239   AllSurfacesProvider allSurfaces;
0240   auto allPortalsAllSurfaces =
0241       Acts::Experimental::ChainedUpdaterImpl<AllPortalsProvider,
0242                                              AllSurfacesProvider>(
0243           std::tie(allPortals, allSurfaces));
0244 
0245   allPortalsAllSurfaces.update(tContext, nState);
0246   BOOST_CHECK_EQUAL(nState.surfaceCandidates.size(), 5u);
0247 }
0248 
0249 BOOST_AUTO_TEST_CASE(AllPortalsGrid1DSurfaces) {
0250   // Create a single object and a single object updator
0251   auto dVolume = std::make_shared<Acts::Experimental::DetectorVolume>();
0252   (*dVolume).sfs = {surfaceA.get(), surfaceB.get(), surfaceC.get()};
0253   (*dVolume).prts = {portalA.get(), portalB.get()};
0254 
0255   Acts::Experimental::NavigationState nState;
0256   nState.currentVolume = dVolume.get();
0257   BOOST_CHECK(nState.surfaceCandidates.empty());
0258 
0259   AllPortalsProvider allPortals;
0260   Acts::MultiGrid1D grid;
0261   using Grid1DSurfacesProvider = Acts::Experimental::IndexedUpdaterImpl<
0262       decltype(grid), Acts::Experimental::IndexedSurfacesExtractor,
0263       Acts::Experimental::SurfacesFiller>;
0264   auto grid1DSurfaces = Grid1DSurfacesProvider(std::move(grid), {Acts::binR});
0265 
0266   auto allPortalsGrid1DSurfaces =
0267       Acts::Experimental::ChainedUpdaterImpl<AllPortalsProvider,
0268                                              Grid1DSurfacesProvider>(
0269           std::tie(allPortals, grid1DSurfaces));
0270 
0271   allPortalsGrid1DSurfaces.update(tContext, nState);
0272   BOOST_CHECK_EQUAL(nState.surfaceCandidates.size(), 4u);
0273 }
0274 
0275 BOOST_AUTO_TEST_CASE(AllPortalsGrid2DSurfaces) {
0276   // Create a single object and a single object updator
0277   auto dVolume = std::make_shared<Acts::Experimental::DetectorVolume>();
0278   (*dVolume).sfs = {surfaceA.get(), surfaceB.get(), surfaceC.get()};
0279   (*dVolume).prts = {portalA.get(), portalB.get()};
0280 
0281   Acts::Experimental::NavigationState nState;
0282   nState.currentVolume = dVolume.get();
0283   BOOST_CHECK(nState.surfaceCandidates.empty());
0284 
0285   AllPortalsProvider allPortals;
0286   Acts::MultiGrid2D grid;
0287   using Grid2DSurfacesProvider = Acts::Experimental::IndexedUpdaterImpl<
0288       decltype(grid), Acts::Experimental::IndexedSurfacesExtractor,
0289       Acts::Experimental::SurfacesFiller>;
0290   auto grid2DSurfaces =
0291       Grid2DSurfacesProvider(std::move(grid), {Acts::binR, Acts::binZ});
0292 
0293   auto allPortalsGrid2DSurfaces =
0294       Acts::Experimental::ChainedUpdaterImpl<AllPortalsProvider,
0295                                              Grid2DSurfacesProvider>(
0296           std::tie(allPortals, grid2DSurfaces));
0297 
0298   allPortalsGrid2DSurfaces.update(tContext, nState);
0299   BOOST_CHECK_EQUAL(nState.surfaceCandidates.size(), 3u);
0300 }
0301 
0302 BOOST_AUTO_TEST_SUITE_END()