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