Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:06

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/EventData/MultiTrajectory.hpp"
0012 #include "Acts/EventData/SourceLink.hpp"
0013 #include "Acts/EventData/TrackParameters.hpp"
0014 #include "Acts/EventData/detail/CorrectedTransformationFreeToBound.hpp"
0015 #include "Acts/Surfaces/Surface.hpp"
0016 #include "Acts/Utilities/CalibrationContext.hpp"
0017 #include "Acts/Utilities/Result.hpp"
0018 
0019 namespace Acts::detail {
0020 
0021 /// This function encapsulates the Kalman update performed on a MultiTrajectory
0022 /// for a single source link.
0023 /// @tparam propagator_state_t The propagator state type
0024 /// @tparam stepper_t The stepper type
0025 /// @tparam extensions_t The type of the extensions used for the update
0026 /// @param state The propagator state
0027 /// @param stepper The stepper
0028 /// @param extensions The extension used for the update
0029 /// @param surface The current surface
0030 /// @param sourceLink The source link used for the update
0031 /// @param fittedStates The Multitrajectory to that we add the state
0032 /// @param lastTrackIndex The parent index for the new state in the MT
0033 /// @param doCovTransport Whether to perform a covariance transport when
0034 /// computing the bound state or not
0035 /// @param freeToBoundCorrection Correction for non-linearity effect during transform from free to bound (only corrected when performing CovTransport)
0036 template <typename propagator_state_t, typename stepper_t,
0037           typename extensions_t, typename traj_t>
0038 auto kalmanHandleMeasurement(
0039     const CalibrationContext &calibrationContext, propagator_state_t &state,
0040     const stepper_t &stepper, const extensions_t &extensions,
0041     const Surface &surface, const SourceLink &sourceLink, traj_t &fittedStates,
0042     const std::size_t lastTrackIndex, bool doCovTransport, const Logger &logger,
0043     const FreeToBoundCorrection &freeToBoundCorrection = FreeToBoundCorrection(
0044         false)) -> Result<typename traj_t::TrackStateProxy> {
0045   // Add a <mask> TrackState entry multi trajectory. This allocates storage for
0046   // all components, which we will set later.
0047   TrackStatePropMask mask =
0048       TrackStatePropMask::Predicted | TrackStatePropMask::Filtered |
0049       TrackStatePropMask::Smoothed | TrackStatePropMask::Jacobian |
0050       TrackStatePropMask::Calibrated;
0051   typename traj_t::TrackStateProxy trackStateProxy =
0052       fittedStates.makeTrackState(mask, lastTrackIndex);
0053 
0054   // Set the trackStateProxy components with the state from the ongoing
0055   // propagation
0056   {
0057     trackStateProxy.setReferenceSurface(surface.getSharedPtr());
0058     // Bind the transported state to the current surface
0059     auto res = stepper.boundState(state.stepping, surface, doCovTransport,
0060                                   freeToBoundCorrection);
0061     if (!res.ok()) {
0062       ACTS_ERROR("Propagate to surface " << surface.geometryId()
0063                                          << " failed: " << res.error());
0064       return res.error();
0065     }
0066     const auto &[boundParams, jacobian, pathLength] = *res;
0067 
0068     // Fill the track state
0069     trackStateProxy.predicted() = boundParams.parameters();
0070     trackStateProxy.predictedCovariance() = state.stepping.cov;
0071 
0072     trackStateProxy.jacobian() = jacobian;
0073     trackStateProxy.pathLength() = pathLength;
0074   }
0075 
0076   // We have predicted parameters, so calibrate the uncalibrated input
0077   // measurement
0078   extensions.calibrator(state.geoContext, calibrationContext, sourceLink,
0079                         trackStateProxy);
0080 
0081   // Get and set the type flags
0082   {
0083     auto typeFlags = trackStateProxy.typeFlags();
0084     typeFlags.set(TrackStateFlag::ParameterFlag);
0085     if (surface.surfaceMaterial() != nullptr) {
0086       typeFlags.set(TrackStateFlag::MaterialFlag);
0087     }
0088 
0089     // Check if the state is an outlier.
0090     // If not:
0091     // - run Kalman update
0092     // - tag it as a measurement
0093     // - update the stepping state.
0094     // Else, just tag it as an outlier
0095     if (!extensions.outlierFinder(trackStateProxy)) {
0096       // Run Kalman update
0097       auto updateRes =
0098           extensions.updater(state.geoContext, trackStateProxy, logger);
0099       if (!updateRes.ok()) {
0100         ACTS_ERROR("Update step failed: " << updateRes.error());
0101         return updateRes.error();
0102       }
0103       // Set the measurement type flag
0104       typeFlags.set(TrackStateFlag::MeasurementFlag);
0105     } else {
0106       ACTS_VERBOSE(
0107           "Filtering step successful. But measurement is determined "
0108           "to be an outlier. Stepping state is not updated.");
0109       // Set the outlier type flag
0110       typeFlags.set(TrackStateFlag::OutlierFlag);
0111       trackStateProxy.shareFrom(trackStateProxy, TrackStatePropMask::Predicted,
0112                                 TrackStatePropMask::Filtered);
0113     }
0114   }
0115 
0116   return trackStateProxy;
0117 }
0118 
0119 /// This function encapsulates what actions should be performed on a
0120 /// MultiTrajectory when we have no measurement.
0121 /// If there are no source links on surface, add either a hole or passive
0122 /// material TrackState entry multi trajectory. No storage allocation for
0123 /// uncalibrated/calibrated measurement and filtered parameter
0124 /// @tparam propagator_state_t The propagator state type
0125 /// @tparam stepper_t The stepper type
0126 /// @param state The propagator state
0127 /// @param stepper The stepper
0128 /// @param surface The current surface
0129 /// @param fittedStates The Multitrajectory to that we add the state
0130 /// @param lastTrackIndex The parent index for the new state in the MT
0131 /// @param doCovTransport Whether to perform a covariance transport when
0132 /// computing the bound state or not
0133 /// @param freeToBoundCorrection Correction for non-linearity effect during transform from free to bound (only corrected when performing CovTransport)
0134 template <typename propagator_state_t, typename stepper_t, typename traj_t>
0135 auto kalmanHandleNoMeasurement(
0136     propagator_state_t &state, const stepper_t &stepper, const Surface &surface,
0137     traj_t &fittedStates, const std::size_t lastTrackIndex, bool doCovTransport,
0138     const Logger &logger, const bool precedingMeasurementExists,
0139     const FreeToBoundCorrection &freeToBoundCorrection = FreeToBoundCorrection(
0140         false)) -> Result<typename traj_t::TrackStateProxy> {
0141   // Add a <mask> TrackState entry multi trajectory. This allocates storage for
0142   // all components, which we will set later.
0143   TrackStatePropMask mask = TrackStatePropMask::Predicted |
0144                             TrackStatePropMask::Smoothed |
0145                             TrackStatePropMask::Jacobian;
0146   typename traj_t::TrackStateProxy trackStateProxy =
0147       fittedStates.makeTrackState(mask, lastTrackIndex);
0148 
0149   // Set the trackStateProxy components with the state from the ongoing
0150   // propagation
0151   {
0152     trackStateProxy.setReferenceSurface(surface.getSharedPtr());
0153     // Bind the transported state to the current surface
0154     auto res = stepper.boundState(state.stepping, surface, doCovTransport,
0155                                   freeToBoundCorrection);
0156     if (!res.ok()) {
0157       return res.error();
0158     }
0159     const auto &[boundParams, jacobian, pathLength] = *res;
0160 
0161     // Fill the track state
0162     trackStateProxy.predicted() = boundParams.parameters();
0163     trackStateProxy.predictedCovariance() = state.stepping.cov;
0164 
0165     trackStateProxy.jacobian() = jacobian;
0166     trackStateProxy.pathLength() = pathLength;
0167 
0168     // Set the filtered parameter index to be the same with predicted
0169     // parameter
0170     trackStateProxy.shareFrom(trackStateProxy, TrackStatePropMask::Predicted,
0171                               TrackStatePropMask::Filtered);
0172   }
0173 
0174   // Set the track state flags
0175   const bool surfaceHasMaterial = surface.surfaceMaterial() != nullptr;
0176   const bool surfaceIsSensitive =
0177       surface.associatedDetectorElement() != nullptr;
0178   auto typeFlags = trackStateProxy.typeFlags();
0179   typeFlags.set(TrackStateFlag::ParameterFlag);
0180 
0181   if (surfaceHasMaterial) {
0182     typeFlags.set(TrackStateFlag::MaterialFlag);
0183   }
0184 
0185   if (surfaceIsSensitive && precedingMeasurementExists) {
0186     ACTS_VERBOSE("Detected hole on " << surface.geometryId());
0187     // If the surface is sensitive, set the hole type flag
0188     typeFlags.set(TrackStateFlag::HoleFlag);
0189   } else if (surfaceIsSensitive) {
0190     ACTS_VERBOSE("Skip hole (no preceding measurements) on surface "
0191                  << surface.geometryId());
0192   } else if (surfaceHasMaterial) {
0193     ACTS_VERBOSE("Detected in-sensitive surface " << surface.geometryId());
0194   }
0195 
0196   return trackStateProxy;
0197 }
0198 
0199 }  // namespace Acts::detail