File indexing completed on 2025-08-05 08:09:19
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
0012
0013 #include "Acts/Utilities/detail/ReferenceWrapperAnyCompat.hpp"
0014
0015
0016 #include "Acts/Definitions/Algebra.hpp"
0017 #include "Acts/Definitions/PdgParticle.hpp"
0018 #include "Acts/Definitions/Units.hpp"
0019 #include "Acts/EventData/TrackParameters.hpp"
0020 #include "Acts/EventData/TrackParametersConcept.hpp"
0021 #include "Acts/Geometry/GeometryContext.hpp"
0022 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0023 #include "Acts/Propagator/AbortList.hpp"
0024 #include "Acts/Propagator/ActionList.hpp"
0025 #include "Acts/Propagator/PropagatorTraits.hpp"
0026 #include "Acts/Propagator/StandardAborters.hpp"
0027 #include "Acts/Propagator/StepperConcept.hpp"
0028 #include "Acts/Propagator/VoidNavigator.hpp"
0029 #include "Acts/Propagator/detail/ParameterTraits.hpp"
0030 #include "Acts/Utilities/Logger.hpp"
0031 #include "Acts/Utilities/Result.hpp"
0032
0033 #include <optional>
0034
0035 namespace Acts {
0036
0037
0038 enum class PropagatorStage {
0039 invalid,
0040 prePropagation,
0041 postPropagation,
0042 preStep,
0043 postStep,
0044 };
0045
0046
0047
0048
0049
0050
0051 template <typename parameters_t, typename... result_list>
0052 struct PropagatorResult : private detail::Extendable<result_list...> {
0053 using detail::Extendable<result_list...>::get;
0054 using detail::Extendable<result_list...>::tuple;
0055
0056
0057 std::optional<parameters_t> endParameters = std::nullopt;
0058
0059
0060 std::optional<BoundMatrix> transportJacobian = std::nullopt;
0061
0062
0063 unsigned int steps = 0;
0064
0065
0066 double pathLength = 0.;
0067 };
0068
0069
0070
0071 struct PropagatorPlainOptions {
0072
0073 Direction direction = Direction::Forward;
0074
0075
0076 unsigned int maxSteps = 1000;
0077
0078
0079 double pathLimit = std::numeric_limits<double>::max();
0080
0081
0082 double surfaceTolerance = s_onSurfaceTolerance;
0083
0084
0085 bool loopProtection = true;
0086 double loopFraction = 0.5;
0087
0088
0089
0090
0091 double stepTolerance = 1e-4;
0092
0093
0094 double stepSizeCutOff = 0.;
0095
0096
0097 double maxStepSize = std::numeric_limits<double>::max();
0098
0099
0100 unsigned int maxRungeKuttaStepTrials = 10000;
0101 };
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111 template <typename action_list_t = ActionList<>,
0112 typename aborter_list_t = AbortList<>>
0113 struct PropagatorOptions : public PropagatorPlainOptions {
0114 using action_list_type = action_list_t;
0115 using aborter_list_type = aborter_list_t;
0116
0117
0118 PropagatorOptions() = delete;
0119
0120
0121 PropagatorOptions(
0122 const PropagatorOptions<action_list_t, aborter_list_t>& po) = default;
0123
0124
0125 PropagatorOptions(const GeometryContext& gctx,
0126 const MagneticFieldContext& mctx)
0127 : geoContext(gctx), magFieldContext(mctx) {}
0128
0129
0130
0131
0132
0133
0134 template <typename extended_aborter_list_t>
0135 PropagatorOptions<action_list_t, extended_aborter_list_t> extend(
0136 extended_aborter_list_t aborters) const {
0137 PropagatorOptions<action_list_t, extended_aborter_list_t> eoptions(
0138 geoContext, magFieldContext);
0139
0140
0141 eoptions.setPlainOptions(*this);
0142
0143
0144 eoptions.actionList = std::move(actionList);
0145 eoptions.abortList = std::move(aborters);
0146
0147
0148 return eoptions;
0149 }
0150
0151
0152
0153
0154 void setPlainOptions(const PropagatorPlainOptions& pOptions) {
0155
0156 direction = pOptions.direction;
0157 maxSteps = pOptions.maxSteps;
0158 surfaceTolerance = pOptions.surfaceTolerance;
0159 pathLimit = direction * std::abs(pOptions.pathLimit);
0160 loopProtection = pOptions.loopProtection;
0161 loopFraction = pOptions.loopFraction;
0162
0163
0164 stepTolerance = pOptions.stepTolerance;
0165 stepSizeCutOff = pOptions.stepSizeCutOff;
0166 maxStepSize = pOptions.maxStepSize;
0167 maxRungeKuttaStepTrials = pOptions.maxRungeKuttaStepTrials;
0168 }
0169
0170
0171 action_list_t actionList;
0172
0173
0174 aborter_list_t abortList;
0175
0176
0177 std::reference_wrapper<const GeometryContext> geoContext;
0178
0179
0180 std::reference_wrapper<const MagneticFieldContext> magFieldContext;
0181 };
0182
0183
0184
0185
0186
0187
0188
0189 class BasePropagator {
0190 public:
0191
0192 using Options = PropagatorOptions<>;
0193
0194
0195
0196
0197
0198
0199 virtual Result<BoundTrackParameters> propagateToSurface(
0200 const BoundTrackParameters& start, const Surface& target,
0201 const Options& options) const = 0;
0202
0203 virtual ~BasePropagator() = default;
0204 };
0205
0206 namespace detail {
0207 class PropagatorStub {};
0208
0209 template <typename derived_t>
0210 class BasePropagatorHelper : public BasePropagator {
0211 public:
0212 Result<BoundTrackParameters> propagateToSurface(
0213 const BoundTrackParameters& start, const Surface& target,
0214 const Options& options) const override;
0215 };
0216 }
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243 template <typename stepper_t, typename navigator_t = VoidNavigator>
0244 class Propagator final
0245 : public std::conditional_t<
0246 SupportsBoundParameters_v<stepper_t, navigator_t>,
0247 detail::BasePropagatorHelper<Propagator<stepper_t, navigator_t>>,
0248 detail::PropagatorStub> {
0249
0250 using StepperBoundTrackParameters =
0251 detail::stepper_bound_parameters_type_t<stepper_t>;
0252 static_assert(
0253 Concepts::BoundTrackParametersConcept<StepperBoundTrackParameters>,
0254 "Stepper bound track parameters do not fulfill bound "
0255 "parameters concept.");
0256
0257
0258 using StepperCurvilinearTrackParameters =
0259 detail::stepper_curvilinear_parameters_type_t<stepper_t>;
0260 static_assert(
0261 Concepts::BoundTrackParametersConcept<StepperCurvilinearTrackParameters>,
0262 "Stepper bound track parameters do not fulfill bound "
0263 "parameters concept.");
0264
0265 using Jacobian = BoundMatrix;
0266 using BoundState = std::tuple<StepperBoundTrackParameters, Jacobian, double>;
0267 using CurvilinearState =
0268 std::tuple<StepperCurvilinearTrackParameters, Jacobian, double>;
0269
0270 static_assert(StepperStateConcept<typename stepper_t::State>,
0271 "Stepper does not fulfill stepper concept.");
0272 static_assert(StepperConcept<stepper_t>,
0273 "Stepper does not fulfill stepper concept.");
0274
0275 public:
0276
0277 using Stepper = stepper_t;
0278
0279
0280 using Navigator = navigator_t;
0281
0282
0283 using StepperState = typename Stepper::State;
0284
0285
0286 using NavigatorState = typename navigator_t::State;
0287
0288
0289
0290
0291
0292
0293 explicit Propagator(stepper_t stepper, navigator_t navigator = navigator_t(),
0294 std::shared_ptr<const Logger> _logger =
0295 getDefaultLogger("Propagator", Acts::Logging::INFO))
0296 : m_stepper(std::move(stepper)),
0297 m_navigator(std::move(navigator)),
0298 m_logger{std::move(_logger)} {}
0299
0300
0301
0302
0303
0304
0305
0306 template <typename propagator_options_t, typename... extension_state_t>
0307 struct State : private detail::Extendable<extension_state_t...> {
0308 using options_type = propagator_options_t;
0309
0310
0311
0312
0313
0314
0315
0316
0317 State(const propagator_options_t& topts, StepperState steppingIn,
0318 NavigatorState navigationIn)
0319 : options(topts),
0320 stepping{std::move(steppingIn)},
0321 navigation{std::move(navigationIn)},
0322 geoContext(topts.geoContext) {}
0323
0324 using detail::Extendable<extension_state_t...>::get;
0325 using detail::Extendable<extension_state_t...>::tuple;
0326
0327
0328 PropagatorStage stage = PropagatorStage::invalid;
0329
0330
0331 propagator_options_t options;
0332
0333
0334 StepperState stepping;
0335
0336
0337 NavigatorState navigation;
0338
0339
0340 std::reference_wrapper<const GeometryContext> geoContext;
0341
0342
0343 unsigned int steps = 0;
0344
0345
0346 double pathLength = 0.;
0347 };
0348
0349 private:
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359 template <typename propagator_options_t, typename action_list_t>
0360 struct state_type_helper {
0361
0362
0363
0364
0365
0366 template <typename... args>
0367 using this_state_type = State<propagator_options_t, args...>;
0368
0369
0370 using type = typename action_list_t::template result_type<this_state_type>;
0371 };
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382 template <typename parameters_t, typename action_list_t>
0383 struct result_type_helper {
0384
0385
0386
0387
0388
0389 template <typename... args>
0390 using this_result_type = PropagatorResult<parameters_t, args...>;
0391
0392
0393 using type = typename action_list_t::template result_type<this_result_type>;
0394 };
0395
0396 public:
0397
0398
0399
0400
0401
0402 template <typename propagator_options_t, typename action_list_t>
0403 using action_list_t_state_t =
0404 typename state_type_helper<propagator_options_t, action_list_t>::type;
0405
0406
0407
0408
0409
0410
0411
0412 template <typename parameters_t, typename action_list_t>
0413 using action_list_t_result_t =
0414 typename result_type_helper<parameters_t, action_list_t>::type;
0415
0416 public:
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435 template <typename parameters_t, typename propagator_options_t,
0436 typename path_aborter_t = PathLimitReached>
0437 Result<
0438 action_list_t_result_t<StepperCurvilinearTrackParameters,
0439 typename propagator_options_t::action_list_type>>
0440 propagate(const parameters_t& start, const propagator_options_t& options,
0441 bool makeCurvilinear = true) const;
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461 template <typename parameters_t, typename propagator_options_t,
0462 typename target_aborter_t = SurfaceReached,
0463 typename path_aborter_t = PathLimitReached>
0464 Result<
0465 action_list_t_result_t<StepperBoundTrackParameters,
0466 typename propagator_options_t::action_list_type>>
0467 propagate(const parameters_t& start, const Surface& target,
0468 const propagator_options_t& options) const;
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484 template <typename propagator_state_t>
0485 Result<void> propagate(propagator_state_t& state) const;
0486
0487 template <typename parameters_t, typename propagator_options_t,
0488 typename path_aborter_t = PathLimitReached>
0489 auto makeState(const parameters_t& start,
0490 const propagator_options_t& options) const;
0491
0492 template <typename parameters_t, typename propagator_options_t,
0493 typename target_aborter_t = SurfaceReached,
0494 typename path_aborter_t = PathLimitReached>
0495 auto makeState(const parameters_t& start, const Surface& target,
0496 const propagator_options_t& options) const;
0497
0498 template <typename propagator_state_t, typename propagator_options_t>
0499 Result<
0500 action_list_t_result_t<StepperCurvilinearTrackParameters,
0501 typename propagator_options_t::action_list_type>>
0502 makeResult(propagator_state_t state, Result<void> result,
0503 const propagator_options_t& options, bool makeCurvilinear) const;
0504
0505 template <typename propagator_state_t, typename propagator_options_t>
0506 Result<
0507 action_list_t_result_t<StepperBoundTrackParameters,
0508 typename propagator_options_t::action_list_type>>
0509 makeResult(propagator_state_t state, Result<void> result,
0510 const Surface& target, const propagator_options_t& options) const;
0511
0512 const stepper_t& stepper() const { return m_stepper; }
0513
0514 const navigator_t& navigator() const { return m_navigator; }
0515
0516 private:
0517 const Logger& logger() const { return *m_logger; }
0518
0519 template <typename propagator_state_t, typename result_t>
0520 void moveStateToResult(propagator_state_t& state, result_t& result) const;
0521
0522
0523 stepper_t m_stepper;
0524
0525
0526 navigator_t m_navigator;
0527
0528 std::shared_ptr<const Logger> m_logger;
0529 };
0530
0531 }
0532
0533 #include "Acts/Propagator/Propagator.ipp"