File indexing completed on 2026-05-19 07:35:38
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/Definitions/Units.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "Acts/MagneticField/ConstantBField.hpp"
0016 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0017 #include "Acts/Propagator/ActorList.hpp"
0018 #include "Acts/Propagator/EigenStepper.hpp"
0019 #include "Acts/Propagator/Navigator.hpp"
0020 #include "Acts/Propagator/Propagator.hpp"
0021 #include "Acts/Utilities/Result.hpp"
0022 #include "ActsTests/CommonHelpers/CubicTrackingGeometry.hpp"
0023 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0024
0025 #include <algorithm>
0026 #include <memory>
0027 #include <optional>
0028 #include <utility>
0029 #include <vector>
0030
0031 namespace Acts {
0032 class Logger;
0033 struct EndOfWorldReached;
0034 }
0035
0036 using namespace Acts;
0037 using namespace Acts::UnitLiterals;
0038
0039 namespace ActsTests {
0040
0041 using Jacobian = BoundMatrix;
0042 using Covariance = BoundMatrix;
0043
0044
0045 GeometryContext tgContext = GeometryContext::dangerouslyDefaultConstruct();
0046 MagneticFieldContext mfContext = MagneticFieldContext();
0047
0048
0049
0050 struct StepWiseActor {
0051
0052 struct this_result {
0053 std::vector<Jacobian> jacobians = {};
0054 std::vector<double> paths = {};
0055
0056 double fullPath = 0.;
0057
0058 bool finalized = false;
0059 };
0060
0061 using result_type = this_result;
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 template <typename propagator_state_t, typename stepper_t,
0074 typename navigator_t>
0075 Result<void> act(propagator_state_t& state, const stepper_t& stepper,
0076 const navigator_t& navigator, result_type& result,
0077 const Logger& ) const {
0078
0079 auto surface = navigator.currentSurface(state.navigation);
0080 if (surface && surface->isSensitive()) {
0081
0082 auto boundState = stepper.boundState(state.stepping, *surface).value();
0083 result.jacobians.push_back(std::move(std::get<Jacobian>(boundState)));
0084 result.paths.push_back(std::get<double>(boundState));
0085 }
0086
0087 if (state.stage == PropagatorStage::postPropagation && !result.finalized) {
0088
0089 result.paths.push_back(state.stepping.pathAccumulated);
0090
0091 result.fullPath = state.stepping.pathAccumulated;
0092
0093 result.finalized = true;
0094 }
0095 return Result<void>::success();
0096 }
0097 };
0098
0099 BOOST_AUTO_TEST_SUITE(PropagatorSuite)
0100
0101
0102
0103
0104 BOOST_AUTO_TEST_CASE(kalman_extrapolator) {
0105
0106 CubicTrackingGeometry cGeometry(tgContext);
0107 auto detector = cGeometry();
0108
0109
0110 Navigator::Config cfg{detector};
0111 cfg.resolvePassive = false;
0112 cfg.resolveMaterial = true;
0113 cfg.resolveSensitive = true;
0114 Navigator navigator(cfg);
0115
0116
0117 auto bField = std::make_shared<ConstantBField>(Vector3(0., 0., 0.));
0118 using Stepper = EigenStepper<>;
0119 Stepper stepper(bField);
0120 using Propagator = Propagator<Stepper, Navigator>;
0121 Propagator propagator(stepper, navigator);
0122
0123
0124 Covariance cov;
0125 cov << 10_mm, 0, 0.123, 0, 0.5, 0, 0, 10_mm, 0, 0.162, 0, 0, 0.123, 0, 0.1, 0,
0126 0, 0, 0, 0.162, 0, 0.1, 0, 0, 0.5, 0, 0, 0, 1. / (10_GeV), 0, 0, 0, 0, 0,
0127 0, 0;
0128
0129 BoundTrackParameters start = BoundTrackParameters::createCurvilinear(
0130 Vector4(-3_m, 0, 0, 42_ns), 0_degree, 90_degree, 1_e / 1_GeV, cov,
0131 ParticleHypothesis::pion());
0132
0133
0134 using StepWiseResult = StepWiseActor::result_type;
0135 using StepWiseActors = ActorList<StepWiseActor, EndOfWorldReached>;
0136
0137
0138 using StepWiseOptions = Propagator::Options<StepWiseActors>;
0139 StepWiseOptions swOptions(tgContext, mfContext);
0140
0141 using PlainActors = ActorList<EndOfWorldReached>;
0142 using PlainOptions = Propagator::Options<PlainActors>;
0143 PlainOptions pOptions(tgContext, mfContext);
0144
0145
0146 const auto& pResult = propagator.propagate(start, pOptions).value();
0147
0148 const auto& pJacobian = *(pResult.transportJacobian);
0149
0150
0151 const auto& swResult = propagator.propagate(start, swOptions).value();
0152 auto swJacobianTest = swResult.template get<StepWiseResult>();
0153
0154
0155 double accPath = 0.;
0156 auto swPaths = swJacobianTest.paths;
0157
0158 for (auto cpath = swPaths.rbegin(); cpath != swPaths.rend(); ++cpath) {
0159 if (cpath != swPaths.rend() - 1) {
0160 accPath += (*cpath) - (*(cpath + 1));
0161 continue;
0162 }
0163 accPath += (*cpath) - 0.;
0164 }
0165 CHECK_CLOSE_REL(swJacobianTest.fullPath, accPath, 1e-6);
0166
0167
0168 Jacobian accJacobian = Jacobian::Identity();
0169
0170 auto swJacobians = swJacobianTest.jacobians;
0171
0172 const auto& swlJacobian = *(swResult.transportJacobian);
0173
0174
0175 for (auto& j : swJacobians) {
0176 accJacobian = j * accJacobian;
0177 }
0178 accJacobian = swlJacobian * accJacobian;
0179 CHECK_CLOSE_OR_SMALL(pJacobian, accJacobian, 1e-6, 1e-9);
0180 }
0181
0182 BOOST_AUTO_TEST_SUITE_END()
0183
0184 }