Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-29 07:33:14

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/MagneticField/MagneticFieldProvider.hpp"
0012 #include "Acts/Utilities/AnnealingUtility.hpp"
0013 #include "Acts/Utilities/Logger.hpp"
0014 #include "Acts/Utilities/Result.hpp"
0015 #include "Acts/Vertexing/AMVFInfo.hpp"
0016 #include "Acts/Vertexing/ImpactPointEstimator.hpp"
0017 #include "Acts/Vertexing/TrackAtVertex.hpp"
0018 #include "Acts/Vertexing/TrackLinearizer.hpp"
0019 #include "Acts/Vertexing/Vertex.hpp"
0020 #include "Acts/Vertexing/VertexingError.hpp"
0021 #include "Acts/Vertexing/VertexingOptions.hpp"
0022 
0023 #include <algorithm>
0024 
0025 namespace Acts {
0026 
0027 /// @class AdaptiveMultiVertexFitter
0028 /// @brief Implements an adaptive multi-vertex fitter as described
0029 ///   in detail in Section 5.3.5 in:
0030 ///   Ref. (1): CERN-THESIS-2010-027, Author: Piacquadio, Giacinto:
0031 ///   `Identification of b-jets and investigation of the discovery potential
0032 ///   of a Higgs boson in the WH−−>lvbb¯ channel with the ATLAS experiment`
0033 ///
0034 class AdaptiveMultiVertexFitter {
0035  public:
0036   /// @brief The fitter state
0037   struct State {
0038     /// Constructor for multi-vertex fitter state
0039     /// @param field Magnetic field provider for track extrapolation
0040     /// @param magContext Magnetic field context for field evaluations
0041     State(const MagneticFieldProvider& field,
0042           const Acts::MagneticFieldContext& magContext)
0043         : ipState{field.makeCache(magContext)},
0044           fieldCache(field.makeCache(magContext)) {}
0045 
0046     /// Vertex collection to be fitted
0047     std::vector<Vertex*> vertexCollection;
0048 
0049     /// Annealing state for thermodynamic track weighting
0050     AnnealingUtility::State annealingState;
0051 
0052     /// Impact point estimator state for track parameter calculations
0053     ImpactPointEstimator::State ipState;
0054 
0055     /// Magnetic field cache for field evaluations during fitting
0056     MagneticFieldProvider::Cache fieldCache;
0057 
0058     /// Map storing vertex information for each vertex in the fit
0059     /// @todo Does this have to be a mutable pointer?
0060     std::map<Vertex*, VertexInfo> vtxInfoMap;
0061 
0062     /// Multimap connecting tracks to their associated vertices
0063     std::multimap<InputTrack, Vertex*> trackToVerticesMultiMap;
0064 
0065     /// Map storing track-at-vertex information for each track-vertex pair
0066     std::map<std::pair<InputTrack, Vertex*>, TrackAtVertex> tracksAtVerticesMap;
0067 
0068     /// Adds a vertex to trackToVerticesMultiMap
0069     /// @param vtx Vertex to add to the multimap with its associated tracks
0070     void addVertexToMultiMap(Vertex& vtx) {
0071       for (auto trk : vtxInfoMap[&vtx].trackLinks) {
0072         trackToVerticesMultiMap.emplace(trk, &vtx);
0073       }
0074     }
0075 
0076     /// Removes a vertex from trackToVerticesMultiMap
0077     /// @param vtx Vertex to remove from the multimap along with its track associations
0078     void removeVertexFromMultiMap(const Vertex& vtx) {
0079       for (auto iter = trackToVerticesMultiMap.begin();
0080            iter != trackToVerticesMultiMap.end();) {
0081         if (iter->second == &vtx) {
0082           iter = trackToVerticesMultiMap.erase(iter);
0083         } else {
0084           ++iter;
0085         }
0086       }
0087     }
0088 
0089     /// Remove a vertex from the vertex collection
0090     /// @param vtxToRemove Vertex to remove from the collection
0091     /// @param logger Logger for diagnostic messages
0092     /// @return Result indicating success or failure of the removal operation
0093     Result<void> removeVertexFromCollection(Vertex& vtxToRemove,
0094                                             const Logger& logger) {
0095       auto it = std::ranges::find(vertexCollection, &vtxToRemove);
0096       // Check if the value was found before erasing
0097       if (it == vertexCollection.end()) {
0098         ACTS_ERROR("vtxToRemove is not part of vertexCollection.");
0099         return VertexingError::ElementNotFound;
0100       }
0101       // Erase the element if found
0102       vertexCollection.erase(it);
0103       return {};
0104     }
0105   };
0106 
0107   /// @brief Configuration options for the adaptive multi-vertex fit.
0108   struct Config {
0109     /// @brief Config constructor
0110     ///
0111     /// @param est ImpactPointEstimator
0112     explicit Config(ImpactPointEstimator est) : ipEst(std::move(est)) {}
0113 
0114     /// ImpactPointEstimator
0115     ImpactPointEstimator ipEst;
0116 
0117     /// Annealing tool used for a thermodynamic annealing scheme for the
0118     /// track weight factors in such a way that with high temperature values
0119     /// (at the beginning) only a slight preference is given to tracks
0120     /// compatible with the estimated vertex position. With lower temperatures
0121     /// the weighting get stricter such that all incompatible tracks will be
0122     /// dropped at the end while keeping all compatible tracks with a weight=1.
0123     ///   Ref. (1): CERN-THESIS-2010-027, Author: Piacquadio, Giacinto:
0124     ///   `Identification of b-jets and investigation of the discovery potential
0125     ///   of a Higgs boson in the WH−−>lvbb¯ channel with the ATLAS experiment`
0126     AnnealingUtility annealingTool;
0127 
0128     /// Number of max iterations
0129     unsigned int maxIterations{30};
0130 
0131     /// Max distance to linearization point allowed
0132     /// without relinearization
0133     double maxDistToLinPoint{0.5};
0134 
0135     /// Minimum track weight needed for track to be considered
0136     double minWeight{0.0001};
0137 
0138     /// Max relative shift of vertex during one iteration
0139     double maxRelativeShift{0.01};
0140 
0141     /// Do smoothing after multivertex fit
0142     bool doSmoothing{false};
0143 
0144     /// Use time information when calculating the vertex compatibility
0145     bool useTime{false};
0146 
0147     /// Function to extract parameters from InputTrack
0148     InputTrack::Extractor extractParameters;
0149 
0150     /// TrackLinearizer
0151     TrackLinearizer trackLinearizer;
0152   };
0153 
0154   /// @brief Constructor for user-defined InputTrack_t type !=
0155   /// BoundTrackParameters
0156   ///
0157   /// @param cfg Configuration object
0158   /// object
0159   /// @param logger The logging instance
0160   explicit AdaptiveMultiVertexFitter(
0161       Config cfg, std::unique_ptr<const Logger> logger = getDefaultLogger(
0162                       "AdaptiveMultiVertexFitter", Logging::INFO));
0163 
0164   /// @brief Adds a new vertex to an existing multi-vertex fit.
0165   /// 1. The 3D impact parameters are calculated for all tracks associated
0166   /// with newVertex.
0167   /// 2. A list of all vertices that are connected with newVertex via shared
0168   /// tracks is created. It also considers indirect connections (e.g., vertex A
0169   /// which shares a track with vertex B which, in turn, shares a track with
0170   /// newVertex).
0171   /// 3. The multivertex fit is performed for all vertices on said list.
0172   ///
0173   /// @param state Fitter state
0174   /// @param newVertices Vertex to be added to fit
0175   /// @param vertexingOptions Vertexing options
0176   ///
0177   /// @return Result<void> object
0178   Result<void> addVtxToFit(State& state,
0179                            const std::vector<Vertex*>& newVertices,
0180                            const VertexingOptions& vertexingOptions) const;
0181 
0182   /// @brief Performs a simultaneous fit of all vertices in
0183   /// state.vertexCollection
0184   ///
0185   /// @param state Fitter state
0186   /// @param vertexingOptions Vertexing options
0187   ///
0188   /// @return Result<void> object
0189   Result<void> fit(State& state,
0190                    const VertexingOptions& vertexingOptions) const;
0191 
0192  private:
0193   /// Configuration object
0194   const Config m_cfg;
0195 
0196   /// Logging instance
0197   std::unique_ptr<const Logger> m_logger;
0198 
0199   /// Private access to logging instance
0200   const Logger& logger() const { return *m_logger; }
0201 
0202   /// @brief Tests if vertex is already in list of vertices or not
0203   ///
0204   /// @param vtx Vertex to test
0205   /// @param verticesVec Vector of vertices to search
0206   ///
0207   /// @return True if vtx is already in verticesVec
0208   bool isAlreadyInList(Vertex* vtx,
0209                        const std::vector<Vertex*>& verticesVec) const;
0210 
0211   /// @brief 1) Calls ImpactPointEstimator::estimate3DImpactParameters
0212   /// for all tracks that are associated with vtx (i.e., all elements
0213   /// of the trackLinks vector in the VertexInfo of vtx).
0214   /// 2) Saves the 3D impact parameters in the VertexInfo of vtx.
0215   ///
0216   /// @param state Vertex fitter state
0217   /// @param vtx Vertex object
0218   /// @param vertexingOptions Vertexing options
0219   Result<void> prepareVertexForFit(
0220       State& state, Vertex* vtx,
0221       const VertexingOptions& vertexingOptions) const;
0222 
0223   /// @brief Sets the vertexCompatibility for all TrackAtVertex objects
0224   /// at the current vertex
0225   ///
0226   /// @param state Fitter state
0227   /// @param currentVtx Current vertex
0228   /// @param vertexingOptions Vertexing options
0229   Result<void> setAllVertexCompatibilities(
0230       State& state, Vertex* currentVtx,
0231       const VertexingOptions& vertexingOptions) const;
0232 
0233   /// @brief Sets weights to the track according to Eq.(5.46) in Ref.(1)
0234   ///  and updates the vertices by calling the VertexUpdater
0235   ///
0236   /// @param state Fitter state
0237   /// @param vertexingOptions Vertexing options
0238   Result<void> setWeightsAndUpdate(
0239       State& state, const VertexingOptions& vertexingOptions) const;
0240 
0241   /// @brief Collects the compatibility values of the track `trk`
0242   /// wrt to all of its associated vertices
0243   ///
0244   /// @param state Fitter state
0245   /// @param trk Track
0246   ///
0247   /// @return Vector of compatibility values
0248   std::vector<double> collectTrackToVertexCompatibilities(
0249       State& state, const InputTrack& trk) const;
0250 
0251   /// @brief Determines if any vertex position has shifted more than
0252   /// m_cfg.maxRelativeShift in the last iteration
0253   ///
0254   /// @param state Fitter state
0255   ///
0256   /// @return False if at least one shift was larger than maxRelativeShift
0257   bool checkSmallShift(State& state) const;
0258 
0259   /// @brief Updates tracks for current vertex with knowledge
0260   /// of current vertex position
0261   ///
0262   /// @param state Fitter state
0263   void doVertexSmoothing(State& state) const;
0264 
0265   /// @brief Logs vertices in state.vertexCollection and associated tracks
0266   ///
0267   /// @param state Fitter state
0268   /// @param geoContext Geometry context
0269   void logDebugData(const State& state,
0270                     const GeometryContext& geoContext) const;
0271 };
0272 
0273 }  // namespace Acts