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