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/Definitions/Algebra.hpp"
0012 #include "Acts/EventData/TrackParameters.hpp"
0013 #include "Acts/MagneticField/MagneticFieldProvider.hpp"
0014 #include "Acts/Utilities/AnnealingUtility.hpp"
0015 #include "Acts/Utilities/Logger.hpp"
0016 #include "Acts/Utilities/Result.hpp"
0017 #include "Acts/Vertexing/AMVFInfo.hpp"
0018 #include "Acts/Vertexing/ImpactPointEstimator.hpp"
0019 #include "Acts/Vertexing/TrackAtVertex.hpp"
0020 #include "Acts/Vertexing/TrackLinearizer.hpp"
0021 #include "Acts/Vertexing/Vertex.hpp"
0022 #include "Acts/Vertexing/VertexingError.hpp"
0023 #include "Acts/Vertexing/VertexingOptions.hpp"
0024 
0025 #include <algorithm>
0026 #include <functional>
0027 
0028 namespace Acts {
0029 
0030 /// @class AdaptiveMultiVertexFitter
0031 /// @brief Implements an adaptive multi-vertex fitter as described
0032 ///   in detail in Section 5.3.5 in:
0033 ///   Ref. (1): CERN-THESIS-2010-027, Author: Piacquadio, Giacinto:
0034 ///   `Identification of b-jets and investigation of the discovery potential
0035 ///   of a Higgs boson in the WH−−>lvbb¯ channel with the ATLAS experiment`
0036 ///
0037 class AdaptiveMultiVertexFitter {
0038  public:
0039   /// @brief The fitter state
0040   struct State {
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
0050     AnnealingUtility::State annealingState;
0051 
0052     ImpactPointEstimator::State ipState;
0053 
0054     MagneticFieldProvider::Cache fieldCache;
0055 
0056     // Map to store vertices information
0057     // @TODO Does this have to be a mutable pointer?
0058     std::map<Vertex*, VertexInfo> vtxInfoMap;
0059 
0060     std::multimap<InputTrack, Vertex*> trackToVerticesMultiMap;
0061 
0062     std::map<std::pair<InputTrack, Vertex*>, TrackAtVertex> tracksAtVerticesMap;
0063 
0064     // Adds a vertex to trackToVerticesMultiMap
0065     void addVertexToMultiMap(Vertex& vtx) {
0066       for (auto trk : vtxInfoMap[&vtx].trackLinks) {
0067         trackToVerticesMultiMap.emplace(trk, &vtx);
0068       }
0069     }
0070 
0071     // Removes a vertex from trackToVerticesMultiMap
0072     void removeVertexFromMultiMap(Vertex& vtx) {
0073       for (auto iter = trackToVerticesMultiMap.begin();
0074            iter != trackToVerticesMultiMap.end();) {
0075         if (iter->second == &vtx) {
0076           iter = trackToVerticesMultiMap.erase(iter);
0077         } else {
0078           ++iter;
0079         }
0080       }
0081     }
0082 
0083     Result<void> removeVertexFromCollection(Vertex& vtxToRemove,
0084                                             const Logger& logger) {
0085       auto it = std::ranges::find(vertexCollection, &vtxToRemove);
0086       // Check if the value was found before erasing
0087       if (it == vertexCollection.end()) {
0088         ACTS_ERROR("vtxToRemove is not part of vertexCollection.");
0089         return VertexingError::ElementNotFound;
0090       }
0091       // Erase the element if found
0092       vertexCollection.erase(it);
0093       return {};
0094     }
0095   };
0096 
0097   struct Config {
0098     /// @brief Config constructor
0099     ///
0100     /// @param est ImpactPointEstimator
0101     Config(ImpactPointEstimator est) : ipEst(std::move(est)) {}
0102 
0103     // ImpactPointEstimator
0104     ImpactPointEstimator ipEst;
0105 
0106     /// Annealing tool used for a thermodynamic annealing scheme for the
0107     /// track weight factors in such a way that with high temperature values
0108     /// (at the beginning) only a slight preference is given to tracks
0109     /// compatible with the estimated vertex position. With lower temperatures
0110     /// the weighting get stricter such that all incompatible tracks will be
0111     /// dropped at the end while keeping all compatible tracks with a weight=1.
0112     ///   Ref. (1): CERN-THESIS-2010-027, Author: Piacquadio, Giacinto:
0113     ///   `Identification of b-jets and investigation of the discovery potential
0114     ///   of a Higgs boson in the WH−−>lvbb¯ channel with the ATLAS experiment`
0115     AnnealingUtility annealingTool;
0116 
0117     // Number of max iterations
0118     unsigned int maxIterations{30};
0119 
0120     // Max distance to linearization point allowed
0121     // without relinearization
0122     double maxDistToLinPoint{0.5};
0123 
0124     // Minimum track weight needed for track to be considered
0125     double minWeight{0.0001};
0126 
0127     // Max relative shift of vertex during one iteration
0128     double maxRelativeShift{0.01};
0129 
0130     // Do smoothing after multivertex fit
0131     bool doSmoothing{false};
0132 
0133     // Use time information when calculating the vertex compatibility
0134     bool useTime{false};
0135 
0136     // Function to extract parameters from InputTrack
0137     InputTrack::Extractor extractParameters;
0138 
0139     TrackLinearizer trackLinearizer;
0140   };
0141 
0142   /// @brief Constructor for user-defined InputTrack_t type !=
0143   /// BoundTrackParameters
0144   ///
0145   /// @param cfg Configuration object
0146   /// object
0147   /// @param logger The logging instance
0148   AdaptiveMultiVertexFitter(Config cfg,
0149                             std::unique_ptr<const Logger> logger =
0150                                 getDefaultLogger("AdaptiveMultiVertexFitter",
0151                                                  Logging::INFO))
0152       : m_cfg(std::move(cfg)), m_logger(std::move(logger)) {
0153     if (!m_cfg.extractParameters.connected()) {
0154       throw std::invalid_argument(
0155           "AdaptiveMultiVertexFitter: No function to extract parameters "
0156           "from InputTrack_t provided.");
0157     }
0158 
0159     if (!m_cfg.trackLinearizer.connected()) {
0160       throw std::invalid_argument(
0161           "AdaptiveMultiVertexFitter: No track linearizer provided.");
0162     }
0163   }
0164 
0165   /// @brief Adds a new vertex to an existing multi-vertex fit.
0166   /// 1. The 3D impact parameters are calculated for all tracks associated
0167   /// with newVertex.
0168   /// 2. A list of all vertices that are connected with newVertex via shared
0169   /// tracks is created. It also considers indirect connections (e.g., vertex A
0170   /// which shares a track with vertex B which, in turn, shares a track with
0171   /// newVertex).
0172   /// 3. The multivertex fit is performed for all vertices on said list.
0173   ///
0174   /// @param state Fitter state
0175   /// @param newVertex Vertex to be added to fit
0176   /// @param vertexingOptions Vertexing options
0177   ///
0178   /// @return Result<void> object
0179   Result<void> addVtxToFit(State& state, Vertex& newVertex,
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