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