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