ECCE @ 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  // Pre-stepping call to the navigator and action list
18  debugLog(state, [&] { return std::string("Entering propagation."); });
19 
20  // Navigator initialize state call
21  m_navigator.status(state, m_stepper);
22  // Pre-Stepping call to the action list
23  state.options.actionList(state, m_stepper, result);
24  // assume negative outcome, only set to true later if we actually have
25  // a positive outcome.
26  // This is needed for correct error logging
27  bool terminatedNormally = false;
28  // Pre-Stepping: abort condition check
29  if (!state.options.abortList(result, state, m_stepper)) {
30  // Pre-Stepping: target setting
31  m_navigator.target(state, m_stepper);
32  // Stepping loop
33  debugLog(state, [&] { return std::string("Starting stepping loop."); });
34  // Propagation loop : stepping
35  for (; result.steps < state.options.maxSteps; ++result.steps) {
36  // Perform a propagation step - it takes the propagation state
37  Result<double> res = m_stepper.step(state);
38  if (res.ok()) {
39  // Accumulate the path length
40  double s = *res;
41  result.pathLength += s;
42  debugLog(state, [&] {
43  std::stringstream dstream;
44  dstream << "Step with size = ";
45  dstream << s;
46  dstream << " performed.";
47  return dstream.str();
48  });
49  } else {
50  debugLog(state, [&] {
51  std::stringstream dstream;
52  dstream << "Step failed: ";
53  dstream << res.error();
54  return dstream.str();
55  });
56  // pass error to caller
57  return res.error();
58  }
59  // Post-stepping:
60  // navigator status call - action list - aborter list - target call
61  m_navigator.status(state, m_stepper);
62  state.options.actionList(state, m_stepper, result);
63  if (state.options.abortList(result, state, m_stepper)) {
64  terminatedNormally = true;
65  break;
66  }
67  m_navigator.target(state, m_stepper);
68  }
69  }
70 
71  // if we didn't terminate normally (via aborters) set navigation break.
72  // this will trigger error output in the lines below
73  if (!terminatedNormally) {
74  debugLog(state, [&] { return std::string("Terminated with failure."); });
75  state.navigation.navigationBreak = true;
76  }
77 
78  // Post-stepping call to the action list
79  debugLog(state, [&] { return std::string("Stepping loop done."); });
80  state.options.actionList(state, m_stepper, result);
81 
82  // return progress flag here, decide on SUCCESS later
83  return std::move(result);
84 }
85 
86 template <typename S, typename N>
87 template <typename parameters_t, typename propagator_options_t,
88  typename path_aborter_t>
90  const parameters_t& start, const propagator_options_t& options) const
93  typename propagator_options_t::action_list_type>> {
94  static_assert(ParameterConcept<parameters_t>,
95  "Parameters do not fulfill parameter concept.");
96 
97  // Type of track parameters produced by the propagation
98  using ReturnParameterType = CurvilinearParameters;
99 
100  // Type of the full propagation result, including output from actions
101  using ResultType =
102  action_list_t_result_t<ReturnParameterType,
103  typename propagator_options_t::action_list_type>;
104 
106  "return track parameter type must be copy-constructible");
107 
108  // Expand the abort list with a path aborter
109  path_aborter_t pathAborter;
110  pathAborter.internalLimit = options.pathLimit;
111 
112  auto abortList = options.abortList.append(pathAborter);
113 
114  // The expanded options (including path limit)
115  auto eOptions = options.extend(abortList);
116  using OptionsType = decltype(eOptions);
117  // Initialize the internal propagator state
118  using StateType = State<OptionsType>;
119  StateType state(start, eOptions);
120 
121  static_assert(
122  concept ::has_method<const S, Result<double>, concept ::Stepper::step_t,
123  StateType&>,
124  "Step method of the Stepper is not compatible with the propagator "
125  "state");
126 
127  // Apply the loop protection - it resets the internal path limit
128  if (options.loopProtection) {
130  lProtection(state, m_stepper);
131  }
132  // Perform the actual propagation & check its outcome
133  auto result = propagate_impl<ResultType>(state);
134  if (result.ok()) {
135  auto& propRes = *result;
137  auto curvState = m_stepper.curvilinearState(state.stepping);
138  auto& curvParameters = std::get<CurvilinearParameters>(curvState);
139  // Fill the end parameters
140  propRes.endParameters = std::make_unique<const CurvilinearParameters>(
141  std::move(curvParameters));
142  // Only fill the transport jacobian when covariance transport was done
143  if (state.stepping.covTransport) {
144  auto& tJacobian = std::get<Jacobian>(curvState);
145  propRes.transportJacobian =
146  std::make_unique<const Jacobian>(std::move(tJacobian));
147  }
148  return result;
149  } else {
150  return result.error();
151  }
152 }
153 
154 template <typename S, typename N>
155 template <typename parameters_t, typename propagator_options_t,
156  typename target_aborter_t, typename path_aborter_t>
158  const parameters_t& start, const Surface& target,
159  const propagator_options_t& options) const
161  BoundParameters, typename propagator_options_t::action_list_type>> {
162  static_assert(ParameterConcept<parameters_t>,
163  "Parameters do not fulfill parameter concept.");
164 
165  // Type of track parameters produced at the end of the propagation
166  using return_parameter_type = BoundParameters;
167 
168  // Type of provided options
169  target_aborter_t targetAborter;
170  path_aborter_t pathAborter;
171  pathAborter.internalLimit = options.pathLimit;
172  auto abortList = options.abortList.append(targetAborter, pathAborter);
173 
174  // Create the extended options and declare their type
175  auto eOptions = options.extend(abortList);
176  using OptionsType = decltype(eOptions);
177 
178  // Type of the full propagation result, including output from actions
179  using ResultType =
180  action_list_t_result_t<return_parameter_type,
181  typename propagator_options_t::action_list_type>;
182 
183  // Initialize the internal propagator state
184  using StateType = State<OptionsType>;
185  StateType state(start, eOptions);
186  state.navigation.targetSurface = &target;
187 
188  static_assert(
189  concept ::has_method<const S, Result<double>, concept ::Stepper::step_t,
190  StateType&>,
191  "Step method of the Stepper is not compatible with the propagator "
192  "state");
193 
194  // Apply the loop protection, it resets the interal path limit
196  lProtection(state, m_stepper);
197 
198  // Perform the actual propagation
199  auto result = propagate_impl<ResultType>(state);
200 
201  if (result.ok()) {
202  auto& propRes = *result;
203  // Compute the final results and mark the propagation as successful
204  auto bs = m_stepper.boundState(state.stepping, target);
205  auto& boundParameters = std::get<BoundParameters>(bs);
206  // Fill the end parameters
207  propRes.endParameters =
208  std::make_unique<const BoundParameters>(std::move(boundParameters));
209  // Only fill the transport jacobian when covariance transport was done
210  if (state.stepping.covTransport) {
211  auto& tJacobian = std::get<Jacobian>(bs);
212  propRes.transportJacobian =
213  std::make_unique<const Jacobian>(std::move(tJacobian));
214  }
215  return result;
216  } else {
217  return result.error();
218  }
219 }
220 
221 template <typename S, typename N>
222 template <typename propagator_state_t>
224  propagator_state_t& state,
225  const std::function<std::string()>& logAction) const {
226  if (state.options.debug) {
227  std::vector<std::string> lines;
228  std::string input = logAction();
229  boost::split(lines, input, boost::is_any_of("\n"));
230  for (const auto& line : lines) {
231  std::stringstream dstream;
232  dstream << "|->" << std::setw(state.options.debugPfxWidth);
233  dstream << "Propagator"
234  << " | ";
235  dstream << std::setw(state.options.debugMsgWidth) << line << '\n';
236  state.options.debugString += dstream.str();
237  }
238  }
239 }