EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Propagator.ipp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Propagator.ipp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2019 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
10 
11 template <typename S, typename N>
12 template <typename result_t, typename propagator_state_t>
13 auto Acts::Propagator<S, N>::propagate_impl(propagator_state_t& state) const
14  -> Result<result_t> {
15  result_t result;
16 
17  const auto& logger = state.options.logger;
18 
19  // Pre-stepping call to the navigator and action list
20  ACTS_VERBOSE("Entering propagation.");
21 
22  // Navigator initialize state call
23  m_navigator.status(state, m_stepper);
24  // Pre-Stepping call to the action list
25  state.options.actionList(state, m_stepper, result);
26  // assume negative outcome, only set to true later if we actually have
27  // a positive outcome.
28 
29  // start at true, if we don't begin the stepping loop we're fine.
30  bool terminatedNormally = true;
31 
32  // Pre-Stepping: abort condition check
33  if (!state.options.abortList(result, state, m_stepper)) {
34  // Pre-Stepping: target setting
35  m_navigator.target(state, m_stepper);
36  // Stepping loop
37  ACTS_VERBOSE("Starting stepping loop.");
38 
39  terminatedNormally = false; // priming error condition
40 
41  // Propagation loop : stepping
42  for (; result.steps < state.options.maxSteps; ++result.steps) {
43  // Perform a propagation step - it takes the propagation state
44  Result<double> res = m_stepper.step(state);
45  if (res.ok()) {
46  // Accumulate the path length
47  double s = *res;
48  result.pathLength += s;
49  ACTS_VERBOSE("Step with size = " << s << " performed");
50  } else {
51  ACTS_ERROR("Step failed: " << res.error());
52  // pass error to caller
53  return res.error();
54  }
55  // Post-stepping:
56  // navigator status call - action list - aborter list - target call
57  m_navigator.status(state, m_stepper);
58  state.options.actionList(state, m_stepper, result);
59  if (state.options.abortList(result, state, m_stepper)) {
60  terminatedNormally = true;
61  break;
62  }
63  m_navigator.target(state, m_stepper);
64  }
65  } else {
66  ACTS_VERBOSE("Propagation terminated without going into stepping loop.");
67  }
68 
69  // if we didn't terminate normally (via aborters) set navigation break.
70  // this will trigger error output in the lines below
71  if (!terminatedNormally) {
72  state.navigation.navigationBreak = true;
73  ACTS_ERROR("Propagation reached the step count limit of "
74  << state.options.maxSteps << " (did " << result.steps
75  << " steps)");
76  return PropagatorError::StepCountLimitReached;
77  }
78 
79  // Post-stepping call to the action list
80  ACTS_VERBOSE("Stepping loop done.");
81  state.options.actionList(state, m_stepper, result);
82 
83  // return progress flag here, decide on SUCCESS later
84  return Result<result_t>(std::move(result));
85 }
86 
87 template <typename S, typename N>
88 template <typename parameters_t, typename propagator_options_t,
89  typename path_aborter_t>
91  const parameters_t& start, const propagator_options_t& options) const
94  typename propagator_options_t::action_list_type>> {
95  static_assert(Concepts::BoundTrackParametersConcept<parameters_t>,
96  "Parameters do not fulfill bound parameters concept.");
97 
98  // Type of track parameters produced by the propagation
99  using ReturnParameterType = CurvilinearTrackParameters;
100 
101  // Type of the full propagation result, including output from actions
102  using ResultType =
103  action_list_t_result_t<ReturnParameterType,
104  typename propagator_options_t::action_list_type>;
105 
107  "return track parameter type must be copy-constructible");
108 
109  // Expand the abort list with a path aborter
110  path_aborter_t pathAborter;
111  pathAborter.internalLimit = options.pathLimit;
112 
113  auto abortList = options.abortList.append(pathAborter);
114 
115  // The expanded options (including path limit)
116  auto eOptions = options.extend(abortList);
117  using OptionsType = decltype(eOptions);
118  // Initialize the internal propagator state
119  using StateType = State<OptionsType>;
120  StateType state(start, eOptions);
121 
122  static_assert(
123  Concepts ::has_method<const S, Result<double>, Concepts ::Stepper::step_t,
124  StateType&>,
125  "Step method of the Stepper is not compatible with the propagator "
126  "state");
127 
128  // Apply the loop protection - it resets the internal path limit
129  if (options.loopProtection) {
131  lProtection(state, m_stepper);
132  }
133  // Perform the actual propagation & check its outcome
134  auto result = propagate_impl<ResultType>(state);
135  if (result.ok()) {
136  auto& propRes = *result;
138  auto curvState = m_stepper.curvilinearState(state.stepping);
139  auto& curvParameters = std::get<CurvilinearTrackParameters>(curvState);
140  // Fill the end parameters
141  propRes.endParameters = std::make_unique<const CurvilinearTrackParameters>(
142  std::move(curvParameters));
143  // Only fill the transport jacobian when covariance transport was done
144  if (state.stepping.covTransport) {
145  auto& tJacobian = std::get<Jacobian>(curvState);
146  propRes.transportJacobian =
147  std::make_unique<const Jacobian>(std::move(tJacobian));
148  }
149  return result;
150  } else {
151  return result.error();
152  }
153 }
154 
155 template <typename S, typename N>
156 template <typename parameters_t, typename propagator_options_t,
157  typename target_aborter_t, typename path_aborter_t>
159  const parameters_t& start, const Surface& target,
160  const propagator_options_t& options) const
163  typename propagator_options_t::action_list_type>> {
164  static_assert(Concepts::BoundTrackParametersConcept<parameters_t>,
165  "Parameters do not fulfill bound parameters concept.");
166 
167  // Type of track parameters produced at the end of the propagation
168  using return_parameter_type = BoundTrackParameters;
169 
170  // Type of provided options
171  target_aborter_t targetAborter;
172  path_aborter_t pathAborter;
173  pathAborter.internalLimit = options.pathLimit;
174  auto abortList = options.abortList.append(targetAborter, pathAborter);
175 
176  // Create the extended options and declare their type
177  auto eOptions = options.extend(abortList);
178  using OptionsType = decltype(eOptions);
179 
180  // Type of the full propagation result, including output from actions
181  using ResultType =
182  action_list_t_result_t<return_parameter_type,
183  typename propagator_options_t::action_list_type>;
184 
185  // Initialize the internal propagator state
186  using StateType = State<OptionsType>;
187  StateType state(start, eOptions);
188  state.navigation.targetSurface = &target;
189 
190  static_assert(
191  Concepts ::has_method<const S, Result<double>, Concepts ::Stepper::step_t,
192  StateType&>,
193  "Step method of the Stepper is not compatible with the propagator "
194  "state");
195 
196  // Apply the loop protection, it resets the interal path limit
198  lProtection(state, m_stepper);
199 
200  // Perform the actual propagation
201  auto result = propagate_impl<ResultType>(state);
202 
203  if (result.ok()) {
204  auto& propRes = *result;
205  // Compute the final results and mark the propagation as successful
206  auto bs = m_stepper.boundState(state.stepping, target);
207  auto& boundParams = std::get<BoundTrackParameters>(bs);
208  // Fill the end parameters
209  propRes.endParameters =
210  std::make_unique<const BoundTrackParameters>(std::move(boundParams));
211  // Only fill the transport jacobian when covariance transport was done
212  if (state.stepping.covTransport) {
213  auto& tJacobian = std::get<Jacobian>(bs);
214  propRes.transportJacobian =
215  std::make_unique<const Jacobian>(std::move(tJacobian));
216  }
217  return result;
218  } else {
219  return result.error();
220  }
221 }