File indexing completed on 2025-12-16 09:25:01
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/data/test_case.hpp>
0010 #include <boost/test/unit_test.hpp>
0011
0012 #include "Acts/Definitions/Algebra.hpp"
0013 #include "Acts/Definitions/Direction.hpp"
0014 #include "Acts/Definitions/Tolerance.hpp"
0015 #include "Acts/Definitions/Units.hpp"
0016 #include "Acts/Geometry/Blueprint.hpp"
0017 #include "Acts/Geometry/ContainerBlueprintNode.hpp"
0018 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
0019 #include "Acts/Geometry/CuboidVolumeBuilder.hpp"
0020 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0021 #include "Acts/Geometry/GeometryContext.hpp"
0022 #include "Acts/Geometry/StaticBlueprintNode.hpp"
0023 #include "Acts/Geometry/TrackingGeometry.hpp"
0024 #include "Acts/Geometry/TrackingGeometryBuilder.hpp"
0025 #include "Acts/Geometry/TrackingVolume.hpp"
0026 #include "Acts/MagneticField/ConstantBField.hpp"
0027 #include "Acts/Propagator/NavigationTarget.hpp"
0028 #include "Acts/Propagator/Navigator.hpp"
0029 #include "Acts/Surfaces/PerigeeSurface.hpp"
0030 #include "Acts/Surfaces/PlaneSurface.hpp"
0031 #include "Acts/Surfaces/RectangleBounds.hpp"
0032 #include "Acts/Surfaces/Surface.hpp"
0033 #include "Acts/Utilities/Intersection.hpp"
0034 #include "Acts/Utilities/Logger.hpp"
0035 #include "ActsTests/CommonHelpers/CylindricalTrackingGeometry.hpp"
0036 #include "ActsTests/CommonHelpers/DetectorElementStub.hpp"
0037 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0038
0039 #include <cstddef>
0040 #include <memory>
0041 #include <string>
0042
0043 namespace bdata = boost::unit_test::data;
0044
0045 using namespace Acts;
0046 using namespace Acts::UnitLiterals;
0047 using Acts::VectorHelpers::perp;
0048
0049 namespace ActsTests {
0050
0051
0052 GeometryContext tgContext = GeometryContext();
0053 MagneticFieldContext mfContext = MagneticFieldContext();
0054
0055 void step(Vector3& pos, const Vector3& dir, double stepSize) {
0056 pos += stepSize * dir;
0057 }
0058
0059 void step(Vector3& pos, const Vector3& dir, const Surface& surface) {
0060 Intersection3D intersection =
0061 surface.intersect(tgContext, pos, dir).closestForward();
0062 step(pos, dir, intersection.pathLength());
0063 }
0064
0065 void step(Vector3& pos, const Vector3& dir, const NavigationTarget& target) {
0066 step(pos, dir, target.surface());
0067 }
0068
0069
0070
0071
0072
0073
0074
0075
0076 bool testNavigatorStateVectors(Navigator::State& state, std::size_t navSurf,
0077 std::size_t navLay, std::size_t navBound) {
0078 return ((state.navSurfaces.size() == navSurf) &&
0079 (state.navLayers.size() == navLay) &&
0080 (state.navBoundaries.size() == navBound));
0081 }
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092 bool testNavigatorStatePointers(Navigator::State& state,
0093 const TrackingVolume* startVol,
0094 const Layer* startLay, const Surface* startSurf,
0095 const Surface* currSurf,
0096 const TrackingVolume* currVol,
0097 const Surface* targetSurf) {
0098 std::cout << "startVol: " << startVol << " startLay: " << startLay
0099 << " startSurf: " << startSurf << " currSurf: " << currSurf
0100 << " currVol: " << currVol << " targetSurf: " << targetSurf
0101 << std::endl;
0102
0103 std::cout << "state.startVolume: " << state.startVolume
0104 << " state.startLayer: " << state.startLayer
0105 << " state.startSurface: " << state.startSurface
0106 << " state.currentSurface: " << state.currentSurface
0107 << " state.currentVolume: " << state.currentVolume
0108 << " state.targetSurface: " << state.targetSurface << std::endl;
0109
0110 return (
0111 (state.startVolume == startVol) && (state.startLayer == startLay) &&
0112 (state.startSurface == startSurf) && (state.currentSurface == currSurf) &&
0113 (state.currentVolume == currVol) && (state.targetSurface == targetSurf));
0114 }
0115
0116
0117 CylindricalTrackingGeometry cGeometry(tgContext);
0118 auto tGeometry = cGeometry();
0119
0120 const double Bz = 2_T;
0121 auto bField = std::make_shared<ConstantBField>(Vector3{0, 0, Bz});
0122
0123 Logging::Level logLevel = Logging::INFO;
0124
0125 BOOST_AUTO_TEST_SUITE(PropagatorSuite)
0126
0127 BOOST_AUTO_TEST_CASE(Navigator_status_methods) {
0128 ACTS_LOCAL_LOGGER(getDefaultLogger("NavigatorTest", logLevel));
0129
0130
0131 Vector3 position = Vector3::Zero();
0132 Vector3 direction = Vector3(1., 1., 0).normalized();
0133
0134 ACTS_INFO("(1) Test for inactivity");
0135 ACTS_INFO(" a) Run without anything present");
0136 {
0137 auto bounds = std::make_shared<CylinderVolumeBounds>(10, 20, 20);
0138 auto tvol = std::make_shared<TrackingVolume>(Transform3::Identity(), bounds,
0139 "Undefined");
0140
0141 auto tgeo = std::make_shared<TrackingGeometry>(tvol);
0142
0143 Navigator::Config navCfg;
0144 navCfg.resolveSensitive = false;
0145 navCfg.resolveMaterial = false;
0146 navCfg.resolvePassive = false;
0147 navCfg.trackingGeometry = tgeo;
0148 Navigator navigator{navCfg};
0149
0150 Navigator::Options options(tgContext);
0151
0152 Navigator::State state = navigator.makeState(options);
0153
0154 BOOST_CHECK(testNavigatorStateVectors(state, 0u, 0u, 0u));
0155 BOOST_CHECK(testNavigatorStatePointers(state, nullptr, nullptr, nullptr,
0156 nullptr, nullptr, nullptr));
0157 }
0158
0159 ACTS_INFO(" b) Run with geometry but without resolving");
0160 {
0161 Navigator::Config navCfg;
0162 navCfg.resolveSensitive = false;
0163 navCfg.resolveMaterial = false;
0164 navCfg.resolvePassive = false;
0165 navCfg.trackingGeometry = tGeometry;
0166 Navigator navigator{navCfg};
0167
0168 Navigator::Options options(tgContext);
0169
0170 Navigator::State state = navigator.makeState(options);
0171
0172 BOOST_CHECK(testNavigatorStateVectors(state, 0u, 0u, 0u));
0173 BOOST_CHECK(testNavigatorStatePointers(state, nullptr, nullptr, nullptr,
0174 nullptr, nullptr, nullptr));
0175 }
0176
0177 ACTS_INFO(
0178 " c) Run with geometry and resolving but broken navigation for "
0179 "various reasons");
0180 {
0181 Navigator::Config navCfg;
0182 navCfg.resolveSensitive = true;
0183 navCfg.resolveMaterial = true;
0184 navCfg.resolvePassive = true;
0185 navCfg.trackingGeometry = tGeometry;
0186 Navigator navigator{navCfg};
0187
0188 Navigator::Options options(tgContext);
0189
0190 Navigator::State state = navigator.makeState(options);
0191
0192 ACTS_INFO(" i) Because target is reached");
0193 state.navigationBreak = true;
0194 navigator.nextTarget(state, position, direction);
0195 BOOST_CHECK(testNavigatorStateVectors(state, 0u, 0u, 0u));
0196 BOOST_CHECK(testNavigatorStatePointers(state, nullptr, nullptr, nullptr,
0197 nullptr, nullptr, nullptr));
0198
0199 ACTS_INFO(" ii) Because of no target surface");
0200 state.targetSurface = nullptr;
0201 navigator.nextTarget(state, position, direction);
0202 BOOST_CHECK(testNavigatorStateVectors(state, 0u, 0u, 0u));
0203 BOOST_CHECK(testNavigatorStatePointers(state, nullptr, nullptr, nullptr,
0204 nullptr, nullptr, nullptr));
0205
0206 ACTS_INFO(" iii) Because the target surface is reached");
0207 auto beamline = Surface::makeShared<PerigeeSurface>(Vector3::Zero());
0208 const Surface* startSurf = beamline.get();
0209 position = startSurf->center(tgContext);
0210 const TrackingVolume* startVol =
0211 tGeometry->lowestTrackingVolume(tgContext, position);
0212 const Layer* startLay = startVol->associatedLayer(tgContext, position);
0213 state.options.startSurface = startSurf;
0214 state.options.targetSurface = startSurf;
0215 BOOST_CHECK(
0216 navigator.initialize(state, position, direction, Direction::Forward())
0217 .ok());
0218 BOOST_CHECK(testNavigatorStateVectors(state, 0u, 0u, 0u));
0219 BOOST_CHECK(testNavigatorStatePointers(state, startVol, startLay, startSurf,
0220 startSurf, startVol, startSurf));
0221
0222 ACTS_INFO("(2) Test the initialisation");
0223 ACTS_INFO(" a) Initialise without additional information");
0224 state = navigator.makeState(options);
0225 position = Vector3::Zero();
0226 startVol = tGeometry->lowestTrackingVolume(tgContext, position);
0227 startLay = startVol->associatedLayer(tgContext, position);
0228 BOOST_CHECK(
0229 navigator.initialize(state, position, direction, Direction::Forward())
0230 .ok());
0231 BOOST_CHECK(testNavigatorStateVectors(state, 0u, 0u, 0u));
0232 BOOST_CHECK(testNavigatorStatePointers(state, startVol, startLay, nullptr,
0233 nullptr, startVol, nullptr));
0234
0235 ACTS_INFO(" b) Initialise having a start surface");
0236 state = navigator.makeState(options);
0237 state.options.startSurface = startSurf;
0238 BOOST_CHECK(
0239 navigator.initialize(state, position, direction, Direction::Forward())
0240 .ok());
0241 BOOST_CHECK(testNavigatorStateVectors(state, 0u, 0u, 0u));
0242 BOOST_CHECK(testNavigatorStatePointers(state, startVol, startLay, startSurf,
0243 startSurf, startVol, nullptr));
0244
0245 ACTS_INFO(" c) Initialise having a start volume");
0246 state = navigator.makeState(options);
0247 state.startVolume = startVol;
0248 BOOST_CHECK(
0249 navigator.initialize(state, position, direction, Direction::Forward())
0250 .ok());
0251 BOOST_CHECK(testNavigatorStateVectors(state, 0u, 0u, 0u));
0252 BOOST_CHECK(testNavigatorStatePointers(state, startVol, startLay, nullptr,
0253 nullptr, startVol, nullptr));
0254 }
0255 }
0256
0257 BOOST_AUTO_TEST_CASE(Navigator_target_methods) {
0258 ACTS_LOCAL_LOGGER(getDefaultLogger("NavigatorTest", logLevel));
0259
0260
0261 Navigator::Config navCfg;
0262 navCfg.trackingGeometry = tGeometry;
0263 navCfg.resolveSensitive = true;
0264 navCfg.resolveMaterial = true;
0265 navCfg.resolvePassive = false;
0266 Navigator navigator{navCfg};
0267
0268 Navigator::Options options(tgContext);
0269
0270 Navigator::State state = navigator.makeState(options);
0271
0272
0273 Vector3 position = Vector3::Zero();
0274 Vector3 direction = Vector3(1., 1., 0).normalized();
0275
0276
0277 ACTS_INFO("<<<<<<<<<<<<<<<<<<<<< FORWARD NAVIGATION >>>>>>>>>>>>>>>>>>");
0278
0279
0280
0281
0282 BOOST_CHECK(
0283 navigator.initialize(state, position, direction, Direction::Forward())
0284 .ok());
0285
0286 BOOST_CHECK_NE(state.currentVolume, nullptr);
0287
0288 BOOST_CHECK_EQUAL(state.currentVolume, state.startVolume);
0289
0290 BOOST_CHECK_EQUAL(state.currentSurface, nullptr);
0291
0292 BOOST_CHECK_EQUAL(state.navLayers.size(), 0u);
0293
0294
0295 NavigationTarget target = navigator.nextTarget(state, position, direction);
0296 BOOST_CHECK(!target.isNone());
0297
0298 BOOST_CHECK_EQUAL(state.navLayers.size(), 1u);
0299
0300 BOOST_CHECK_EQUAL(state.navLayerIndex.value(), 0);
0301
0302 BOOST_CHECK_EQUAL(&target.surface(), &state.navLayer().surface());
0303
0304 Intersection3D targetIntersection =
0305 target.surface()
0306 .intersect(tgContext, position, direction)
0307 .closestForward();
0308
0309 double beamPipeR = perp(state.navLayer().position());
0310
0311 CHECK_CLOSE_ABS(targetIntersection.pathLength(), beamPipeR,
0312 s_onSurfaceTolerance);
0313
0314 ACTS_INFO("<<< Test 1a >>> initialize at " << toString(position));
0315
0316
0317 step(position, direction, target);
0318
0319
0320
0321 navigator.handleSurfaceReached(state, position, direction, target.surface());
0322
0323 BOOST_CHECK_EQUAL(state.currentVolume, state.startVolume);
0324
0325 BOOST_CHECK_EQUAL(state.navLayers.size(), 1u);
0326
0327 BOOST_CHECK_EQUAL(state.navLayerIndex.value(), 0);
0328
0329 ACTS_INFO("<<< Test 1b >>> step to the BeamPipe at " << toString(position));
0330
0331
0332 target = navigator.nextTarget(state, position, direction);
0333 BOOST_CHECK(!target.isNone());
0334
0335
0336 step(position, direction, target);
0337
0338
0339
0340 navigator.handleSurfaceReached(state, position, direction, target.surface());
0341
0342 ACTS_INFO("<<< Test 1c >>> step to the Boundary at " << toString(position));
0343
0344
0345 target = navigator.nextTarget(state, position, direction);
0346 BOOST_CHECK(!target.isNone());
0347
0348 targetIntersection = target.surface()
0349 .intersect(tgContext, position, direction)
0350 .closestForward();
0351
0352
0353 step(position, direction, target);
0354
0355
0356
0357 navigator.handleSurfaceReached(state, position, direction, target.surface());
0358
0359 ACTS_INFO("<<< Test 1d >>> step to 1st layer at " << toString(position));
0360
0361
0362 target = navigator.nextTarget(state, position, direction);
0363 BOOST_CHECK(!target.isNone());
0364
0365
0366 for (std::size_t isf = 0; isf < 5; ++isf) {
0367 step(position, direction, target);
0368
0369
0370 navigator.handleSurfaceReached(state, position, direction,
0371 target.surface());
0372
0373 target = navigator.nextTarget(state, position, direction);
0374 BOOST_CHECK(!target.isNone());
0375
0376 ACTS_INFO("<<< Test 1e-1i >>> step within 1st layer at "
0377 << toString(position));
0378 }
0379
0380
0381 step(position, direction, target);
0382
0383
0384 navigator.handleSurfaceReached(state, position, direction, target.surface());
0385
0386 target = navigator.nextTarget(state, position, direction);
0387 BOOST_CHECK(!target.isNone());
0388
0389 ACTS_INFO("<<< Test 1j >>> step to 2nd layer at " << toString(position));
0390
0391
0392 for (std::size_t isf = 0; isf < 5; ++isf) {
0393 step(position, direction, target);
0394
0395
0396 navigator.handleSurfaceReached(state, position, direction,
0397 target.surface());
0398
0399 target = navigator.nextTarget(state, position, direction);
0400 BOOST_CHECK(!target.isNone());
0401
0402 ACTS_INFO("<<< Test 1k-1o >>> step within 2nd layer at "
0403 << toString(position));
0404 }
0405
0406
0407 step(position, direction, target);
0408
0409
0410 navigator.handleSurfaceReached(state, position, direction, target.surface());
0411
0412 target = navigator.nextTarget(state, position, direction);
0413 BOOST_CHECK(!target.isNone());
0414
0415 ACTS_INFO("<<< Test 1p >>> step to 3rd layer at " << toString(position));
0416
0417
0418 for (std::size_t isf = 0; isf < 3; ++isf) {
0419 step(position, direction, target);
0420
0421
0422 navigator.handleSurfaceReached(state, position, direction,
0423 target.surface());
0424
0425 target = navigator.nextTarget(state, position, direction);
0426 BOOST_CHECK(!target.isNone());
0427
0428 ACTS_INFO("<<< Test 1q-1s >>> step within 3rd layer at "
0429 << toString(position));
0430 }
0431
0432
0433 step(position, direction, target);
0434
0435
0436 navigator.handleSurfaceReached(state, position, direction, target.surface());
0437
0438 target = navigator.nextTarget(state, position, direction);
0439 BOOST_CHECK(!target.isNone());
0440
0441 ACTS_INFO("<<< Test 1t >>> step to 4th layer at " << toString(position));
0442
0443
0444 for (std::size_t isf = 0; isf < 3; ++isf) {
0445 step(position, direction, target);
0446
0447
0448 navigator.handleSurfaceReached(state, position, direction,
0449 target.surface());
0450
0451 target = navigator.nextTarget(state, position, direction);
0452 BOOST_CHECK(!target.isNone());
0453
0454 ACTS_INFO("<<< Test 1t-1v >>> step within 4th layer at "
0455 << toString(position));
0456 }
0457
0458
0459 step(position, direction, target);
0460
0461
0462 navigator.handleSurfaceReached(state, position, direction, target.surface());
0463
0464 target = navigator.nextTarget(state, position, direction);
0465 BOOST_CHECK(target.isNone());
0466
0467 ACTS_INFO("<<< Test 1w >>> step to boundary at " << toString(position));
0468 }
0469
0470 inline std::tuple<std::shared_ptr<const TrackingGeometry>,
0471 std::vector<const Surface*>>
0472 createDenseTelescope(const GeometryContext& geoCtx) {
0473 using namespace Acts;
0474 using namespace UnitLiterals;
0475
0476 CuboidVolumeBuilder::Config conf;
0477 conf.position = {0., 0., 0.};
0478 conf.length = {2_m, 2_m, 2_m};
0479
0480 {
0481 CuboidVolumeBuilder::SurfaceConfig surfaceTop;
0482 surfaceTop.position = {0, 0.5_m, 0.5_m};
0483 surfaceTop.rBounds = std::make_shared<RectangleBounds>(0.8_m, 0.2_m);
0484
0485 CuboidVolumeBuilder::SurfaceConfig surfaceBottom;
0486 surfaceBottom.position = {0, -0.5_m, 0.5_m};
0487 surfaceBottom.rBounds = std::make_shared<RectangleBounds>(0.8_m, 0.2_m);
0488
0489 CuboidVolumeBuilder::LayerConfig layer;
0490 layer.surfaceCfg.push_back(surfaceTop);
0491 layer.surfaceCfg.push_back(surfaceBottom);
0492
0493 CuboidVolumeBuilder::VolumeConfig start;
0494 start.position = {0, 0, 0};
0495 start.length = {1.9_m, 1.9_m, 1.9_m};
0496 start.name = "start";
0497 start.layerCfg.push_back(layer);
0498
0499 conf.volumeCfg.push_back(start);
0500 }
0501
0502 CuboidVolumeBuilder cvb(conf);
0503
0504 TrackingGeometryBuilder::Config tgbCfg;
0505 tgbCfg.trackingVolumeBuilders.push_back(
0506 [=](const auto& context, const auto& inner, const auto&) {
0507 return cvb.trackingVolume(context, inner, nullptr);
0508 });
0509 auto detector = TrackingGeometryBuilder(tgbCfg).trackingGeometry(geoCtx);
0510
0511 std::vector<const Surface*> surfaces;
0512 detector->visitSurfaces(
0513 [&](const Surface* surface) { surfaces.push_back(surface); });
0514
0515 return {std::move(detector), std::move(surfaces)};
0516 }
0517
0518 BOOST_AUTO_TEST_CASE(Navigator_external_surfaces) {
0519 ACTS_LOCAL_LOGGER(getDefaultLogger("NavigatorTest", logLevel));
0520
0521 auto [detector, surfaces] = createDenseTelescope(tgContext);
0522 BOOST_CHECK_EQUAL(surfaces.size(), 2ul);
0523 const Surface& surfaceTop = *surfaces.at(0);
0524 const Surface& surfaceBottom = *surfaces.at(1);
0525 CHECK_CLOSE_ABS(surfaceTop.center(tgContext).y(), 0.5_m, 1e-6);
0526 CHECK_CLOSE_ABS(surfaceBottom.center(tgContext).y(), -0.5_m, 1e-6);
0527
0528 Navigator::Config navCfg;
0529 navCfg.trackingGeometry = detector;
0530 navCfg.resolveSensitive = true;
0531 navCfg.resolveMaterial = true;
0532 navCfg.resolvePassive = false;
0533 Navigator navigator(navCfg, logger().clone("Navigator"));
0534
0535
0536
0537 {
0538 ACTS_INFO("Test 1: start in the middle without external surfaces");
0539
0540 Navigator::Options options(tgContext);
0541 Navigator::State state = navigator.makeState(options);
0542
0543 Vector3 position = Vector3::Zero();
0544 Vector3 direction = Vector3::UnitZ();
0545
0546 Result<void> result =
0547 navigator.initialize(state, position, direction, Direction::Forward());
0548 BOOST_CHECK(result.ok());
0549
0550 NavigationTarget target = navigator.nextTarget(state, position, direction);
0551
0552 BOOST_CHECK_NE(&target.surface(), surfaces.at(0));
0553 BOOST_CHECK_NE(&target.surface(), surfaces.at(1));
0554 }
0555
0556
0557 {
0558 ACTS_INFO("Test 2: start from top without external surfaces");
0559
0560 Navigator::Options options(tgContext);
0561 Navigator::State state = navigator.makeState(options);
0562
0563 Vector3 position = {0, 0.5_m, 0};
0564 Vector3 direction = Vector3::UnitZ();
0565
0566 Result<void> result =
0567 navigator.initialize(state, position, direction, Direction::Forward());
0568 BOOST_CHECK(result.ok());
0569
0570 NavigationTarget target = navigator.nextTarget(state, position, direction);
0571
0572 BOOST_CHECK(!target.isNone());
0573 BOOST_CHECK_EQUAL(&target.surface(), &surfaceTop);
0574 }
0575
0576
0577
0578 {
0579 ACTS_INFO("Test 2: start from bottom without external surfaces");
0580
0581 Navigator::Options options(tgContext);
0582 Navigator::State state = navigator.makeState(options);
0583
0584 Vector3 position = {0, -0.5_m, 0};
0585 Vector3 direction = Vector3::UnitZ();
0586
0587 Result<void> result =
0588 navigator.initialize(state, position, direction, Direction::Forward());
0589 BOOST_CHECK(result.ok());
0590
0591 NavigationTarget target = navigator.nextTarget(state, position, direction);
0592
0593 BOOST_CHECK(!target.isNone());
0594 BOOST_CHECK_EQUAL(&target.surface(), &surfaceBottom);
0595 }
0596
0597
0598
0599 {
0600 ACTS_INFO("Test 3: start in the middle with external surfaces");
0601
0602 Navigator::Options options(tgContext);
0603 options.insertExternalSurface(surfaceTop.geometryId());
0604 Navigator::State state = navigator.makeState(options);
0605
0606 Vector3 position = {0, 0, 0};
0607 Vector3 direction = Vector3::UnitZ();
0608
0609 Result<void> result =
0610 navigator.initialize(state, position, direction, Direction::Forward());
0611 BOOST_CHECK(result.ok());
0612
0613 NavigationTarget target = navigator.nextTarget(state, position, direction);
0614
0615 BOOST_CHECK(!target.isNone());
0616 BOOST_CHECK_EQUAL(&target.surface(), &surfaceTop);
0617 }
0618
0619
0620
0621 {
0622 ACTS_INFO("Test 4: start from top with external surfaces");
0623
0624 Navigator::Options options(tgContext);
0625 options.insertExternalSurface(surfaceBottom.geometryId());
0626 Navigator::State state = navigator.makeState(options);
0627
0628 Vector3 position = {0, 0.5_m, 0};
0629 Vector3 direction = Vector3::UnitZ();
0630
0631 Result<void> result =
0632 navigator.initialize(state, position, direction, Direction::Forward());
0633 BOOST_CHECK(result.ok());
0634
0635 NavigationTarget target = navigator.nextTarget(state, position, direction);
0636
0637 BOOST_CHECK(!target.isNone());
0638 BOOST_CHECK_EQUAL(&target.surface(), &surfaceBottom);
0639 }
0640
0641
0642
0643 {
0644 ACTS_INFO("Test 5: start from bottom with external surfaces");
0645
0646 Navigator::Options options(tgContext);
0647 options.insertExternalSurface(surfaceTop.geometryId());
0648 Navigator::State state = navigator.makeState(options);
0649
0650 Vector3 position = {0, -0.5_m, 0};
0651 Vector3 direction = Vector3::UnitZ();
0652
0653 Result<void> result =
0654 navigator.initialize(state, position, direction, Direction::Forward());
0655 BOOST_CHECK(result.ok());
0656
0657 NavigationTarget target = navigator.nextTarget(state, position, direction);
0658
0659 BOOST_CHECK(!target.isNone());
0660 BOOST_CHECK_EQUAL(&target.surface(), &surfaceTop);
0661 }
0662 }
0663
0664 BOOST_AUTO_TEST_CASE(TryAllNavigationPolicy_SurfaceInsideVolume) {
0665 auto logger = getDefaultLogger("UnitTests", Logging::VERBOSE);
0666
0667 Experimental::Blueprint::Config cfg;
0668 cfg.envelope = ExtentEnvelope{{
0669 .z = {20_mm, 20_mm},
0670 .r = {0_mm, 20_mm},
0671 }};
0672
0673 Experimental::Blueprint root{cfg};
0674
0675 auto& cubcontainer =
0676 root.addCuboidContainer("CuboidContainer", AxisDirection::AxisZ);
0677
0678 auto parentBounds = std::make_shared<CuboidVolumeBounds>(1_m, 1_m, 1_m);
0679
0680 auto parentVol = std::make_unique<TrackingVolume>(Transform3::Identity(),
0681 parentBounds, "parent");
0682
0683 std::shared_ptr<const PlanarBounds> planarBounds =
0684 std::make_shared<const RectangleBounds>(5., 10.);
0685
0686 auto surface = Surface::makeShared<PlaneSurface>(Transform3::Identity(),
0687 std::move(planarBounds));
0688
0689 auto detElement =
0690 std::make_unique<DetectorElementStub>(Transform3::Identity());
0691
0692 surface->assignDetectorElement(*detElement);
0693
0694 parentVol->assignGeometryId(GeometryIdentifier{}.withVolume(1));
0695 parentVol->addSurface(surface);
0696 auto parentNode =
0697 std::make_shared<Experimental::StaticBlueprintNode>(std::move(parentVol));
0698
0699
0700
0701 double startZ1 = -1000. + 100. + 1.;
0702 double startZ2 = 1000. - 100. - 1.;
0703 Transform3 trf1 = Transform3(Translation3(0., 0., startZ1));
0704 Transform3 trf2 = Transform3(Translation3(0., 0., startZ2));
0705
0706 auto childBounds = std::make_shared<CuboidVolumeBounds>(1_m, 1_m, 10_cm);
0707 auto childVol1 =
0708 std::make_unique<TrackingVolume>(trf1, childBounds, "child1");
0709 childVol1->assignGeometryId(GeometryIdentifier{}.withVolume(2));
0710
0711 auto childNode1 =
0712 std::make_shared<Experimental::StaticBlueprintNode>(std::move(childVol1));
0713
0714 auto childVol2 =
0715 std::make_unique<TrackingVolume>(trf2, childBounds, "child2");
0716 childVol2->assignGeometryId(GeometryIdentifier{}.withVolume(3));
0717
0718 auto childNode2 =
0719 std::make_shared<Experimental::StaticBlueprintNode>(std::move(childVol2));
0720
0721 parentNode->addChild(childNode1);
0722 parentNode->addChild(childNode2);
0723
0724 cubcontainer.addChild(std::move(parentNode));
0725
0726 auto trackingGeometry = root.construct({}, tgContext, *logger);
0727
0728 Navigator::Config navCfg;
0729 navCfg.trackingGeometry =
0730 std::shared_ptr<const TrackingGeometry>(std::move(trackingGeometry));
0731 navCfg.resolveSensitive = true;
0732 navCfg.resolveMaterial = true;
0733 navCfg.resolvePassive = false;
0734 Navigator navigator(navCfg, logger->clone("Navigator"));
0735
0736 Navigator::Options options(tgContext);
0737 Navigator::State state = navigator.makeState(options);
0738
0739 Vector3 position{0., 0., -1000. + 0.5};
0740 Vector3 direction = Vector3::UnitZ();
0741
0742 Result<void> result =
0743 navigator.initialize(state, position, direction, Direction::Forward());
0744 BOOST_CHECK(result.ok());
0745 BOOST_CHECK(state.currentVolume != nullptr);
0746 BOOST_CHECK(state.currentVolume->volumeName() == "parent");
0747 BOOST_CHECK_EQUAL(state.currentSurface, nullptr);
0748
0749
0750
0751
0752 NavigationTarget target = navigator.nextTarget(state, position, direction);
0753
0754
0755 BOOST_CHECK(!target.isNone());
0756 auto targetGeoId = target.surface().geometryId();
0757
0758 BOOST_CHECK(targetGeoId.volume() == 2 && targetGeoId.boundary() == 1);
0759
0760 step(position, direction, target);
0761 navigator.handleSurfaceReached(state, position, direction, target.surface());
0762
0763 BOOST_CHECK(state.currentVolume->volumeName() == "child1");
0764
0765 target = navigator.nextTarget(state, position, direction);
0766 BOOST_CHECK(!target.isNone());
0767 targetGeoId = target.surface().geometryId();
0768
0769 BOOST_CHECK(targetGeoId.volume() == 2 && targetGeoId.boundary() == 2);
0770
0771 step(position, direction, target);
0772 navigator.handleSurfaceReached(state, position, direction, target.surface());
0773
0774 BOOST_CHECK(state.currentVolume->volumeName() == "parent");
0775
0776 target = navigator.nextTarget(state, position, direction);
0777 BOOST_CHECK(!target.isNone());
0778 BOOST_CHECK_EQUAL(&target.surface(), surface.get());
0779
0780 step(position, direction, target);
0781 navigator.handleSurfaceReached(state, position, direction, target.surface());
0782
0783 BOOST_CHECK(state.currentVolume->volumeName() == "parent");
0784
0785 target = navigator.nextTarget(state, position, direction);
0786 BOOST_CHECK(!target.isNone());
0787 targetGeoId = target.surface().geometryId();
0788
0789 BOOST_CHECK(targetGeoId.volume() == 3 && targetGeoId.boundary() == 1);
0790
0791 step(position, direction, target);
0792 navigator.handleSurfaceReached(state, position, direction, target.surface());
0793
0794 BOOST_CHECK(state.currentVolume->volumeName() == "child2");
0795 target = navigator.nextTarget(state, position, direction);
0796 BOOST_CHECK(!target.isNone());
0797 targetGeoId = target.surface().geometryId();
0798
0799 BOOST_CHECK(targetGeoId.volume() == 3 && targetGeoId.boundary() == 2);
0800
0801 step(position, direction, target);
0802 navigator.handleSurfaceReached(state, position, direction, target.surface());
0803
0804 BOOST_CHECK(state.currentVolume->volumeName() == "parent");
0805 }
0806
0807 BOOST_AUTO_TEST_SUITE_END()
0808
0809 }