Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-23 08:20:09

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