Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-15 08:11:44

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/Units.hpp"
0012 #include "Acts/EventData/TrackContainer.hpp"
0013 #include "Acts/EventData/TrackContainerFrontendConcept.hpp"
0014 #include "Acts/EventData/TrackProxyConcept.hpp"
0015 #include "Acts/EventData/TrackStateProxy.hpp"
0016 #include "Acts/Utilities/Delegate.hpp"
0017 #include "Acts/Utilities/Logger.hpp"
0018 
0019 #include <cstddef>
0020 #include <map>
0021 #include <memory>
0022 #include <numbers>
0023 #include <string>
0024 #include <tuple>
0025 #include <vector>
0026 
0027 #include <boost/container/flat_map.hpp>
0028 #include <boost/container/flat_set.hpp>
0029 
0030 namespace Acts {
0031 
0032 /// Generic implementation of the score based ambiguity resolution.
0033 /// The alhorithm is based on the following steps:
0034 /// 1) Compute the initial state of the tracks
0035 /// 2) Compute the score of each track
0036 /// 3) Removes hits that are not good enough for each track
0037 /// 4) Remove tracks that have a score below a certain threshold or not have
0038 /// enough hits
0039 /// 5) Remove tracks that are not good enough based on cuts Contains method for
0040 /// data preparations
0041 
0042 class ScoreBasedAmbiguityResolution {
0043  public:
0044   /// @brief Detector configuration struct : contains the configuration for each detector
0045   ///
0046   /// The configuration can be saved in a json file and loaded from there.
0047   ///
0048   struct DetectorConfig {
0049     int hitsScoreWeight = 0;
0050     int holesScoreWeight = 0;
0051     int outliersScoreWeight = 0;
0052     int otherScoreWeight = 0;
0053 
0054     // the eta bins for the detector
0055     std::vector<double> etaBins = {-5, 5};
0056 
0057     // the minimum number of hits for each eta bin
0058     std::vector<std::size_t> minHitsPerEta = {0};
0059 
0060     // the maximum number of holes for each eta bin
0061     std::vector<std::size_t> maxHolesPerEta = {0};
0062 
0063     // the maximum number of outliers for each eta bin
0064     std::vector<std::size_t> maxOutliersPerEta = {0};
0065 
0066     // the maximum number of shared hits for each eta bin
0067     std::vector<std::size_t> maxSharedHitsPerEta = {0};
0068 
0069     std::size_t maxHits = 0;
0070     std::size_t maxHoles = 0;
0071 
0072     /// if true, the shared hits are considered as bad hits for this detector
0073     bool sharedHitsFlag = false;
0074 
0075     std::size_t detectorId = 0;
0076 
0077     /// a list of values from  0 to 1, the higher number of hits, higher value
0078     /// in the list is multiplied to ambuiguity score applied only if
0079     /// useAmbiguityScoring is true
0080     std::vector<double> factorHits = {1.0};
0081 
0082     /// a list of values from  0 to 1, the higher number of holes, lower value
0083     /// in the list is multiplied to ambuiguity score applied only if
0084     /// useAmbiguityScoring is true
0085     std::vector<double> factorHoles = {1.0};
0086   };
0087 
0088   /// @brief  TrackFeatures struct : contains the features that are counted for each track.
0089   ///
0090   /// The trackFeatures is used to compute the score of each track
0091   struct TrackFeatures {
0092     std::size_t nHits = 0;
0093     std::size_t nHoles = 0;
0094     std::size_t nOutliers = 0;
0095     std::size_t nSharedHits = 0;
0096   };
0097 
0098   enum class TrackStateTypes : std::uint8_t {
0099     // A measurement not yet used in any other track
0100     UnsharedHit,
0101     // A measurement shared with another track
0102     SharedHit,
0103     // A hit that needs to be removed from the track
0104     RejectedHit,
0105     // An outlier, to be copied in case
0106     Outlier,
0107     // Other trackstate types to be copied in case
0108     OtherTrackStateType
0109   };
0110 
0111   /// @brief Configuration struct : contains the configuration for the ambiguity resolution.
0112   struct Config {
0113     std::map<std::size_t, std::size_t> volumeMap = {{0, 0}};
0114     std::vector<DetectorConfig> detectorConfigs;
0115     /// minimum score for any track
0116     double minScore = 0;
0117     /// minimum score for shared tracks
0118     double minScoreSharedTracks = 0;
0119     /// maximum number of shared tracks per measurement
0120     std::size_t maxSharedTracksPerMeasurement = 10;
0121     /// maximum number of shared hit per track
0122     std::size_t maxShared = 5;
0123     /// minimum number of unshared hits per track
0124     std::size_t minUnshared = 5;
0125 
0126     // if true, the ambiguity score is computed based on a different function.
0127     bool useAmbiguityScoring = false;
0128   };
0129 
0130   /// @brief Optionals struct: contains the optional cuts, weights and score to be applied.
0131   ///
0132   /// The default cuts and scoring has only a basic set of cuts and
0133   /// score-modifiers. For more flexibility users can define custom cuts and
0134   /// scores using this structure.
0135   template <TrackProxyConcept track_proxy_t>
0136   struct Optionals {
0137     using OptionalCuts = std::function<bool(const track_proxy_t&)>;
0138 
0139     using OptionalScoreModifier =
0140         std::function<void(const track_proxy_t&, double&)>;
0141 
0142     using OptionalHitSelection = std::function<void(
0143         const track_proxy_t&,
0144         const typename track_proxy_t::ConstTrackStateProxy&, TrackStateTypes&)>;
0145 
0146     std::vector<OptionalCuts> cuts = {};
0147     std::vector<OptionalScoreModifier> weights = {};
0148 
0149     /// applied only if useAmbiguityScoring is true
0150     std::vector<OptionalScoreModifier> scores = {};
0151     std::vector<OptionalHitSelection> hitSelections = {};
0152   };
0153 
0154   explicit ScoreBasedAmbiguityResolution(
0155       const Config& cfg,
0156       std::unique_ptr<const Logger> logger =
0157           getDefaultLogger("ScoreBasedAmbiguityResolution", Logging::INFO))
0158       : m_cfg{cfg}, m_logger{std::move(logger)} {}
0159 
0160   /// Compute the initial state of the tracks.
0161   ///
0162   /// @param tracks is the input track container
0163   /// @return trackFeaturesVectors is the trackFeatures map from detector ID to trackFeatures
0164   template <TrackContainerFrontend track_container_t>
0165   std::vector<std::vector<TrackFeatures>> computeInitialState(
0166       const track_container_t& tracks) const;
0167 
0168   /// Compute the score of each track.
0169   ///
0170   /// @param tracks is the input track container
0171   /// @param trackFeaturesVectors is the trackFeatures map from detector ID to trackFeatures
0172   /// @param optionals is the user defined optional cuts to be applied.
0173   /// @return a vector of scores for each track
0174   template <TrackContainerFrontend track_container_t>
0175   std::vector<double> simpleScore(
0176       const track_container_t& tracks,
0177       const std::vector<std::vector<TrackFeatures>>& trackFeaturesVectors,
0178       const Optionals<typename track_container_t::ConstTrackProxy>& optionals =
0179           {}) const;
0180 
0181   /// Compute the score of each track based on the ambiguity function.
0182   ///
0183   /// @param tracks is the input track container
0184   /// @param trackFeaturesVectors is the trackFeatures map from detector ID to trackFeatures
0185   /// @param optionals is the user defined optional cuts to be applied.
0186   /// @return a vector of scores for each track
0187   template <TrackContainerFrontend track_container_t>
0188   std::vector<double> ambiguityScore(
0189       const track_container_t& tracks,
0190       const std::vector<std::vector<TrackFeatures>>& trackFeaturesVectors,
0191       const Optionals<typename track_container_t::ConstTrackProxy>& optionals =
0192           {}) const;
0193 
0194   /// Rejects Tracks based on eta dependent cuts.
0195   ///
0196   /// @param detector is the detector configuration object
0197   /// @param trackFeatures is the trackFeatures object for a specific detector
0198   /// @param eta is the eta of the track
0199   /// @return true if the track is rejected, false otherwise
0200   bool etaBasedCuts(const DetectorConfig& detector,
0201                     const TrackFeatures& trackFeatures,
0202                     const double& eta) const;
0203 
0204   /// Remove hits that are not good enough for each track and removes tracks
0205   /// that have a score below a certain threshold or not enough hits.
0206   ///
0207   /// @brief Remove tracks that are not good enough based on cuts
0208   /// @param track is the input track
0209   /// @param trackScore is the score of each track
0210   /// @param measurementsPerTrack is the list of measurements for each track
0211   /// @param nTracksPerMeasurement is the number of tracks per measurement
0212   /// @param optionalHitSelections is the optional hit selections to be applied
0213   /// @return a vector of IDs of the tracks we want to keep
0214   template <TrackProxyConcept track_proxy_t>
0215   bool getCleanedOutTracks(
0216       const track_proxy_t& track, const double& trackScore,
0217       const std::vector<std::size_t>& measurementsPerTrack,
0218       const std::map<std::size_t, std::size_t>& nTracksPerMeasurement,
0219       const std::vector<std::function<
0220           void(const track_proxy_t&,
0221                const typename track_proxy_t::ConstTrackStateProxy&,
0222                TrackStateTypes&)>>& optionalHitSelections = {}) const;
0223 
0224   /// Remove tracks that are bad based on cuts and weighted scores.
0225   ///
0226   /// @brief Remove tracks that are not good enough
0227   /// @param tracks is the input track container
0228   /// @param sourceLinkHash is the  source links
0229   /// @param sourceLinkEquality is the equality function for the source links
0230   /// @param optionals are the optional cuts and score modifiers to be applied
0231   /// @return a vector of IDs of the tracks we want to keep
0232   template <TrackContainerFrontend track_container_t,
0233             typename source_link_hash_t, typename source_link_equality_t>
0234   std::vector<int> solveAmbiguity(
0235       const track_container_t& tracks, source_link_hash_t sourceLinkHash,
0236       source_link_equality_t sourceLinkEquality,
0237       const Optionals<typename track_container_t::ConstTrackProxy>& optionals =
0238           {}) const;
0239 
0240  private:
0241   Config m_cfg;
0242 
0243   /// Logging instance
0244   std::unique_ptr<const Logger> m_logger = nullptr;
0245 
0246   /// Private access to logging instance
0247   const Logger& logger() const;
0248 };
0249 
0250 }  // namespace Acts
0251 
0252 #include "Acts/AmbiguityResolution/ScoreBasedAmbiguityResolution.ipp"