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