File indexing completed on 2025-12-16 09:24:58
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/test_tools.hpp>
0010 #include <boost/test/unit_test.hpp>
0011
0012 #include "Acts/Definitions/Algebra.hpp"
0013 #include "Acts/Definitions/Common.hpp"
0014 #include "Acts/Definitions/Direction.hpp"
0015 #include "Acts/Definitions/Tolerance.hpp"
0016 #include "Acts/Definitions/TrackParametrization.hpp"
0017 #include "Acts/Definitions/Units.hpp"
0018 #include "Acts/EventData/GenericBoundTrackParameters.hpp"
0019 #include "Acts/EventData/ParticleHypothesis.hpp"
0020 #include "Acts/EventData/TrackParameters.hpp"
0021 #include "Acts/EventData/TransformationHelpers.hpp"
0022 #include "Acts/Geometry/GeometryContext.hpp"
0023 #include "Acts/MagneticField/ConstantBField.hpp"
0024 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0025 #include "Acts/MagneticField/MagneticFieldProvider.hpp"
0026 #include "Acts/Propagator/AtlasStepper.hpp"
0027 #include "Acts/Propagator/ConstrainedStep.hpp"
0028 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0029 #include "Acts/Surfaces/CurvilinearSurface.hpp"
0030 #include "Acts/Surfaces/DiscSurface.hpp"
0031 #include "Acts/Surfaces/PerigeeSurface.hpp"
0032 #include "Acts/Surfaces/PlaneSurface.hpp"
0033 #include "Acts/Surfaces/StrawSurface.hpp"
0034 #include "Acts/Surfaces/Surface.hpp"
0035 #include "Acts/Utilities/Result.hpp"
0036 #include "ActsTests/CommonHelpers/Assertions.hpp"
0037 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0038
0039 #include <algorithm>
0040 #include <array>
0041 #include <iterator>
0042 #include <limits>
0043 #include <memory>
0044 #include <optional>
0045 #include <type_traits>
0046 #include <utility>
0047
0048 using namespace Acts;
0049 using namespace Acts::UnitLiterals;
0050
0051 namespace ActsTests {
0052
0053 using VectorHelpers::makeVector4;
0054 using Covariance = BoundSquareMatrix;
0055 using Jacobian = BoundMatrix;
0056 using Stepper = AtlasStepper;
0057
0058
0059 static constexpr auto eps = 1024 * std::numeric_limits<double>::epsilon();
0060
0061
0062 static constexpr auto stepSize = 10_mm;
0063 static constexpr Direction navDir = Direction::Backward();
0064 static auto magneticField =
0065 std::make_shared<ConstantBField>(Vector3(0.1_T, -0.2_T, 2_T));
0066
0067
0068 static const Vector4 pos4(1_mm, -1_mm, 2_mm, 2_ns);
0069 static const Vector3 pos = pos4.segment<3>(ePos0);
0070 static const auto time = pos4[eTime];
0071 static const Vector3 unitDir = Vector3(-2, 2, 1).normalized();
0072 static constexpr auto absMom = 1_GeV;
0073 static constexpr auto charge = -1_e;
0074 static const auto particleHypothesis = ParticleHypothesis::pion();
0075 static const Covariance cov = Covariance::Identity();
0076
0077
0078 static const GeometryContext geoCtx;
0079 static const MagneticFieldContext magCtx;
0080
0081 BOOST_AUTO_TEST_SUITE(PropagatorSuite)
0082
0083
0084 BOOST_AUTO_TEST_CASE(ConstructState) {
0085 BoundTrackParameters cp = BoundTrackParameters::createCurvilinear(
0086 pos4, unitDir, charge / absMom, std::nullopt, particleHypothesis);
0087
0088 Stepper stepper(magneticField);
0089
0090 Stepper::Options options(geoCtx, magCtx);
0091 options.maxStepSize = stepSize;
0092
0093 Stepper::State state = stepper.makeState(options);
0094 stepper.initialize(state, cp);
0095
0096 BOOST_CHECK(!state.covTransport);
0097 BOOST_CHECK_EQUAL(state.covariance, nullptr);
0098 BOOST_CHECK_EQUAL(state.pVector[0], pos.x());
0099 BOOST_CHECK_EQUAL(state.pVector[1], pos.y());
0100 BOOST_CHECK_EQUAL(state.pVector[2], pos.z());
0101 BOOST_CHECK_EQUAL(state.pVector[3], time);
0102 CHECK_CLOSE_ABS(state.pVector[4], unitDir.x(), eps);
0103 CHECK_CLOSE_ABS(state.pVector[5], unitDir.y(), eps);
0104 CHECK_CLOSE_ABS(state.pVector[6], unitDir.z(), eps);
0105 BOOST_CHECK_EQUAL(state.pVector[7], charge / absMom);
0106 BOOST_CHECK_EQUAL(state.pathAccumulated, 0.);
0107 BOOST_CHECK_EQUAL(state.stepSize.value(), stepSize);
0108 BOOST_CHECK_EQUAL(state.previousStepSize, 0.);
0109 }
0110
0111
0112 BOOST_AUTO_TEST_CASE(ConstructStateWithCovariance) {
0113 BoundTrackParameters cp = BoundTrackParameters::createCurvilinear(
0114 pos4, unitDir, charge / absMom, cov, particleHypothesis);
0115
0116 Stepper stepper(magneticField);
0117
0118 Stepper::Options options(geoCtx, magCtx);
0119 options.maxStepSize = stepSize;
0120
0121 Stepper::State state = stepper.makeState(options);
0122 stepper.initialize(state, cp);
0123
0124 BOOST_CHECK(state.covTransport);
0125 BOOST_CHECK_EQUAL(*state.covariance, cov);
0126 BOOST_CHECK_EQUAL(state.pVector[0], pos.x());
0127 BOOST_CHECK_EQUAL(state.pVector[1], pos.y());
0128 BOOST_CHECK_EQUAL(state.pVector[2], pos.z());
0129 BOOST_CHECK_EQUAL(state.pVector[3], time);
0130 CHECK_CLOSE_ABS(state.pVector[4], unitDir.x(), eps);
0131 CHECK_CLOSE_ABS(state.pVector[5], unitDir.y(), eps);
0132 CHECK_CLOSE_ABS(state.pVector[6], unitDir.z(), eps);
0133 BOOST_CHECK_EQUAL(state.pVector[7], charge / absMom);
0134 BOOST_CHECK_EQUAL(state.pathAccumulated, 0.);
0135 BOOST_CHECK_EQUAL(state.stepSize.value(), stepSize);
0136 BOOST_CHECK_EQUAL(state.previousStepSize, 0.);
0137 }
0138
0139
0140 BOOST_AUTO_TEST_CASE(Getters) {
0141 BoundTrackParameters cp = BoundTrackParameters::createCurvilinear(
0142 pos4, unitDir, charge / absMom, cov, particleHypothesis);
0143
0144 Stepper stepper(magneticField);
0145
0146 Stepper::Options options(geoCtx, magCtx);
0147 options.maxStepSize = stepSize;
0148
0149 Stepper::State state = stepper.makeState(options);
0150 stepper.initialize(state, cp);
0151
0152 CHECK_CLOSE_ABS(stepper.position(state), pos, eps);
0153 CHECK_CLOSE_ABS(stepper.time(state), time, eps);
0154 CHECK_CLOSE_ABS(stepper.direction(state), unitDir, eps);
0155 CHECK_CLOSE_ABS(stepper.absoluteMomentum(state), absMom, eps);
0156 BOOST_CHECK_EQUAL(stepper.charge(state), charge);
0157 }
0158
0159
0160 BOOST_AUTO_TEST_CASE(UpdateFromBound) {
0161 BoundTrackParameters cp = BoundTrackParameters::createCurvilinear(
0162 pos4, unitDir, charge / absMom, cov, particleHypothesis);
0163
0164 Stepper stepper(magneticField);
0165
0166 Stepper::Options options(geoCtx, magCtx);
0167 options.maxStepSize = stepSize;
0168
0169 Stepper::State state = stepper.makeState(options);
0170 stepper.initialize(state, cp);
0171
0172 auto newPos4 = (pos4 + Vector4(1_mm, 2_mm, 3_mm, 20_ns)).eval();
0173 auto newPos = newPos4.segment<3>(ePos0);
0174 auto newTime = newPos4[eTime];
0175 auto newUnitDir = (unitDir + Vector3(1, -1, -1)).normalized();
0176 auto newAbsMom = 0.9 * absMom;
0177
0178
0179 std::shared_ptr<PlaneSurface> plane =
0180 CurvilinearSurface(newPos, newUnitDir).planeSurface();
0181 auto params =
0182 BoundTrackParameters::create(geoCtx, plane, newPos4, newUnitDir,
0183 charge / absMom, cov, particleHypothesis)
0184 .value();
0185 FreeVector freeParams;
0186 freeParams[eFreePos0] = newPos4[ePos0];
0187 freeParams[eFreePos1] = newPos4[ePos1];
0188 freeParams[eFreePos2] = newPos4[ePos2];
0189 freeParams[eFreeTime] = newPos4[eTime];
0190 freeParams[eFreeDir0] = newUnitDir[eMom0];
0191 freeParams[eFreeDir1] = newUnitDir[eMom1];
0192 freeParams[eFreeDir2] = newUnitDir[eMom2];
0193 freeParams[eFreeQOverP] = charge / newAbsMom;
0194
0195
0196
0197 state.state_ready = false;
0198 BOOST_CHECK(params.covariance().has_value());
0199 stepper.update(state, freeParams, params.parameters(), *params.covariance(),
0200 *plane);
0201 CHECK_CLOSE_ABS(stepper.position(state), newPos, eps);
0202 CHECK_CLOSE_ABS(stepper.time(state), newTime, eps);
0203 CHECK_CLOSE_ABS(stepper.direction(state), newUnitDir, eps);
0204 CHECK_CLOSE_ABS(stepper.absoluteMomentum(state), newAbsMom, eps);
0205 BOOST_CHECK_EQUAL(stepper.charge(state), charge);
0206 }
0207
0208
0209 BOOST_AUTO_TEST_CASE(UpdateFromComponents) {
0210 BoundTrackParameters cp = BoundTrackParameters::createCurvilinear(
0211 pos4, unitDir, charge / absMom, cov, particleHypothesis);
0212
0213 Stepper stepper(magneticField);
0214
0215 Stepper::Options options(geoCtx, magCtx);
0216 options.maxStepSize = stepSize;
0217
0218 Stepper::State state = stepper.makeState(options);
0219 stepper.initialize(state, cp);
0220
0221 auto newPos = (pos + Vector3(1_mm, 2_mm, 3_mm)).eval();
0222 auto newTime = time + 20_ns;
0223 auto newUnitDir = (unitDir + Vector3(1, -1, -1)).normalized();
0224 auto newAbsMom = 0.9 * absMom;
0225
0226 stepper.update(state, newPos, newUnitDir, charge / newAbsMom, newTime);
0227 CHECK_CLOSE_ABS(stepper.position(state), newPos, eps);
0228 CHECK_CLOSE_ABS(stepper.time(state), newTime, eps);
0229 CHECK_CLOSE_ABS(stepper.direction(state), newUnitDir, eps);
0230 CHECK_CLOSE_ABS(stepper.absoluteMomentum(state), newAbsMom, eps);
0231 BOOST_CHECK_EQUAL(stepper.charge(state), charge);
0232 }
0233
0234
0235 BOOST_AUTO_TEST_CASE(BuildBound) {
0236 BoundTrackParameters cp = BoundTrackParameters::createCurvilinear(
0237 pos4, unitDir, charge / absMom, cov, particleHypothesis);
0238
0239 Stepper stepper(magneticField);
0240
0241 Stepper::Options options(geoCtx, magCtx);
0242 options.maxStepSize = stepSize;
0243
0244 Stepper::State state = stepper.makeState(options);
0245 stepper.initialize(state, cp);
0246
0247
0248 std::shared_ptr<PlaneSurface> plane =
0249 CurvilinearSurface(pos, unitDir).planeSurface();
0250
0251 auto&& [pars, jac, pathLength] = stepper.boundState(state, *plane).value();
0252
0253 CHECK_CLOSE_ABS(pars.position(geoCtx), pos, eps);
0254 CHECK_CLOSE_ABS(pars.time(), time, eps);
0255 CHECK_CLOSE_ABS(pars.momentum(), absMom * unitDir, eps);
0256 BOOST_CHECK_EQUAL(pars.charge(), charge);
0257 BOOST_CHECK(pars.covariance().has_value());
0258 BOOST_CHECK_NE(*pars.covariance(), cov);
0259
0260 CHECK_CLOSE_ABS(jac, Jacobian(Jacobian::Identity()), eps);
0261
0262 CHECK_CLOSE_ABS(pathLength, 0., eps);
0263 }
0264
0265
0266 BOOST_AUTO_TEST_CASE(BuildCurvilinear) {
0267 BoundTrackParameters cp = BoundTrackParameters::createCurvilinear(
0268 pos4, unitDir, charge / absMom, cov, particleHypothesis);
0269
0270 Stepper stepper(magneticField);
0271
0272 Stepper::Options options(geoCtx, magCtx);
0273 options.maxStepSize = stepSize;
0274
0275 Stepper::State state = stepper.makeState(options);
0276 stepper.initialize(state, cp);
0277
0278 auto&& [pars, jac, pathLength] = stepper.curvilinearState(state);
0279
0280 CHECK_CLOSE_ABS(pars.position(geoCtx), pos, eps);
0281 CHECK_CLOSE_ABS(pars.time(), time, eps);
0282 CHECK_CLOSE_ABS(pars.momentum(), absMom * unitDir, eps);
0283 BOOST_CHECK_EQUAL(pars.charge(), charge);
0284 BOOST_CHECK(pars.covariance().has_value());
0285 BOOST_CHECK_NE(*pars.covariance(), cov);
0286
0287 CHECK_CLOSE_ABS(jac, Jacobian(Jacobian::Identity()), eps);
0288
0289 CHECK_CLOSE_ABS(pathLength, 0., eps);
0290 }
0291
0292
0293 BOOST_AUTO_TEST_CASE(Step) {
0294 BoundTrackParameters cp = BoundTrackParameters::createCurvilinear(
0295 pos4, unitDir, charge / absMom, cov, particleHypothesis);
0296
0297 Stepper stepper(magneticField);
0298
0299 Stepper::Options options(geoCtx, magCtx);
0300 options.maxStepSize = stepSize;
0301
0302 auto state = stepper.makeState(options);
0303 stepper.initialize(state, cp);
0304 state.covTransport = false;
0305
0306
0307 auto res = stepper.step(state, Direction::Backward(), nullptr);
0308 BOOST_CHECK(res.ok());
0309
0310
0311 auto h = res.value();
0312 BOOST_CHECK_EQUAL(state.stepSize.value(), stepSize);
0313 BOOST_CHECK_EQUAL(state.stepSize.value(), h * navDir);
0314
0315
0316 auto deltaPos = (stepper.position(state) - pos).eval();
0317 BOOST_CHECK_LT(0, deltaPos.norm());
0318
0319 auto deltaTime = stepper.time(state) - time;
0320 BOOST_CHECK_LT(0, std::abs(deltaTime));
0321
0322 auto projDir = stepper.direction(state).dot(unitDir);
0323 BOOST_CHECK_LT(projDir, 1);
0324
0325
0326 CHECK_CLOSE_ABS(stepper.absoluteMomentum(state), absMom, eps);
0327 BOOST_CHECK_EQUAL(stepper.charge(state), charge);
0328 }
0329
0330
0331 BOOST_AUTO_TEST_CASE(StepWithCovariance) {
0332 BoundTrackParameters cp = BoundTrackParameters::createCurvilinear(
0333 pos4, unitDir, charge / absMom, cov, particleHypothesis);
0334
0335 Stepper stepper(magneticField);
0336
0337 Stepper::Options options(geoCtx, magCtx);
0338 options.maxStepSize = stepSize;
0339
0340 auto state = stepper.makeState(options);
0341 stepper.initialize(state, cp);
0342 state.covTransport = true;
0343
0344
0345 auto res = stepper.step(state, Direction::Backward(), nullptr);
0346 BOOST_CHECK(res.ok());
0347
0348
0349 auto h = res.value();
0350 BOOST_CHECK_EQUAL(state.stepSize.value(), stepSize);
0351 BOOST_CHECK_EQUAL(state.stepSize.value(), h * navDir);
0352
0353
0354 auto deltaPos = (stepper.position(state) - pos).eval();
0355 BOOST_CHECK_LT(0, deltaPos.norm());
0356
0357 auto deltaTime = stepper.time(state) - time;
0358 BOOST_CHECK_LT(0, std::abs(deltaTime));
0359
0360 auto projDir = stepper.direction(state).dot(unitDir);
0361 BOOST_CHECK_LT(projDir, 1);
0362
0363
0364 CHECK_CLOSE_ABS(stepper.absoluteMomentum(state), absMom, eps);
0365 BOOST_CHECK_EQUAL(stepper.charge(state), charge);
0366
0367 stepper.transportCovarianceToCurvilinear(state);
0368 BOOST_CHECK_NE(state.cov, cov);
0369 }
0370
0371
0372 BOOST_AUTO_TEST_CASE(Reset) {
0373 BoundTrackParameters cp = BoundTrackParameters::createCurvilinear(
0374 pos4, unitDir, charge / absMom, cov, particleHypothesis);
0375
0376 Stepper stepper(magneticField);
0377
0378 Stepper::Options options(geoCtx, magCtx);
0379 options.maxStepSize = stepSize;
0380
0381 auto state = stepper.makeState(options);
0382 stepper.initialize(state, cp);
0383 state.covTransport = true;
0384
0385
0386 stepper.step(state, Direction::Backward(), nullptr);
0387
0388
0389 Vector3 newPos(1.5, -2.5, 3.5);
0390 auto newAbsMom = 4.2 * absMom;
0391 double newTime = 7.5;
0392 double newCharge = 1.;
0393 BoundSquareMatrix newCov = 8.5 * Covariance::Identity();
0394 cp = BoundTrackParameters::createCurvilinear(makeVector4(newPos, newTime),
0395 unitDir, newCharge / newAbsMom,
0396 newCov, particleHypothesis);
0397 FreeVector freeParams = transformBoundToFreeParameters(
0398 cp.referenceSurface(), geoCtx, cp.parameters());
0399
0400 auto copyState = [&](auto& field, const auto& other) {
0401 using field_t = std::decay_t<decltype(field)>;
0402 std::decay_t<decltype(other)> copy = stepper.makeState(options);
0403 stepper.initialize(state, cp);
0404
0405 copy.state_ready = other.state_ready;
0406 copy.useJacobian = other.useJacobian;
0407 copy.step = other.step;
0408 copy.maxPathLength = other.maxPathLength;
0409 copy.mcondition = other.mcondition;
0410 copy.needgradient = other.needgradient;
0411 copy.newfield = other.newfield;
0412 copy.field = other.field;
0413 copy.pVector = other.pVector;
0414 std::copy(std::begin(other.parameters), std::end(other.parameters),
0415 std::begin(copy.parameters));
0416 copy.covariance = other.covariance;
0417 copy.covTransport = other.covTransport;
0418 std::copy(std::begin(other.jacobian), std::end(other.jacobian),
0419 std::begin(copy.jacobian));
0420 copy.pathAccumulated = other.pathAccumulated;
0421 copy.stepSize = other.stepSize;
0422 copy.previousStepSize = other.previousStepSize;
0423
0424 copy.fieldCache = MagneticFieldProvider::Cache(
0425 std::in_place_type<typename field_t::Cache>,
0426 other.fieldCache.template as<typename field_t::Cache>());
0427
0428 copy.debug = other.debug;
0429 copy.debugString = other.debugString;
0430 copy.debugPfxWidth = other.debugPfxWidth;
0431 copy.debugMsgWidth = other.debugMsgWidth;
0432
0433 return copy;
0434 };
0435
0436
0437 Stepper::State stateCopy = copyState(*magneticField, state);
0438 BOOST_CHECK(cp.covariance().has_value());
0439 stepper.initialize(stateCopy, cp.parameters(), *cp.covariance(),
0440 cp.particleHypothesis(), cp.referenceSurface());
0441
0442 BOOST_CHECK(stateCopy.covTransport);
0443 BOOST_CHECK_EQUAL(*stateCopy.covariance, newCov);
0444 BOOST_CHECK_EQUAL(stepper.position(stateCopy),
0445 freeParams.template segment<3>(eFreePos0));
0446 BOOST_CHECK_EQUAL(stepper.direction(stateCopy),
0447 freeParams.template segment<3>(eFreeDir0).normalized());
0448 BOOST_CHECK_EQUAL(stepper.absoluteMomentum(stateCopy),
0449 std::abs(1. / freeParams[eFreeQOverP]));
0450 BOOST_CHECK_EQUAL(stepper.charge(stateCopy), stepper.charge(state));
0451 BOOST_CHECK_EQUAL(stepper.time(stateCopy), freeParams[eFreeTime]);
0452 BOOST_CHECK_EQUAL(stateCopy.pathAccumulated, 0.);
0453 BOOST_CHECK_EQUAL(stateCopy.stepSize.value(), stepSize);
0454 BOOST_CHECK_EQUAL(stateCopy.previousStepSize, state.previousStepSize);
0455
0456
0457
0458
0459 newPos << 0.5, -1.5, 0.;
0460 newAbsMom *= 1.23;
0461 newTime = 8.4;
0462 newCharge = -1.;
0463 newCov = 10.9 * Covariance::Identity();
0464 Transform3 trafo = Transform3::Identity();
0465 auto disc = Surface::makeShared<DiscSurface>(trafo);
0466 auto boundDisc = BoundTrackParameters::create(
0467 geoCtx, disc, makeVector4(newPos, newTime), unitDir,
0468 newCharge / newAbsMom, newCov, particleHypothesis)
0469 .value();
0470
0471
0472 Stepper::State stateDisc = copyState(*magneticField, state);
0473 BOOST_CHECK(boundDisc.covariance().has_value());
0474 stepper.initialize(stateDisc, boundDisc.parameters(), *boundDisc.covariance(),
0475 cp.particleHypothesis(), boundDisc.referenceSurface());
0476
0477 CHECK_NE_COLLECTIONS(stateDisc.pVector, stateCopy.pVector);
0478 CHECK_NE_COLLECTIONS(stateDisc.pVector, state.pVector);
0479
0480
0481
0482 newPos << -2.06155, -2.06155, 3.5;
0483 newAbsMom *= 0.45;
0484 newTime = 2.3;
0485 newCharge = 1.;
0486 newCov = 8.7 * Covariance::Identity();
0487 auto perigee = Surface::makeShared<PerigeeSurface>(trafo);
0488 auto boundPerigee =
0489 BoundTrackParameters::create(
0490 geoCtx, perigee, makeVector4(newPos, newTime), unitDir,
0491 newCharge / newAbsMom, newCov, particleHypothesis)
0492 .value();
0493
0494
0495 Stepper::State statePerigee = copyState(*magneticField, state);
0496 BOOST_CHECK(boundPerigee.covariance().has_value());
0497 stepper.initialize(statePerigee, boundPerigee.parameters(),
0498 *boundPerigee.covariance(), cp.particleHypothesis(),
0499 boundPerigee.referenceSurface());
0500 CHECK_NE_COLLECTIONS(statePerigee.pVector, stateCopy.pVector);
0501 CHECK_NE_COLLECTIONS(statePerigee.pVector, state.pVector);
0502 CHECK_NE_COLLECTIONS(statePerigee.pVector, stateDisc.pVector);
0503
0504
0505
0506 auto straw = Surface::makeShared<StrawSurface>(trafo);
0507 auto boundStraw = BoundTrackParameters::create(
0508 geoCtx, straw, makeVector4(newPos, newTime), unitDir,
0509 newCharge / newAbsMom, newCov, particleHypothesis)
0510 .value();
0511
0512
0513 Stepper::State stateStraw = copyState(*magneticField, state);
0514 BOOST_CHECK(boundStraw.covariance().has_value());
0515 stepper.initialize(stateStraw, boundStraw.parameters(),
0516 *boundStraw.covariance(), cp.particleHypothesis(),
0517 boundStraw.referenceSurface());
0518 CHECK_NE_COLLECTIONS(stateStraw.pVector, stateCopy.pVector);
0519 CHECK_NE_COLLECTIONS(stateStraw.pVector, state.pVector);
0520 CHECK_NE_COLLECTIONS(stateStraw.pVector, stateDisc.pVector);
0521 BOOST_CHECK_EQUAL_COLLECTIONS(
0522 stateStraw.pVector.begin(), stateStraw.pVector.end(),
0523 statePerigee.pVector.begin(), statePerigee.pVector.end());
0524 }
0525
0526 BOOST_AUTO_TEST_CASE(StepSize) {
0527 BoundTrackParameters cp = BoundTrackParameters::createCurvilinear(
0528 pos4, unitDir, charge / absMom, cov, particleHypothesis);
0529
0530 Stepper stepper(magneticField);
0531
0532 Stepper::Options options(geoCtx, magCtx);
0533 options.maxStepSize = stepSize;
0534
0535 Stepper::State state = stepper.makeState(options);
0536 stepper.initialize(state, cp);
0537
0538 stepper.updateStepSize(state, -5_cm, ConstrainedStep::Type::Navigator);
0539 BOOST_CHECK_EQUAL(state.previousStepSize, stepSize);
0540 BOOST_CHECK_EQUAL(state.stepSize.value(), -5_cm);
0541
0542 stepper.releaseStepSize(state, ConstrainedStep::Type::Navigator);
0543 BOOST_CHECK_EQUAL(state.stepSize.value(), stepSize);
0544 }
0545
0546
0547 BOOST_AUTO_TEST_CASE(StepSizeSurface) {
0548 BoundTrackParameters cp = BoundTrackParameters::createCurvilinear(
0549 pos4, unitDir, charge / absMom, cov, particleHypothesis);
0550
0551 Stepper stepper(magneticField);
0552
0553 Stepper::Options options(geoCtx, magCtx);
0554 options.maxStepSize = stepSize;
0555
0556 Stepper::State state = stepper.makeState(options);
0557 stepper.initialize(state, cp);
0558
0559 auto distance = 10_mm;
0560 std::shared_ptr<PlaneSurface> target =
0561 CurvilinearSurface(pos + navDir * distance * unitDir, unitDir)
0562 .planeSurface();
0563
0564 stepper.updateSurfaceStatus(
0565 state, *target, 0, navDir, BoundaryTolerance::Infinite(),
0566 s_onSurfaceTolerance, ConstrainedStep::Type::Navigator);
0567 BOOST_CHECK_EQUAL(state.stepSize.value(ConstrainedStep::Type::Navigator),
0568 distance);
0569
0570 const auto getNavigationTarget = [&](const Surface& s,
0571 const BoundaryTolerance& bt) {
0572 auto [intersection, intersectionIndex] =
0573 s.intersect(geoCtx, stepper.position(state),
0574 navDir * stepper.direction(state), bt)
0575 .closestWithIndex();
0576 return NavigationTarget(intersection, intersectionIndex, s, bt);
0577 };
0578
0579
0580 stepper.updateStepSize(
0581 state, getNavigationTarget(*target, BoundaryTolerance::Infinite()),
0582 navDir, ConstrainedStep::Type::Navigator);
0583 BOOST_CHECK_EQUAL(state.stepSize.value(), distance);
0584
0585
0586 state.stepSize.setUser(navDir * stepSize);
0587 stepper.releaseStepSize(state, ConstrainedStep::Type::Navigator);
0588 stepper.updateStepSize(
0589 state, getNavigationTarget(*target, BoundaryTolerance::Infinite()),
0590 navDir, ConstrainedStep::Type::Navigator);
0591 BOOST_CHECK_EQUAL(state.stepSize.value(), navDir * stepSize);
0592 }
0593
0594 BOOST_AUTO_TEST_SUITE_END()
0595
0596 }