File indexing completed on 2025-08-06 08:11:26
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/data/test_case.hpp>
0010 #include <boost/test/tools/output_test_stream.hpp>
0011 #include <boost/test/unit_test.hpp>
0012
0013 #include "Acts/Definitions/Algebra.hpp"
0014 #include "Acts/Definitions/Common.hpp"
0015 #include "Acts/Definitions/Direction.hpp"
0016 #include "Acts/Definitions/Tolerance.hpp"
0017 #include "Acts/Definitions/TrackParametrization.hpp"
0018 #include "Acts/Definitions/Units.hpp"
0019 #include "Acts/EventData/GenericBoundTrackParameters.hpp"
0020 #include "Acts/EventData/TrackParameters.hpp"
0021 #include "Acts/Geometry/GeometryContext.hpp"
0022 #include "Acts/Geometry/TrackingGeometry.hpp"
0023 #include "Acts/Geometry/TrackingVolume.hpp"
0024 #include "Acts/Propagator/ConstrainedStep.hpp"
0025 #include "Acts/Propagator/Navigator.hpp"
0026 #include "Acts/Propagator/StepperConcept.hpp"
0027 #include "Acts/Propagator/detail/SteppingHelper.hpp"
0028 #include "Acts/Surfaces/BoundaryCheck.hpp"
0029 #include "Acts/Surfaces/Surface.hpp"
0030 #include "Acts/Tests/CommonHelpers/CylindricalTrackingGeometry.hpp"
0031 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0032 #include "Acts/Utilities/Helpers.hpp"
0033 #include "Acts/Utilities/Intersection.hpp"
0034 #include "Acts/Utilities/Logger.hpp"
0035 #include "Acts/Utilities/Result.hpp"
0036
0037 #include <cstddef>
0038 #include <cstdint>
0039 #include <iostream>
0040 #include <map>
0041 #include <memory>
0042 #include <string>
0043 #include <system_error>
0044 #include <tuple>
0045 #include <utility>
0046
0047 namespace Acts {
0048 class Layer;
0049 struct FreeToBoundCorrection;
0050 }
0051
0052 using namespace Acts::UnitLiterals;
0053 using Acts::VectorHelpers::perp;
0054
0055 namespace Acts::Test {
0056
0057
0058 GeometryContext tgContext = GeometryContext();
0059
0060
0061
0062 struct PropagatorState {
0063
0064 struct Stepper {
0065
0066 using Jacobian = BoundMatrix;
0067 using Covariance = BoundSquareMatrix;
0068 using BoundState = std::tuple<BoundTrackParameters, Jacobian, double>;
0069 using CurvilinearState =
0070 std::tuple<CurvilinearTrackParameters, Jacobian, double>;
0071 using BField = int;
0072
0073 template <typename, typename>
0074 using return_parameter_type = void;
0075
0076
0077
0078 struct State {
0079
0080 Vector4 pos4 = Vector4(0., 0., 0., 0.);
0081
0082
0083 Vector3 dir = Vector3(1., 0., 0.);
0084
0085
0086 double p = 0;
0087
0088
0089 double q = 0;
0090
0091
0092 ParticleHypothesis particleHypothesis = ParticleHypothesis::pion();
0093
0094
0095 double pathAccumulated = 0.;
0096
0097
0098 ConstrainedStep stepSize = ConstrainedStep(100_cm);
0099
0100
0101 double previousStepSize = 0.;
0102
0103 GeometryContext geoContext = GeometryContext();
0104 };
0105
0106
0107 void resetState(State& , const BoundVector& ,
0108 const BoundSquareMatrix& ,
0109 const Surface& ,
0110 const double ) const {}
0111
0112
0113 Vector3 position(const State& state) const {
0114 return state.pos4.segment<3>(Acts::ePos0);
0115 }
0116
0117
0118 double time(const State& state) const { return state.pos4[Acts::eTime]; }
0119
0120
0121 Vector3 direction(const State& state) const { return state.dir; }
0122
0123
0124 double qOverP(const State& state) const {
0125 return (state.q == 0 ? 1 : state.q) / state.p;
0126 }
0127
0128
0129 double absoluteMomentum(const State& state) const { return state.p; }
0130
0131
0132 Vector3 momentum(const State& state) const { return state.p * state.dir; }
0133
0134
0135 double charge(const State& state) const { return state.q; }
0136
0137
0138 double overstepLimit(const State& ) const {
0139 return s_onSurfaceTolerance;
0140 }
0141
0142 Intersection3D::Status updateSurfaceStatus(
0143 State& state, const Surface& surface, std::uint8_t index,
0144 Direction navDir, const BoundaryCheck& bcheck,
0145 ActsScalar surfaceTolerance, const Logger& logger) const {
0146 return detail::updateSingleSurfaceStatus<Stepper>(
0147 *this, state, surface, index, navDir, bcheck, surfaceTolerance,
0148 logger);
0149 }
0150
0151 template <typename object_intersection_t>
0152 void updateStepSize(State& state,
0153 const object_intersection_t& oIntersection,
0154 Direction , bool release = true) const {
0155 detail::updateSingleStepSize<Stepper>(state, oIntersection, release);
0156 }
0157
0158 void updateStepSize(State& state, double stepSize,
0159 ConstrainedStep::Type stype,
0160 bool release = true) const {
0161 state.previousStepSize = state.stepSize.value();
0162 state.stepSize.update(stepSize, stype, release);
0163 }
0164
0165 double getStepSize(const State& state, ConstrainedStep::Type stype) const {
0166 return state.stepSize.value(stype);
0167 }
0168
0169 void releaseStepSize(State& state, ConstrainedStep::Type stype) const {
0170 state.stepSize.release(stype);
0171 }
0172
0173 std::string outputStepSize(const State& state) const {
0174 return state.stepSize.toString();
0175 }
0176
0177 Result<BoundState> boundState(
0178 State& state, const Surface& surface, bool ,
0179 const FreeToBoundCorrection&
0180 ) const {
0181 auto bound = BoundTrackParameters::create(
0182 surface.getSharedPtr(), tgContext, state.pos4, state.dir,
0183 state.q / state.p, std::nullopt, state.particleHypothesis);
0184 if (!bound.ok()) {
0185 return bound.error();
0186 }
0187 BoundState bState{std::move(*bound), Jacobian::Identity(),
0188 state.pathAccumulated};
0189 return bState;
0190 }
0191
0192 CurvilinearState curvilinearState(State& state, bool
0193 ) const {
0194 CurvilinearTrackParameters parameters(state.pos4, state.dir,
0195 state.q / state.p, std::nullopt,
0196 state.particleHypothesis);
0197
0198 CurvilinearState curvState{std::move(parameters), Jacobian::Identity(),
0199 state.pathAccumulated};
0200 return curvState;
0201 }
0202
0203 void update(State& , const FreeVector& ,
0204 const BoundVector& , const Covariance& ,
0205 const Surface& ) const {}
0206
0207 void update(State& , const Vector3& ,
0208 const Vector3& , double ,
0209 double ) const {}
0210
0211 void transportCovarianceToCurvilinear(State& ) const {}
0212
0213 void transportCovarianceToBound(
0214 State& , const Surface& ,
0215 const FreeToBoundCorrection& ) const {}
0216
0217 Result<Vector3> getField(State& , const Vector3& ) const {
0218
0219 return Result<Vector3>::success({0., 0., 0.});
0220 }
0221 };
0222
0223 static_assert(StepperConcept<Stepper>,
0224 "Dummy stepper does not fulfill concept");
0225
0226
0227 struct Options {
0228
0229
0230 bool debug = false;
0231 std::string debugString = "";
0232
0233 std::size_t debugPfxWidth = 30;
0234 std::size_t debugMsgWidth = 50;
0235
0236 Direction direction = Direction::Forward;
0237
0238 const Acts::Logger& logger = Acts::getDummyLogger();
0239
0240 ActsScalar surfaceTolerance = s_onSurfaceTolerance;
0241 };
0242
0243
0244 const Surface* startSurface = nullptr;
0245
0246
0247 const Surface* currentSurface = nullptr;
0248
0249
0250 const Surface* targetSurface = nullptr;
0251 bool targetReached = false;
0252
0253
0254 Options options;
0255
0256
0257 Stepper::State stepping;
0258
0259
0260 Navigator::State navigation;
0261
0262
0263 GeometryContext geoContext = GeometryContext();
0264 };
0265
0266 template <typename stepper_state_t>
0267 void step(stepper_state_t& sstate) {
0268
0269 sstate.pos4[Acts::ePos0] += sstate.stepSize.value() * sstate.dir[Acts::eMom0];
0270 sstate.pos4[Acts::ePos1] += sstate.stepSize.value() * sstate.dir[Acts::eMom1];
0271 sstate.pos4[Acts::ePos2] += sstate.stepSize.value() * sstate.dir[Acts::eMom2];
0272
0273 return;
0274 }
0275
0276
0277
0278
0279
0280
0281
0282
0283 bool testNavigatorStateVectors(Navigator::State& state, std::size_t navSurf,
0284 std::size_t navLay, std::size_t navBound,
0285 std::size_t extSurf) {
0286 return ((state.navSurfaces.size() == navSurf) &&
0287 (state.navLayers.size() == navLay) &&
0288 (state.navBoundaries.size() == navBound) &&
0289 (state.externalSurfaces.size() == extSurf));
0290 }
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304 bool testNavigatorStatePointers(
0305 Navigator::State& state, const TrackingVolume* worldVol,
0306 const TrackingVolume* startVol, const Layer* startLay,
0307 const Surface* startSurf, const Surface* currSurf,
0308 const TrackingVolume* currVol, const TrackingVolume* targetVol,
0309 const Layer* targetLay, const Surface* targetSurf) {
0310 return (
0311 (state.worldVolume == worldVol) && (state.startVolume == startVol) &&
0312 (state.startLayer == startLay) && (state.startSurface == startSurf) &&
0313 (state.currentSurface == currSurf) && (state.currentVolume == currVol) &&
0314 (state.targetVolume == targetVol) && (state.targetLayer == targetLay) &&
0315 (state.targetSurface == targetSurf));
0316 }
0317
0318
0319 CylindricalTrackingGeometry cGeometry(tgContext);
0320 auto tGeometry = cGeometry();
0321
0322
0323 bool debug = true;
0324
0325 BOOST_AUTO_TEST_CASE(Navigator_status_methods) {
0326
0327 Vector4 position4(0., 0., 0, 0);
0328 Vector3 momentum(1., 1., 0);
0329
0330
0331 PropagatorState state;
0332 state.options.debug = debug;
0333
0334
0335 state.stepping.pos4 = position4;
0336 state.stepping.dir = momentum.normalized();
0337
0338
0339 PropagatorState::Stepper stepper;
0340
0341
0342
0343
0344
0345 {
0346 Navigator::Config navCfg;
0347 navCfg.resolveSensitive = false;
0348 navCfg.resolveMaterial = false;
0349 navCfg.resolvePassive = false;
0350 Navigator navigator{navCfg};
0351
0352 navigator.postStep(state, stepper);
0353 BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u, 0u));
0354 BOOST_CHECK(testNavigatorStatePointers(state.navigation, nullptr, nullptr,
0355 nullptr, nullptr, nullptr, nullptr,
0356 nullptr, nullptr, nullptr));
0357 }
0358
0359
0360 {
0361 Navigator::Config navCfg;
0362 navCfg.resolveSensitive = false;
0363 navCfg.resolveMaterial = false;
0364 navCfg.resolvePassive = false;
0365 navCfg.trackingGeometry = tGeometry;
0366 Navigator navigator{navCfg};
0367
0368 navigator.postStep(state, stepper);
0369 BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u, 0u));
0370 BOOST_CHECK(testNavigatorStatePointers(state.navigation, nullptr, nullptr,
0371 nullptr, nullptr, nullptr, nullptr,
0372 nullptr, nullptr, nullptr));
0373 }
0374
0375
0376 {
0377 Navigator::Config navCfg;
0378 navCfg.resolveSensitive = true;
0379 navCfg.resolveMaterial = true;
0380 navCfg.resolvePassive = true;
0381 navCfg.trackingGeometry = tGeometry;
0382 Navigator navigator{navCfg};
0383
0384 state.navigation.navigationBreak = true;
0385
0386 state.navigation.targetReached = true;
0387 navigator.postStep(state, stepper);
0388 BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u, 0u));
0389 BOOST_CHECK(testNavigatorStatePointers(state.navigation, nullptr, nullptr,
0390 nullptr, nullptr, nullptr, nullptr,
0391 nullptr, nullptr, nullptr));
0392
0393
0394 state.navigation.targetReached = false;
0395 state.navigation.targetSurface = nullptr;
0396 navigator.postStep(state, stepper);
0397 BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u, 0u));
0398 BOOST_CHECK(testNavigatorStatePointers(state.navigation, nullptr, nullptr,
0399 nullptr, nullptr, nullptr, nullptr,
0400 nullptr, nullptr, nullptr));
0401
0402 const Surface* startSurf = tGeometry->getBeamline();
0403 state.stepping.pos4.segment<3>(Acts::ePos0) =
0404 startSurf->center(state.geoContext);
0405 const Surface* targetSurf = startSurf;
0406 state.navigation.targetSurface = targetSurf;
0407 navigator.postStep(state, stepper);
0408 BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u, 0u));
0409 BOOST_CHECK(testNavigatorStatePointers(
0410 state.navigation, nullptr, nullptr, nullptr, nullptr, targetSurf,
0411 nullptr, nullptr, nullptr, targetSurf));
0412
0413
0414
0415
0416
0417 state.navigation = Navigator::State();
0418 state.stepping.pos4 << 0., 0., 0., 0.;
0419 const TrackingVolume* worldVol = tGeometry->highestTrackingVolume();
0420 const TrackingVolume* startVol = tGeometry->lowestTrackingVolume(
0421 state.geoContext, stepper.position(state.stepping));
0422 const Layer* startLay = startVol->associatedLayer(
0423 state.geoContext, stepper.position(state.stepping));
0424 navigator.initialize(state, stepper);
0425 BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u, 0u));
0426 BOOST_CHECK(testNavigatorStatePointers(state.navigation, worldVol, startVol,
0427 startLay, nullptr, nullptr, startVol,
0428 nullptr, nullptr, nullptr));
0429
0430
0431 state.navigation = Navigator::State();
0432 state.navigation.startSurface = startSurf;
0433 navigator.initialize(state, stepper);
0434 BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u, 0u));
0435 BOOST_CHECK(testNavigatorStatePointers(
0436 state.navigation, worldVol, startVol, startLay, startSurf, startSurf,
0437 startVol, nullptr, nullptr, nullptr));
0438
0439
0440 state.navigation = Navigator::State();
0441 state.navigation.startVolume = startVol;
0442 navigator.initialize(state, stepper);
0443 BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u, 0u));
0444 BOOST_CHECK(testNavigatorStatePointers(state.navigation, worldVol, startVol,
0445 startLay, nullptr, nullptr, startVol,
0446 nullptr, nullptr, nullptr));
0447 }
0448 }
0449
0450 BOOST_AUTO_TEST_CASE(Navigator_target_methods) {
0451
0452 Navigator::Config navCfg;
0453 navCfg.trackingGeometry = tGeometry;
0454 navCfg.resolveSensitive = true;
0455 navCfg.resolveMaterial = true;
0456 navCfg.resolvePassive = false;
0457 Navigator navigator{navCfg};
0458
0459
0460 Vector4 position4(0., 0., 0, 0);
0461 Vector3 momentum(1., 1., 0);
0462
0463
0464 PropagatorState state;
0465 state.options.debug = debug;
0466
0467
0468 state.stepping.pos4 = position4;
0469 state.stepping.dir = momentum.normalized();
0470
0471
0472 if (debug) {
0473 std::cout << "<<<<<<<<<<<<<<<<<<<<< FORWARD NAVIGATION >>>>>>>>>>>>>>>>>>"
0474 << std::endl;
0475 }
0476
0477
0478 PropagatorState::Stepper stepper;
0479
0480
0481
0482
0483 navigator.initialize(state, stepper);
0484
0485 BOOST_CHECK_NE(state.navigation.currentVolume, nullptr);
0486
0487 BOOST_CHECK_EQUAL(state.navigation.currentVolume,
0488 state.navigation.startVolume);
0489
0490 BOOST_CHECK_EQUAL(state.navigation.currentSurface, nullptr);
0491
0492 BOOST_CHECK_EQUAL(state.navigation.navLayers.size(), 0u);
0493
0494 navigator.preStep(state, stepper);
0495
0496 BOOST_CHECK_EQUAL(state.navigation.navLayers.size(), 1u);
0497
0498 BOOST_CHECK_EQUAL(state.navigation.navLayerIndex, 0);
0499
0500 double beamPipeR = perp(state.navigation.navLayer().first.position());
0501
0502 CHECK_CLOSE_ABS(state.stepping.stepSize.value(), beamPipeR,
0503 s_onSurfaceTolerance);
0504 if (debug) {
0505 std::cout << "<<< Test 1a >>> initialize at "
0506 << toString(state.stepping.pos4) << std::endl;
0507 std::cout << state.options.debugString << std::endl;
0508
0509 state.options.debugString = "";
0510 }
0511
0512
0513 step(state.stepping);
0514
0515
0516
0517 navigator.postStep(state, stepper);
0518
0519 BOOST_CHECK_EQUAL(state.navigation.currentVolume,
0520 state.navigation.startVolume);
0521
0522 BOOST_CHECK_EQUAL(state.navigation.navLayers.size(), 1u);
0523
0524 BOOST_CHECK_EQUAL(state.navigation.navLayerIndex, 0);
0525
0526 navigator.preStep(state, stepper);
0527
0528 if (debug) {
0529 std::cout << "<<< Test 1b >>> step to the BeamPipe at "
0530 << toString(state.stepping.pos4) << std::endl;
0531 std::cout << state.options.debugString << std::endl;
0532 state.options.debugString = "";
0533 }
0534
0535
0536 step(state.stepping);
0537
0538
0539
0540 navigator.postStep(state, stepper);
0541
0542 navigator.preStep(state, stepper);
0543
0544 if (debug) {
0545 std::cout << "<<< Test 1c >>> step to the Boundary at "
0546 << toString(state.stepping.pos4) << std::endl;
0547 std::cout << state.options.debugString << std::endl;
0548 state.options.debugString = "";
0549 }
0550
0551
0552 step(state.stepping);
0553
0554
0555 navigator.postStep(state, stepper);
0556
0557 navigator.preStep(state, stepper);
0558
0559 if (debug) {
0560 std::cout << "<<< Test 1d >>> step to 1st layer at "
0561 << toString(state.stepping.pos4) << std::endl;
0562 std::cout << state.options.debugString << std::endl;
0563 state.options.debugString = "";
0564 }
0565
0566
0567 for (std::size_t isf = 0; isf < 5; ++isf) {
0568 step(state.stepping);
0569
0570
0571 navigator.postStep(state, stepper);
0572
0573 navigator.preStep(state, stepper);
0574
0575 if (debug) {
0576 std::cout << "<<< Test 1e-1i >>> step within 1st layer at "
0577 << toString(state.stepping.pos4) << std::endl;
0578 std::cout << state.options.debugString << std::endl;
0579 state.options.debugString = "";
0580 }
0581 }
0582
0583
0584 step(state.stepping);
0585
0586
0587 navigator.postStep(state, stepper);
0588
0589 navigator.preStep(state, stepper);
0590
0591 if (debug) {
0592 std::cout << "<<< Test 1j >>> step to 2nd layer at "
0593 << toString(state.stepping.pos4) << std::endl;
0594 std::cout << state.options.debugString << std::endl;
0595 state.options.debugString = "";
0596 }
0597
0598
0599 for (std::size_t isf = 0; isf < 5; ++isf) {
0600 step(state.stepping);
0601
0602
0603 navigator.postStep(state, stepper);
0604
0605 navigator.preStep(state, stepper);
0606
0607 if (debug) {
0608 std::cout << "<<< Test 1k-1o >>> step within 2nd layer at "
0609 << toString(state.stepping.pos4) << std::endl;
0610 std::cout << state.options.debugString << std::endl;
0611 state.options.debugString = "";
0612 }
0613 }
0614
0615
0616 step(state.stepping);
0617
0618
0619 navigator.postStep(state, stepper);
0620
0621 navigator.preStep(state, stepper);
0622
0623 if (debug) {
0624 std::cout << "<<< Test 1p >>> step to 3rd layer at "
0625 << toString(state.stepping.pos4) << std::endl;
0626 std::cout << state.options.debugString << std::endl;
0627 state.options.debugString = "";
0628 }
0629
0630
0631 for (std::size_t isf = 0; isf < 3; ++isf) {
0632 step(state.stepping);
0633
0634
0635 navigator.postStep(state, stepper);
0636
0637 navigator.preStep(state, stepper);
0638
0639 if (debug) {
0640 std::cout << "<<< Test 1q-1s >>> step within 3rd layer at "
0641 << toString(state.stepping.pos4) << std::endl;
0642 std::cout << state.options.debugString << std::endl;
0643 state.options.debugString = "";
0644 }
0645 }
0646
0647
0648 step(state.stepping);
0649
0650
0651 navigator.postStep(state, stepper);
0652
0653 navigator.preStep(state, stepper);
0654
0655 if (debug) {
0656 std::cout << "<<< Test 1t >>> step to 4th layer at "
0657 << toString(state.stepping.pos4) << std::endl;
0658 std::cout << state.options.debugString << std::endl;
0659 state.options.debugString = "";
0660 }
0661
0662
0663 for (std::size_t isf = 0; isf < 3; ++isf) {
0664 step(state.stepping);
0665
0666
0667 navigator.postStep(state, stepper);
0668
0669 navigator.preStep(state, stepper);
0670
0671 if (debug) {
0672 std::cout << "<<< Test 1t-1v >>> step within 4th layer at "
0673 << toString(state.stepping.pos4) << std::endl;
0674 std::cout << state.options.debugString << std::endl;
0675 state.options.debugString = "";
0676 }
0677 }
0678
0679
0680 step(state.stepping);
0681
0682
0683 navigator.postStep(state, stepper);
0684
0685 navigator.preStep(state, stepper);
0686
0687 if (debug) {
0688 std::cout << "<<< Test 1w >>> step to boundary at "
0689 << toString(state.stepping.pos4) << std::endl;
0690 std::cout << state.options.debugString << std::endl;
0691 state.options.debugString = "";
0692 }
0693 }
0694
0695 }