Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-13 08:16:15

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/Definitions/Units.hpp"
0013 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0014 #include "Acts/Utilities/Logger.hpp"
0015 #include "Acts/Utilities/Result.hpp"
0016 #include "Acts/Vertexing/AdaptiveMultiVertexFitter.hpp"
0017 #include "Acts/Vertexing/IVertexFinder.hpp"
0018 #include "Acts/Vertexing/ImpactPointEstimator.hpp"
0019 #include "Acts/Vertexing/VertexingOptions.hpp"
0020 
0021 namespace Acts {
0022 
0023 /// @brief Implements an iterative vertex finder
0024 class AdaptiveMultiVertexFinder final : public IVertexFinder {
0025   using VertexFitter = AdaptiveMultiVertexFitter;
0026   using VertexFitterState = VertexFitter::State;
0027 
0028  public:
0029   /// Configuration struct
0030   struct Config {
0031     /// @brief Config constructor
0032     ///
0033     /// @param fitter The vertex fitter
0034     /// @param sfinder The seed finder
0035     /// @param ipEst ImpactPointEstimator
0036     /// @param bIn Input magnetic field
0037     Config(VertexFitter fitter, std::shared_ptr<const IVertexFinder> sfinder,
0038            ImpactPointEstimator ipEst,
0039            std::shared_ptr<const MagneticFieldProvider> bIn)
0040         : vertexFitter(std::move(fitter)),
0041           seedFinder(std::move(sfinder)),
0042           ipEstimator(std::move(ipEst)),
0043           bField{std::move(bIn)} {}
0044 
0045     /// Vertex fitter
0046     VertexFitter vertexFitter;
0047 
0048     /// Vertex seed finder
0049     std::shared_ptr<const IVertexFinder> seedFinder;
0050 
0051     /// ImpactPointEstimator
0052     ImpactPointEstimator ipEstimator;
0053 
0054     /// Magnetic field provider for track propagation and vertex finding
0055     std::shared_ptr<const MagneticFieldProvider> bField;
0056 
0057     /// Max z interval used for adding tracks to fit:
0058     /// When adding a new vertex to the multi vertex fit,
0059     /// only the tracks whose z at PCA is closer
0060     /// to the seeded vertex than tracksMaxZinterval
0061     /// are added to this new vertex.
0062     ///
0063     /// Note: If you cut too hard, you cut out
0064     /// the good cases where the seed finder is not
0065     /// reliable, but the fit would be still able to converge
0066     /// towards the right vertex. If you cut too soft, you
0067     /// consider a lot of tracks which just slow down the fit.
0068     double tracksMaxZinterval = 3. * Acts::UnitConstants::mm;
0069 
0070     /// Maximum allowed significance of track position to vertex seed to
0071     /// consider track as compatible to vertex. If useTime is set to true, the
0072     /// time coordinate also contributes to the significance and
0073     /// tracksMaxSignificance needs to be increased. 5 corresponds to a p-value
0074     /// of ~0.92 using `chi2(x=5,ndf=2)`
0075     double tracksMaxSignificance = 5.;
0076 
0077     /// Max chi2 value for which tracks are considered compatible with
0078     /// the fitted vertex. These tracks are removed from the seedTracks
0079     /// after the fit has been performed.
0080     double maxVertexChi2 = 18.42;
0081 
0082     /// Perform a 'real' multi-vertex fit as intended by the algorithm.
0083     /// If switched to true, always all (!) tracks are considered to be
0084     /// added to the new vertex candidate after seeding. If switched to
0085     /// false, only the seedTracks, i.e. all tracks that are considered
0086     /// as outliers of previously fitted vertices, are used.
0087     bool doRealMultiVertex = true;
0088 
0089     /// Decides if you want to use the ```vertexCompatibility``` of the
0090     ///  track (set to true) or the ```chi2Track``` (set to false) as an
0091     /// estimate for a track being an outlier or not.
0092     /// In case the track refitting is switched on in the AMVFitter, you
0093     /// may want to use the refitted ```chi2Track```.
0094     bool useFastCompatibility = true;
0095 
0096     /// Maximum significance on the distance between two vertices
0097     /// to allow merging of two vertices.
0098     /// 3 corresponds to a p-value of ~0.92 using `chi2(x=3,ndf=1)`
0099     double maxMergeVertexSignificance = 3.;
0100 
0101     /// Minimum weight a track has to have to be considered a compatible
0102     /// track with a vertex candidate.
0103     ///
0104     /// Note: This value has to be the same as the one in the AMVFitter.
0105     double minWeight = 0.0001;
0106 
0107     /// Maximal number of iterations in the finding procedure
0108     int maxIterations = 100;
0109 
0110     /// Include also single track vertices
0111     bool addSingleTrackVertices = false;
0112 
0113     /// If doFullSplitting == true, we check the 3D distance (if useTime ==
0114     /// false) or the 4D distance (if useTime == true) of the vertices to
0115     /// determine whether they are merged.
0116     /// If doFullSplitting == false, we check the z distance (if useTime ==
0117     /// false) or the z-t distance (if useTime == true) of the vertices to
0118     /// determine whether they are merged.
0119     bool doFullSplitting = false;
0120 
0121     /// Maximum vertex contamination value
0122     double maximumVertexContamination = 0.5;
0123 
0124     /// Use seed vertex as a constraint for the fit
0125     bool useSeedConstraint = true;
0126 
0127     /// Variances of the 4D vertex position before the vertex fit if no beamspot
0128     /// constraint is provided
0129     Vector4 initialVariances = Vector4::Constant(1e+8);
0130 
0131     /// Default fitQuality for constraint vertex in case no beamspot
0132     /// constraint is provided
0133     std::pair<double, double> defaultConstrFitQuality{0., -3.};
0134 
0135     /// Use the full available vertex covariance information after
0136     /// seeding for the IP estimation. In original implementation
0137     /// this is not (!) done, however, this is probably not correct.
0138     /// So definitely consider setting this to true.
0139     bool useVertexCovForIPEstimation = false;
0140 
0141     /// Use time information when assigning tracks to vertices. If this is set
0142     /// to true, useTime of the vertex fitter configuration should also be set
0143     /// to true, and time seeding should be enabled.
0144     bool useTime = false;
0145 
0146     /// If set to true, the vertex finder will not break the finding loop.
0147     /// Some seeders are not able to cope with this therefore this is
0148     /// disabled by default.
0149     bool doNotBreakWhileSeeding = false;
0150 
0151     /// Function to extract parameters from InputTrack
0152     InputTrack::Extractor extractParameters;
0153   };
0154 
0155   /// State struct for fulfilling interface
0156   struct State {
0157     /// Magnetic field context for field evaluations
0158     std::reference_wrapper<const MagneticFieldContext> magContext;
0159 
0160     /// State object for the seed vertex finder
0161     IVertexFinder::State seedFinderState;
0162   };
0163 
0164   /// @brief Constructor for user-defined InputTrack_t type !=
0165   /// BoundTrackParameters
0166   ///
0167   /// @param cfg Configuration object
0168   /// @param logger The logging instance
0169   explicit AdaptiveMultiVertexFinder(
0170       Config cfg, std::unique_ptr<const Logger> logger = getDefaultLogger(
0171                       "AdaptiveMultiVertexFinder", Logging::INFO))
0172       : m_cfg(std::move(cfg)), m_logger(std::move(logger)) {
0173     if (!m_cfg.extractParameters.connected()) {
0174       throw std::invalid_argument(
0175           "AdaptiveMultiVertexFinder: "
0176           "No function to extract parameters "
0177           "from InputTrack provided.");
0178     }
0179 
0180     if (!m_cfg.seedFinder) {
0181       throw std::invalid_argument(
0182           "AdaptiveMultiVertexFinder: "
0183           "No vertex fitter provided.");
0184     }
0185   }
0186 
0187   /// @brief Function that performs the adaptive
0188   /// multi-vertex finding
0189   ///
0190   /// @param allTracks Input track collection
0191   /// @param vertexingOptions Vertexing options
0192   /// @param anyState The state object
0193   ///
0194   /// @return Vector of all reconstructed vertices
0195   Result<std::vector<Vertex>> find(
0196       const std::vector<InputTrack>& allTracks,
0197       const VertexingOptions& vertexingOptions,
0198       IVertexFinder::State& anyState) const override;
0199 
0200   IVertexFinder::State makeState(
0201       const Acts::MagneticFieldContext& mctx) const override {
0202     return IVertexFinder::State{
0203         State{mctx, IVertexFinder::State{m_cfg.seedFinder->makeState(mctx)}}};
0204   }
0205 
0206   void setTracksToRemove(
0207       IVertexFinder::State& /*state*/,
0208       const std::vector<InputTrack>& /*removedTracks*/) const override {
0209     // Nothing to do here
0210   }
0211 
0212  private:
0213   /// Configuration object
0214   Config m_cfg;
0215 
0216   /// Logging instance
0217   std::unique_ptr<const Logger> m_logger;
0218 
0219   /// Private access to logging instance
0220   const Logger& logger() const { return *m_logger; }
0221 
0222   /// @brief Calls the seed finder and sets constraints on the found seed
0223   /// vertex if desired
0224   ///
0225   /// @param trackVector All tracks to be used for seeding
0226   /// @param currentConstraint Vertex constraint
0227   /// @param vertexingOptions Vertexing options
0228   /// @param seedFinderState The seed finder state
0229   /// @param removedSeedTracks Seed track that have been removed
0230   /// from seed track collection in last iteration
0231   ///
0232   /// @return The seed vertex
0233   Result<std::vector<Vertex>> doSeeding(
0234       const std::vector<InputTrack>& trackVector, Vertex& currentConstraint,
0235       const VertexingOptions& vertexingOptions,
0236       IVertexFinder::State& seedFinderState,
0237       const std::vector<InputTrack>& removedSeedTracks) const;
0238 
0239   /// @brief Sets constraint vertex after seeding
0240   ///
0241   /// @param currentConstraint Vertex constraint
0242   /// @param useVertexConstraintInFit Indicates whether constraint is used during vertex fit
0243   /// @param seedVertex Seed vertex
0244   void setConstraintAfterSeeding(Vertex& currentConstraint,
0245                                  bool useVertexConstraintInFit,
0246                                  Vertex& seedVertex) const;
0247 
0248   /// @brief Calculates the IP significance of a track to a given vertex
0249   ///
0250   /// @param track The track
0251   /// @param vtx The vertex
0252   /// @param vertexingOptions Vertexing options
0253   ///
0254   /// @return The IP significance
0255   Result<double> getIPSignificance(
0256       const InputTrack& track, const Vertex& vtx,
0257       const VertexingOptions& vertexingOptions) const;
0258 
0259   /// @brief Adds compatible track to vertex candidate
0260   ///
0261   /// @param tracks The tracks
0262   /// @param vtx The vertex candidate
0263   /// @param[out] fitterState The vertex fitter state
0264   /// @param vertexingOptions Vertexing options
0265   Result<void> addCompatibleTracksToVertex(
0266       const std::vector<InputTrack>& tracks, Vertex& vtx,
0267       VertexFitterState& fitterState,
0268       const VertexingOptions& vertexingOptions) const;
0269 
0270   /// @brief Method that tries to recover from cases where no tracks
0271   /// were added to the vertex candidate after seeding
0272   ///
0273   /// @param allTracks The tracks to be considered (either origTrack or
0274   /// seedTracks)
0275   /// @param seedTracks The seed tracks
0276   /// @param[out] vtx The vertex candidate
0277   /// @param currentConstraint Vertex constraint
0278   /// @param[out] fitterState The vertex fitter state
0279   /// @param vertexingOptions Vertexing options
0280   ///
0281   /// return True if recovery was successful, false otherwise
0282   Result<bool> canRecoverFromNoCompatibleTracks(
0283       const std::vector<InputTrack>& allTracks,
0284       const std::vector<InputTrack>& seedTracks, Vertex& vtx,
0285       const Vertex& currentConstraint, VertexFitterState& fitterState,
0286       const VertexingOptions& vertexingOptions) const;
0287 
0288   /// @brief Method that tries to prepare the vertex for the fit
0289   ///
0290   /// @param allTracks The tracks to be considered (either origTrack or
0291   /// seedTracks)
0292   /// @param seedTracks The seed tracks
0293   /// @param[out] vtx The vertex candidate
0294   /// @param currentConstraint Vertex constraint
0295   /// @param[out] fitterState The vertex fitter state
0296   /// @param vertexingOptions Vertexing options
0297   ///
0298   /// @return True if preparation was successful, false otherwise
0299   Result<bool> canPrepareVertexForFit(
0300       const std::vector<InputTrack>& allTracks,
0301       const std::vector<InputTrack>& seedTracks, Vertex& vtx,
0302       const Vertex& currentConstraint, VertexFitterState& fitterState,
0303       const VertexingOptions& vertexingOptions) const;
0304 
0305   /// @brief Method that checks if vertex is a good vertex and if
0306   /// compatible tracks are available
0307   ///
0308   /// @param vtx The vertex candidate
0309   /// @param seedTracks The seed tracks
0310   /// @param fitterState The vertex fitter state
0311   /// @param useVertexConstraintInFit Indicates whether constraint is used in the vertex fit
0312   ///
0313   /// @return pair(nCompatibleTracks, isGoodVertex)
0314   std::pair<int, bool> checkVertexAndCompatibleTracks(
0315       Vertex& vtx, const std::vector<InputTrack>& seedTracks,
0316       VertexFitterState& fitterState, bool useVertexConstraintInFit) const;
0317 
0318   /// @brief Method that removes all tracks that are compatible with
0319   /// current vertex from seedTracks
0320   ///
0321   /// @param vtx The vertex candidate
0322   /// @param[out] seedTracks The seed tracks
0323   /// @param fitterState The vertex fitter state
0324   /// @param[out] removedSeedTracks Collection of seed track that will be
0325   /// removed
0326   void removeCompatibleTracksFromSeedTracks(
0327       Vertex& vtx, std::vector<InputTrack>& seedTracks,
0328       VertexFitterState& fitterState,
0329       std::vector<InputTrack>& removedSeedTracks) const;
0330 
0331   /// @brief Method that tries to remove an incompatible track
0332   /// from seed tracks after removing a compatible track failed.
0333   ///
0334   /// @param vtx The vertex candidate
0335   /// @param[out] seedTracks The seed tracks
0336   /// @param fitterState The vertex fitter state
0337   /// @param[out] removedSeedTracks Collection of seed track that will be
0338   /// removed
0339   /// @param[in] geoCtx The geometry context to access global positions
0340   ///
0341   /// @return Incompatible track was removed
0342   Result<void> removeTrackIfIncompatible(
0343       Vertex& vtx, std::vector<InputTrack>& seedTracks,
0344       VertexFitterState& fitterState,
0345       std::vector<InputTrack>& removedSeedTracks,
0346       const GeometryContext& geoCtx) const;
0347 
0348   /// @brief Method that evaluates if the new vertex candidate should
0349   /// be kept, i.e. saved, or not
0350   ///
0351   /// @param vtx The vertex candidate
0352   /// @param allVertices All so far found vertices
0353   /// @param fitterState The vertex fitter state
0354   ///
0355   /// @return Keep new vertex
0356   Result<bool> keepNewVertex(Vertex& vtx,
0357                              const std::vector<Vertex*>& allVertices,
0358                              VertexFitterState& fitterState) const;
0359 
0360   /// @brief Method that evaluates if the new vertex candidate is
0361   /// merged with one of the previously found vertices
0362   ///
0363   /// @param vtx The vertex candidate
0364   /// @param allVertices All vertices that were found so far
0365   ///
0366   /// @return Bool indicating whether the vertex is merged
0367   Result<bool> isMergedVertex(const Vertex& vtx,
0368                               const std::vector<Vertex*>& allVertices) const;
0369 
0370   /// @brief Method that deletes last vertex from list of all vertices
0371   /// and refits all vertices afterwards
0372   ///
0373   /// @param vtx The last added vertex which will be removed
0374   /// @param allVertices Vector containing the unique_ptr to vertices
0375   /// @param allVerticesPtr Vector containing the actual addresses
0376   /// @param fitterState The current vertex fitter state
0377   /// @param vertexingOptions Vertexing options
0378   Result<void> deleteLastVertex(
0379       Vertex& vtx, std::vector<std::unique_ptr<Vertex>>& allVertices,
0380       std::vector<Vertex*>& allVerticesPtr, VertexFitterState& fitterState,
0381       const VertexingOptions& vertexingOptions) const;
0382 
0383   /// @brief Prepares the output vector of vertices
0384   ///
0385   /// @param allVerticesPtr Vector of pointers to vertices
0386   /// @param fitterState The vertex fitter state
0387   ///
0388   /// @return The output vertex collection
0389   Result<std::vector<Vertex>> getVertexOutputList(
0390       const std::vector<Vertex*>& allVerticesPtr,
0391       VertexFitterState& fitterState) const;
0392 };
0393 
0394 }  // namespace Acts