File indexing completed on 2025-01-18 09:12:29
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/Units.hpp"
0014 #include "Acts/EventData/TrackParameters.hpp"
0015 #include "Acts/Geometry/GeometryContext.hpp"
0016 #include "Acts/MagneticField/ConstantBField.hpp"
0017 #include "Acts/Propagator/EigenStepper.hpp"
0018 #include "Acts/Propagator/Navigator.hpp"
0019 #include "Acts/Propagator/Propagator.hpp"
0020 #include "Acts/Propagator/StraightLineStepper.hpp"
0021 #include "Acts/Propagator/SurfaceCollector.hpp"
0022 #include "Acts/Propagator/TryAllNavigator.hpp"
0023 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0024 #include "Acts/Tests/CommonHelpers/CylindricalTrackingGeometry.hpp"
0025 #include "Acts/Utilities/Logger.hpp"
0026 #include "Acts/Utilities/VectorHelpers.hpp"
0027
0028 #include <algorithm>
0029 #include <numbers>
0030
0031 namespace bdata = boost::unit_test::data;
0032 using namespace Acts::UnitLiterals;
0033 using Acts::VectorHelpers::perp;
0034
0035 namespace Acts::Test {
0036
0037
0038 GeometryContext tgContext = GeometryContext();
0039 MagneticFieldContext mfContext = MagneticFieldContext();
0040
0041 CylindricalTrackingGeometry cGeometry(tgContext);
0042 auto tGeometry = cGeometry();
0043
0044 const double Bz = 2_T;
0045 auto bField = std::make_shared<ConstantBField>(Vector3{0, 0, Bz});
0046
0047 using SurfaceCollector = SurfaceCollector<SurfaceSelector>;
0048
0049 std::vector<GeometryIdentifier> collectRelevantGeoIds(
0050 const SurfaceCollector::result_type& surfaceHits) {
0051 std::vector<GeometryIdentifier> geoIds;
0052 for (const auto& surfaceHit : surfaceHits.collected) {
0053 auto geoId = surfaceHit.surface->geometryId();
0054 auto material = surfaceHit.surface->surfaceMaterial();
0055 if (geoId.sensitive() == 0 && material == nullptr) {
0056 continue;
0057 }
0058 geoIds.push_back(geoId);
0059 }
0060 return geoIds;
0061 }
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071 template <typename propagator_t>
0072 void runSelfConsistencyTest(const propagator_t& prop,
0073 const CurvilinearTrackParameters& start,
0074 const Acts::Logger& logger) {
0075
0076 using ActorList = ActorList<SurfaceCollector>;
0077 using Options = typename propagator_t::template Options<ActorList>;
0078
0079
0080 Options fwdOptions(tgContext, mfContext);
0081 fwdOptions.pathLimit = 25_cm;
0082
0083
0084 auto& fwdSurfaceCollector =
0085 fwdOptions.actorList.template get<SurfaceCollector>();
0086 fwdSurfaceCollector.selector.selectSensitive = true;
0087 fwdSurfaceCollector.selector.selectMaterial = true;
0088 fwdSurfaceCollector.selector.selectPassive = true;
0089
0090 ACTS_DEBUG(">>> Forward Propagation : start.");
0091 auto fwdResult = prop.propagate(start, fwdOptions).value();
0092 auto fwdSurfaceHits =
0093 fwdResult.template get<SurfaceCollector::result_type>().collected;
0094 auto fwdSurfaces = collectRelevantGeoIds(
0095 fwdResult.template get<SurfaceCollector::result_type>());
0096
0097 ACTS_DEBUG(">>> Surface hits found on ...");
0098 for (const auto& fwdSteps : fwdSurfaces) {
0099 ACTS_DEBUG("--> Surface with " << fwdSteps);
0100 }
0101 ACTS_DEBUG(">>> Forward Propagation : end.");
0102
0103
0104 Options bwdOptions(tgContext, mfContext);
0105 bwdOptions.pathLimit = 25_cm;
0106 bwdOptions.direction = Direction::Backward();
0107
0108
0109 auto& bwdMSurfaceCollector =
0110 bwdOptions.actorList.template get<SurfaceCollector>();
0111 bwdMSurfaceCollector.selector.selectSensitive = true;
0112 bwdMSurfaceCollector.selector.selectMaterial = true;
0113 bwdMSurfaceCollector.selector.selectPassive = true;
0114
0115 const auto& startSurface = start.referenceSurface();
0116
0117 ACTS_DEBUG(">>> Backward Propagation : start.");
0118 auto bwdResult =
0119 prop.propagate(*fwdResult.endParameters, startSurface, bwdOptions)
0120 .value();
0121 auto bwdSurfaceHits =
0122 bwdResult.template get<SurfaceCollector::result_type>().collected;
0123 auto bwdSurfaces = collectRelevantGeoIds(
0124 bwdResult.template get<SurfaceCollector::result_type>());
0125
0126 ACTS_DEBUG(">>> Surface hits found on ...");
0127 for (auto& bwdSteps : bwdSurfaces) {
0128 ACTS_DEBUG("--> Surface with " << bwdSteps);
0129 }
0130 ACTS_DEBUG(">>> Backward Propagation : end.");
0131
0132
0133 {
0134 std::ranges::reverse(bwdSurfaces);
0135 BOOST_CHECK_EQUAL_COLLECTIONS(bwdSurfaces.begin(), bwdSurfaces.end(),
0136 fwdSurfaces.begin(), fwdSurfaces.end());
0137 }
0138
0139
0140
0141 Options fwdStepOptions(tgContext, mfContext);
0142
0143
0144 auto& fwdStepSurfaceCollector =
0145 fwdOptions.actorList.template get<SurfaceCollector>();
0146 fwdStepSurfaceCollector.selector.selectSensitive = true;
0147 fwdStepSurfaceCollector.selector.selectMaterial = true;
0148 fwdStepSurfaceCollector.selector.selectPassive = true;
0149
0150 std::vector<GeometryIdentifier> fwdStepSurfaces;
0151
0152
0153 BoundTrackParameters sParameters = start;
0154 std::vector<BoundTrackParameters> stepParameters;
0155 for (auto& fwdSteps : fwdSurfaceHits) {
0156 ACTS_DEBUG(">>> Forward step : "
0157 << sParameters.referenceSurface().geometryId() << " --> "
0158 << fwdSteps.surface->geometryId());
0159
0160
0161 auto fwdStep =
0162 prop.propagate(sParameters, *fwdSteps.surface, fwdStepOptions).value();
0163
0164 auto fwdStepSurfacesTmp = collectRelevantGeoIds(
0165 fwdStep.template get<SurfaceCollector::result_type>());
0166 fwdStepSurfaces.insert(fwdStepSurfaces.end(), fwdStepSurfacesTmp.begin(),
0167 fwdStepSurfacesTmp.end());
0168
0169 if (fwdStep.endParameters.has_value()) {
0170
0171 stepParameters.push_back(*fwdStep.endParameters);
0172 sParameters = stepParameters.back();
0173 }
0174 }
0175
0176 const Surface& dSurface = fwdResult.endParameters->referenceSurface();
0177 ACTS_DEBUG(">>> Forward step : "
0178 << sParameters.referenceSurface().geometryId() << " --> "
0179 << dSurface.geometryId());
0180 auto fwdStepFinal =
0181 prop.propagate(sParameters, dSurface, fwdStepOptions).value();
0182 auto fwdStepSurfacesTmp = collectRelevantGeoIds(
0183 fwdStepFinal.template get<SurfaceCollector::result_type>());
0184 fwdStepSurfaces.insert(fwdStepSurfaces.end(), fwdStepSurfacesTmp.begin(),
0185 fwdStepSurfacesTmp.end());
0186
0187
0188
0189
0190
0191 Options bwdStepOptions(tgContext, mfContext);
0192 bwdStepOptions.direction = Direction::Backward();
0193
0194
0195 auto& bwdStepSurfaceCollector =
0196 bwdOptions.actorList.template get<SurfaceCollector>();
0197 bwdStepSurfaceCollector.selector.selectSensitive = true;
0198 bwdStepSurfaceCollector.selector.selectMaterial = true;
0199 bwdStepSurfaceCollector.selector.selectPassive = true;
0200
0201 std::vector<GeometryIdentifier> bwdStepSurfaces;
0202
0203
0204 sParameters = *fwdResult.endParameters;
0205 for (auto& bwdSteps : bwdSurfaceHits) {
0206 ACTS_DEBUG(">>> Backward step : "
0207 << sParameters.referenceSurface().geometryId() << " --> "
0208 << bwdSteps.surface->geometryId());
0209
0210
0211 auto bwdStep =
0212 prop.propagate(sParameters, *bwdSteps.surface, bwdStepOptions).value();
0213
0214 auto bwdStepSurfacesTmp = collectRelevantGeoIds(
0215 bwdStep.template get<SurfaceCollector::result_type>());
0216 bwdStepSurfaces.insert(bwdStepSurfaces.end(), bwdStepSurfacesTmp.begin(),
0217 bwdStepSurfacesTmp.end());
0218
0219 if (bwdStep.endParameters.has_value()) {
0220
0221 stepParameters.push_back(*bwdStep.endParameters);
0222 sParameters = stepParameters.back();
0223 }
0224 }
0225
0226 const Surface& dbSurface = start.referenceSurface();
0227 ACTS_DEBUG(">>> Backward step : "
0228 << sParameters.referenceSurface().geometryId() << " --> "
0229 << dSurface.geometryId());
0230 auto bwdStepFinal =
0231 prop.propagate(sParameters, dbSurface, bwdStepOptions).value();
0232 auto bwdStepSurfacesTmp = collectRelevantGeoIds(
0233 bwdStepFinal.template get<SurfaceCollector::result_type>());
0234 bwdStepSurfaces.insert(bwdStepSurfaces.end(), bwdStepSurfacesTmp.begin(),
0235 bwdStepSurfacesTmp.end());
0236
0237
0238
0239 std::ranges::reverse(bwdStepSurfaces);
0240 BOOST_CHECK_EQUAL_COLLECTIONS(bwdStepSurfaces.begin(), bwdStepSurfaces.end(),
0241 fwdStepSurfaces.begin(), fwdStepSurfaces.end());
0242 }
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254 template <typename propagator_probe_t, typename propagator_ref_t>
0255 void runConsistencyTest(const propagator_probe_t& propProbe,
0256 const propagator_ref_t& propRef,
0257 const CurvilinearTrackParameters& start,
0258 const Acts::Logger& logger) {
0259
0260 using ActorList = ActorList<SurfaceCollector>;
0261
0262 auto run = [&](const auto& prop) {
0263 using propagator_t = std::decay_t<decltype(prop)>;
0264 using Options = typename propagator_t::template Options<ActorList>;
0265
0266
0267 Options fwdOptions(tgContext, mfContext);
0268 fwdOptions.pathLimit = 25_cm;
0269 fwdOptions.stepping.maxStepSize = 1_cm;
0270
0271
0272 auto& fwdSurfaceCollector =
0273 fwdOptions.actorList.template get<SurfaceCollector>();
0274 fwdSurfaceCollector.selector.selectSensitive = true;
0275 fwdSurfaceCollector.selector.selectMaterial = true;
0276 fwdSurfaceCollector.selector.selectPassive = true;
0277
0278 auto fwdResult = prop.propagate(start, fwdOptions).value();
0279 auto fwdSurfaces = collectRelevantGeoIds(
0280 fwdResult.template get<SurfaceCollector::result_type>());
0281
0282 ACTS_DEBUG(">>> Surface hits found on ...");
0283 for (const auto& fwdSteps : fwdSurfaces) {
0284 ACTS_DEBUG("--> Surface with " << fwdSteps);
0285 }
0286
0287 return fwdSurfaces;
0288 };
0289
0290 ACTS_DEBUG(">>> Probe Propagation : start.");
0291 const auto& probeSurfaces = run(propProbe);
0292 ACTS_DEBUG(">>> Probe Propagation : end.");
0293
0294 ACTS_DEBUG(">>> Reference Propagation : start.");
0295 const auto& refSurfaces = run(propRef);
0296 ACTS_DEBUG(">>> Reference Propagation : end.");
0297
0298
0299 BOOST_CHECK_EQUAL_COLLECTIONS(probeSurfaces.begin(), probeSurfaces.end(),
0300 refSurfaces.begin(), refSurfaces.end());
0301 }
0302
0303 Acts::Logging::Level logLevel = Acts::Logging::INFO;
0304
0305 const int nTestsSelfConsistency = 500;
0306 const int nTestsRefConsistency = 500;
0307
0308 using StraightLinePropagator = Propagator<StraightLineStepper, Navigator>;
0309 using EigenStepper = Acts::EigenStepper<>;
0310 using EigenPropagator = Propagator<EigenStepper, Navigator>;
0311 using Reference1StraightLinePropagator =
0312 Propagator<StraightLineStepper, TryAllNavigator>;
0313 using Reference1EigenPropagator = Propagator<EigenStepper, TryAllNavigator>;
0314 using Reference2StraightLinePropagator =
0315 Propagator<StraightLineStepper, TryAllOverstepNavigator>;
0316 using Reference2EigenPropagator =
0317 Propagator<EigenStepper, TryAllOverstepNavigator>;
0318
0319 StraightLineStepper slstepper;
0320 EigenStepper estepper(bField);
0321
0322 StraightLinePropagator slpropagator(slstepper,
0323 Navigator({tGeometry, true, true, false},
0324 getDefaultLogger("sl_nav",
0325 Logging::INFO)),
0326 getDefaultLogger("sl_prop", Logging::INFO));
0327 EigenPropagator epropagator(estepper,
0328 Navigator({tGeometry, true, true, false},
0329 getDefaultLogger("e_nav", Logging::INFO)),
0330 getDefaultLogger("e_prop", Logging::INFO));
0331
0332 Reference1StraightLinePropagator refslpropagator1(
0333 slstepper,
0334 TryAllNavigator({tGeometry, true, true, false},
0335 getDefaultLogger("ref1_sl_nav", Logging::INFO)),
0336 getDefaultLogger("ref1_sl_prop", Logging::INFO));
0337 Reference1EigenPropagator refepropagator1(
0338 estepper,
0339 TryAllNavigator({tGeometry, true, true, false,
0340 BoundaryTolerance::Infinite()},
0341 getDefaultLogger("ref1_e_nav", Logging::INFO)),
0342 getDefaultLogger("ref1_e_prop", Logging::INFO));
0343
0344 Reference2EigenPropagator refepropagator2(
0345 estepper,
0346 TryAllOverstepNavigator({tGeometry, true, true, false,
0347 BoundaryTolerance::Infinite()},
0348 getDefaultLogger("ref2_e_nav", Logging::INFO)),
0349 getDefaultLogger("ref2_e_prop", Logging::INFO));
0350 Reference2StraightLinePropagator refslpropagator2(
0351 slstepper,
0352 TryAllOverstepNavigator({tGeometry, true, true, false},
0353 getDefaultLogger("ref2_sl_nav", Logging::INFO)),
0354 getDefaultLogger("ref2_sl_prop", Logging::INFO));
0355
0356 auto eventGen =
0357 bdata::random((bdata::engine = std::mt19937(), bdata::seed = 20,
0358 bdata::distribution = std::uniform_real_distribution<double>(
0359 0.5_GeV, 10_GeV))) ^
0360 bdata::random((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((bdata::engine = std::mt19937(), bdata::seed = 22,
0364 bdata::distribution = std::uniform_real_distribution<double>(
0365 1., std::numbers::pi - 1.))) ^
0366 bdata::random(
0367 (bdata::engine = std::mt19937(), bdata::seed = 23,
0368 bdata::distribution = std::uniform_int_distribution<int>(0, 1)));
0369
0370 CurvilinearTrackParameters createStartParameters(double pT, double phi,
0371 double theta, int charge) {
0372 double p = pT / std::sin(theta);
0373 double q = -1 + 2 * charge;
0374 return CurvilinearTrackParameters(Vector4(0, 0, 0, 0), phi, theta, q / p,
0375 std::nullopt, ParticleHypothesis::pion());
0376 }
0377
0378 BOOST_DATA_TEST_CASE(NavigatorStraightLineSelfConsistency,
0379 eventGen ^ bdata::xrange(nTestsSelfConsistency), pT, phi,
0380 theta, charge, index) {
0381 ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("NavigatorTest", logLevel));
0382
0383 CurvilinearTrackParameters start =
0384 createStartParameters(pT, phi, theta, charge);
0385
0386 ACTS_DEBUG(">>> Run navigation tests with:\n pT = "
0387 << pT << "\n phi = " << phi << "\n theta = " << theta
0388 << "\n charge = " << charge << "\n index = " << index);
0389
0390 ACTS_DEBUG(">>> Test self consistency slpropagator");
0391 runSelfConsistencyTest(slpropagator, start, logger());
0392 }
0393
0394 BOOST_DATA_TEST_CASE(NavigatorEigenSelfConsistency,
0395 eventGen ^ bdata::xrange(nTestsSelfConsistency), pT, phi,
0396 theta, charge, index) {
0397 ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("NavigatorTest", logLevel));
0398
0399 CurvilinearTrackParameters start =
0400 createStartParameters(pT, phi, theta, charge);
0401
0402 ACTS_DEBUG(">>> Run navigation tests with:\n pT = "
0403 << pT << "\n phi = " << phi << "\n theta = " << theta
0404 << "\n charge = " << charge << "\n index = " << index);
0405
0406 ACTS_DEBUG(">>> Test self consistency epropagator");
0407 runSelfConsistencyTest(epropagator, start, logger());
0408 }
0409
0410 BOOST_DATA_TEST_CASE(NavigatorRef1StraightLineConsistency,
0411 eventGen ^ bdata::xrange(nTestsRefConsistency), pT, phi,
0412 theta, charge, index) {
0413 ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("NavigatorTest", logLevel));
0414
0415 CurvilinearTrackParameters start =
0416 createStartParameters(pT, phi, theta, charge);
0417
0418 ACTS_DEBUG(">>> Run navigation tests with:\n pT = "
0419 << pT << "\n phi = " << phi << "\n theta = " << theta
0420 << "\n charge = " << charge << "\n index = " << index);
0421
0422 ACTS_DEBUG(">>> Test reference 1 consistency slpropagator");
0423 runConsistencyTest(slpropagator, refslpropagator1, start, logger());
0424 }
0425
0426 BOOST_DATA_TEST_CASE(NavigatorRef1EigenConsistency,
0427 eventGen ^ bdata::xrange(nTestsRefConsistency), pT, phi,
0428 theta, charge, index) {
0429 ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("NavigatorTest", logLevel));
0430
0431 CurvilinearTrackParameters start =
0432 createStartParameters(pT, phi, theta, charge);
0433
0434 ACTS_DEBUG(">>> Run navigation tests with:\n pT = "
0435 << pT << "\n phi = " << phi << "\n theta = " << theta
0436 << "\n charge = " << charge << "\n index = " << index);
0437
0438 ACTS_DEBUG(">>> Test reference 1 consistency epropagator");
0439 runConsistencyTest(epropagator, refepropagator1, start, logger());
0440 }
0441
0442 BOOST_DATA_TEST_CASE(NavigatorRef2StraightLineConsistency,
0443 eventGen ^ bdata::xrange(nTestsRefConsistency), pT, phi,
0444 theta, charge, index) {
0445 ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("NavigatorTest", logLevel));
0446
0447 CurvilinearTrackParameters start =
0448 createStartParameters(pT, phi, theta, charge);
0449
0450 ACTS_DEBUG(">>> Run navigation tests with:\n pT = "
0451 << pT << "\n phi = " << phi << "\n theta = " << theta
0452 << "\n charge = " << charge << "\n index = " << index);
0453
0454 ACTS_DEBUG(">>> Test reference 2 consistency slpropagator");
0455 runConsistencyTest(slpropagator, refslpropagator2, start, logger());
0456 }
0457
0458 BOOST_DATA_TEST_CASE(NavigatorRef2EigenConsistency,
0459 eventGen ^ bdata::xrange(nTestsRefConsistency), pT, phi,
0460 theta, charge, index) {
0461 ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("NavigatorTest", logLevel));
0462
0463 CurvilinearTrackParameters start =
0464 createStartParameters(pT, phi, theta, charge);
0465
0466 ACTS_DEBUG(">>> Run navigation tests with:\n pT = "
0467 << pT << "\n phi = " << phi << "\n theta = " << theta
0468 << "\n charge = " << charge << "\n index = " << index);
0469
0470 ACTS_DEBUG(">>> Test reference 2 consistency epropagator");
0471 runConsistencyTest(epropagator, refepropagator2, start, logger());
0472 }
0473
0474 }