File indexing completed on 2025-11-30 09:22:59
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 }