Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-05 07:45:18

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/Vertexing/TrackAtVertex.hpp"
0012 
0013 #include <map>
0014 #include <set>
0015 
0016 namespace Acts {
0017 
0018 /// @class GaussianTrackDensity
0019 ///
0020 /// @brief Class to model tracks as 2D density functions based on
0021 /// their d0 and z0 perigee parameters (mean value) and covariance
0022 /// matrices (determining the width of the function)
0023 class GaussianTrackDensity {
0024  public:
0025   /// @brief Struct to store information for a single track
0026   struct TrackEntry {
0027     /// @brief Default constructor
0028     TrackEntry() = default;
0029     /// @brief Constructor initializing all members
0030     /// @param z_ Trial z position
0031     /// @param c0_ z-independent term in exponent
0032     /// @param c1_ Linear coefficient in exponent
0033     /// @param c2_ Quadratic coefficient in exponent
0034     /// @param lowerBound_ The lower bound
0035     /// @param upperBound_ The upper bound
0036     TrackEntry(double z_, double c0_, double c1_, double c2_,
0037                double lowerBound_, double upperBound_)
0038         : z(z_),
0039           c0(c0_),
0040           c1(c1_),
0041           c2(c2_),
0042           lowerBound(lowerBound_),
0043           upperBound(upperBound_) {}
0044 
0045     /// Trial z position for the track
0046     double z = 0;
0047     // Cached information for a single track
0048     /// z-independent term in exponent
0049     double c0 = 0;
0050     /// linear coefficient in exponent
0051     double c1 = 0;
0052     /// quadratic coefficient in exponent
0053     double c2 = 0;
0054     /// The lower bound for track density evaluation
0055     double lowerBound = 0;
0056     /// The upper bound for track density evaluation
0057     double upperBound = 0;
0058   };
0059 
0060   /// @brief The Config struct
0061   struct Config {
0062     /// Constructor with significance parameters
0063     /// @param d0Sig Maximum d0 significance for track selection (default: 3.5)
0064     /// @param z0Sig Maximum z0 significance for track selection (default: 12.0)
0065     explicit Config(double d0Sig = 3.5, double z0Sig = 12.)
0066         : d0MaxSignificance(d0Sig),
0067           z0MaxSignificance(z0Sig),
0068           d0SignificanceCut(d0Sig * d0Sig),
0069           z0SignificanceCut(z0Sig * z0Sig) {}
0070 
0071     /// Assumed shape of density function: Gaussian (true) or parabolic (false)
0072     bool isGaussianShaped = true;
0073 
0074     /// Maximum d0 impact parameter significance to use a track
0075     double d0MaxSignificance;
0076     /// Maximum z0 impact parameter significance to use a track
0077     double z0MaxSignificance;
0078     /// Corresponding cut values for d0 significance
0079     double d0SignificanceCut;
0080     /// Corresponding cut values for z0 significance
0081     double z0SignificanceCut;
0082 
0083     /// Function to extract parameters from InputTrack
0084     InputTrack::Extractor extractParameters;
0085   };
0086 
0087   /// @brief The State struct
0088   struct State {
0089     /// Constructor with expected number of tracks
0090     /// @param nTracks Expected number of tracks (used to reserve memory)
0091     explicit State(unsigned int nTracks) { trackEntries.reserve(nTracks); }
0092     /// Vector to cache track information for density calculation
0093     std::vector<TrackEntry> trackEntries;
0094   };
0095 
0096   /// Constructor with config
0097   /// @param cfg The configuration parameters
0098   explicit GaussianTrackDensity(const Config& cfg) : m_cfg(cfg) {
0099     if (!m_cfg.extractParameters.connected()) {
0100       throw std::invalid_argument(
0101           "GaussianTrackDensity: "
0102           "No parameter extractor provided.");
0103     }
0104   }
0105 
0106   /// @brief Calculates z position of global maximum with Gaussian width
0107   /// for density function.
0108   /// Strategy:
0109   /// The global maximum must be somewhere near a track.
0110   /// Since we can calculate the first and second derivatives, at each point we
0111   /// can determine a) whether the function is curved up (minimum) or down
0112   /// (maximum) b) the distance to nearest maximum, assuming either Newton
0113   /// (parabolic) or Gaussian local behavior.
0114   /// For each track where the second derivative is negative, find step to
0115   /// nearest maximum, take that step and then do one final refinement. The
0116   /// largest density encountered in this procedure (after checking all tracks)
0117   /// is considered the maximum.
0118   ///
0119   /// @param state The track density state
0120   /// @param trackList All input tracks
0121   ///
0122   /// @return Pair of position of global maximum and Gaussian width
0123   Result<std::optional<std::pair<double, double>>> globalMaximumWithWidth(
0124       State& state, const std::vector<InputTrack>& trackList) const;
0125 
0126   /// @brief Calculates the z position of the global maximum
0127   ///
0128   /// @param state The track density state
0129   /// @param trackList All input tracks
0130   ///
0131   /// @return z position of the global maximum
0132   Result<std::optional<double>> globalMaximum(
0133       State& state, const std::vector<InputTrack>& trackList) const;
0134 
0135  private:
0136   /// The configuration
0137   Config m_cfg;
0138 
0139   /// @brief Add a track to the set being considered
0140   ///
0141   /// @param state The track density state
0142   /// @param trackList All input tracks
0143   Result<void> addTracks(State& state,
0144                          const std::vector<InputTrack>& trackList) const;
0145 
0146   /// @brief Evaluate the density function and its two first
0147   /// derivatives at the specified coordinate along the beamline
0148   ///
0149   /// @param state The track density state
0150   /// @param z z-position along the beamline
0151   ///
0152   /// @return Track density, first and second derivatives
0153   std::tuple<double, double, double> trackDensityAndDerivatives(State& state,
0154                                                                 double z) const;
0155 
0156   /// @brief Update the current maximum values
0157   ///
0158   /// @param newZ The new z value
0159   /// @param newValue The new value at z position
0160   /// @param newSecondDerivative The new second derivative
0161   /// @param maxZ Maximum z value, will be compared against @p newZ
0162   /// @param maxValue Maximum value
0163   /// @param maxSecondDerivative Maximum of the second derivative
0164   /// @return The max z position, the max value at z position, the max second
0165   /// derivative
0166   std::tuple<double, double, double> updateMaximum(
0167       double newZ, double newValue, double newSecondDerivative, double maxZ,
0168       double maxValue, double maxSecondDerivative) const;
0169 
0170   /// @brief Calculates the step size
0171   ///
0172   /// @param y Position value
0173   /// @param dy First derivative
0174   /// @param ddy Second derivative
0175   ///
0176   /// @return The step size
0177   double stepSize(double y, double dy, double ddy) const;
0178 
0179   // Helper class to evaluate and store track density at specific position
0180   class GaussianTrackDensityStore {
0181    public:
0182     // Initialise at the z coordinate at which the density is to be evaluated
0183     explicit GaussianTrackDensityStore(double z_coordinate)
0184         : m_z(z_coordinate) {}
0185 
0186     // Add the contribution of a single track to the density
0187     void addTrackToDensity(const TrackEntry& entry);
0188 
0189     // Return density, first and second derivatives
0190     inline std::tuple<double, double, double> densityAndDerivatives() const {
0191       return {m_density, m_firstDerivative, m_secondDerivative};
0192     }
0193 
0194    private:
0195     // Store density and derivatives for z position m_z
0196     double m_z;
0197     double m_density{0};
0198     double m_firstDerivative{0};
0199     double m_secondDerivative{0};
0200   };
0201 };
0202 
0203 }  // namespace Acts