File indexing completed on 2025-08-06 08:11:25
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/Units.hpp"
0016 #include "Acts/EventData/TrackParameters.hpp"
0017 #include "Acts/Geometry/GeometryContext.hpp"
0018 #include "Acts/MagneticField/ConstantBField.hpp"
0019 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0020 #include "Acts/Propagator/AbortList.hpp"
0021 #include "Acts/Propagator/ActionList.hpp"
0022 #include "Acts/Propagator/DirectNavigator.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/SurfaceCollector.hpp"
0029 #include "Acts/Tests/CommonHelpers/CylindricalTrackingGeometry.hpp"
0030 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0031
0032 #include <algorithm>
0033 #include <array>
0034 #include <cmath>
0035 #include <iostream>
0036 #include <memory>
0037 #include <random>
0038 #include <tuple>
0039 #include <utility>
0040 #include <vector>
0041
0042 namespace Acts {
0043 class Surface;
0044 }
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 CylindricalTrackingGeometry cGeometry(tgContext);
0056 auto tGeometry = cGeometry();
0057
0058
0059 Navigator navigator({tGeometry});
0060 DirectNavigator dnavigator;
0061
0062 using BField = ConstantBField;
0063 using Stepper = EigenStepper<>;
0064 using ReferencePropagator = Propagator<Stepper, Navigator>;
0065 using DirectPropagator = Propagator<Stepper, DirectNavigator>;
0066
0067 const double Bz = 2_T;
0068 auto bField = std::make_shared<BField>(Vector3{0, 0, Bz});
0069 Stepper estepper(bField);
0070 Stepper dstepper(bField);
0071
0072 ReferencePropagator rpropagator(std::move(estepper), std::move(navigator));
0073 DirectPropagator dpropagator(std::move(dstepper), std::move(dnavigator));
0074
0075 const int ntests = 1000;
0076 const int skip = 0;
0077 bool referenceTiming = false;
0078 bool oversteppingTest = false;
0079 double oversteppingMaxStepSize = 1_mm;
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 template <typename rpropagator_t, typename dpropagator_t>
0095 void runTest(const rpropagator_t& rprop, const dpropagator_t& dprop, double pT,
0096 double phi, double theta, int charge, int index) {
0097 double dcharge = -1 + 2 * charge;
0098
0099 if (index < skip) {
0100 return;
0101 }
0102
0103
0104 double p = pT / sin(theta);
0105 CurvilinearTrackParameters start(Vector4(0, 0, 0, 0), phi, theta, dcharge / p,
0106 std::nullopt, ParticleHypothesis::pion());
0107
0108 using EndOfWorld = EndOfWorldReached;
0109
0110
0111 using RefereceActionList = ActionList<MaterialInteractor, SurfaceCollector<>>;
0112 using ReferenceAbortList = AbortList<EndOfWorld>;
0113
0114
0115 using Options = PropagatorOptions<RefereceActionList, ReferenceAbortList>;
0116 Options pOptions(tgContext, mfContext);
0117 if (oversteppingTest) {
0118 pOptions.maxStepSize = oversteppingMaxStepSize;
0119 }
0120
0121
0122 auto& sCollector = pOptions.actionList.template get<SurfaceCollector<>>();
0123 sCollector.selector.selectSensitive = true;
0124 sCollector.selector.selectMaterial = true;
0125
0126
0127 const auto& pResult = rprop.propagate(start, pOptions).value();
0128 auto& cSurfaces = pResult.template get<SurfaceCollector<>::result_type>();
0129 auto& cMaterial = pResult.template get<MaterialInteractor::result_type>();
0130 const Surface& destination = pResult.endParameters->referenceSurface();
0131
0132 std::cout << " - the standard navigator yielded "
0133 << cSurfaces.collected.size() << " collected surfaces" << std::endl;
0134
0135 if (!referenceTiming) {
0136
0137 std::vector<const Surface*> surfaceSequence;
0138 surfaceSequence.reserve(cSurfaces.collected.size());
0139 for (auto& cs : cSurfaces.collected) {
0140 surfaceSequence.push_back(cs.surface);
0141 }
0142
0143
0144 using DirectActionList = ActionList<DirectNavigator::Initializer,
0145 MaterialInteractor, SurfaceCollector<>>;
0146
0147
0148 using DirectOptions = PropagatorOptions<DirectActionList, AbortList<>>;
0149 DirectOptions dOptions(tgContext, mfContext);
0150
0151 auto& dInitializer =
0152 dOptions.actionList.get<DirectNavigator::Initializer>();
0153 dInitializer.navSurfaces = surfaceSequence;
0154
0155 auto& dCollector = dOptions.actionList.template get<SurfaceCollector<>>();
0156 dCollector.selector.selectSensitive = true;
0157 dCollector.selector.selectMaterial = true;
0158
0159
0160 const auto& ddResult =
0161 dprop.propagate(start, destination, dOptions).value();
0162 auto& ddSurfaces = ddResult.template get<SurfaceCollector<>::result_type>();
0163 auto& ddMaterial = ddResult.template get<MaterialInteractor::result_type>();
0164
0165
0166 BOOST_CHECK_EQUAL(cSurfaces.collected.size(), ddSurfaces.collected.size());
0167 CHECK_CLOSE_REL(cMaterial.materialInX0, ddMaterial.materialInX0, 1e-3);
0168
0169
0170 const auto& dwResult = dprop.propagate(start, dOptions).value();
0171 auto& dwSurfaces = dwResult.template get<SurfaceCollector<>::result_type>();
0172
0173
0174 BOOST_CHECK_EQUAL(cSurfaces.collected.size(), dwSurfaces.collected.size());
0175 }
0176 }
0177
0178
0179
0180 BOOST_DATA_TEST_CASE(
0181 test_direct_navigator,
0182 bdata::random((bdata::engine = std::mt19937(), bdata::seed = 20,
0183 bdata::distribution = std::uniform_real_distribution<double>(
0184 0.15_GeV, 10_GeV))) ^
0185 bdata::random((bdata::engine = std::mt19937(), bdata::seed = 21,
0186 bdata::distribution =
0187 std::uniform_real_distribution<double>(-M_PI,
0188 M_PI))) ^
0189 bdata::random(
0190 (bdata::engine = std::mt19937(), bdata::seed = 22,
0191 bdata::distribution =
0192 std::uniform_real_distribution<double>(1.0, M_PI - 1.0))) ^
0193 bdata::random((bdata::engine = std::mt19937(), bdata::seed = 23,
0194 bdata::distribution =
0195 std::uniform_int_distribution<std::uint8_t>(0, 1))) ^
0196 bdata::xrange(ntests),
0197 pT, phi, theta, charge, index) {
0198
0199 runTest(rpropagator, dpropagator, pT, phi, theta, charge, index);
0200 }
0201
0202 }