File indexing completed on 2025-07-15 08:13:40
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/Tolerance.hpp"
0014 #include "Acts/Definitions/TrackParametrization.hpp"
0015 #include "Acts/EventData/GenericBoundTrackParameters.hpp"
0016 #include "Acts/EventData/TrackParameters.hpp"
0017 #include "Acts/EventData/TransformationHelpers.hpp"
0018 #include "Acts/EventData/detail/CorrectedTransformationFreeToBound.hpp"
0019 #include "Acts/Geometry/GeometryContext.hpp"
0020 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0021 #include "Acts/Propagator/ConstrainedStep.hpp"
0022 #include "Acts/Propagator/StraightLineStepper.hpp"
0023 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0024 #include "Acts/Surfaces/CurvilinearSurface.hpp"
0025 #include "Acts/Surfaces/PlaneSurface.hpp"
0026 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0027 #include "Acts/Utilities/Result.hpp"
0028
0029 #include <limits>
0030 #include <memory>
0031 #include <optional>
0032 #include <string>
0033
0034 using namespace Acts::UnitLiterals;
0035 using Acts::VectorHelpers::makeVector4;
0036
0037 namespace Acts::Test {
0038
0039 using Covariance = BoundSquareMatrix;
0040
0041 static constexpr auto eps = 2 * std::numeric_limits<double>::epsilon();
0042
0043
0044 BOOST_AUTO_TEST_CASE(straight_line_stepper_state_test) {
0045
0046 GeometryContext tgContext = GeometryContext();
0047 MagneticFieldContext mfContext = MagneticFieldContext();
0048 double stepSize = 123.;
0049
0050 Vector3 pos(1., 2., 3.);
0051 Vector3 dir(4., 5., 6.);
0052 double time = 7.;
0053 double absMom = 8.;
0054 double charge = -1.;
0055
0056 StraightLineStepper::Options slsOptions(tgContext, mfContext);
0057 slsOptions.maxStepSize = stepSize;
0058
0059
0060 BoundTrackParameters cp = BoundTrackParameters::createCurvilinear(
0061 makeVector4(pos, time), dir, charge / absMom, std::nullopt,
0062 ParticleHypothesis::pion());
0063
0064 StraightLineStepper sls;
0065 StraightLineStepper::State slsState = sls.makeState(slsOptions);
0066 sls.initialize(slsState, cp);
0067
0068
0069 BOOST_CHECK_EQUAL(slsState.jacToGlobal, BoundToFreeMatrix::Zero());
0070 BOOST_CHECK_EQUAL(slsState.jacTransport, FreeMatrix::Identity());
0071 BOOST_CHECK_EQUAL(slsState.derivative, FreeVector::Zero());
0072 BOOST_CHECK(!slsState.covTransport);
0073 BOOST_CHECK_EQUAL(slsState.cov, Covariance::Zero());
0074 CHECK_CLOSE_OR_SMALL(sls.position(slsState), pos, eps, eps);
0075 CHECK_CLOSE_OR_SMALL(sls.direction(slsState), dir.normalized(), eps, eps);
0076 CHECK_CLOSE_REL(sls.absoluteMomentum(slsState), absMom, eps);
0077 BOOST_CHECK_EQUAL(sls.charge(slsState), charge);
0078 CHECK_CLOSE_OR_SMALL(sls.time(slsState), time, eps, eps);
0079 BOOST_CHECK_EQUAL(slsState.pathAccumulated, 0.);
0080 BOOST_CHECK_EQUAL(slsState.stepSize.value(), stepSize);
0081 BOOST_CHECK_EQUAL(slsState.previousStepSize, 0.);
0082
0083
0084 BoundTrackParameters ncp = BoundTrackParameters::createCurvilinear(
0085 makeVector4(pos, time), dir, 1 / absMom, std::nullopt,
0086 ParticleHypothesis::pion0());
0087 sls.initialize(slsState, ncp);
0088
0089
0090 Covariance cov = 8. * Covariance::Identity();
0091 ncp = BoundTrackParameters::createCurvilinear(makeVector4(pos, time), dir,
0092 1 / absMom, cov,
0093 ParticleHypothesis::pion0());
0094 sls.initialize(slsState, ncp);
0095 BOOST_CHECK_NE(slsState.jacToGlobal, BoundToFreeMatrix::Zero());
0096 BOOST_CHECK(slsState.covTransport);
0097 BOOST_CHECK_EQUAL(slsState.cov, cov);
0098 }
0099
0100
0101
0102 BOOST_AUTO_TEST_CASE(straight_line_stepper_test) {
0103
0104 GeometryContext tgContext = GeometryContext();
0105 MagneticFieldContext mfContext = MagneticFieldContext();
0106 Direction navDir = Direction::Backward();
0107 double stepSize = 123.;
0108
0109
0110 Vector3 pos(1., 2., 3.);
0111 Vector3 dir = Vector3(4., 5., 6.).normalized();
0112 double time = 7.;
0113 double absMom = 8.;
0114 double charge = -1.;
0115 Covariance cov = 8. * Covariance::Identity();
0116 BoundTrackParameters cp = BoundTrackParameters::createCurvilinear(
0117 makeVector4(pos, time), dir, charge / absMom, cov,
0118 ParticleHypothesis::pion());
0119
0120 StraightLineStepper::Options options(tgContext, mfContext);
0121 options.maxStepSize = stepSize;
0122 options.initialStepSize = 10_m;
0123
0124
0125 StraightLineStepper sls;
0126 StraightLineStepper::State slsState = sls.makeState(options);
0127 sls.initialize(slsState, cp);
0128
0129
0130 CHECK_CLOSE_ABS(sls.position(slsState), pos, 1e-6);
0131 CHECK_CLOSE_ABS(sls.direction(slsState), dir, 1e-6);
0132 CHECK_CLOSE_ABS(sls.absoluteMomentum(slsState), absMom, 1e-6);
0133 BOOST_CHECK_EQUAL(sls.charge(slsState), charge);
0134 BOOST_CHECK_EQUAL(sls.time(slsState), time);
0135
0136
0137 const std::string originalStepSize = slsState.stepSize.toString();
0138
0139 sls.updateStepSize(slsState, -1337., ConstrainedStep::Type::Navigator);
0140 BOOST_CHECK_EQUAL(slsState.previousStepSize, stepSize);
0141 BOOST_CHECK_EQUAL(slsState.stepSize.value(), -1337.);
0142
0143 sls.releaseStepSize(slsState, ConstrainedStep::Type::Navigator);
0144 BOOST_CHECK_EQUAL(slsState.stepSize.value(), stepSize);
0145 BOOST_CHECK_EQUAL(sls.outputStepSize(slsState), originalStepSize);
0146
0147
0148 auto curvState = sls.curvilinearState(slsState);
0149 auto curvPars = std::get<0>(curvState);
0150 CHECK_CLOSE_ABS(curvPars.position(tgContext), cp.position(tgContext), 1e-6);
0151 CHECK_CLOSE_ABS(curvPars.absoluteMomentum(), cp.absoluteMomentum(), 1e-6);
0152 CHECK_CLOSE_ABS(curvPars.charge(), cp.charge(), 1e-6);
0153 CHECK_CLOSE_ABS(curvPars.time(), cp.time(), 1e-6);
0154 BOOST_CHECK(curvPars.covariance().has_value());
0155 BOOST_CHECK_NE(*curvPars.covariance(), cov);
0156 CHECK_CLOSE_COVARIANCE(std::get<1>(curvState),
0157 BoundMatrix(BoundMatrix::Identity()), 1e-6);
0158 CHECK_CLOSE_ABS(std::get<2>(curvState), 0., 1e-6);
0159
0160
0161 Vector3 newPos(2., 4., 8.);
0162 Vector3 newMom(3., 9., 27.);
0163 double newTime(321.);
0164 sls.update(slsState, newPos, newMom.normalized(), charge / newMom.norm(),
0165 newTime);
0166 CHECK_CLOSE_ABS(sls.position(slsState), newPos, 1e-6);
0167 CHECK_CLOSE_ABS(sls.direction(slsState), newMom.normalized(), 1e-6);
0168 CHECK_CLOSE_ABS(sls.absoluteMomentum(slsState), newMom.norm(), 1e-6);
0169 BOOST_CHECK_EQUAL(sls.charge(slsState), charge);
0170 BOOST_CHECK_EQUAL(sls.time(slsState), newTime);
0171
0172
0173 slsState.cov = cov;
0174 sls.transportCovarianceToCurvilinear(slsState);
0175 BOOST_CHECK_NE(slsState.cov, cov);
0176 BOOST_CHECK_NE(slsState.jacToGlobal, BoundToFreeMatrix::Zero());
0177 BOOST_CHECK_EQUAL(slsState.jacTransport, FreeMatrix::Identity());
0178 BOOST_CHECK_EQUAL(slsState.derivative, FreeVector::Zero());
0179
0180
0181 slsState.cov = cov;
0182
0183 slsState.covTransport = false;
0184 double h = sls.step(slsState, navDir, nullptr).value();
0185 BOOST_CHECK_EQUAL(slsState.stepSize.value(), stepSize);
0186 BOOST_CHECK_EQUAL(slsState.stepSize.value(), h * navDir);
0187 CHECK_CLOSE_COVARIANCE(slsState.cov, cov, 1e-6);
0188 BOOST_CHECK_GT(sls.position(slsState).norm(), newPos.norm());
0189 CHECK_CLOSE_ABS(sls.direction(slsState), newMom.normalized(), 1e-6);
0190 CHECK_CLOSE_ABS(sls.absoluteMomentum(slsState), newMom.norm(), 1e-6);
0191 CHECK_CLOSE_ABS(sls.charge(slsState), charge, 1e-6);
0192 BOOST_CHECK_LT(sls.time(slsState), newTime);
0193 BOOST_CHECK_EQUAL(slsState.derivative, FreeVector::Zero());
0194 BOOST_CHECK_EQUAL(slsState.jacTransport, FreeMatrix::Identity());
0195
0196 slsState.covTransport = true;
0197 double h2 = sls.step(slsState, navDir, nullptr).value();
0198 BOOST_CHECK_EQUAL(slsState.stepSize.value(), stepSize);
0199 BOOST_CHECK_EQUAL(h2, h);
0200 CHECK_CLOSE_COVARIANCE(slsState.cov, cov, 1e-6);
0201 BOOST_CHECK_GT(sls.position(slsState).norm(), newPos.norm());
0202 CHECK_CLOSE_ABS(sls.direction(slsState), newMom.normalized(), 1e-6);
0203 CHECK_CLOSE_ABS(sls.absoluteMomentum(slsState), newMom.norm(), 1e-6);
0204 CHECK_CLOSE_ABS(sls.charge(slsState), charge, 1e-6);
0205 BOOST_CHECK_LT(sls.time(slsState), newTime);
0206 BOOST_CHECK_NE(slsState.derivative, FreeVector::Zero());
0207 BOOST_CHECK_NE(slsState.jacTransport, FreeMatrix::Identity());
0208
0209
0210
0211 Vector3 pos2(1.5, -2.5, 3.5);
0212 Vector3 dir2 = Vector3(4.5, -5.5, 6.5).normalized();
0213 double time2 = 7.5;
0214 double absMom2 = 8.5;
0215 double charge2 = 1.;
0216 BoundSquareMatrix cov2 = 8.5 * Covariance::Identity();
0217 BoundTrackParameters cp2 = BoundTrackParameters::createCurvilinear(
0218 makeVector4(pos2, time2), dir2, charge2 / absMom2, cov2,
0219 ParticleHypothesis::pion());
0220 BOOST_CHECK(cp2.covariance().has_value());
0221 FreeVector freeParams = transformBoundToFreeParameters(
0222 cp2.referenceSurface(), tgContext, cp2.parameters());
0223 navDir = Direction::Forward();
0224
0225
0226 StraightLineStepper::State slsStateCopy = slsState;
0227 sls.initialize(slsStateCopy, cp2.parameters(), cp2.covariance(),
0228 cp2.particleHypothesis(), cp2.referenceSurface());
0229
0230 BOOST_CHECK_NE(slsStateCopy.jacToGlobal, BoundToFreeMatrix::Zero());
0231 BOOST_CHECK_NE(slsStateCopy.jacToGlobal, slsState.jacToGlobal);
0232 BOOST_CHECK_EQUAL(slsStateCopy.jacTransport, FreeMatrix::Identity());
0233 BOOST_CHECK_EQUAL(slsStateCopy.derivative, FreeVector::Zero());
0234 BOOST_CHECK(slsStateCopy.covTransport);
0235 BOOST_CHECK_EQUAL(slsStateCopy.cov, cov2);
0236 CHECK_CLOSE_ABS(sls.position(slsStateCopy),
0237 freeParams.template segment<3>(eFreePos0), 1e-6);
0238 CHECK_CLOSE_ABS(sls.direction(slsStateCopy),
0239 freeParams.template segment<3>(eFreeDir0).normalized(), 1e-6);
0240 CHECK_CLOSE_ABS(sls.absoluteMomentum(slsStateCopy),
0241 std::abs(1. / freeParams[eFreeQOverP]), 1e-6);
0242 CHECK_CLOSE_ABS(sls.charge(slsStateCopy), -sls.charge(slsState), 1e-6);
0243 CHECK_CLOSE_ABS(sls.time(slsStateCopy), freeParams[eFreeTime], 1e-6);
0244 BOOST_CHECK_EQUAL(slsStateCopy.pathAccumulated, 0.);
0245 BOOST_CHECK_EQUAL(slsStateCopy.stepSize.value(), stepSize);
0246 BOOST_CHECK_EQUAL(slsStateCopy.previousStepSize, 0.);
0247
0248
0249 std::shared_ptr<PlaneSurface> plane =
0250 CurvilinearSurface(pos, dir).planeSurface();
0251 auto bp = BoundTrackParameters::create(
0252 tgContext, plane, makeVector4(pos, time), dir, charge / absMom,
0253 cov, ParticleHypothesis::pion())
0254 .value();
0255 slsState = sls.makeState(options);
0256 sls.initialize(slsState, bp);
0257
0258
0259 std::shared_ptr<PlaneSurface> targetSurface =
0260 CurvilinearSurface(pos + navDir * 2. * dir, dir).planeSurface();
0261 sls.updateSurfaceStatus(slsState, *targetSurface, 0, navDir,
0262 BoundaryTolerance::Infinite(), s_onSurfaceTolerance,
0263 ConstrainedStep::Type::Navigator);
0264 CHECK_CLOSE_ABS(slsState.stepSize.value(ConstrainedStep::Type::Navigator),
0265 navDir * 2., 1e-6);
0266
0267
0268 sls.updateStepSize(slsState,
0269 targetSurface
0270 ->intersect(tgContext, sls.position(slsState),
0271 navDir * sls.direction(slsState),
0272 BoundaryTolerance::Infinite())
0273 .closest(),
0274 navDir, ConstrainedStep::Type::Navigator);
0275 CHECK_CLOSE_ABS(slsState.stepSize.value(), 2, 1e-6);
0276 slsState.stepSize.setUser(navDir * stepSize);
0277 sls.releaseStepSize(slsState, ConstrainedStep::Type::Navigator);
0278 sls.updateStepSize(slsState,
0279 targetSurface
0280 ->intersect(tgContext, sls.position(slsState),
0281 navDir * sls.direction(slsState),
0282 BoundaryTolerance::Infinite())
0283 .closest(),
0284 navDir, ConstrainedStep::Type::Navigator);
0285 CHECK_CLOSE_ABS(slsState.stepSize.value(), 2, 1e-6);
0286
0287
0288 FreeToBoundCorrection freeToBoundCorrection(false);
0289 auto boundState =
0290 sls.boundState(slsState, *plane, true, freeToBoundCorrection).value();
0291 auto boundPars = std::get<0>(boundState);
0292 CHECK_CLOSE_ABS(boundPars.position(tgContext), bp.position(tgContext), 1e-6);
0293 CHECK_CLOSE_ABS(boundPars.momentum(), bp.momentum(), 1e-6);
0294 CHECK_CLOSE_ABS(boundPars.charge(), bp.charge(), 1e-6);
0295 CHECK_CLOSE_ABS(boundPars.time(), bp.time(), 1e-6);
0296 BOOST_CHECK(boundPars.covariance().has_value());
0297 BOOST_CHECK_NE(*boundPars.covariance(), cov);
0298 CHECK_CLOSE_COVARIANCE(std::get<1>(boundState),
0299 BoundMatrix(BoundMatrix::Identity()), 1e-6);
0300 CHECK_CLOSE_ABS(std::get<2>(boundState), 0., 1e-6);
0301
0302
0303 sls.transportCovarianceToBound(slsState, *plane, freeToBoundCorrection);
0304 BOOST_CHECK_NE(slsState.cov, cov);
0305 BOOST_CHECK_NE(slsState.jacToGlobal, BoundToFreeMatrix::Zero());
0306 BOOST_CHECK_EQUAL(slsState.jacTransport, FreeMatrix::Identity());
0307 BOOST_CHECK_EQUAL(slsState.derivative, FreeVector::Zero());
0308
0309
0310 freeParams = transformBoundToFreeParameters(bp.referenceSurface(), tgContext,
0311 bp.parameters());
0312
0313 BOOST_CHECK(bp.covariance().has_value());
0314 sls.update(slsState, freeParams, bp.parameters(), 2 * (*bp.covariance()),
0315 *plane);
0316 CHECK_CLOSE_OR_SMALL(sls.position(slsState), pos, eps, eps);
0317 BOOST_CHECK_EQUAL(sls.charge(slsState), charge);
0318 CHECK_CLOSE_OR_SMALL(sls.time(slsState), time, eps, eps);
0319 CHECK_CLOSE_COVARIANCE(slsState.cov, Covariance(2. * cov), 1e-6);
0320 }
0321
0322 }