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/Direction.hpp"
0015 #include "Acts/Definitions/TrackParametrization.hpp"
0016 #include "Acts/Definitions/Units.hpp"
0017 #include "Acts/EventData/GenericCurvilinearTrackParameters.hpp"
0018 #include "Acts/EventData/TrackParameters.hpp"
0019 #include "Acts/Geometry/GeometryContext.hpp"
0020 #include "Acts/Geometry/GeometryIdentifier.hpp"
0021 #include "Acts/MagneticField/ConstantBField.hpp"
0022 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0023 #include "Acts/Propagator/AbortList.hpp"
0024 #include "Acts/Propagator/ActionList.hpp"
0025 #include "Acts/Propagator/EigenStepper.hpp"
0026 #include "Acts/Propagator/MaterialInteractor.hpp"
0027 #include "Acts/Propagator/Navigator.hpp"
0028 #include "Acts/Propagator/Propagator.hpp"
0029 #include "Acts/Propagator/StandardAborters.hpp"
0030 #include "Acts/Propagator/StraightLineStepper.hpp"
0031 #include "Acts/Surfaces/Surface.hpp"
0032 #include "Acts/Tests/CommonHelpers/CylindricalTrackingGeometry.hpp"
0033 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0034
0035 #include <algorithm>
0036 #include <array>
0037 #include <cmath>
0038 #include <iostream>
0039 #include <memory>
0040 #include <optional>
0041 #include <random>
0042 #include <tuple>
0043 #include <utility>
0044 #include <vector>
0045
0046 namespace bdata = boost::unit_test::data;
0047 using namespace Acts::UnitLiterals;
0048
0049 namespace Acts::Test {
0050
0051
0052 GeometryContext tgContext = GeometryContext();
0053 MagneticFieldContext mfContext = MagneticFieldContext();
0054
0055
0056 CylindricalTrackingGeometry cGeometry(tgContext);
0057 auto tGeometry = cGeometry();
0058
0059
0060 Navigator navigatorES({tGeometry});
0061 Navigator navigatorSL({tGeometry});
0062
0063 using BField = ConstantBField;
0064 using EigenStepper = Acts::EigenStepper<>;
0065 using EigenPropagator = Propagator<EigenStepper, Navigator>;
0066 using StraightLinePropagator = Propagator<StraightLineStepper, Navigator>;
0067
0068 const double Bz = 2_T;
0069 auto bField = std::make_shared<BField>(Vector3{0, 0, Bz});
0070 EigenStepper estepper(bField);
0071 EigenPropagator epropagator(std::move(estepper), std::move(navigatorES));
0072
0073 StraightLineStepper slstepper;
0074 StraightLinePropagator slpropagator(slstepper, std::move(navigatorSL));
0075 const int ntests = 500;
0076 const int skip = 0;
0077 bool debugModeFwd = false;
0078 bool debugModeBwd = false;
0079 bool debugModeFwdStep = false;
0080 bool debugModeBwdStep = false;
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092 template <typename propagator_t>
0093 void runTest(const propagator_t& prop, double pT, double phi, double theta,
0094 int charge, int index) {
0095 double p = pT / sin(theta);
0096 double q = -1 + 2 * charge;
0097
0098 if (index < skip) {
0099 return;
0100 }
0101
0102
0103 BoundSquareMatrix cov;
0104
0105
0106 cov <<
0107 10_mm, 0, 0.123, 0, 0.5, 0,
0108 0, 10_mm, 0, 0.162, 0, 0,
0109 0.123, 0, 0.1, 0, 0, 0,
0110 0, 0.162, 0, 0.1, 0, 0,
0111 0.5, 0, 0, 0, 1_e / 10_GeV, 0,
0112 0, 0, 0, 0, 0, 1_us;
0113
0114 CurvilinearTrackParameters start(Vector4(0, 0, 0, 0), phi, theta, q / p, cov,
0115 ParticleHypothesis::pion());
0116
0117
0118 using ActionListType = ActionList<MaterialInteractor>;
0119 using AbortListType = AbortList<>;
0120
0121 using Options = PropagatorOptions<ActionListType, AbortListType>;
0122 Options fwdOptions(tgContext, mfContext);
0123
0124 fwdOptions.maxStepSize = 25_cm;
0125 fwdOptions.pathLimit = 25_cm;
0126
0127
0128 auto& fwdMaterialInteractor =
0129 fwdOptions.actionList.template get<MaterialInteractor>();
0130 fwdMaterialInteractor.recordInteractions = true;
0131 fwdMaterialInteractor.energyLoss = false;
0132 fwdMaterialInteractor.multipleScattering = false;
0133
0134 if (debugModeFwd) {
0135 std::cout << ">>> Forward Propagation : start." << std::endl;
0136 }
0137
0138 const auto& fwdResult = prop.propagate(start, fwdOptions).value();
0139 auto& fwdMaterial = fwdResult.template get<MaterialInteractor::result_type>();
0140
0141 BOOST_CHECK_NE(fwdMaterial.materialInX0, 0.);
0142 BOOST_CHECK_NE(fwdMaterial.materialInL0, 0.);
0143
0144 double fwdStepMaterialInX0 = 0.;
0145 double fwdStepMaterialInL0 = 0.;
0146
0147 for (auto& mInteraction : fwdMaterial.materialInteractions) {
0148 fwdStepMaterialInX0 += mInteraction.materialSlab.thicknessInX0();
0149 fwdStepMaterialInL0 += mInteraction.materialSlab.thicknessInL0();
0150 }
0151 CHECK_CLOSE_REL(fwdMaterial.materialInX0, fwdStepMaterialInX0, 1e-3);
0152 CHECK_CLOSE_REL(fwdMaterial.materialInL0, fwdStepMaterialInL0, 1e-3);
0153
0154
0155 if (debugModeFwd) {
0156
0157 std::cout << ">>> Material steps found on ..." << std::endl;
0158 for (auto& fwdStepsC : fwdMaterial.materialInteractions) {
0159 std::cout << "--> Surface with " << fwdStepsC.surface->geometryId()
0160 << std::endl;
0161 }
0162 }
0163
0164
0165 Options bwdOptions(tgContext, mfContext);
0166 bwdOptions.maxStepSize = 25_cm;
0167 bwdOptions.pathLimit = -25_cm;
0168 bwdOptions.direction = Direction::Backward;
0169
0170
0171 auto& bwdMaterialInteractor =
0172 bwdOptions.actionList.template get<MaterialInteractor>();
0173 bwdMaterialInteractor.recordInteractions = true;
0174 bwdMaterialInteractor.energyLoss = false;
0175 bwdMaterialInteractor.multipleScattering = false;
0176
0177 const auto& startSurface = start.referenceSurface();
0178
0179 if (debugModeBwd) {
0180 std::cout << ">>> Backward Propagation : start." << std::endl;
0181 }
0182 const auto& bwdResult =
0183 prop.propagate(*fwdResult.endParameters, startSurface, bwdOptions)
0184 .value();
0185
0186 if (debugModeBwd) {
0187 std::cout << ">>> Backward Propagation : end." << std::endl;
0188 }
0189
0190 auto& bwdMaterial =
0191 bwdResult.template get<typename MaterialInteractor::result_type>();
0192
0193 BOOST_CHECK_NE(bwdMaterial.materialInX0, 0.);
0194 BOOST_CHECK_NE(bwdMaterial.materialInL0, 0.);
0195
0196 double bwdStepMaterialInX0 = 0.;
0197 double bwdStepMaterialInL0 = 0.;
0198
0199 for (auto& mInteraction : bwdMaterial.materialInteractions) {
0200 bwdStepMaterialInX0 += mInteraction.materialSlab.thicknessInX0();
0201 bwdStepMaterialInL0 += mInteraction.materialSlab.thicknessInL0();
0202 }
0203 CHECK_CLOSE_REL(bwdMaterial.materialInX0, bwdStepMaterialInX0, 1e-3);
0204 CHECK_CLOSE_REL(bwdMaterial.materialInL0, bwdStepMaterialInL0, 1e-3);
0205
0206
0207 if (debugModeBwd) {
0208
0209 std::cout << ">>> Material steps found on ..." << std::endl;
0210 for (auto& bwdStepsC : bwdMaterial.materialInteractions) {
0211 std::cout << "--> Surface with " << bwdStepsC.surface->geometryId()
0212 << std::endl;
0213 }
0214 }
0215
0216
0217 BOOST_CHECK_EQUAL(bwdMaterial.materialInteractions.size(),
0218 fwdMaterial.materialInteractions.size());
0219
0220 CHECK_CLOSE_REL(bwdMaterial.materialInX0, fwdMaterial.materialInX0, 1e-3);
0221 CHECK_CLOSE_REL(bwdMaterial.materialInL0, bwdMaterial.materialInL0, 1e-3);
0222
0223
0224
0225 Options fwdStepOptions(tgContext, mfContext);
0226 fwdStepOptions.maxStepSize = 25_cm;
0227 fwdStepOptions.pathLimit = 25_cm;
0228
0229
0230 auto& fwdStepMaterialInteractor =
0231 fwdStepOptions.actionList.template get<MaterialInteractor>();
0232 fwdStepMaterialInteractor.recordInteractions = true;
0233 fwdStepMaterialInteractor.energyLoss = false;
0234 fwdStepMaterialInteractor.multipleScattering = false;
0235
0236 double fwdStepStepMaterialInX0 = 0.;
0237 double fwdStepStepMaterialInL0 = 0.;
0238
0239 if (debugModeFwdStep) {
0240
0241 std::cout << ">>> Forward steps to be processed sequentially ..."
0242 << std::endl;
0243 for (auto& fwdStepsC : fwdMaterial.materialInteractions) {
0244 std::cout << "--> Surface with " << fwdStepsC.surface->geometryId()
0245 << std::endl;
0246 }
0247 }
0248
0249
0250 BoundTrackParameters sParameters = start;
0251 std::vector<BoundTrackParameters> stepParameters;
0252 for (auto& fwdSteps : fwdMaterial.materialInteractions) {
0253 if (debugModeFwdStep) {
0254 std::cout << ">>> Forward step : "
0255 << sParameters.referenceSurface().geometryId() << " --> "
0256 << fwdSteps.surface->geometryId() << std::endl;
0257 }
0258
0259
0260 const auto& fwdStep =
0261 prop.propagate(sParameters, (*fwdSteps.surface), fwdStepOptions)
0262 .value();
0263
0264 auto& fwdStepMaterial =
0265 fwdStep.template get<typename MaterialInteractor::result_type>();
0266 fwdStepStepMaterialInX0 += fwdStepMaterial.materialInX0;
0267 fwdStepStepMaterialInL0 += fwdStepMaterial.materialInL0;
0268
0269 if (fwdStep.endParameters.has_value()) {
0270
0271 stepParameters.push_back(*fwdStep.endParameters);
0272 sParameters = stepParameters.back();
0273 }
0274 }
0275
0276 const Surface& dSurface = fwdResult.endParameters->referenceSurface();
0277
0278 if (debugModeFwdStep) {
0279 std::cout << ">>> Forward step : "
0280 << sParameters.referenceSurface().geometryId() << " --> "
0281 << dSurface.geometryId() << std::endl;
0282 }
0283
0284 const auto& fwdStepFinal =
0285 prop.propagate(sParameters, dSurface, fwdStepOptions).value();
0286
0287 auto& fwdStepMaterial =
0288 fwdStepFinal.template get<typename MaterialInteractor::result_type>();
0289 fwdStepStepMaterialInX0 += fwdStepMaterial.materialInX0;
0290 fwdStepStepMaterialInL0 += fwdStepMaterial.materialInL0;
0291
0292
0293 CHECK_CLOSE_REL(fwdStepStepMaterialInX0, fwdStepMaterialInX0, 1e-3);
0294 CHECK_CLOSE_REL(fwdStepStepMaterialInL0, fwdStepMaterialInL0, 1e-3);
0295
0296
0297
0298 Options bwdStepOptions(tgContext, mfContext);
0299
0300 bwdStepOptions.maxStepSize = 25_cm;
0301 bwdStepOptions.pathLimit = -25_cm;
0302 bwdStepOptions.direction = Direction::Backward;
0303
0304
0305 auto& bwdStepMaterialInteractor =
0306 bwdStepOptions.actionList.template get<MaterialInteractor>();
0307 bwdStepMaterialInteractor.recordInteractions = true;
0308 bwdStepMaterialInteractor.multipleScattering = false;
0309 bwdStepMaterialInteractor.energyLoss = false;
0310
0311 double bwdStepStepMaterialInX0 = 0.;
0312 double bwdStepStepMaterialInL0 = 0.;
0313
0314 if (debugModeBwdStep) {
0315
0316 std::cout << ">>> Backward steps to be processed sequentially ..."
0317 << std::endl;
0318 for (auto& bwdStepsC : bwdMaterial.materialInteractions) {
0319 std::cout << "--> Surface with " << bwdStepsC.surface->geometryId()
0320 << std::endl;
0321 }
0322 }
0323
0324
0325 sParameters = *fwdResult.endParameters;
0326 for (auto& bwdSteps : bwdMaterial.materialInteractions) {
0327 if (debugModeBwdStep) {
0328 std::cout << ">>> Backward step : "
0329 << sParameters.referenceSurface().geometryId() << " --> "
0330 << bwdSteps.surface->geometryId() << std::endl;
0331 }
0332
0333 const auto& bwdStep =
0334 prop.propagate(sParameters, (*bwdSteps.surface), bwdStepOptions)
0335 .value();
0336
0337 auto& bwdStepMaterial =
0338 bwdStep.template get<typename MaterialInteractor::result_type>();
0339 bwdStepStepMaterialInX0 += bwdStepMaterial.materialInX0;
0340 bwdStepStepMaterialInL0 += bwdStepMaterial.materialInL0;
0341
0342 if (bwdStep.endParameters.has_value()) {
0343
0344 stepParameters.push_back(*bwdStep.endParameters);
0345 sParameters = stepParameters.back();
0346 }
0347 }
0348
0349 const Surface& dbSurface = start.referenceSurface();
0350
0351 if (debugModeBwdStep) {
0352 std::cout << ">>> Backward step : "
0353 << sParameters.referenceSurface().geometryId() << " --> "
0354 << dSurface.geometryId() << std::endl;
0355 }
0356
0357 const auto& bwdStepFinal =
0358 prop.propagate(sParameters, dbSurface, bwdStepOptions).value();
0359
0360 auto& bwdStepMaterial =
0361 bwdStepFinal.template get<typename MaterialInteractor::result_type>();
0362 bwdStepStepMaterialInX0 += bwdStepMaterial.materialInX0;
0363 bwdStepStepMaterialInL0 += bwdStepMaterial.materialInL0;
0364
0365
0366 CHECK_CLOSE_REL(bwdStepStepMaterialInX0, bwdStepMaterialInX0, 1e-3);
0367 CHECK_CLOSE_REL(bwdStepStepMaterialInL0, bwdStepMaterialInL0, 1e-3);
0368
0369
0370
0371 auto& covfwdMaterialInteractor =
0372 fwdOptions.actionList.template get<MaterialInteractor>();
0373 covfwdMaterialInteractor.recordInteractions = false;
0374 covfwdMaterialInteractor.energyLoss = true;
0375 covfwdMaterialInteractor.multipleScattering = true;
0376
0377
0378 const auto& covfwdResult = prop.propagate(start, fwdOptions).value();
0379
0380 BOOST_CHECK_LE(
0381 cov.determinant(),
0382 covfwdResult.endParameters->covariance().value().determinant());
0383 }
0384
0385
0386
0387 BOOST_DATA_TEST_CASE(
0388 test_material_collector,
0389 bdata::random((bdata::engine = std::mt19937(), bdata::seed = 20,
0390 bdata::distribution = std::uniform_real_distribution<double>(
0391 0.5_GeV, 10_GeV))) ^
0392 bdata::random((bdata::engine = std::mt19937(), bdata::seed = 21,
0393 bdata::distribution =
0394 std::uniform_real_distribution<double>(-M_PI,
0395 M_PI))) ^
0396 bdata::random(
0397 (bdata::engine = std::mt19937(), bdata::seed = 22,
0398 bdata::distribution =
0399 std::uniform_real_distribution<double>(1.0, M_PI - 1.0))) ^
0400 bdata::random((bdata::engine = std::mt19937(), bdata::seed = 23,
0401 bdata::distribution =
0402 std::uniform_int_distribution<std::uint8_t>(0, 1))) ^
0403 bdata::xrange(ntests),
0404 pT, phi, theta, charge, index) {
0405 runTest(epropagator, pT, phi, theta, charge, index);
0406 runTest(slpropagator, pT, phi, theta, charge, index);
0407 }
0408
0409 }