File indexing completed on 2025-08-06 08:11:24
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Direction.hpp"
0013 #include "Acts/Definitions/Units.hpp"
0014 #include "Acts/Detector/Detector.hpp"
0015 #include "Acts/Detector/DetectorVolume.hpp"
0016 #include "Acts/Detector/GeometryIdGenerator.hpp"
0017 #include "Acts/Detector/PortalGenerators.hpp"
0018 #include "Acts/Detector/detail/CuboidalDetectorHelper.hpp"
0019 #include "Acts/EventData/TrackParameters.hpp"
0020 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
0021 #include "Acts/Geometry/GeometryContext.hpp"
0022 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0023 #include "Acts/Navigation/DetectorNavigator.hpp"
0024 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
0025 #include "Acts/Navigation/SurfaceCandidatesUpdaters.hpp"
0026 #include "Acts/Propagator/AbortList.hpp"
0027 #include "Acts/Propagator/ActionList.hpp"
0028 #include "Acts/Propagator/Propagator.hpp"
0029 #include "Acts/Propagator/StraightLineStepper.hpp"
0030 #include "Acts/Surfaces/CylinderSurface.hpp"
0031 #include "Acts/Surfaces/PlaneSurface.hpp"
0032 #include "Acts/Surfaces/RectangleBounds.hpp"
0033 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0034 #include "Acts/Utilities/Logger.hpp"
0035
0036 using namespace Acts::UnitLiterals;
0037
0038 namespace Acts {
0039 class Surface;
0040 }
0041
0042 Acts::GeometryContext geoContext;
0043 Acts::MagneticFieldContext mfContext;
0044
0045
0046 struct StateRecorder {
0047 using result_type = std::vector<Acts::Experimental::DetectorNavigator::State>;
0048
0049 template <typename propagator_state_t, typename stepper_t,
0050 typename navigator_t>
0051 void operator()(propagator_state_t& state, const stepper_t& ,
0052 const navigator_t& , result_type& result,
0053 const Acts::Logger& ) const {
0054 result.push_back(state.navigation);
0055 }
0056 };
0057
0058 BOOST_AUTO_TEST_SUITE(DetectorNavigator)
0059
0060
0061 BOOST_AUTO_TEST_CASE(DetectorNavigatorTestsInitialization) {
0062 auto bounds = std::make_unique<Acts::CuboidVolumeBounds>(3, 3, 3);
0063 auto volume = Acts::Experimental::DetectorVolumeFactory::construct(
0064 Acts::Experimental::defaultPortalAndSubPortalGenerator(), geoContext,
0065 "volume", Acts::Transform3::Identity(), std::move(bounds), {}, {},
0066 Acts::Experimental::tryNoVolumes(),
0067 Acts::Experimental::tryAllPortalsAndSurfaces());
0068 volume->assignGeometryId(1);
0069 auto detector = Acts::Experimental::Detector::makeShared(
0070 "detector", {volume}, Acts::Experimental::tryRootVolumes());
0071
0072 using ActionList = Acts::ActionList<>;
0073 using AbortList = Acts::AbortList<>;
0074
0075 auto options =
0076 Acts::PropagatorOptions<ActionList, AbortList>(geoContext, mfContext);
0077
0078 auto stepper = Acts::StraightLineStepper();
0079
0080 Acts::Vector4 pos(-2, 0, 0, 0);
0081 auto start = Acts::CurvilinearTrackParameters(
0082 pos, 0_degree, 90_degree, 1_e / 1_GeV, std::nullopt,
0083 Acts::ParticleHypothesis::electron());
0084
0085
0086
0087
0088
0089 {
0090 Acts::Experimental::DetectorNavigator::Config navCfg;
0091 navCfg.resolveSensitive = false;
0092 navCfg.resolveMaterial = false;
0093 navCfg.resolvePassive = false;
0094
0095 auto navigator = Acts::Experimental::DetectorNavigator(navCfg);
0096
0097 auto propagator = Acts::Propagator<Acts::StraightLineStepper,
0098 Acts::Experimental::DetectorNavigator>(
0099 stepper, navigator);
0100
0101 auto state = propagator.makeState(start, options);
0102
0103 BOOST_CHECK_THROW(navigator.initialize(state, stepper),
0104 std::invalid_argument);
0105
0106 navigator.preStep(state, stepper);
0107 auto preStepState = state.navigation;
0108 BOOST_CHECK_EQUAL(preStepState.currentDetector, nullptr);
0109 BOOST_CHECK_EQUAL(preStepState.currentVolume, nullptr);
0110 BOOST_CHECK_EQUAL(preStepState.currentSurface, nullptr);
0111 BOOST_CHECK_EQUAL(preStepState.currentPortal, nullptr);
0112 BOOST_CHECK(preStepState.surfaceCandidates.empty());
0113
0114 navigator.postStep(state, stepper);
0115 auto postStepState = state.navigation;
0116 BOOST_CHECK_EQUAL(postStepState.currentDetector, nullptr);
0117 BOOST_CHECK_EQUAL(postStepState.currentVolume, nullptr);
0118 BOOST_CHECK_EQUAL(postStepState.currentSurface, nullptr);
0119 BOOST_CHECK_EQUAL(postStepState.currentPortal, nullptr);
0120 BOOST_CHECK(postStepState.surfaceCandidates.empty());
0121 }
0122
0123
0124 {
0125 Acts::Experimental::DetectorNavigator::Config navCfg;
0126 navCfg.resolveSensitive = false;
0127 navCfg.resolveMaterial = false;
0128 navCfg.resolvePassive = false;
0129 navCfg.detector = detector.get();
0130
0131 auto navigator = Acts::Experimental::DetectorNavigator(navCfg);
0132
0133 auto propagator = Acts::Propagator<Acts::StraightLineStepper,
0134 Acts::Experimental::DetectorNavigator>(
0135 stepper, navigator);
0136
0137 auto state = propagator.makeState(start, options);
0138
0139 navigator.initialize(state, stepper);
0140
0141 navigator.preStep(state, stepper);
0142 auto preStepState = state.navigation;
0143 BOOST_CHECK_EQUAL(preStepState.currentSurface, nullptr);
0144 BOOST_CHECK_EQUAL(preStepState.currentPortal, nullptr);
0145
0146 navigator.postStep(state, stepper);
0147 auto postStepState = state.navigation;
0148 BOOST_CHECK_EQUAL(postStepState.currentSurface, nullptr);
0149 BOOST_CHECK_EQUAL(postStepState.currentPortal, nullptr);
0150 }
0151
0152
0153
0154
0155
0156 {
0157 Acts::Vector4 posEoW(-20, 0, 0, 0);
0158 auto startEoW = Acts::CurvilinearTrackParameters(
0159 posEoW, 0_degree, 90_degree, 1_e / 1_GeV, std::nullopt,
0160 Acts::ParticleHypothesis::electron());
0161
0162 Acts::Experimental::DetectorNavigator::Config navCfg;
0163 navCfg.detector = detector.get();
0164
0165 auto navigator = Acts::Experimental::DetectorNavigator(navCfg);
0166
0167 auto propagator = Acts::Propagator<Acts::StraightLineStepper,
0168 Acts::Experimental::DetectorNavigator>(
0169 stepper, navigator);
0170
0171 auto state = propagator.makeState(startEoW, options);
0172
0173 BOOST_CHECK(navigator.endOfWorldReached(state.navigation));
0174
0175 BOOST_CHECK_THROW(navigator.initialize(state, stepper),
0176 std::invalid_argument);
0177 auto initState = state.navigation;
0178 BOOST_CHECK_EQUAL(initState.currentVolume, nullptr);
0179 BOOST_CHECK_EQUAL(initState.currentSurface, nullptr);
0180 BOOST_CHECK_EQUAL(initState.currentPortal, nullptr);
0181 BOOST_CHECK(initState.surfaceCandidates.empty());
0182
0183 navigator.preStep(state, stepper);
0184 auto preStepState = state.navigation;
0185 BOOST_CHECK_EQUAL(preStepState.currentVolume, nullptr);
0186 BOOST_CHECK_EQUAL(preStepState.currentSurface, nullptr);
0187 BOOST_CHECK_EQUAL(preStepState.currentPortal, nullptr);
0188 BOOST_CHECK(preStepState.surfaceCandidates.empty());
0189
0190 navigator.postStep(state, stepper);
0191 auto postStepState = state.navigation;
0192 BOOST_CHECK_EQUAL(postStepState.currentVolume, nullptr);
0193 BOOST_CHECK_EQUAL(postStepState.currentSurface, nullptr);
0194 BOOST_CHECK_EQUAL(postStepState.currentPortal, nullptr);
0195 BOOST_CHECK(postStepState.surfaceCandidates.empty());
0196 }
0197
0198
0199 {
0200 Acts::Experimental::DetectorNavigator::Config navCfg;
0201 navCfg.detector = detector.get();
0202
0203 auto navigator = Acts::Experimental::DetectorNavigator(navCfg);
0204
0205 auto propagator = Acts::Propagator<Acts::StraightLineStepper,
0206 Acts::Experimental::DetectorNavigator>(
0207 stepper, navigator);
0208
0209 auto state = propagator.makeState(start, options);
0210
0211 navigator.initialize(state, stepper);
0212 auto initState = state.navigation;
0213 BOOST_CHECK_EQUAL(initState.currentDetector, detector.get());
0214 BOOST_CHECK_EQUAL(
0215 initState.currentVolume,
0216 detector->findDetectorVolume(geoContext, start.position()));
0217 BOOST_CHECK_EQUAL(initState.currentSurface, nullptr);
0218 BOOST_CHECK_EQUAL(initState.currentPortal, nullptr);
0219 BOOST_CHECK_EQUAL(initState.surfaceCandidates.size(), 1);
0220 }
0221 }
0222
0223
0224
0225
0226 BOOST_AUTO_TEST_CASE(DetectorNavigatorTestsForwardBackward) {
0227
0228 Acts::RotationMatrix3 rotation;
0229 double angle = 90_degree;
0230 Acts::Vector3 xPos(cos(angle), 0., sin(angle));
0231 Acts::Vector3 yPos(0., 1., 0.);
0232 Acts::Vector3 zPos(-sin(angle), 0., cos(angle));
0233 rotation.col(0) = xPos;
0234 rotation.col(1) = yPos;
0235 rotation.col(2) = zPos;
0236
0237 auto bounds1 = std::make_unique<Acts::CuboidVolumeBounds>(3, 3, 3);
0238 auto transform1 = Acts::Transform3::Identity();
0239 auto surface1 = Acts::Surface::makeShared<Acts::PlaneSurface>(
0240 transform1 * Acts::Transform3(rotation),
0241 std::make_shared<Acts::RectangleBounds>(2, 2));
0242 auto volume1 = Acts::Experimental::DetectorVolumeFactory::construct(
0243 Acts::Experimental::defaultPortalAndSubPortalGenerator(), geoContext,
0244 "volume1", transform1, std::move(bounds1), {surface1}, {},
0245 Acts::Experimental::tryNoVolumes(),
0246 Acts::Experimental::tryAllPortalsAndSurfaces());
0247
0248 auto bounds2 = std::make_unique<Acts::CuboidVolumeBounds>(3, 3, 3);
0249 auto transform2 =
0250 Acts::Transform3::Identity() * Acts::Translation3(Acts::Vector3(6, 0, 0));
0251 auto surface2 = Acts::Surface::makeShared<Acts::PlaneSurface>(
0252 transform2 * Acts::Transform3(rotation),
0253 std::make_shared<Acts::RectangleBounds>(2, 2));
0254 auto volume2 = Acts::Experimental::DetectorVolumeFactory::construct(
0255 Acts::Experimental::defaultPortalAndSubPortalGenerator(), geoContext,
0256 "volume2", transform2, std::move(bounds2), {surface2}, {},
0257 Acts::Experimental::tryNoVolumes(),
0258 Acts::Experimental::tryAllPortalsAndSurfaces());
0259
0260 auto bounds3 = std::make_unique<Acts::CuboidVolumeBounds>(3, 3, 3);
0261 auto transform3 = Acts::Transform3::Identity() *
0262 Acts::Translation3(Acts::Vector3(12, 0, 0));
0263 auto surface3 = Acts::Surface::makeShared<Acts::PlaneSurface>(
0264 transform3 * Acts::Transform3(rotation),
0265 std::make_shared<Acts::RectangleBounds>(2, 2));
0266 auto volume3 = Acts::Experimental::DetectorVolumeFactory::construct(
0267 Acts::Experimental::defaultPortalAndSubPortalGenerator(), geoContext,
0268 "volume3", transform3, std::move(bounds3), {surface3}, {},
0269 Acts::Experimental::tryNoVolumes(),
0270 Acts::Experimental::tryAllPortalsAndSurfaces());
0271
0272 std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>>
0273 detectorVolumes = {volume1, volume2, volume3};
0274
0275 auto portalContainer =
0276 Acts::Experimental::detail::CuboidalDetectorHelper::connect(
0277 geoContext, detectorVolumes, Acts::BinningValue::binX, {},
0278 Acts::Logging::VERBOSE);
0279
0280
0281
0282
0283 int id = 1;
0284
0285
0286 for (auto& volume : detectorVolumes) {
0287 volume->assignGeometryId(id);
0288 id++;
0289 }
0290
0291 for (auto& volume : detectorVolumes) {
0292 for (auto& port : volume->portalPtrs()) {
0293 if (port->surface().geometryId() == 0) {
0294 port->surface().assignGeometryId(id);
0295 id++;
0296 }
0297 }
0298 }
0299
0300 for (auto& surf : {surface1, surface2, surface3}) {
0301 surf->assignGeometryId(id);
0302 id++;
0303 }
0304
0305 auto detector = Acts::Experimental::Detector::makeShared(
0306 "cubicDetector", detectorVolumes, Acts::Experimental::tryRootVolumes());
0307
0308 using ActionList = Acts::ActionList<StateRecorder>;
0309 using AbortList = Acts::AbortList<Acts::EndOfWorldReached>;
0310
0311 Acts::Experimental::DetectorNavigator::Config navCfg;
0312 navCfg.detector = detector.get();
0313
0314 auto stepper = Acts::StraightLineStepper();
0315
0316 auto navigator = Acts::Experimental::DetectorNavigator(
0317 navCfg, Acts::getDefaultLogger("DetectorNavigator",
0318 Acts::Logging::Level::VERBOSE));
0319
0320 auto options =
0321 Acts::PropagatorOptions<ActionList, AbortList>(geoContext, mfContext);
0322 options.direction = Acts::Direction::Forward;
0323
0324 auto propagator = Acts::Propagator<Acts::StraightLineStepper,
0325 Acts::Experimental::DetectorNavigator>(
0326 stepper, navigator,
0327 Acts::getDefaultLogger("Propagator", Acts::Logging::Level::VERBOSE));
0328
0329
0330
0331 Acts::Vector4 posFwd(-2, 0, 0, 0);
0332 auto startFwd = Acts::CurvilinearTrackParameters(
0333 posFwd, 0_degree, 90_degree, 1_e / 1_GeV, std::nullopt,
0334 Acts::ParticleHypothesis::electron());
0335
0336 auto resultFwd = propagator.propagate(startFwd, options).value();
0337 auto statesFwd = resultFwd.get<StateRecorder::result_type>();
0338
0339 options.direction = Acts::Direction::Backward;
0340
0341 Acts::Vector4 posBwd(14, 0, 0, 0);
0342 auto startBwd = Acts::CurvilinearTrackParameters(
0343 posBwd, 0_degree, 90_degree, 1_e / 1_GeV, std::nullopt,
0344 Acts::ParticleHypothesis::electron());
0345
0346 auto resultBwd = propagator.propagate(startBwd, options).value();
0347 auto statesBwd = resultBwd.get<StateRecorder::result_type>();
0348
0349
0350
0351
0352 BOOST_CHECK_EQUAL(statesFwd.size(), 9u);
0353 BOOST_CHECK_EQUAL(statesFwd.size(), statesBwd.size());
0354 BOOST_CHECK_EQUAL(statesFwd[0].surfaceCandidates.size(), 2u);
0355 BOOST_CHECK_EQUAL(statesBwd[0].surfaceCandidates.size(), 2u);
0356
0357
0358
0359 BOOST_CHECK_EQUAL(statesFwd[0].currentVolume->geometryId(), 1);
0360 BOOST_CHECK_EQUAL(statesFwd[0].currentSurface, nullptr);
0361 BOOST_CHECK_EQUAL(statesFwd[0].currentPortal, nullptr);
0362
0363
0364 BOOST_CHECK_EQUAL(statesFwd[1].currentVolume->geometryId(), 1);
0365 BOOST_CHECK_EQUAL(statesFwd[1].currentSurface->geometryId(), 12);
0366 BOOST_CHECK_EQUAL(statesFwd[1].currentPortal, nullptr);
0367
0368
0369 BOOST_CHECK_EQUAL(statesFwd[2].currentVolume->geometryId(), 1);
0370 BOOST_CHECK_EQUAL(statesFwd[2].currentSurface, nullptr);
0371 BOOST_CHECK_EQUAL(statesFwd[2].currentPortal->surface().geometryId(), 7);
0372
0373
0374 BOOST_CHECK_EQUAL(statesFwd[3].currentVolume->geometryId(), 2);
0375 BOOST_CHECK_EQUAL(statesFwd[3].currentSurface->geometryId(), 13);
0376 BOOST_CHECK_EQUAL(statesFwd[3].currentPortal, nullptr);
0377
0378
0379 BOOST_CHECK_EQUAL(statesFwd[4].currentVolume->geometryId(), 2);
0380 BOOST_CHECK_EQUAL(statesFwd[4].currentSurface, nullptr);
0381 BOOST_CHECK_EQUAL(statesFwd[4].currentPortal->surface().geometryId(), 10);
0382
0383
0384 BOOST_CHECK_EQUAL(statesFwd[5].currentVolume->geometryId(), 3);
0385 BOOST_CHECK_EQUAL(statesFwd[5].currentSurface->geometryId(), 14);
0386 BOOST_CHECK_EQUAL(statesFwd[5].currentPortal, nullptr);
0387
0388
0389 BOOST_CHECK_EQUAL(statesFwd[6].currentVolume->geometryId(), 3);
0390 BOOST_CHECK_EQUAL(statesFwd[6].currentSurface, nullptr);
0391 BOOST_CHECK_EQUAL(statesFwd[6].currentPortal->surface().geometryId(), 11);
0392
0393
0394 BOOST_CHECK(navigator.endOfWorldReached(statesFwd[7]));
0395 BOOST_CHECK(navigator.endOfWorldReached(statesBwd[7]));
0396
0397
0398
0399 BOOST_CHECK_EQUAL(statesBwd[6].currentVolume->geometryId(), 1);
0400 BOOST_CHECK_EQUAL(statesBwd[6].currentSurface, nullptr);
0401 BOOST_CHECK_EQUAL(statesBwd[6].currentPortal->surface().geometryId(), 6);
0402
0403
0404 BOOST_CHECK_EQUAL(statesBwd[5].currentVolume->geometryId(), 1);
0405 BOOST_CHECK_EQUAL(statesBwd[5].currentSurface->geometryId(), 12);
0406 BOOST_CHECK_EQUAL(statesBwd[5].currentPortal, nullptr);
0407
0408
0409 BOOST_CHECK_EQUAL(statesBwd[4].currentVolume->geometryId(), 2);
0410 BOOST_CHECK_EQUAL(statesBwd[4].currentSurface, nullptr);
0411 BOOST_CHECK_EQUAL(statesBwd[4].currentPortal->surface().geometryId(), 7);
0412
0413
0414 BOOST_CHECK_EQUAL(statesBwd[3].currentVolume->geometryId(), 2);
0415 BOOST_CHECK_EQUAL(statesBwd[3].currentSurface->geometryId(), 13);
0416 BOOST_CHECK_EQUAL(statesBwd[3].currentPortal, nullptr);
0417
0418
0419 BOOST_CHECK_EQUAL(statesBwd[2].currentVolume->geometryId(), 3);
0420 BOOST_CHECK_EQUAL(statesBwd[2].currentSurface, nullptr);
0421 BOOST_CHECK_EQUAL(statesBwd[2].currentPortal->surface().geometryId(), 10);
0422 BOOST_CHECK_EQUAL(statesBwd[2].surfaceCandidates.size(), 2u);
0423
0424
0425 BOOST_CHECK_EQUAL(statesBwd[1].currentVolume->geometryId(), 3);
0426 BOOST_CHECK_EQUAL(statesBwd[1].currentSurface->geometryId(), 14);
0427 BOOST_CHECK_EQUAL(statesBwd[1].currentPortal, nullptr);
0428
0429
0430 BOOST_CHECK_EQUAL(statesBwd[0].currentVolume->geometryId(), 3);
0431 BOOST_CHECK_EQUAL(statesBwd[0].currentSurface, nullptr);
0432 BOOST_CHECK_EQUAL(statesBwd[0].currentPortal, nullptr);
0433 }
0434
0435
0436
0437
0438 BOOST_AUTO_TEST_CASE(DetectorNavigatorTestsAmbiguity) {
0439
0440 auto bounds = std::make_unique<Acts::CuboidVolumeBounds>(10, 10, 10);
0441 auto surface = Acts::Surface::makeShared<Acts::CylinderSurface>(
0442 Acts::Transform3::Identity(),
0443 std::make_shared<Acts::CylinderBounds>(4, 9));
0444 auto volume = Acts::Experimental::DetectorVolumeFactory::construct(
0445 Acts::Experimental::defaultPortalAndSubPortalGenerator(), geoContext,
0446 "volume", Acts::Transform3::Identity(), std::move(bounds), {surface}, {},
0447 Acts::Experimental::tryNoVolumes(),
0448 Acts::Experimental::tryAllPortalsAndSurfaces());
0449
0450 volume->assignGeometryId(1);
0451 surface->assignGeometryId(2);
0452 int id = 3;
0453 for (auto& port : volume->portalPtrs()) {
0454 port->surface().assignGeometryId(id);
0455 id++;
0456 }
0457
0458 auto detector = Acts::Experimental::Detector::makeShared(
0459 "detector", {volume}, Acts::Experimental::tryRootVolumes());
0460
0461 using ActionList = Acts::ActionList<StateRecorder>;
0462 using AbortList = Acts::AbortList<Acts::EndOfWorldReached>;
0463
0464 Acts::Experimental::DetectorNavigator::Config navCfg;
0465 navCfg.detector = detector.get();
0466
0467 auto stepper = Acts::StraightLineStepper();
0468
0469 auto navigator = Acts::Experimental::DetectorNavigator(
0470 navCfg, Acts::getDefaultLogger("DetectorNavigator",
0471 Acts::Logging::Level::VERBOSE));
0472
0473 auto options =
0474 Acts::PropagatorOptions<ActionList, AbortList>(geoContext, mfContext);
0475 options.direction = Acts::Direction::Forward;
0476
0477 auto propagator = Acts::Propagator<Acts::StraightLineStepper,
0478 Acts::Experimental::DetectorNavigator>(
0479 stepper, navigator,
0480 Acts::getDefaultLogger("Propagator", Acts::Logging::Level::VERBOSE));
0481
0482
0483
0484 Acts::Vector4 pos(0, 0, 0, 0);
0485 auto start = Acts::CurvilinearTrackParameters(
0486 pos, 0_degree, 90_degree, 1_e / 1_GeV, std::nullopt,
0487 Acts::ParticleHypothesis::electron());
0488
0489
0490
0491 auto resultFwd = propagator.propagate(start, options).value();
0492 auto statesFwd = resultFwd.get<StateRecorder::result_type>();
0493
0494 options.direction = Acts::Direction::Backward;
0495
0496 auto resultBwd = propagator.propagate(start, options).value();
0497 auto statesBwd = resultBwd.get<StateRecorder::result_type>();
0498
0499
0500
0501
0502 BOOST_CHECK_EQUAL(statesFwd.size(), 5u);
0503 BOOST_CHECK_EQUAL(statesFwd.size(), statesBwd.size());
0504 BOOST_CHECK_EQUAL(statesFwd[0].surfaceCandidates.size(), 2u);
0505 BOOST_CHECK_EQUAL(statesBwd[0].surfaceCandidates.size(), 2u);
0506
0507
0508
0509 BOOST_CHECK_EQUAL(statesFwd[0].currentVolume->geometryId(), 1);
0510 BOOST_CHECK_EQUAL(statesFwd[0].currentSurface, nullptr);
0511 BOOST_CHECK_EQUAL(statesFwd[0].currentPortal, nullptr);
0512
0513
0514 BOOST_CHECK_EQUAL(statesFwd[1].currentVolume->geometryId(), 1);
0515 BOOST_CHECK_EQUAL(statesFwd[1].currentSurface->geometryId(), 2);
0516 BOOST_CHECK_EQUAL(statesFwd[1].currentPortal, nullptr);
0517 BOOST_CHECK_EQUAL(statesFwd[1].surfaceCandidates.size(), 2u);
0518 CHECK_CLOSE_REL(statesFwd[1].position.x(), 4, 1e-6);
0519
0520
0521 BOOST_CHECK_EQUAL(statesFwd[2].currentVolume->geometryId(), 1);
0522 BOOST_CHECK_EQUAL(statesFwd[2].currentSurface, nullptr);
0523 BOOST_CHECK_EQUAL(statesFwd[2].currentPortal->surface().geometryId(), 6);
0524
0525
0526 BOOST_CHECK(navigator.endOfWorldReached(statesFwd[3]));
0527 BOOST_CHECK(navigator.endOfWorldReached(statesBwd[3]));
0528
0529
0530 BOOST_CHECK_EQUAL(statesBwd[2].currentVolume->geometryId(), 1);
0531 BOOST_CHECK_EQUAL(statesBwd[2].currentSurface, nullptr);
0532 BOOST_CHECK_EQUAL(statesBwd[2].currentPortal->surface().geometryId(), 5);
0533
0534
0535 BOOST_CHECK_EQUAL(statesBwd[1].currentVolume->geometryId(), 1);
0536 BOOST_CHECK_EQUAL(statesBwd[1].currentSurface->geometryId(), 2);
0537 BOOST_CHECK_EQUAL(statesBwd[1].currentPortal, nullptr);
0538 CHECK_CLOSE_REL(statesBwd[1].position.x(), -4, 1e-6);
0539
0540
0541
0542 BOOST_CHECK_EQUAL(statesBwd[0].currentVolume->geometryId(), 1);
0543 BOOST_CHECK_EQUAL(statesBwd[0].currentSurface, nullptr);
0544 BOOST_CHECK_EQUAL(statesBwd[0].currentPortal, nullptr);
0545 }
0546
0547
0548
0549
0550 BOOST_AUTO_TEST_CASE(DetectorNavigatorTestsMultipleIntersection) {
0551
0552 auto bounds = std::make_unique<Acts::CuboidVolumeBounds>(10, 10, 10);
0553 auto surface = Acts::Surface::makeShared<Acts::CylinderSurface>(
0554 Acts::Transform3::Identity(),
0555 std::make_shared<Acts::CylinderBounds>(4, 9));
0556 auto volume = Acts::Experimental::DetectorVolumeFactory::construct(
0557 Acts::Experimental::defaultPortalAndSubPortalGenerator(), geoContext,
0558 "volume", Acts::Transform3::Identity(), std::move(bounds), {surface}, {},
0559 Acts::Experimental::tryNoVolumes(),
0560 Acts::Experimental::tryAllPortalsAndSurfaces());
0561
0562 volume->assignGeometryId(1);
0563 surface->assignGeometryId(2);
0564 int id = 3;
0565 for (auto& port : volume->portalPtrs()) {
0566 port->surface().assignGeometryId(id);
0567 id++;
0568 }
0569
0570 auto detector = Acts::Experimental::Detector::makeShared(
0571 "detector", {volume}, Acts::Experimental::tryRootVolumes());
0572
0573 using ActionList = Acts::ActionList<StateRecorder>;
0574 using AbortList = Acts::AbortList<Acts::EndOfWorldReached>;
0575
0576 Acts::Experimental::DetectorNavigator::Config navCfg;
0577 navCfg.detector = detector.get();
0578
0579 auto stepper = Acts::StraightLineStepper();
0580
0581 auto navigator = Acts::Experimental::DetectorNavigator(
0582 navCfg, Acts::getDefaultLogger("DetectorNavigator",
0583 Acts::Logging::Level::VERBOSE));
0584
0585 auto options =
0586 Acts::PropagatorOptions<ActionList, AbortList>(geoContext, mfContext);
0587 options.direction = Acts::Direction::Forward;
0588
0589 auto propagator = Acts::Propagator<Acts::StraightLineStepper,
0590 Acts::Experimental::DetectorNavigator>(
0591 stepper, navigator,
0592 Acts::getDefaultLogger("Propagator", Acts::Logging::Level::VERBOSE));
0593
0594
0595
0596
0597
0598 Acts::Vector4 posFwd(-5, 0, 0, 0);
0599 auto startFwd = Acts::CurvilinearTrackParameters(
0600 posFwd, 0_degree, 90_degree, 1_e / 1_GeV, std::nullopt,
0601 Acts::ParticleHypothesis::electron());
0602
0603 auto resultFwd = propagator.propagate(startFwd, options).value();
0604 auto statesFwd = resultFwd.get<StateRecorder::result_type>();
0605
0606 options.direction = Acts::Direction::Backward;
0607 Acts::Vector4 posBwd(5, 0, 0, 0);
0608 auto startBwd = Acts::CurvilinearTrackParameters(
0609 posBwd, 0_degree, 90_degree, 1_e / 1_GeV, std::nullopt,
0610 Acts::ParticleHypothesis::electron());
0611
0612 auto resultBwd = propagator.propagate(startBwd, options).value();
0613 auto statesBwd = resultBwd.get<StateRecorder::result_type>();
0614
0615
0616
0617
0618 BOOST_CHECK_EQUAL(statesFwd.size(), 6u);
0619 BOOST_CHECK_EQUAL(statesFwd.size(), statesBwd.size());
0620 BOOST_CHECK_EQUAL(statesFwd[0].surfaceCandidates.size(), 3u);
0621 BOOST_CHECK_EQUAL(statesBwd[0].surfaceCandidates.size(), 3u);
0622
0623
0624
0625 BOOST_CHECK_EQUAL(statesFwd[0].currentVolume->geometryId(), 1);
0626 BOOST_CHECK_EQUAL(statesFwd[0].currentSurface, nullptr);
0627 BOOST_CHECK_EQUAL(statesFwd[0].currentPortal, nullptr);
0628
0629
0630 BOOST_CHECK_EQUAL(statesFwd[1].currentVolume->geometryId(), 1);
0631 BOOST_CHECK_EQUAL(statesFwd[1].currentSurface->geometryId(), 2);
0632 BOOST_CHECK_EQUAL(statesFwd[1].currentPortal, nullptr);
0633 CHECK_CLOSE_REL(statesFwd[1].position.x(), -4, 1e-6);
0634
0635
0636 BOOST_CHECK_EQUAL(statesFwd[2].currentVolume->geometryId(), 1);
0637 BOOST_CHECK_EQUAL(statesFwd[2].currentSurface->geometryId(), 2);
0638 BOOST_CHECK_EQUAL(statesFwd[2].currentPortal, nullptr);
0639 CHECK_CLOSE_REL(statesFwd[2].position.x(), 4, 1e-6);
0640
0641
0642 BOOST_CHECK_EQUAL(statesFwd[3].currentVolume->geometryId(), 1);
0643 BOOST_CHECK_EQUAL(statesFwd[3].currentSurface, nullptr);
0644 BOOST_CHECK_EQUAL(statesFwd[3].currentPortal->surface().geometryId(), 6);
0645
0646
0647 BOOST_CHECK(navigator.endOfWorldReached(statesFwd[4]));
0648 BOOST_CHECK(navigator.endOfWorldReached(statesBwd[4]));
0649
0650
0651 BOOST_CHECK_EQUAL(statesBwd[3].currentVolume->geometryId(), 1);
0652 BOOST_CHECK_EQUAL(statesBwd[3].currentSurface, nullptr);
0653 BOOST_CHECK_EQUAL(statesBwd[3].currentPortal->surface().geometryId(), 5);
0654
0655
0656 BOOST_CHECK_EQUAL(statesBwd[2].currentVolume->geometryId(), 1);
0657 BOOST_CHECK_EQUAL(statesBwd[2].currentSurface->geometryId(), 2);
0658 BOOST_CHECK_EQUAL(statesBwd[2].currentPortal, nullptr);
0659 CHECK_CLOSE_REL(statesBwd[2].position.x(), -4, 1e-6);
0660
0661
0662 BOOST_CHECK_EQUAL(statesBwd[1].currentVolume->geometryId(), 1);
0663 BOOST_CHECK_EQUAL(statesBwd[1].currentSurface->geometryId(), 2);
0664 BOOST_CHECK_EQUAL(statesBwd[1].currentPortal, nullptr);
0665 CHECK_CLOSE_REL(statesBwd[1].position.x(), 4, 1e-6);
0666
0667
0668
0669 BOOST_CHECK_EQUAL(statesBwd[0].currentVolume->geometryId(), 1);
0670 BOOST_CHECK_EQUAL(statesBwd[0].currentSurface, nullptr);
0671 BOOST_CHECK_EQUAL(statesBwd[0].currentPortal, nullptr);
0672 }
0673
0674 BOOST_AUTO_TEST_SUITE_END()