Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-20 07:34:27

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/MagneticField/MagneticFieldContext.hpp"
0013 #include "Acts/MagneticField/MagneticFieldProvider.hpp"
0014 #include "Acts/Utilities/Logger.hpp"
0015 #include "Acts/Utilities/Result.hpp"
0016 #include "Acts/Vertexing/FullBilloirVertexFitter.hpp"
0017 #include "Acts/Vertexing/HelicalTrackLinearizer.hpp"
0018 #include "Acts/Vertexing/IVertexFinder.hpp"
0019 #include "Acts/Vertexing/ImpactPointEstimator.hpp"
0020 #include "Acts/Vertexing/TrackLinearizer.hpp"
0021 #include "Acts/Vertexing/Vertex.hpp"
0022 #include "Acts/Vertexing/VertexingOptions.hpp"
0023 
0024 #include <functional>
0025 
0026 namespace Acts {
0027 
0028 /// @class IterativeVertexFinder
0029 ///
0030 /// @brief Implements an iterative vertex finder
0031 ///
0032 ////////////////////////////////////////////////////////////
0033 ///
0034 /// Brief description of the algorithm implemented:
0035 /// Iterative vertex finder which iteratively finds and fits vertices:
0036 /// 1. A list of seed tracks (`seedTracks`, which is the same as the
0037 ///   input track list to the finder at the very first iteration) is used
0038 ///   to retrieve a single vertex seed using the ZScanVertexFinder.
0039 /// 2. All tracks compatible with the current vertex seed are kept and used
0040 ///   for fitting the single vertex.
0041 /// 3.1 If the vertex is a 'good' vertex (i.e. meets requirements) and no
0042 ///   track reassignment after first fit is required, go to step 4. If vertex
0043 ///   is not a good vertex, remove all tracks in tracksToFit from seedTracks.
0044 /// 3.2 If vertex meets requirements and track reassignment after first fit
0045 ///   is required, iterate over all previously found vertices ("old vertex")
0046 ///   and over all their tracksAtVertex. Compare compatibility of each track
0047 ///   with old vertex and current vertex. If track is more compatible with
0048 ///   current vertex, remove track from old vertex, put track back to
0049 ///   tracksToFit and refit current vertex with additional track.
0050 /// 4. If good vertex, `removeUsedCompatibleTracks` method is called, which
0051 ///   removes all used tracks that are compatible with the fitted vertex
0052 ///   from `tracksToFit` and `seedTracks`. It also removes outliers tracks
0053 ///   from tracksAtVertex if not compatible.
0054 /// 5. Add vertex to vertexCollection
0055 /// 6. Repeat until no seedTracks are left or max. number of vertices found
0056 class IterativeVertexFinder final : public IVertexFinder {
0057   using VertexFitter = FullBilloirVertexFitter;
0058 
0059  public:
0060   /// Configuration struct
0061   struct Config {
0062     /// @brief Config constructor
0063     ///
0064     /// @param fitter Vertex fitter
0065     /// @param sfinder The seed finder
0066     /// @param est ImpactPointEstimator
0067     Config(VertexFitter fitter, std::shared_ptr<IVertexFinder> sfinder,
0068            ImpactPointEstimator est)
0069         : vertexFitter(std::move(fitter)),
0070           seedFinder(std::move(sfinder)),
0071           ipEst(std::move(est)) {}
0072 
0073     /// Vertex fitter
0074     VertexFitter vertexFitter;
0075 
0076     /// Track linearizer
0077     TrackLinearizer trackLinearizer;
0078 
0079     /// Vertex seed finder
0080     std::shared_ptr<IVertexFinder> seedFinder;
0081 
0082     /// ImpactPointEstimator
0083     ImpactPointEstimator ipEst;
0084 
0085     /// Vertex finder configuration variables.
0086     /// Tracks that are within a distance of
0087     ///
0088     /// significanceCutSeeding * sqrt(sigma(d0)^2+sigma(z0)^2)
0089     ///
0090     /// are considered compatible with the vertex.
0091     double significanceCutSeeding = 10;
0092     /// Maximum chi-squared cut for seeding vertex candidates
0093     double maximumChi2cutForSeeding = 36.;
0094     /// Maximum number of vertices to find per event
0095     int maxVertices = 50;
0096 
0097     /// Assign a certain fraction of compatible tracks to a different (so-called
0098     /// split) vertex if boolean is set to true.
0099     bool createSplitVertices = false;
0100     /// Inverse of the fraction of tracks that will be assigned to the split
0101     /// vertex. E.g., if splitVerticesTrkInvFraction = 2, about 50% of
0102     /// compatible tracks will be assigned to the split vertex.
0103     int splitVerticesTrkInvFraction = 2;
0104     /// Flag to enable track reassignment after first vertex fit
0105     bool reassignTracksAfterFirstFit = false;
0106     /// Flag to enable maximum tracks cut per vertex
0107     bool doMaxTracksCut = false;
0108     /// Maximum number of tracks to consider per vertex
0109     int maxTracks = 5000;
0110     /// Minimum track weight threshold for vertex association
0111     double cutOffTrackWeight = 0.01;
0112     /// If `reassignTracksAfterFirstFit` is set this threshold will be used to
0113     /// decide if a track should be checked for reassignment to other vertices
0114     double cutOffTrackWeightReassign = 1;
0115 
0116     /// Function to extract parameters from InputTrack
0117     InputTrack::Extractor extractParameters;
0118 
0119     /// Magnetic field provider
0120     std::shared_ptr<const MagneticFieldProvider> field;
0121   };
0122 
0123   /// State struct
0124   struct State {
0125     /// Constructor with magnetic field provider and context
0126     /// @param field Magnetic field provider for track extrapolation
0127     /// @param _magContext Magnetic field context for field evaluation
0128     State(const MagneticFieldProvider& field,
0129           const Acts::MagneticFieldContext& _magContext)
0130         : magContext(_magContext),
0131           ipState{field.makeCache(magContext)},
0132           fieldCache(field.makeCache(magContext)) {}
0133 
0134     /// Reference to magnetic field context for vertex finding
0135     std::reference_wrapper<const Acts::MagneticFieldContext> magContext;
0136 
0137     /// The IP estimator state
0138     ImpactPointEstimator::State ipState;
0139 
0140     /// Cached magnetic field information for efficient access
0141     MagneticFieldProvider::Cache fieldCache;
0142   };
0143 
0144   /// @brief Constructor for user-defined InputTrack type
0145   ///
0146   /// @param cfg Configuration object
0147   /// @param logger The logging instance
0148   explicit IterativeVertexFinder(Config cfg,
0149                                  std::unique_ptr<const Logger> logger =
0150                                      getDefaultLogger("IterativeVertexFinder",
0151                                                       Logging::INFO));
0152 
0153   /// @brief Finds vertices corresponding to input trackVector
0154   ///
0155   /// @param trackVector Input tracks
0156   /// @param vertexingOptions Vertexing options
0157   /// @param anyState State for fulfilling interfaces
0158   ///
0159   /// @return Collection of vertices found by finder
0160   Result<std::vector<Vertex>> find(
0161       const std::vector<InputTrack>& trackVector,
0162       const VertexingOptions& vertexingOptions,
0163       IVertexFinder::State& anyState) const override;
0164 
0165   IVertexFinder::State makeState(
0166       const MagneticFieldContext& mctx) const override {
0167     return IVertexFinder::State{State{*m_cfg.field, mctx}};
0168   }
0169 
0170   void setTracksToRemove(
0171       IVertexFinder::State& /*anyState*/,
0172       const std::vector<InputTrack>& /*removedTracks*/) const override {
0173     // Nothing to do here
0174   }
0175 
0176  private:
0177   /// Configuration object
0178   const Config m_cfg;
0179 
0180   /// Logging instance
0181   std::unique_ptr<const Logger> m_logger;
0182 
0183   /// Private access to logging instance
0184   const Logger& logger() const { return *m_logger; }
0185 
0186   /// @brief Method that calls seed finder to retrieve a vertex seed
0187   ///
0188   /// @param state The state object
0189   /// @param seedTracks Seeding tracks
0190   /// @param vertexingOptions Vertexing options
0191   ///
0192   /// @return Vertex seed
0193   Result<std::optional<Vertex>> getVertexSeed(
0194       State& state, const std::vector<InputTrack>& seedTracks,
0195       const VertexingOptions& vertexingOptions) const;
0196 
0197   /// @brief Removes all tracks in tracksToRemove from seedTracks
0198   ///
0199   /// @param tracksToRemove Tracks to be removed from seedTracks
0200   /// @param seedTracks List to remove tracks from
0201   void removeTracks(const std::vector<InputTrack>& tracksToRemove,
0202                     std::vector<InputTrack>& seedTracks) const;
0203 
0204   /// @brief Function for calculating how compatible
0205   /// a given track is to a given vertex
0206   ///
0207   /// @param params Track parameters
0208   /// @param vertex The vertex
0209   /// @param perigeeSurface The perigee surface at vertex position
0210   /// @param vertexingOptions Vertexing options
0211   /// @param state The state object
0212   Result<double> getCompatibility(const BoundTrackParameters& params,
0213                                   const Vertex& vertex,
0214                                   const Surface& perigeeSurface,
0215                                   const VertexingOptions& vertexingOptions,
0216                                   State& state) const;
0217 
0218   /// @brief Function that removes used tracks compatible with
0219   /// current vertex (`vertex`) from `tracksToFit` and `seedTracks`
0220   /// as well as outliers from vertex.tracksAtVertex
0221   ///
0222   /// @param vertex Current vertex
0223   /// @param tracksToFit Tracks used to fit `vertex`
0224   /// @param seedTracks Tracks used for vertex seeding
0225   /// @param vertexingOptions Vertexing options
0226   /// @param state The state object
0227   Result<void> removeUsedCompatibleTracks(
0228       Vertex& vertex, std::vector<InputTrack>& tracksToFit,
0229       std::vector<InputTrack>& seedTracks,
0230       const VertexingOptions& vertexingOptions, State& state) const;
0231 
0232   /// @brief Function that fills vector with tracks compatible with seed vertex
0233   ///
0234   /// @param seedTracks List of all available tracks used for seeding
0235   /// @param seedVertex Seed vertex
0236   /// @param tracksToFitOut Tracks to fit
0237   /// @param tracksToFitSplitVertexOut Tracks to fit to split vertex
0238   /// @param vertexingOptions Vertexing options
0239   /// @param state The state object
0240   Result<void> fillTracksToFit(
0241       const std::vector<InputTrack>& seedTracks, const Vertex& seedVertex,
0242       std::vector<InputTrack>& tracksToFitOut,
0243       std::vector<InputTrack>& tracksToFitSplitVertexOut,
0244       const VertexingOptions& vertexingOptions, State& state) const;
0245 
0246   /// @brief Function that reassigns tracks from other vertices
0247   ///        to the current vertex if they are more compatible
0248   ///
0249   /// @param vertexCollection Collection of vertices
0250   /// @param currentVertex Current vertex to assign tracks to
0251   /// @param tracksToFit Tracks to fit vector
0252   /// @param seedTracks Seed tracks vector
0253   /// @param origTracks Vector of original track objects
0254   /// @param vertexingOptions Vertexing options
0255   /// @param state The state object
0256   ///
0257   /// @return Bool if currentVertex is still a good vertex
0258   Result<bool> reassignTracksToNewVertex(
0259       std::vector<Vertex>& vertexCollection, Vertex& currentVertex,
0260       std::vector<InputTrack>& tracksToFit, std::vector<InputTrack>& seedTracks,
0261       const std::vector<InputTrack>& origTracks,
0262       const VertexingOptions& vertexingOptions, State& state) const;
0263 
0264   /// @brief Counts all tracks that are significant for a vertex
0265   ///
0266   /// @param vtx The vertex
0267   ///
0268   /// @return Number of significant tracks
0269   int countSignificantTracks(const Vertex& vtx) const;
0270 };
0271 
0272 }  // namespace Acts