Back to home page

EIC code displayed by LXR

 
 

    


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

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     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
0055     double lowerBound = 0;
0056     // The upper bound
0057     double upperBound = 0;
0058   };
0059 
0060   /// @brief The Config struct
0061   struct Config {
0062     Config(double d0Sig = 3.5, double z0Sig = 12.)
0063         : d0MaxSignificance(d0Sig),
0064           z0MaxSignificance(z0Sig),
0065           d0SignificanceCut(d0Sig * d0Sig),
0066           z0SignificanceCut(z0Sig * z0Sig) {}
0067 
0068     // Assumed shape of density function:
0069     // Gaussian (true) or parabolic (false)
0070     bool isGaussianShaped = true;
0071 
0072     // Maximum d0 impact parameter significance to use a track
0073     double d0MaxSignificance;
0074     // Maximum z0 impact parameter significance to use a track
0075     double z0MaxSignificance;
0076     // Corresponding cut values
0077     double d0SignificanceCut;
0078     double z0SignificanceCut;
0079 
0080     // Function to extract parameters from InputTrack
0081     InputTrack::Extractor extractParameters;
0082   };
0083 
0084   /// @brief The State struct
0085   struct State {
0086     // Constructor with size track map
0087     State(unsigned int nTracks) { trackEntries.reserve(nTracks); }
0088     // Vector to cache track information
0089     std::vector<TrackEntry> trackEntries;
0090   };
0091 
0092   /// Constructor with config
0093   GaussianTrackDensity(const Config& cfg) : m_cfg(cfg) {
0094     if (!m_cfg.extractParameters.connected()) {
0095       throw std::invalid_argument(
0096           "GaussianTrackDensity: "
0097           "No parameter extractor provided.");
0098     }
0099   }
0100 
0101   /// @brief Calculates z position of global maximum with Gaussian width
0102   /// for density function.
0103   /// Strategy:
0104   /// The global maximum must be somewhere near a track.
0105   /// Since we can calculate the first and second derivatives, at each point we
0106   /// can determine a) whether the function is curved up (minimum) or down
0107   /// (maximum) b) the distance to nearest maximum, assuming either Newton
0108   /// (parabolic) or Gaussian local behavior.
0109   /// For each track where the second derivative is negative, find step to
0110   /// nearest maximum, take that step and then do one final refinement. The
0111   /// largest density encountered in this procedure (after checking all tracks)
0112   /// is considered the maximum.
0113   ///
0114   /// @param state The track density state
0115   /// @param trackList All input tracks
0116   ///
0117   /// @return Pair of position of global maximum and Gaussian width
0118   Result<std::optional<std::pair<double, double>>> globalMaximumWithWidth(
0119       State& state, const std::vector<InputTrack>& trackList) const;
0120 
0121   /// @brief Calculates the z position of the global maximum
0122   ///
0123   /// @param state The track density state
0124   /// @param trackList All input tracks
0125   ///
0126   /// @return z position of the global maximum
0127   Result<std::optional<double>> globalMaximum(
0128       State& state, const std::vector<InputTrack>& trackList) const;
0129 
0130  private:
0131   /// The configuration
0132   Config m_cfg;
0133 
0134   /// @brief Add a track to the set being considered
0135   ///
0136   /// @param state The track density state
0137   /// @param trackList All input tracks
0138   Result<void> addTracks(State& state,
0139                          const std::vector<InputTrack>& trackList) const;
0140 
0141   /// @brief Evaluate the density function and its two first
0142   /// derivatives at the specified coordinate along the beamline
0143   ///
0144   /// @param state The track density state
0145   /// @param z z-position along the beamline
0146   ///
0147   /// @return Track density, first and second derivatives
0148   std::tuple<double, double, double> trackDensityAndDerivatives(State& state,
0149                                                                 double z) const;
0150 
0151   /// @brief Update the current maximum values
0152   ///
0153   /// @param newZ The new z value
0154   /// @param newValue The new value at z position
0155   /// @param newSecondDerivative The new second derivative
0156   /// @param maxZ Maximum z value, will be compared against @p newZ
0157   /// @param maxValue Maximum value
0158   /// @param maxSecondDerivative Maximum of the second derivative
0159   /// @return The max z position, the max value at z position, the max second
0160   /// derivative
0161   std::tuple<double, double, double> updateMaximum(
0162       double newZ, double newValue, double newSecondDerivative, double maxZ,
0163       double maxValue, double maxSecondDerivative) const;
0164 
0165   /// @brief Calculates the step size
0166   ///
0167   /// @param y Position value
0168   /// @param dy First derivative
0169   /// @param ddy Second derivative
0170   ///
0171   /// @return The step size
0172   double stepSize(double y, double dy, double ddy) const;
0173 
0174   // Helper class to evaluate and store track density at specific position
0175   class GaussianTrackDensityStore {
0176    public:
0177     // Initialise at the z coordinate at which the density is to be evaluated
0178     GaussianTrackDensityStore(double z_coordinate) : m_z(z_coordinate) {}
0179 
0180     // Add the contribution of a single track to the density
0181     void addTrackToDensity(const TrackEntry& entry);
0182 
0183     // Return density, first and second derivatives
0184     inline std::tuple<double, double, double> densityAndDerivatives() const {
0185       return {m_density, m_firstDerivative, m_secondDerivative};
0186     }
0187 
0188    private:
0189     // Store density and derivatives for z position m_z
0190     double m_z;
0191     double m_density{0};
0192     double m_firstDerivative{0};
0193     double m_secondDerivative{0};
0194   };
0195 };
0196 
0197 }  // namespace Acts