Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 09:42:31

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