|
|
|||
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/MagneticField/MagneticFieldProvider.hpp" 0012 #include "Acts/Utilities/AnnealingUtility.hpp" 0013 #include "Acts/Utilities/Logger.hpp" 0014 #include "Acts/Utilities/Result.hpp" 0015 #include "Acts/Vertexing/AMVFInfo.hpp" 0016 #include "Acts/Vertexing/ImpactPointEstimator.hpp" 0017 #include "Acts/Vertexing/TrackAtVertex.hpp" 0018 #include "Acts/Vertexing/TrackLinearizer.hpp" 0019 #include "Acts/Vertexing/Vertex.hpp" 0020 #include "Acts/Vertexing/VertexFitProblem.hpp" 0021 #include "Acts/Vertexing/VertexingError.hpp" 0022 #include "Acts/Vertexing/VertexingOptions.hpp" 0023 0024 #include <algorithm> 0025 0026 namespace Acts { 0027 0028 /// @class AdaptiveMultiVertexFitter 0029 /// @brief Implements an adaptive multi-vertex fitter as described 0030 /// in detail in Section 5.3.5 in: 0031 /// Ref. (1): CERN-THESIS-2010-027, Author: Piacquadio, Giacinto: 0032 /// `Identification of b-jets and investigation of the discovery potential 0033 /// of a Higgs boson in the WH−−>lvbb¯ channel with the ATLAS experiment` 0034 /// 0035 class AdaptiveMultiVertexFitter { 0036 /// @brief Per-vertex scratch data of the adaptive multi-vertex fitter 0037 /// 0038 /// This is the fitter-private counterpart of @c VertexFitCandidate: everything 0039 /// here is regenerated during fitting and carries no meaning for a caller. It 0040 /// lives in the fitter cache rather than in the fit problem. 0041 /// 0042 /// @note @c linPoint and @c oldPosition must be initialised to the seed 0043 /// position of the corresponding vertex when the scratch entry is first 0044 /// created. Starting them at zero would make the first iteration measure the 0045 /// distance to the origin rather than to the seed, and spuriously trigger 0046 /// relinearization for any displaced vertex. See 0047 /// @c AdaptiveMultiVertexFitter::scratchFor. 0048 struct VertexScratch { 0049 VertexScratch() = default; 0050 0051 /// Construct scratch data seeded at @p pos 0052 /// @param pos Initial linearization point and previous position 0053 explicit VertexScratch(const Vector4& pos) 0054 : linPoint(pos), oldPosition(pos) {} 0055 0056 /// Point where all associated tracks are linearized 0057 Vector4 linPoint{Vector4::Zero()}; 0058 0059 /// Vertex position from the last iteration of the fit 0060 Vector4 oldPosition{Vector4::Zero()}; 0061 0062 /// Flag indicating if associated tracks need relinearization 0063 bool relinearize = true; 0064 0065 /// Map of 3D impact parameters for each associated track 0066 std::map<InputTrack, const BoundTrackParameters> impactParams3D; 0067 }; 0068 0069 public: 0070 /// @brief The fitter-private cache 0071 /// 0072 /// Holds everything that is scratch data of a running fit: the annealing 0073 /// state, the impact point estimator state, the magnetic field cache and the 0074 /// per-vertex linearization bookkeeping. The data describing *what* is being 0075 /// fitted lives in @c VertexFitProblem instead. 0076 struct Cache { 0077 /// Constructor for the multi-vertex fitter cache 0078 /// @param field Magnetic field provider for track extrapolation 0079 /// @param magContext Magnetic field context for field evaluations 0080 Cache(const MagneticFieldProvider& field, 0081 const Acts::MagneticFieldContext& magContext) 0082 : ipState{field.makeCache(magContext)}, 0083 fieldCache(field.makeCache(magContext)) {} 0084 0085 /// Drop the scratch data associated with @p vtx 0086 /// 0087 /// Must be called whenever a vertex's candidate description is re-seeded 0088 /// after it has already been fitted, since the cached linearization point 0089 /// and impact parameters then refer to a stale seed position. 0090 /// @param vtx Vertex whose scratch data is to be discarded 0091 void invalidate(const Vertex& vtx) { vertexScratch.erase(&vtx); } 0092 0093 private: 0094 /// Annealing state for thermodynamic track weighting 0095 AnnealingUtility::State annealingState; 0096 0097 /// Impact point estimator state for track parameter calculations 0098 ImpactPointEstimator::State ipState; 0099 0100 /// Magnetic field cache for field evaluations during fitting 0101 MagneticFieldProvider::Cache fieldCache; 0102 0103 /// Per-vertex scratch data, lazily created by @c scratchFor 0104 std::map<const Vertex*, VertexScratch> vertexScratch; 0105 0106 /// Construct a cache adopting an already existing impact point estimator 0107 /// state and magnetic field cache. Used by the deprecated @c State based 0108 /// entry points, which own those two caches themselves. 0109 /// @param ipStateIn Impact point estimator state to adopt 0110 /// @param fieldCacheIn Magnetic field cache to adopt 0111 Cache(ImpactPointEstimator::State ipStateIn, 0112 MagneticFieldProvider::Cache fieldCacheIn) 0113 : ipState(std::move(ipStateIn)), fieldCache(std::move(fieldCacheIn)) {} 0114 0115 friend class AdaptiveMultiVertexFitter; 0116 }; 0117 0118 /// @brief Configuration options for the adaptive multi-vertex fit. 0119 struct Config { 0120 /// @brief Config constructor 0121 /// 0122 /// @param est ImpactPointEstimator 0123 explicit Config(ImpactPointEstimator est) : ipEst(std::move(est)) {} 0124 0125 /// ImpactPointEstimator 0126 ImpactPointEstimator ipEst; 0127 0128 /// Annealing tool used for a thermodynamic annealing scheme for the 0129 /// track weight factors in such a way that with high temperature values 0130 /// (at the beginning) only a slight preference is given to tracks 0131 /// compatible with the estimated vertex position. With lower temperatures 0132 /// the weighting get stricter such that all incompatible tracks will be 0133 /// dropped at the end while keeping all compatible tracks with a weight=1. 0134 /// Ref. (1): CERN-THESIS-2010-027, Author: Piacquadio, Giacinto: 0135 /// `Identification of b-jets and investigation of the discovery potential 0136 /// of a Higgs boson in the WH−−>lvbb¯ channel with the ATLAS experiment` 0137 AnnealingUtility annealingTool; 0138 0139 /// Number of max iterations 0140 unsigned int maxIterations{30}; 0141 0142 /// Max distance to linearization point allowed 0143 /// without relinearization 0144 double maxDistToLinPoint{0.5}; 0145 0146 /// Minimum track weight needed for track to be considered 0147 double minWeight{0.0001}; 0148 0149 /// Max relative shift of vertex during one iteration 0150 double maxRelativeShift{0.01}; 0151 0152 /// Do smoothing after multivertex fit 0153 bool doSmoothing{false}; 0154 0155 /// Use time information when calculating the vertex compatibility 0156 bool useTime{false}; 0157 0158 /// Function to extract parameters from InputTrack 0159 InputTrack::Extractor extractParameters; 0160 0161 /// TrackLinearizer 0162 TrackLinearizer trackLinearizer; 0163 }; 0164 0165 /// @brief Constructor for user-defined InputTrack_t type != 0166 /// BoundTrackParameters 0167 /// 0168 /// @param cfg Configuration object 0169 /// object 0170 /// @param logger The logging instance 0171 explicit AdaptiveMultiVertexFitter( 0172 Config cfg, std::unique_ptr<const Logger> logger = getDefaultLogger( 0173 "AdaptiveMultiVertexFitter", Logging::INFO)); 0174 0175 /// Move constructor 0176 /// @param other The fitter to move from 0177 AdaptiveMultiVertexFitter(AdaptiveMultiVertexFitter&& other) noexcept = 0178 default; 0179 0180 /// @brief Adds a new vertex to an existing multi-vertex fit. 0181 /// 1. The 3D impact parameters are calculated for all tracks associated 0182 /// with newVertex. 0183 /// 2. A list of all vertices that are connected with newVertex via shared 0184 /// tracks is created. It also considers indirect connections (e.g., vertex A 0185 /// which shares a track with vertex B which, in turn, shares a track with 0186 /// newVertex). 0187 /// 3. The multivertex fit is performed for all vertices on said list. 0188 /// 0189 /// @param problem The multi-vertex fit problem 0190 /// @param newVertices Vertex to be added to fit 0191 /// @param vertexingOptions Vertexing options 0192 /// @param cache Fitter cache 0193 /// 0194 /// @return Result<void> object 0195 Result<void> addVtxToFit(VertexFitProblem& problem, 0196 const std::vector<Vertex*>& newVertices, 0197 const VertexingOptions& vertexingOptions, 0198 Cache& cache) const; 0199 0200 /// @brief Performs a simultaneous fit of all vertices in 0201 /// problem.vertices 0202 /// 0203 /// @param problem The multi-vertex fit problem 0204 /// @param vertexingOptions Vertexing options 0205 /// @param cache Fitter cache 0206 /// 0207 /// @return Result<void> object 0208 Result<void> fit(VertexFitProblem& problem, 0209 const VertexingOptions& vertexingOptions, 0210 Cache& cache) const; 0211 0212 // Backwards compatibility: the pre-split fitter state and the entry points 0213 // taking it. Both are adapters on top of the interface above, which they 0214 // reproduce exactly: the state is decomposed into a problem and a cache on 0215 // the way in and recomposed from them on the way out. 0216 // 0217 // Only the entry points carry the deprecation attribute. The types are 0218 // documented as deprecated but not attributed, so that naming them in the 0219 // adapter's own declarations does not warn -- a caller reaching the legacy 0220 // interface has to go through fit() or addVtxToFit() anyway. 0221 0222 /// @brief The fitter state 0223 /// 0224 /// @deprecated Split into @c VertexFitProblem, which describes the vertices 0225 /// to be fitted and is owned by the caller, and @c Cache, which holds the 0226 /// fitter's scratch data. Construct those two separately and use the 0227 /// corresponding @c fit and @c addVtxToFit overloads instead. 0228 struct State { 0229 /// Constructor for multi-vertex fitter state 0230 /// @param field Magnetic field provider for track extrapolation 0231 /// @param magContext Magnetic field context for field evaluations 0232 State(const MagneticFieldProvider& field, 0233 const MagneticFieldContext& magContext) 0234 : ipState{field.makeCache(magContext)}, 0235 fieldCache(field.makeCache(magContext)) {} 0236 0237 /// Vertex collection to be fitted 0238 std::vector<Vertex*> vertexCollection; 0239 0240 /// Annealing state for thermodynamic track weighting 0241 AnnealingUtility::State annealingState; 0242 0243 /// Impact point estimator state for track parameter calculations 0244 ImpactPointEstimator::State ipState; 0245 0246 /// Magnetic field cache for field evaluations during fitting 0247 MagneticFieldProvider::Cache fieldCache; 0248 0249 /// Map storing vertex information for each vertex in the fit 0250 std::map<Vertex*, VertexInfo> vtxInfoMap; 0251 0252 /// Multimap connecting tracks to their associated vertices 0253 std::multimap<InputTrack, Vertex*> trackToVerticesMultiMap; 0254 0255 /// Map storing track-at-vertex information for each track-vertex pair 0256 std::map<std::pair<InputTrack, Vertex*>, TrackAtVertex> tracksAtVerticesMap; 0257 0258 /// Adds a vertex to trackToVerticesMultiMap 0259 /// @param vtx Vertex to add to the multimap with its associated tracks 0260 void addVertexToMultiMap(Vertex& vtx) { 0261 for (auto trk : vtxInfoMap[&vtx].trackLinks) { 0262 trackToVerticesMultiMap.emplace(trk, &vtx); 0263 } 0264 } 0265 0266 /// Removes a vertex from trackToVerticesMultiMap 0267 /// @param vtx Vertex to remove from the multimap along with its track associations 0268 void removeVertexFromMultiMap(const Vertex& vtx) { 0269 for (auto iter = trackToVerticesMultiMap.begin(); 0270 iter != trackToVerticesMultiMap.end();) { 0271 if (iter->second == &vtx) { 0272 iter = trackToVerticesMultiMap.erase(iter); 0273 } else { 0274 ++iter; 0275 } 0276 } 0277 } 0278 0279 /// Remove a vertex from the vertex collection 0280 /// @param vtxToRemove Vertex to remove from the collection 0281 /// @param logger Logger for diagnostic messages 0282 /// @return Result indicating success or failure of the removal operation 0283 Result<void> removeVertexFromCollection(Vertex& vtxToRemove, 0284 const Logger& logger) { 0285 auto it = std::ranges::find(vertexCollection, &vtxToRemove); 0286 // Check if the value was found before erasing 0287 if (it == vertexCollection.end()) { 0288 ACTS_ERROR("vtxToRemove is not part of vertexCollection."); 0289 return VertexingError::ElementNotFound; 0290 } 0291 // Erase the element if found 0292 vertexCollection.erase(it); 0293 return {}; 0294 } 0295 }; 0296 0297 /// @brief Adds a new vertex to an existing multi-vertex fit 0298 /// 0299 /// @deprecated Use the overload taking a @c VertexFitProblem and a @c Cache 0300 /// 0301 /// @param state Fitter state 0302 /// @param newVertices Vertex to be added to fit 0303 /// @param vertexingOptions Vertexing options 0304 /// 0305 /// @return Result<void> object 0306 [[deprecated( 0307 "Use addVtxToFit(VertexFitProblem&, const std::vector<Vertex*>&, const " 0308 "VertexingOptions&, Cache&)")]] 0309 Result<void> addVtxToFit(State& state, 0310 const std::vector<Vertex*>& newVertices, 0311 const VertexingOptions& vertexingOptions) const; 0312 0313 /// @brief Performs a simultaneous fit of all vertices in 0314 /// state.vertexCollection 0315 /// 0316 /// @deprecated Use the overload taking a @c VertexFitProblem and a @c Cache 0317 /// 0318 /// @param state Fitter state 0319 /// @param vertexingOptions Vertexing options 0320 /// 0321 /// @return Result<void> object 0322 [[deprecated("Use fit(VertexFitProblem&, const VertexingOptions&, Cache&)")]] 0323 Result<void> fit(State& state, 0324 const VertexingOptions& vertexingOptions) const; 0325 0326 private: 0327 /// Configuration object 0328 const Config m_cfg; 0329 0330 /// Logging instance 0331 std::unique_ptr<const Logger> m_logger; 0332 0333 /// Private access to logging instance 0334 const Logger& logger() const { return *m_logger; } 0335 0336 /// @brief Tests if vertex is already in list of vertices or not 0337 /// 0338 /// @param vtx Vertex to test 0339 /// @param verticesVec Vector of vertices to search 0340 /// 0341 /// @return True if vtx is already in verticesVec 0342 bool isAlreadyInList(Vertex* vtx, 0343 const std::vector<Vertex*>& verticesVec) const; 0344 0345 /// @brief Returns the scratch data for @p vtx, creating it on first access 0346 /// 0347 /// A newly created entry is seeded with the vertex's seed position, so that 0348 /// the first iteration measures the distance to the seed rather than to the 0349 /// origin. 0350 /// 0351 /// @param problem The multi-vertex fit problem 0352 /// @param vtx Vertex object 0353 /// @param cache Fitter cache 0354 /// 0355 /// @return Reference to the scratch data of @p vtx 0356 static VertexScratch& scratchFor(const VertexFitProblem& problem, Vertex* vtx, 0357 Cache& cache); 0358 0359 /// @brief 1) Calls ImpactPointEstimator::estimate3DImpactParameters 0360 /// for all tracks that are associated with vtx (i.e., all elements 0361 /// of the trackLinks vector in the candidate of vtx). 0362 /// 2) Saves the 3D impact parameters in the scratch data of vtx. 0363 /// 0364 /// @param problem The multi-vertex fit problem 0365 /// @param vtx Vertex object 0366 /// @param vertexingOptions Vertexing options 0367 /// @param cache Fitter cache 0368 Result<void> prepareVertexForFit(const VertexFitProblem& problem, Vertex* vtx, 0369 const VertexingOptions& vertexingOptions, 0370 Cache& cache) const; 0371 0372 /// @brief Sets the vertexCompatibility for all TrackAtVertex objects 0373 /// at the current vertex 0374 /// 0375 /// @param problem The multi-vertex fit problem 0376 /// @param currentVtx Current vertex 0377 /// @param vertexingOptions Vertexing options 0378 /// @param cache Fitter cache 0379 Result<void> setAllVertexCompatibilities( 0380 VertexFitProblem& problem, Vertex* currentVtx, 0381 const VertexingOptions& vertexingOptions, Cache& cache) const; 0382 0383 /// @brief Sets weights to the track according to Eq.(5.46) in Ref.(1) 0384 /// and updates the vertices by calling the VertexUpdater 0385 /// 0386 /// @param problem The multi-vertex fit problem 0387 /// @param vertexingOptions Vertexing options 0388 /// @param cache Fitter cache 0389 Result<void> setWeightsAndUpdate(VertexFitProblem& problem, 0390 const VertexingOptions& vertexingOptions, 0391 Cache& cache) const; 0392 0393 /// @brief Collects the compatibility values of the track `trk` 0394 /// wrt to all of its associated vertices 0395 /// 0396 /// @param problem The multi-vertex fit problem 0397 /// @param trk Track 0398 /// 0399 /// @return Vector of compatibility values 0400 std::vector<double> collectTrackToVertexCompatibilities( 0401 const VertexFitProblem& problem, const InputTrack& trk) const; 0402 0403 /// @brief Determines if any vertex position has shifted more than 0404 /// m_cfg.maxRelativeShift in the last iteration 0405 /// 0406 /// @param problem The multi-vertex fit problem 0407 /// @param cache Fitter cache 0408 /// 0409 /// @return False if at least one shift was larger than maxRelativeShift 0410 bool checkSmallShift(const VertexFitProblem& problem, Cache& cache) const; 0411 0412 /// @brief Updates tracks for current vertex with knowledge 0413 /// of current vertex position 0414 /// 0415 /// @param problem The multi-vertex fit problem 0416 void doVertexSmoothing(VertexFitProblem& problem) const; 0417 0418 /// @brief Logs vertices in problem.vertices and associated tracks 0419 /// 0420 /// @param problem The multi-vertex fit problem 0421 /// @param geoContext Geometry context 0422 /// @param cache Fitter cache 0423 void logDebugData(const VertexFitProblem& problem, 0424 const GeometryContext& geoContext, Cache& cache) const; 0425 0426 /// @brief Moves the contents of a deprecated state into a problem and a cache 0427 /// 0428 /// @param state Fitter state to take the contents from 0429 /// @param[out] problem The multi-vertex fit problem 0430 /// @param[out] cache Fitter cache 0431 static void decomposeState(State& state, VertexFitProblem& problem, 0432 Cache& cache); 0433 0434 /// @brief Moves a problem and a cache back into a deprecated state 0435 /// 0436 /// @param[out] state Fitter state to write the contents to 0437 /// @param problem The multi-vertex fit problem 0438 /// @param cache Fitter cache 0439 static void recomposeState(State& state, VertexFitProblem& problem, 0440 Cache& cache); 0441 }; 0442 0443 } // namespace Acts
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|