File indexing completed on 2025-01-18 09:10:59
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
0012 #include "Acts/Utilities/detail/ReferenceWrapperAnyCompat.hpp"
0013
0014 #include "Acts/Definitions/Algebra.hpp"
0015 #include "Acts/Definitions/Direction.hpp"
0016 #include "Acts/Definitions/TrackParametrization.hpp"
0017 #include "Acts/EventData/TrackParameters.hpp"
0018 #include "Acts/EventData/detail/CorrectedTransformationFreeToBound.hpp"
0019 #include "Acts/MagneticField/NullBField.hpp"
0020 #include "Acts/Propagator/ConstrainedStep.hpp"
0021 #include "Acts/Propagator/PropagatorTraits.hpp"
0022 #include "Acts/Propagator/StepperOptions.hpp"
0023 #include "Acts/Propagator/StepperStatistics.hpp"
0024 #include "Acts/Propagator/detail/SteppingHelper.hpp"
0025 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0026 #include "Acts/Surfaces/Surface.hpp"
0027 #include "Acts/Utilities/Intersection.hpp"
0028 #include "Acts/Utilities/Logger.hpp"
0029 #include "Acts/Utilities/MathHelpers.hpp"
0030 #include "Acts/Utilities/Result.hpp"
0031
0032 #include <cmath>
0033 #include <limits>
0034 #include <string>
0035 #include <tuple>
0036
0037 namespace Acts {
0038
0039
0040
0041
0042
0043
0044 class StraightLineStepper {
0045 public:
0046 using Jacobian = BoundMatrix;
0047 using Covariance = BoundSquareMatrix;
0048 using BoundState = std::tuple<BoundTrackParameters, Jacobian, double>;
0049 using CurvilinearState =
0050 std::tuple<CurvilinearTrackParameters, Jacobian, double>;
0051 using BField = NullBField;
0052
0053 struct Config {};
0054
0055 struct Options : public StepperPlainOptions {
0056 Options(const GeometryContext& gctx, const MagneticFieldContext& mctx)
0057 : StepperPlainOptions(gctx, mctx) {}
0058
0059 void setPlainOptions(const StepperPlainOptions& options) {
0060 static_cast<StepperPlainOptions&>(*this) = options;
0061 }
0062 };
0063
0064
0065
0066 struct State {
0067
0068
0069
0070
0071
0072 explicit State(const Options& optionsIn) : options(optionsIn) {}
0073
0074 Options options;
0075
0076
0077 BoundToFreeMatrix jacToGlobal = BoundToFreeMatrix::Zero();
0078
0079
0080 FreeMatrix jacTransport = FreeMatrix::Identity();
0081
0082
0083 Jacobian jacobian = Jacobian::Identity();
0084
0085
0086 FreeVector derivative = FreeVector::Zero();
0087
0088
0089 FreeVector pars = FreeVector::Zero();
0090
0091
0092 ParticleHypothesis particleHypothesis = ParticleHypothesis::pion();
0093
0094
0095 bool covTransport = false;
0096 Covariance cov = Covariance::Zero();
0097
0098
0099 double pathAccumulated = 0.;
0100
0101
0102 std::size_t nSteps = 0;
0103
0104
0105 std::size_t nStepTrials = 0;
0106
0107
0108 ConstrainedStep stepSize;
0109
0110
0111 double previousStepSize = 0.;
0112
0113
0114 StepperStatistics statistics;
0115 };
0116
0117 StraightLineStepper() = default;
0118
0119 State makeState(const Options& options,
0120 const BoundTrackParameters& par) const {
0121 State state{options};
0122
0123 state.particleHypothesis = par.particleHypothesis();
0124
0125 Vector3 position = par.position(options.geoContext);
0126 Vector3 direction = par.direction();
0127 state.pars.template segment<3>(eFreePos0) = position;
0128 state.pars.template segment<3>(eFreeDir0) = direction;
0129 state.pars[eFreeTime] = par.time();
0130 state.pars[eFreeQOverP] = par.parameters()[eBoundQOverP];
0131
0132
0133 if (par.covariance()) {
0134
0135 const auto& surface = par.referenceSurface();
0136
0137 state.covTransport = true;
0138 state.cov = BoundSquareMatrix(*par.covariance());
0139 state.jacToGlobal =
0140 surface.boundToFreeJacobian(options.geoContext, position, direction);
0141 }
0142
0143 state.stepSize = ConstrainedStep(options.maxStepSize);
0144
0145 return state;
0146 }
0147
0148
0149
0150
0151
0152
0153
0154
0155 void resetState(
0156 State& state, const BoundVector& boundParams,
0157 const BoundSquareMatrix& cov, const Surface& surface,
0158 const double stepSize = std::numeric_limits<double>::max()) const;
0159
0160
0161 Result<Vector3> getField(State& , const Vector3& ) const {
0162
0163 return Result<Vector3>::success({0., 0., 0.});
0164 }
0165
0166
0167
0168
0169 Vector3 position(const State& state) const {
0170 return state.pars.template segment<3>(eFreePos0);
0171 }
0172
0173
0174
0175
0176 Vector3 direction(const State& state) const {
0177 return state.pars.template segment<3>(eFreeDir0);
0178 }
0179
0180
0181
0182
0183 double qOverP(const State& state) const { return state.pars[eFreeQOverP]; }
0184
0185
0186
0187
0188 double absoluteMomentum(const State& state) const {
0189 return particleHypothesis(state).extractMomentum(qOverP(state));
0190 }
0191
0192
0193
0194
0195 Vector3 momentum(const State& state) const {
0196 return absoluteMomentum(state) * direction(state);
0197 }
0198
0199
0200
0201
0202 double charge(const State& state) const {
0203 return particleHypothesis(state).extractCharge(qOverP(state));
0204 }
0205
0206
0207
0208
0209 const ParticleHypothesis& particleHypothesis(const State& state) const {
0210 return state.particleHypothesis;
0211 }
0212
0213
0214
0215
0216 double time(const State& state) const { return state.pars[eFreeTime]; }
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233 IntersectionStatus updateSurfaceStatus(
0234 State& state, const Surface& surface, std::uint8_t index,
0235 Direction navDir, const BoundaryTolerance& boundaryTolerance,
0236 double surfaceTolerance, ConstrainedStep::Type stype,
0237 const Logger& logger = getDummyLogger()) const {
0238 return detail::updateSingleSurfaceStatus<StraightLineStepper>(
0239 *this, state, surface, index, navDir, boundaryTolerance,
0240 surfaceTolerance, stype, logger);
0241 }
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252 template <typename object_intersection_t>
0253 void updateStepSize(State& state, const object_intersection_t& oIntersection,
0254 Direction direction, ConstrainedStep::Type stype) const {
0255 (void)direction;
0256 double stepSize = oIntersection.pathLength();
0257 updateStepSize(state, stepSize, stype);
0258 }
0259
0260
0261
0262
0263
0264
0265 void updateStepSize(State& state, double stepSize,
0266 ConstrainedStep::Type stype) const {
0267 state.previousStepSize = state.stepSize.value();
0268 state.stepSize.update(stepSize, stype);
0269 }
0270
0271
0272
0273
0274
0275 double getStepSize(const State& state, ConstrainedStep::Type stype) const {
0276 return state.stepSize.value(stype);
0277 }
0278
0279
0280
0281
0282
0283 void releaseStepSize(State& state, ConstrainedStep::Type stype) const {
0284 state.stepSize.release(stype);
0285 }
0286
0287
0288
0289
0290 std::string outputStepSize(const State& state) const {
0291 return state.stepSize.toString();
0292 }
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308 Result<BoundState> boundState(
0309 State& state, const Surface& surface, bool transportCov = true,
0310 const FreeToBoundCorrection& freeToBoundCorrection =
0311 FreeToBoundCorrection(false)) const;
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321 template <typename propagator_state_t, typename navigator_t>
0322 bool prepareCurvilinearState(
0323 [[maybe_unused]] propagator_state_t& prop_state,
0324 [[maybe_unused]] const navigator_t& navigator) const {
0325
0326 if (prop_state.stepping.pathAccumulated == 0.) {
0327
0328 prop_state.stepping.derivative.template head<3>() =
0329 direction(prop_state.stepping);
0330
0331 prop_state.stepping.derivative(eFreeTime) =
0332 fastHypot(1., prop_state.stepping.particleHypothesis.mass() /
0333 absoluteMomentum(prop_state.stepping));
0334
0335 prop_state.stepping.derivative.template segment<3>(4) =
0336 Acts::Vector3::Zero().transpose();
0337
0338 prop_state.stepping.derivative(eFreeQOverP) = 0.;
0339 }
0340 return true;
0341 }
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354 CurvilinearState curvilinearState(State& state,
0355 bool transportCov = true) const;
0356
0357
0358
0359
0360
0361
0362
0363
0364 void update(State& state, const FreeVector& freeParams,
0365 const BoundVector& boundParams, const Covariance& covariance,
0366 const Surface& surface) const;
0367
0368
0369
0370
0371
0372
0373
0374
0375 void update(State& state, const Vector3& uposition, const Vector3& udirection,
0376 double qop, double time) const;
0377
0378
0379
0380
0381
0382
0383 void transportCovarianceToCurvilinear(State& state) const;
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397 void transportCovarianceToBound(
0398 State& state, const Surface& surface,
0399 const FreeToBoundCorrection& freeToBoundCorrection =
0400 FreeToBoundCorrection(false)) const;
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412 template <typename propagator_state_t, typename navigator_t>
0413 Result<double> step(propagator_state_t& state,
0414 const navigator_t& ) const {
0415
0416 const auto h = state.stepping.stepSize.value() * state.options.direction;
0417 const auto m = state.stepping.particleHypothesis.mass();
0418 const auto p = absoluteMomentum(state.stepping);
0419
0420 const auto dtds = fastHypot(1., m / p);
0421
0422 Vector3 dir = direction(state.stepping);
0423 state.stepping.pars.template segment<3>(eFreePos0) += h * dir;
0424 state.stepping.pars[eFreeTime] += h * dtds;
0425
0426
0427 if (state.stepping.covTransport) {
0428
0429 FreeMatrix D = FreeMatrix::Identity();
0430 D.block<3, 3>(0, 4) = ActsSquareMatrix<3>::Identity() * h;
0431
0432
0433 D(3, 7) = h * m * m * state.stepping.pars[eFreeQOverP] / dtds;
0434
0435 state.stepping.derivative(3) = dtds;
0436
0437 state.stepping.jacTransport = D * state.stepping.jacTransport;
0438 state.stepping.derivative.template head<3>() = dir;
0439 }
0440
0441
0442 state.stepping.pathAccumulated += h;
0443 ++state.stepping.nSteps;
0444 ++state.stepping.nStepTrials;
0445
0446 ++state.stepping.statistics.nAttemptedSteps;
0447 ++state.stepping.statistics.nSuccessfulSteps;
0448 if (state.options.direction != Direction::fromScalarZeroAsPositive(h)) {
0449 ++state.stepping.statistics.nReverseSteps;
0450 }
0451 state.stepping.statistics.pathLength += h;
0452 state.stepping.statistics.absolutePathLength += std::abs(h);
0453
0454 return h;
0455 }
0456 };
0457
0458 template <typename navigator_t>
0459 struct SupportsBoundParameters<StraightLineStepper, navigator_t>
0460 : public std::true_type {};
0461
0462 }