Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
KalmanUpdateHelpers.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file KalmanUpdateHelpers.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2021-2023 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 
9 #pragma once
10 
17 
18 namespace Acts {
19 namespace detail {
20 
36 template <typename propagator_state_t, typename stepper_t,
37  typename extensions_t, typename traj_t>
39  const CalibrationContext &calibrationContext, propagator_state_t &state,
40  const stepper_t &stepper, const extensions_t &extensions,
41  const Surface &surface, const SourceLink &source_link, traj_t &fittedStates,
42  const size_t lastTrackIndex, bool doCovTransport, const Logger &logger,
43  const FreeToBoundCorrection &freeToBoundCorrection = FreeToBoundCorrection(
45  // Add a <mask> TrackState entry multi trajectory. This allocates storage for
46  // all components, which we will set later.
47  TrackStatePropMask mask = TrackStatePropMask::All;
48  const size_t currentTrackIndex =
49  fittedStates.addTrackState(mask, lastTrackIndex);
50 
51  // now get track state proxy back
52  typename traj_t::TrackStateProxy trackStateProxy =
53  fittedStates.getTrackState(currentTrackIndex);
54 
55  // Set the trackStateProxy components with the state from the ongoing
56  // propagation
57  {
58  trackStateProxy.setReferenceSurface(surface.getSharedPtr());
59  // Bind the transported state to the current surface
60  auto res = stepper.boundState(state.stepping, surface, doCovTransport,
61  freeToBoundCorrection);
62  if (!res.ok()) {
63  ACTS_ERROR("Propagate to surface " << surface.geometryId()
64  << " failed: " << res.error());
65  return res.error();
66  }
67  auto &[boundParams, jacobian, pathLength] = *res;
68 
69  // Fill the track state
70  trackStateProxy.predicted() = std::move(boundParams.parameters());
71  if (boundParams.covariance().has_value()) {
72  trackStateProxy.predictedCovariance() =
73  std::move(*boundParams.covariance());
74  }
75 
76  trackStateProxy.jacobian() = std::move(jacobian);
77  trackStateProxy.pathLength() = std::move(pathLength);
78  }
79 
80  // We have predicted parameters, so calibrate the uncalibrated input
81  // measurement
82  extensions.calibrator(state.geoContext, calibrationContext, source_link,
83  trackStateProxy);
84 
85  // Get and set the type flags
86  {
87  auto typeFlags = trackStateProxy.typeFlags();
88  typeFlags.set(TrackStateFlag::ParameterFlag);
89  if (surface.surfaceMaterial() != nullptr) {
90  typeFlags.set(TrackStateFlag::MaterialFlag);
91  }
92 
93  // Check if the state is an outlier.
94  // If not:
95  // - run Kalman update
96  // - tag it as a measurement
97  // - update the stepping state.
98  // Else, just tag it as an outlier
99  if (not extensions.outlierFinder(trackStateProxy)) {
100  // Run Kalman update
101  auto updateRes = extensions.updater(state.geoContext, trackStateProxy,
102  state.options.direction, logger);
103  if (!updateRes.ok()) {
104  ACTS_ERROR("Update step failed: " << updateRes.error());
105  return updateRes.error();
106  }
107  // Set the measurement type flag
108  typeFlags.set(TrackStateFlag::MeasurementFlag);
109  } else {
110  ACTS_VERBOSE(
111  "Filtering step successful. But measurement is determined "
112  "to be an outlier. Stepping state is not updated.")
113  // Set the outlier type flag
114  typeFlags.set(TrackStateFlag::OutlierFlag);
115  trackStateProxy.shareFrom(trackStateProxy, TrackStatePropMask::Predicted,
116  TrackStatePropMask::Filtered);
117  }
118  }
119 
120  return trackStateProxy;
121 }
122 
138 template <typename propagator_state_t, typename stepper_t, typename traj_t>
140  propagator_state_t &state, const stepper_t &stepper, const Surface &surface,
141  traj_t &fittedStates, const size_t lastTrackIndex, bool doCovTransport,
142  const Logger &logger,
143  const FreeToBoundCorrection &freeToBoundCorrection = FreeToBoundCorrection(
145  // Add a <mask> TrackState entry multi trajectory. This allocates storage for
146  // all components, which we will set later.
148  ~(TrackStatePropMask::Calibrated | TrackStatePropMask::Filtered);
149  const size_t currentTrackIndex =
150  fittedStates.addTrackState(mask, lastTrackIndex);
151 
152  // now get track state proxy back
153  typename traj_t::TrackStateProxy trackStateProxy =
154  fittedStates.getTrackState(currentTrackIndex);
155 
156  // Set the trackStateProxy components with the state from the ongoing
157  // propagation
158  {
159  trackStateProxy.setReferenceSurface(surface.getSharedPtr());
160  // Bind the transported state to the current surface
161  auto res = stepper.boundState(state.stepping, surface, doCovTransport,
162  freeToBoundCorrection);
163  if (!res.ok()) {
164  return res.error();
165  }
166  auto &[boundParams, jacobian, pathLength] = *res;
167 
168  // Fill the track state
169  trackStateProxy.predicted() = std::move(boundParams.parameters());
170  if (boundParams.covariance().has_value()) {
171  trackStateProxy.predictedCovariance() =
172  std::move(*boundParams.covariance());
173  }
174 
175  trackStateProxy.jacobian() = std::move(jacobian);
176  trackStateProxy.pathLength() = std::move(pathLength);
177 
178  // Set the filtered parameter index to be the same with predicted
179  // parameter
180  trackStateProxy.shareFrom(trackStateProxy, TrackStatePropMask::Predicted,
181  TrackStatePropMask::Filtered);
182  }
183 
184  // Set the track state flags
185  auto typeFlags = trackStateProxy.typeFlags();
186  typeFlags.set(TrackStateFlag::ParameterFlag);
187  if (surface.surfaceMaterial() != nullptr) {
188  typeFlags.set(TrackStateFlag::MaterialFlag);
189  }
190  if (surface.associatedDetectorElement() != nullptr) {
191  ACTS_VERBOSE("Detected hole on " << surface.geometryId());
192  // If the surface is sensitive, set the hole type flag
193  typeFlags.set(TrackStateFlag::HoleFlag);
194  } else if (surface.surfaceMaterial() != nullptr) {
195  ACTS_VERBOSE("Detected in-sensitive surface " << surface.geometryId());
196  }
197 
198  return trackStateProxy;
199 }
200 
201 } // namespace detail
202 } // namespace Acts