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