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) 2020 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/Definitions/Units.hpp"
0013 #include "Acts/EventData/TrackParameters.hpp"
0014 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0015 #include "Acts/Utilities/Logger.hpp"
0016 #include "Acts/Utilities/Result.hpp"
0017 #include "Acts/Vertexing/AMVFInfo.hpp"
0018 #include "Acts/Vertexing/AdaptiveMultiVertexFitter.hpp"
0019 #include "Acts/Vertexing/IVertexFinder.hpp"
0020 #include "Acts/Vertexing/ImpactPointEstimator.hpp"
0021 #include "Acts/Vertexing/TrackLinearizer.hpp"
0022 #include "Acts/Vertexing/VertexingOptions.hpp"
0023 
0024 #include <functional>
0025 #include <type_traits>
0026 
0027 namespace Acts {
0028 /// @brief Implements an iterative vertex finder
0029 class AdaptiveMultiVertexFinder final : public IVertexFinder {
0030   using VertexFitter = AdaptiveMultiVertexFitter;
0031   using VertexFitterState = VertexFitter::State;
0032 
0033  public:
0034   /// Configuration struct
0035   struct Config {
0036     /// @brief Config constructor
0037     ///
0038     /// @param fitter The vertex fitter
0039     /// @param sfinder The seed finder
0040     /// @param ipEst ImpactPointEstimator
0041     /// @param bIn Input magnetic field
0042     Config(VertexFitter fitter, std::shared_ptr<const IVertexFinder> sfinder,
0043            ImpactPointEstimator ipEst,
0044            std::shared_ptr<const MagneticFieldProvider> bIn)
0045         : vertexFitter(std::move(fitter)),
0046           seedFinder(std::move(sfinder)),
0047           ipEstimator(std::move(ipEst)),
0048           bField{std::move(bIn)} {}
0049 
0050     // Vertex fitter
0051     VertexFitter vertexFitter;
0052 
0053     // Vertex seed finder
0054     std::shared_ptr<const IVertexFinder> seedFinder;
0055 
0056     // ImpactPointEstimator
0057     ImpactPointEstimator ipEstimator;
0058 
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 consider
0075     // track as compatible to vertex. If useTime is set to true, the time
0076     // coordinate also contributes to the significance and tracksMaxSignificance
0077     // needs to be increased.
0078     // 5 corresponds to a p-value 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 to
0146     // true, useTime of the vertex fitter configuration should also be set to
0147     // true, and time seeding should be enabled.
0148     bool useTime = false;
0149 
0150     // Function to extract parameters from InputTrack
0151     InputTrack::Extractor extractParameters;
0152   };  // Config struct
0153 
0154   /// State struct for fulfilling interface
0155   struct State {
0156     std::reference_wrapper<const MagneticFieldContext> magContext;
0157   };
0158 
0159   /// @brief Constructor for user-defined InputTrack_t type !=
0160   /// BoundTrackParameters
0161   ///
0162   /// @param cfg Configuration object
0163   /// @param logger The logging instance
0164   AdaptiveMultiVertexFinder(Config cfg,
0165                             std::unique_ptr<const Logger> logger =
0166                                 getDefaultLogger("AdaptiveMultiVertexFinder",
0167                                                  Logging::INFO))
0168       : m_cfg(std::move(cfg)), m_logger(std::move(logger)) {
0169     if (!m_cfg.extractParameters.connected()) {
0170       throw std::invalid_argument(
0171           "AdaptiveMultiVertexFinder: "
0172           "No function to extract parameters "
0173           "from InputTrack provided.");
0174     }
0175 
0176     if (!m_cfg.seedFinder) {
0177       throw std::invalid_argument(
0178           "AdaptiveMultiVertexFinder: "
0179           "No vertex fitter provided.");
0180     }
0181   }
0182 
0183   AdaptiveMultiVertexFinder(AdaptiveMultiVertexFinder&&) = default;
0184 
0185   /// @brief Function that performs the adaptive
0186   /// multi-vertex finding
0187   ///
0188   /// @param allTracks Input track collection
0189   /// @param vertexingOptions Vertexing options
0190   /// @param anyState The state object
0191   ///
0192   /// @return Vector of all reconstructed vertices
0193   Result<std::vector<Vertex>> find(
0194       const std::vector<InputTrack>& allTracks,
0195       const VertexingOptions& vertexingOptions,
0196       IVertexFinder::State& anyState) const override;
0197 
0198   IVertexFinder::State makeState(
0199       const Acts::MagneticFieldContext& mctx) const override {
0200     return IVertexFinder::State{State{mctx}};
0201   }
0202 
0203   void setTracksToRemove(
0204       IVertexFinder::State& /*state*/,
0205       const std::vector<InputTrack>& /*removedTracks*/) const override {
0206     // Nothing to do here
0207   }
0208 
0209  private:
0210   /// Configuration object
0211   Config m_cfg;
0212 
0213   /// Logging instance
0214   std::unique_ptr<const Logger> m_logger;
0215 
0216   /// Private access to logging instance
0217   const Logger& logger() const { return *m_logger; }
0218 
0219   /// @brief Calls the seed finder and sets constraints on the found seed
0220   /// vertex if desired
0221   ///
0222   /// @param trackVector All tracks to be used for seeding
0223   /// @param currentConstraint Vertex constraint
0224   /// @param vertexingOptions Vertexing options
0225   /// @param seedFinderState The seed finder state
0226   /// @param removedSeedTracks Seed track that have been removed
0227   /// from seed track collection in last iteration
0228   ///
0229   /// @return The seed vertex
0230   Result<std::optional<Vertex>> doSeeding(
0231       const std::vector<InputTrack>& trackVector, Vertex& currentConstraint,
0232       const VertexingOptions& vertexingOptions,
0233       IVertexFinder::State& seedFinderState,
0234       const std::vector<InputTrack>& removedSeedTracks) const;
0235 
0236   /// @brief Sets constraint vertex after seeding
0237   ///
0238   /// @param currentConstraint Vertex constraint
0239   /// @param useVertexConstraintInFit Indicates whether constraint is used during vertex fit
0240   /// @param seedVertex Seed vertex
0241   void setConstraintAfterSeeding(Vertex& currentConstraint,
0242                                  bool useVertexConstraintInFit,
0243                                  Vertex& seedVertex) const;
0244 
0245   /// @brief Calculates the IP significance of a track to a given vertex
0246   ///
0247   /// @param track The track
0248   /// @param vtx The vertex
0249   /// @param vertexingOptions Vertexing options
0250   ///
0251   /// @return The IP significance
0252   Result<double> getIPSignificance(
0253       const InputTrack& track, const Vertex& vtx,
0254       const VertexingOptions& vertexingOptions) const;
0255 
0256   /// @brief Adds compatible track to vertex candidate
0257   ///
0258   /// @param tracks The tracks
0259   /// @param vtx The vertex candidate
0260   /// @param[out] fitterState The vertex fitter state
0261   /// @param vertexingOptions Vertexing options
0262   Result<void> addCompatibleTracksToVertex(
0263       const std::vector<InputTrack>& tracks, Vertex& vtx,
0264       VertexFitterState& fitterState,
0265       const VertexingOptions& vertexingOptions) const;
0266 
0267   /// @brief Method that tries to recover from cases where no tracks
0268   /// were added to the vertex candidate after seeding
0269   ///
0270   /// @param allTracks The tracks to be considered (either origTrack or
0271   /// seedTracks)
0272   /// @param seedTracks The seed tracks
0273   /// @param[out] vtx The vertex candidate
0274   /// @param currentConstraint Vertex constraint
0275   /// @param[out] fitterState The vertex fitter state
0276   /// @param vertexingOptions Vertexing options
0277   ///
0278   /// return True if recovery was successful, false otherwise
0279   Result<bool> canRecoverFromNoCompatibleTracks(
0280       const std::vector<InputTrack>& allTracks,
0281       const std::vector<InputTrack>& seedTracks, Vertex& vtx,
0282       const Vertex& currentConstraint, VertexFitterState& fitterState,
0283       const VertexingOptions& vertexingOptions) const;
0284 
0285   /// @brief Method that tries to prepare the vertex for the fit
0286   ///
0287   /// @param allTracks The tracks to be considered (either origTrack or
0288   /// seedTracks)
0289   /// @param seedTracks The seed tracks
0290   /// @param[out] vtx The vertex candidate
0291   /// @param currentConstraint Vertex constraint
0292   /// @param[out] fitterState The vertex fitter state
0293   /// @param vertexingOptions Vertexing options
0294   ///
0295   /// @return True if preparation was successful, false otherwise
0296   Result<bool> canPrepareVertexForFit(
0297       const std::vector<InputTrack>& allTracks,
0298       const std::vector<InputTrack>& seedTracks, Vertex& vtx,
0299       const Vertex& currentConstraint, VertexFitterState& fitterState,
0300       const VertexingOptions& vertexingOptions) const;
0301 
0302   /// @brief Method that checks if vertex is a good vertex and if
0303   /// compatible tracks are available
0304   ///
0305   /// @param vtx The vertex candidate
0306   /// @param seedTracks The seed tracks
0307   /// @param fitterState The vertex fitter state
0308   /// @param useVertexConstraintInFit Indicates whether constraint is used in the vertex fit
0309   ///
0310   /// @return pair(nCompatibleTracks, isGoodVertex)
0311   std::pair<int, bool> checkVertexAndCompatibleTracks(
0312       Vertex& vtx, const std::vector<InputTrack>& seedTracks,
0313       VertexFitterState& fitterState, bool useVertexConstraintInFit) const;
0314 
0315   /// @brief Method that removes all tracks that are compatible with
0316   /// current vertex from seedTracks
0317   ///
0318   /// @param vtx The vertex candidate
0319   /// @param[out] seedTracks The seed tracks
0320   /// @param fitterState The vertex fitter state
0321   /// @param[out] removedSeedTracks Collection of seed track that will be
0322   /// removed
0323   void removeCompatibleTracksFromSeedTracks(
0324       Vertex& vtx, std::vector<InputTrack>& seedTracks,
0325       VertexFitterState& fitterState,
0326       std::vector<InputTrack>& removedSeedTracks) const;
0327 
0328   /// @brief Method that tries to remove an incompatible track
0329   /// from seed tracks after removing a compatible track failed.
0330   ///
0331   /// @param vtx The vertex candidate
0332   /// @param[out] seedTracks The seed tracks
0333   /// @param fitterState The vertex fitter state
0334   /// @param[out] removedSeedTracks Collection of seed track that will be
0335   /// removed
0336   /// @param[in] geoCtx The geometry context to access global positions
0337   ///
0338   /// @return Incompatible track was removed
0339   bool removeTrackIfIncompatible(Vertex& vtx,
0340                                  std::vector<InputTrack>& seedTracks,
0341                                  VertexFitterState& fitterState,
0342                                  std::vector<InputTrack>& removedSeedTracks,
0343                                  const GeometryContext& geoCtx) const;
0344 
0345   /// @brief Method that evaluates if the new vertex candidate should
0346   /// be kept, i.e. saved, or not
0347   ///
0348   /// @param vtx The vertex candidate
0349   /// @param allVertices All so far found vertices
0350   /// @param fitterState The vertex fitter state
0351   ///
0352   /// @return Keep new vertex
0353   Result<bool> keepNewVertex(Vertex& vtx,
0354                              const std::vector<Vertex*>& allVertices,
0355                              VertexFitterState& fitterState) const;
0356 
0357   /// @brief Method that evaluates if the new vertex candidate is
0358   /// merged with one of the previously found vertices
0359   ///
0360   /// @param vtx The vertex candidate
0361   /// @param allVertices All vertices that were found so far
0362   ///
0363   /// @return Bool indicating whether the vertex is merged
0364   Result<bool> isMergedVertex(const Vertex& vtx,
0365                               const std::vector<Vertex*>& allVertices) const;
0366 
0367   /// @brief Method that deletes last vertex from list of all vertices
0368   /// and refits all vertices afterwards
0369   ///
0370   /// @param vtx The last added vertex which will be removed
0371   /// @param allVertices Vector containing the unique_ptr to vertices
0372   /// @param allVerticesPtr Vector containing the actual addresses
0373   /// @param fitterState The current vertex fitter state
0374   /// @param vertexingOptions Vertexing options
0375   Result<void> deleteLastVertex(
0376       Vertex& vtx, std::vector<std::unique_ptr<Vertex>>& allVertices,
0377       std::vector<Vertex*>& allVerticesPtr, VertexFitterState& fitterState,
0378       const VertexingOptions& vertexingOptions) const;
0379 
0380   /// @brief Prepares the output vector of vertices
0381   ///
0382   /// @param allVerticesPtr Vector of pointers to vertices
0383   /// @param fitterState The vertex fitter state
0384   ///
0385   /// @return The output vertex collection
0386   Result<std::vector<Vertex>> getVertexOutputList(
0387       const std::vector<Vertex*>& allVerticesPtr,
0388       VertexFitterState& fitterState) const;
0389 };
0390 
0391 }  // namespace Acts