Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-26 07:33:59

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