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