** Warning **
Issuing rollback() due to DESTROY without explicit disconnect() of DBD::mysql::db handle dbname=lxr_sphenix at /usr/local/share/lxr/lxr-2.3.7/lib/LXR/Common.pm line 1161, <GEN78> line 1.
Last-Modified: Tue, 20 Oct 2025 09:11:52 GMT
Content-Type: text/html; charset=utf-8
/master/include/Acts/TrackFitting/detail/GsfUtils.hpp
File indexing completed on 2025-10-20 08:16:22
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp "
0012 #include "Acts/Definitions/TrackParametrization.hpp "
0013 #include "Acts/EventData/MultiComponentTrackParameters.hpp "
0014 #include "Acts/EventData/MultiTrajectory.hpp "
0015 #include "Acts/EventData/TrackParameters.hpp "
0016 #include "Acts/EventData/Types.hpp "
0017 #include "Acts/Utilities/Logger.hpp "
0018
0019 #include <array>
0020 #include <cassert>
0021 #include <cmath>
0022 #include <cstddef>
0023 #include <iomanip>
0024 #include <map>
0025 #include <numeric>
0026 #include <ostream>
0027 #include <tuple>
0028 #include <vector>
0029
0030 namespace Acts {
0031
0032
0033 constexpr static double s_normalizationTolerance = 1.e -4;
0034
0035 namespace detail {
0036
0037 template <typename component_range_t, typename projector_t>
0038 bool weightsAreNormalized (const component_range_t &cmps ,
0039 const projector_t &proj ,
0040 double tol = s_normalizationTolerance ) {
0041 double sumOfWeights = 0.0;
0042
0043 for (auto it = cmps .begin (); it != cmps .end (); ++it ) {
0044 sumOfWeights += proj (*it );
0045 }
0046
0047 return std ::abs (sumOfWeights - 1.0) < tol ;
0048 }
0049
0050 template <typename component_range_t, typename projector_t>
0051 void normalizeWeights (component_range_t &cmps , const projector_t &proj ) {
0052 double sumOfWeights = 0.0;
0053
0054
0055
0056 for (auto it = cmps .begin (); it != cmps .end (); ++it ) {
0057 decltype(auto ) cmp = *it ;
0058 assert (std ::isfinite (proj (cmp )) && "weight not finite in normalization" );
0059 sumOfWeights += proj (cmp );
0060 }
0061
0062 assert (sumOfWeights > 0 && "sum of weights is not > 0" );
0063
0064 for (auto it = cmps .begin (); it != cmps .end (); ++it ) {
0065 decltype(auto ) cmp = *it ;
0066 proj (cmp ) /= sumOfWeights ;
0067 }
0068 }
0069
0070
0071
0072
0073
0074 template <typename propagator_state_t, typename stepper_t, typename navigator_t>
0075 class ScopedGsfInfoPrinterAndChecker {
0076 const propagator_state_t &m_state ;
0077 const stepper_t &m_stepper ;
0078 const navigator_t &m_navigator ;
0079 double m_p_initial ;
0080 const Logger &m_logger ;
0081
0082 const Logger &logger () const { return m_logger ; }
0083
0084 void print_component_stats () const {
0085 std ::size_t i = 0;
0086 for (auto cmp : m_stepper .constComponentIterable (m_state .stepping )) {
0087 auto getVector = [&](auto idx ) {
0088 return cmp .pars ().template segment <3>(idx ).transpose ();
0089 };
0090 ACTS_VERBOSE (" #" << i ++ << " pos: " << getVector (eFreePos0 ) << ", dir: "
0091 << getVector (eFreeDir0 ) << ", weight: " << cmp .weight ()
0092 << ", status: " << cmp .status ()
0093 << ", qop: " << cmp .pars ()[eFreeQOverP ]
0094 << ", det(cov): " << cmp .cov ().determinant ());
0095 }
0096 }
0097
0098 void checks (bool onStart ) const {
0099 const auto cmps = m_stepper .constComponentIterable (m_state .stepping );
0100 [[maybe_unused]] const bool allFinite =
0101 std ::all_of (cmps .begin (), cmps .end (),
0102 [](auto cmp ) { return std ::isfinite (cmp .weight ()); });
0103 [[maybe_unused]] const bool allNormalized = detail ::weightsAreNormalized (
0104 cmps , [](const auto &cmp ) { return cmp .weight (); });
0105 [[maybe_unused]] const bool zeroComponents =
0106 m_stepper .numberComponents (m_state .stepping ) == 0;
0107
0108 if (onStart ) {
0109 assert (!zeroComponents && "no cmps at the start" );
0110 assert (allFinite && "weights not finite at the start" );
0111 assert (allNormalized && "not normalized at the start" );
0112 } else {
0113 assert (!zeroComponents && "no cmps at the end" );
0114 assert (allFinite && "weights not finite at the end" );
0115 assert (allNormalized && "not normalized at the end" );
0116 }
0117 }
0118
0119 public :
0120 ScopedGsfInfoPrinterAndChecker (const propagator_state_t &state ,
0121 const stepper_t &stepper ,
0122 const navigator_t &navigator ,
0123 const Logger &logger )
0124 : m_state (state ),
0125 m_stepper (stepper ),
0126 m_navigator (navigator ),
0127 m_p_initial (stepper .absoluteMomentum (state .stepping )),
0128 m_logger {logger } {
0129
0130 checks (true );
0131 ACTS_VERBOSE ("Gsf step "
0132 << state .stepping .steps << " at mean position "
0133 << stepper .position (state .stepping ).transpose ()
0134 << " with direction "
0135 << stepper .direction (state .stepping ).transpose ()
0136 << " and momentum " << stepper .absoluteMomentum (state .stepping )
0137 << " and charge " << stepper .charge (state .stepping ));
0138 ACTS_VERBOSE ("Propagation is in " << state .options .direction << " mode" );
0139 print_component_stats ();
0140 }
0141
0142 ~ScopedGsfInfoPrinterAndChecker () {
0143 if (m_navigator .currentSurface (m_state .navigation )) {
0144 const auto p_final = m_stepper .absoluteMomentum (m_state .stepping );
0145 ACTS_VERBOSE ("Component status at end of step:" );
0146 print_component_stats ();
0147 ACTS_VERBOSE ("Delta Momentum = " << std ::setprecision(5)
0148 << p_final - m_p_initial );
0149 }
0150 checks (false );
0151 }
0152 };
0153
0154 double calculateDeterminant (
0155 const double *fullCalibratedCovariance,
0156 TrackStateTraits <MultiTrajectoryTraits ::MeasurementSizeMax ,
0157 true >::Covariance predictedCovariance ,
0158 BoundSubspaceIndices projector , unsigned int calibratedSize );
0159
0160
0161
0162
0163
0164 template <typename traj_t >
0165 void computePosteriorWeights (
0166 const traj_t &mt , const std ::vector <MultiTrajectoryTraits ::IndexType > &tips ,
0167 std ::map <MultiTrajectoryTraits ::IndexType , double > &weights ) {
0168
0169
0170
0171
0172 const auto minChi2 =
0173 mt .getTrackState (*std ::min_element (tips .begin (), tips .end (),
0174 [&](const auto &a , const auto &b ) {
0175 return mt .getTrackState (a ).chi2 () <
0176 mt .getTrackState (b ).chi2 ();
0177 }))
0178 .chi2 ();
0179
0180
0181 for (auto tip : tips ) {
0182 const auto state = mt .getTrackState (tip );
0183 const double chi2 = state .chi2 () - minChi2 ;
0184 const double detR = calculateDeterminant (
0185
0186
0187
0188 state
0189 .template calibratedCovariance <
0190 MultiTrajectoryTraits ::MeasurementSizeMax >()
0191 .data (),
0192 state .predictedCovariance (), state .projectorSubspaceIndices (),
0193 state .calibratedSize ());
0194
0195 if (detR <= 0) {
0196
0197 continue ;
0198 }
0199
0200 const auto factor = std ::sqrt (1. / detR ) * safeExp (-0.5 * chi2 );
0201
0202 if (!std ::isfinite (factor )) {
0203
0204 continue ;
0205 }
0206
0207 weights .at (tip ) *= factor ;
0208 }
0209 }
0210
0211
0212
0213 enum class StatesType { ePredicted , eFiltered , eSmoothed };
0214
0215 inline std ::ostream &operator <<(std ::ostream &os , StatesType type ) {
0216 constexpr static std ::array names = {"predicted" , "filtered" , "smoothed" };
0217 os << names [static_cast <int >(type )];
0218 return os ;
0219 }
0220
0221
0222
0223
0224 template <StatesType type , typename traj_t >
0225 struct MultiTrajectoryProjector {
0226 const traj_t &mt ;
0227 const std ::map <MultiTrajectoryTraits ::IndexType , double > &weights ;
0228
0229 auto operator ()(MultiTrajectoryTraits ::IndexType idx ) const {
0230 const auto proxy = mt .getTrackState (idx );
0231 switch (type ) {
0232 case StatesType ::ePredicted :
0233 return std ::make_tuple (weights .at (idx ), proxy .predicted (),
0234 proxy .predictedCovariance ());
0235 case StatesType ::eFiltered :
0236 return std ::make_tuple (weights .at (idx ), proxy .filtered (),
0237 proxy .filteredCovariance ());
0238 case StatesType ::eSmoothed :
0239 return std ::make_tuple (weights .at (idx ), proxy .smoothed (),
0240 proxy .smoothedCovariance ());
0241 default :
0242 throw std ::invalid_argument (
0243 "Incorrect StatesType, should be ePredicted"
0244 ", eFiltered, or eSmoothed." );
0245 }
0246 }
0247 };
0248
0249
0250
0251
0252 template <typename T >
0253 class Updatable {
0254 T m_tmp {};
0255 T m_val {};
0256
0257 public :
0258 Updatable () : m_tmp (0), m_val (0) {}
0259
0260 T &tmp () { return m_tmp ; }
0261 void update () { m_val = m_tmp ; }
0262
0263 const T &val () const { return m_val ; }
0264 };
0265
0266 }
0267 }