Warning, file /include/Acts/Propagator/Propagator.ipp 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 #include "Acts/EventData/TrackParametersConcept.hpp"
0010 #include "Acts/Propagator/ActionList.hpp"
0011 #include "Acts/Propagator/ConstrainedStep.hpp"
0012 #include "Acts/Propagator/PropagatorError.hpp"
0013 #include "Acts/Propagator/StandardAborters.hpp"
0014 #include "Acts/Propagator/detail/LoopProtection.hpp"
0015
0016 #include <type_traits>
0017
0018 template <typename S, typename N>
0019 template <typename propagator_state_t>
0020 auto Acts::Propagator<S, N>::propagate(propagator_state_t& state) const
0021 -> Result<void> {
0022
0023 ACTS_VERBOSE("Entering propagation.");
0024
0025 state.stage = PropagatorStage::prePropagation;
0026
0027
0028 state.options.actionList(state, m_stepper, m_navigator, logger());
0029
0030
0031
0032
0033 bool terminatedNormally = true;
0034
0035
0036 if (!state.options.abortList(state, m_stepper, m_navigator, logger())) {
0037
0038 ACTS_VERBOSE("Starting stepping loop.");
0039
0040 terminatedNormally = false;
0041
0042
0043 for (; state.steps < state.options.maxSteps; ++state.steps) {
0044
0045 state.stage = PropagatorStage::preStep;
0046 m_navigator.preStep(state, m_stepper);
0047
0048 Result<double> res = m_stepper.step(state, m_navigator);
0049 if (res.ok()) {
0050
0051 double s = *res;
0052 state.pathLength += s;
0053 ACTS_VERBOSE("Step with size = " << s << " performed");
0054 } else {
0055 ACTS_ERROR("Step failed with " << res.error() << ": "
0056 << res.error().message());
0057
0058 return res.error();
0059 }
0060
0061 m_stepper.releaseStepSize(state.stepping, ConstrainedStep::actor);
0062 m_stepper.releaseStepSize(state.stepping, ConstrainedStep::aborter);
0063
0064
0065 state.stage = PropagatorStage::postStep;
0066 m_navigator.postStep(state, m_stepper);
0067 state.options.actionList(state, m_stepper, m_navigator, logger());
0068 if (state.options.abortList(state, m_stepper, m_navigator, logger())) {
0069 terminatedNormally = true;
0070 break;
0071 }
0072 }
0073 } else {
0074 ACTS_VERBOSE("Propagation terminated without going into stepping loop.");
0075 }
0076
0077 state.stage = PropagatorStage::postPropagation;
0078
0079
0080
0081 if (!terminatedNormally) {
0082 m_navigator.navigationBreak(state.navigation, true);
0083 ACTS_ERROR("Propagation reached the step count limit of "
0084 << state.options.maxSteps << " (did " << state.steps
0085 << " steps)");
0086 return PropagatorError::StepCountLimitReached;
0087 }
0088
0089
0090 ACTS_VERBOSE("Stepping loop done.");
0091 state.options.actionList(state, m_stepper, m_navigator, logger());
0092
0093
0094 return Result<void>::success();
0095 }
0096
0097 template <typename S, typename N>
0098 template <typename parameters_t, typename propagator_options_t,
0099 typename path_aborter_t>
0100 auto Acts::Propagator<S, N>::propagate(const parameters_t& start,
0101 const propagator_options_t& options,
0102 bool makeCurvilinear) const
0103 -> Result<action_list_t_result_t<
0104 StepperCurvilinearTrackParameters,
0105 typename propagator_options_t::action_list_type>> {
0106 static_assert(
0107 std::is_copy_constructible<StepperCurvilinearTrackParameters>::value,
0108 "return track parameter type must be copy-constructible");
0109
0110 auto state = makeState(start, options);
0111
0112
0113 auto propagationResult = propagate(state);
0114
0115 return makeResult(std::move(state), propagationResult, options,
0116 makeCurvilinear);
0117 }
0118
0119 template <typename S, typename N>
0120 template <typename parameters_t, typename propagator_options_t,
0121 typename target_aborter_t, typename path_aborter_t>
0122 auto Acts::Propagator<S, N>::propagate(
0123 const parameters_t& start, const Surface& target,
0124 const propagator_options_t& options) const
0125 -> Result<action_list_t_result_t<
0126 StepperBoundTrackParameters,
0127 typename propagator_options_t::action_list_type>> {
0128 static_assert(Concepts::BoundTrackParametersConcept<parameters_t>,
0129 "Parameters do not fulfill bound parameters concept.");
0130
0131 auto state = makeState<parameters_t, propagator_options_t, target_aborter_t,
0132 path_aborter_t>(start, target, options);
0133
0134
0135 auto propagationResult = propagate(state);
0136
0137 return makeResult(std::move(state), propagationResult, target, options);
0138 }
0139
0140 template <typename S, typename N>
0141 template <typename parameters_t, typename propagator_options_t,
0142 typename path_aborter_t>
0143 auto Acts::Propagator<S, N>::makeState(
0144 const parameters_t& start, const propagator_options_t& options) const {
0145 static_assert(Concepts::BoundTrackParametersConcept<parameters_t>,
0146 "Parameters do not fulfill bound parameters concept.");
0147
0148
0149 using ReturnParameterType = StepperCurvilinearTrackParameters;
0150
0151 static_assert(std::is_copy_constructible<ReturnParameterType>::value,
0152 "return track parameter type must be copy-constructible");
0153
0154
0155 path_aborter_t pathAborter;
0156 pathAborter.internalLimit = options.pathLimit;
0157
0158 auto abortList = options.abortList.append(pathAborter);
0159
0160
0161 auto eOptions = options.extend(abortList);
0162 using OptionsType = decltype(eOptions);
0163
0164 using StateType =
0165 action_list_t_state_t<OptionsType,
0166 typename propagator_options_t::action_list_type>;
0167 StateType state{
0168 eOptions,
0169 m_stepper.makeState(eOptions.geoContext, eOptions.magFieldContext, start,
0170 eOptions.maxStepSize),
0171 m_navigator.makeState(&start.referenceSurface(), nullptr)};
0172
0173 static_assert(
0174 Concepts::has_method<const S, Result<double>, Concepts::Stepper::step_t,
0175 StateType&, const N&>,
0176 "Step method of the Stepper is not compatible with the propagator "
0177 "state");
0178
0179 initialize<StateType, path_aborter_t>(state);
0180
0181 return state;
0182 }
0183
0184 template <typename S, typename N>
0185 template <typename parameters_t, typename propagator_options_t,
0186 typename target_aborter_t, typename path_aborter_t>
0187 auto Acts::Propagator<S, N>::makeState(
0188 const parameters_t& start, const Surface& target,
0189 const propagator_options_t& options) const {
0190 static_assert(Concepts::BoundTrackParametersConcept<parameters_t>,
0191 "Parameters do not fulfill bound parameters concept.");
0192
0193
0194 target_aborter_t targetAborter;
0195 targetAborter.surface = ⌖
0196 path_aborter_t pathAborter;
0197 pathAborter.internalLimit = options.pathLimit;
0198 auto abortList = options.abortList.append(targetAborter, pathAborter);
0199
0200
0201 auto eOptions = options.extend(abortList);
0202 using OptionsType = decltype(eOptions);
0203
0204
0205 using StateType =
0206 action_list_t_state_t<OptionsType,
0207 typename propagator_options_t::action_list_type>;
0208 StateType state{
0209 eOptions,
0210 m_stepper.makeState(eOptions.geoContext, eOptions.magFieldContext, start,
0211 eOptions.maxStepSize),
0212 m_navigator.makeState(&start.referenceSurface(), &target)};
0213
0214 static_assert(
0215 Concepts::has_method<const S, Result<double>, Concepts::Stepper::step_t,
0216 StateType&, const N&>,
0217 "Step method of the Stepper is not compatible with the propagator "
0218 "state");
0219
0220 initialize<StateType, path_aborter_t>(state);
0221
0222 return state;
0223 }
0224
0225 template <typename S, typename N>
0226 template <typename propagator_state_t, typename propagator_options_t>
0227 auto Acts::Propagator<S, N>::makeResult(propagator_state_t state,
0228 Result<void> propagationResult,
0229 const propagator_options_t& ,
0230 bool makeCurvilinear) const
0231 -> Result<action_list_t_result_t<
0232 StepperCurvilinearTrackParameters,
0233 typename propagator_options_t::action_list_type>> {
0234
0235 using ReturnParameterType = StepperCurvilinearTrackParameters;
0236
0237 static_assert(std::is_copy_constructible<ReturnParameterType>::value,
0238 "return track parameter type must be copy-constructible");
0239
0240
0241 using ResultType =
0242 action_list_t_result_t<ReturnParameterType,
0243 typename propagator_options_t::action_list_type>;
0244
0245 if (!propagationResult.ok()) {
0246 return propagationResult.error();
0247 }
0248
0249 ResultType result{};
0250 moveStateToResult(state, result);
0251
0252 if (makeCurvilinear) {
0253 if (!m_stepper.prepareCurvilinearState(state, m_navigator)) {
0254
0255 return propagationResult.error();
0256 }
0257
0258 auto curvState = m_stepper.curvilinearState(state.stepping);
0259
0260 result.endParameters =
0261 std::get<StepperCurvilinearTrackParameters>(curvState);
0262
0263 if (state.stepping.covTransport) {
0264 result.transportJacobian = std::get<Jacobian>(curvState);
0265 }
0266 }
0267
0268 return Result<ResultType>::success(std::move(result));
0269 }
0270
0271 template <typename S, typename N>
0272 template <typename propagator_state_t, typename propagator_options_t>
0273 auto Acts::Propagator<S, N>::makeResult(
0274 propagator_state_t state, Result<void> propagationResult,
0275 const Surface& target, const propagator_options_t& ) const
0276 -> Result<action_list_t_result_t<
0277 StepperBoundTrackParameters,
0278 typename propagator_options_t::action_list_type>> {
0279
0280 using ReturnParameterType = StepperBoundTrackParameters;
0281
0282 static_assert(std::is_copy_constructible<ReturnParameterType>::value,
0283 "return track parameter type must be copy-constructible");
0284
0285
0286 using ResultType =
0287 action_list_t_result_t<ReturnParameterType,
0288 typename propagator_options_t::action_list_type>;
0289
0290 if (!propagationResult.ok()) {
0291 return propagationResult.error();
0292 }
0293
0294 ResultType result{};
0295 moveStateToResult(state, result);
0296
0297
0298 auto bsRes = m_stepper.boundState(state.stepping, target);
0299 if (!bsRes.ok()) {
0300 return bsRes.error();
0301 }
0302 const auto& bs = *bsRes;
0303
0304
0305 result.endParameters = std::get<StepperBoundTrackParameters>(bs);
0306
0307 if (state.stepping.covTransport) {
0308 result.transportJacobian = std::get<Jacobian>(bs);
0309 }
0310 return Result<ResultType>::success(std::move(result));
0311 }
0312
0313 template <typename S, typename N>
0314 template <typename propagator_state_t, typename path_aborter_t>
0315 void Acts::Propagator<S, N>::initialize(propagator_state_t& state) const {
0316
0317 m_navigator.initialize(state, m_stepper);
0318
0319
0320 detail::setupLoopProtection(
0321 state, m_stepper, state.options.abortList.template get<path_aborter_t>(),
0322 false, logger());
0323 }
0324
0325 template <typename S, typename N>
0326 template <typename propagator_state_t, typename result_t>
0327 void Acts::Propagator<S, N>::moveStateToResult(propagator_state_t& state,
0328 result_t& result) const {
0329 result.tuple() = std::move(state.tuple());
0330
0331 result.steps = state.steps;
0332 result.pathLength = state.pathLength;
0333 }
0334
0335 template <typename derived_t>
0336 Acts::Result<Acts::BoundTrackParameters>
0337 Acts::detail::BasePropagatorHelper<derived_t>::propagateToSurface(
0338 const BoundTrackParameters& start, const Surface& target,
0339 const Options& options) const {
0340 using ResultType = Result<typename derived_t::template action_list_t_result_t<
0341 BoundTrackParameters, ActionList<>>>;
0342
0343
0344 ResultType res = ResultType::failure(PropagatorError::Failure);
0345
0346
0347
0348 if (target.type() == Surface::SurfaceType::Perigee) {
0349 res = static_cast<const derived_t*>(this)
0350 ->template propagate<BoundTrackParameters, PropagatorOptions<>,
0351 ForcedSurfaceReached, PathLimitReached>(
0352 start, target, options);
0353 } else {
0354 res = static_cast<const derived_t*>(this)
0355 ->template propagate<BoundTrackParameters, PropagatorOptions<>,
0356 SurfaceReached, PathLimitReached>(
0357 start, target, options);
0358 }
0359
0360 if (res.ok()) {
0361
0362
0363 assert((*res).endParameters);
0364 return std::move((*res).endParameters.value());
0365 } else {
0366 return res.error();
0367 }
0368 }