Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:27:59

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