Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2026-07-16 08:07:25

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/AmbiguityResolution/AmbiguityNetworkConcept.hpp"
0012 #include "Acts/Utilities/Logger.hpp"
0013 
0014 #include <cstddef>
0015 #include <map>
0016 #include <memory>
0017 #include <string>
0018 #include <vector>
0019 
0020 namespace Acts {
0021 
0022 /// Generic implementation of the machine learning ambiguity resolution
0023 /// Contains method for data preparations
0024 template <AmbiguityNetworkConcept AmbiguityNetwork>
0025 class AmbiguityResolutionML {
0026  public:
0027   struct Config {
0028     /// Path to the model file for the duplicate neural network
0029     std::string inputDuplicateNN = "";
0030     /// Minimum number of measurement to form a track.
0031     std::size_t nMeasurementsMin = 7;
0032   };
0033   /// Construct the ambiguity resolution algorithm.
0034   ///
0035   /// @param cfg is the algorithm configuration
0036   /// @param logger is the logging instance
0037   explicit AmbiguityResolutionML(const Config& cfg,
0038                                  std::unique_ptr<const Logger> logger =
0039                                      getDefaultLogger("AmbiguityResolutionML",
0040                                                       Logging::INFO))
0041       : m_cfg{cfg},
0042         m_duplicateClassifier(m_cfg.inputDuplicateNN.c_str()),
0043         m_logger{std::move(logger)} {}
0044 
0045   /// Associate the hits to the tracks
0046   ///
0047   /// This algorithm performs the mapping of hits ID to track ID. Our final goal
0048   /// is too loop over all the tracks (and their associated hits) by order of
0049   /// decreasing number hits for this we use a multimap where the key is the
0050   /// number of hits as this will automatically perform the sorting.
0051   ///
0052   /// @param tracks is the input track container
0053   /// @param sourceLinkHash is the hash function for the source link, will be used to associate to tracks
0054   /// @param sourceLinkEquality is the equality function for the source link used used to associated hits to tracks
0055   /// @return an ordered list containing pairs of track ID and associated measurement ID
0056   template <TrackContainerFrontend track_container_t,
0057             typename source_link_hash_t, typename source_link_equality_t>
0058   std::multimap<int, std::pair<std::size_t, std::vector<std::size_t>>>
0059   mapTrackHits(const track_container_t& tracks,
0060                const source_link_hash_t& sourceLinkHash,
0061                const source_link_equality_t& sourceLinkEquality) const {
0062     // A map to store (and generate) the measurement index for each source link
0063     auto measurementIndexMap =
0064         std::unordered_map<SourceLink, std::size_t, source_link_hash_t,
0065                            source_link_equality_t>(0, sourceLinkHash,
0066                                                    sourceLinkEquality);
0067 
0068     // A map to store the track Id and their associated measurements ID, a
0069     // multimap is used to automatically sort the tracks by the number of
0070     // measurements
0071     std::multimap<int, std::pair<std::size_t, std::vector<std::size_t>>>
0072         trackMap;
0073     std::size_t trackIndex = 0;
0074     std::vector<std::size_t> measurements;
0075     // Loop over all the trajectories in the events
0076     for (const auto& track : tracks) {
0077       // Kick out tracks that do not fulfill our initial requirements
0078       if (track.nMeasurements() < m_cfg.nMeasurementsMin) {
0079         continue;
0080       }
0081       measurements.clear();
0082       for (auto ts : track.trackStatesReversed()) {
0083         if (ts.typeFlags().isMeasurement()) {
0084           SourceLink sourceLink = ts.getUncalibratedSourceLink();
0085           // assign a new measurement index if the source link was not seen yet
0086           auto emplace = measurementIndexMap.try_emplace(
0087               sourceLink, measurementIndexMap.size());
0088           measurements.push_back(emplace.first->second);
0089         }
0090       }
0091       trackMap.emplace(track.nMeasurements(),
0092                        std::make_pair(trackIndex, measurements));
0093       ++trackIndex;
0094     }
0095     return trackMap;
0096   }
0097 
0098   /// Select the track associated with each cluster
0099   ///
0100   /// In this algorithm the call the neural network to score the tracks and then
0101   /// select the track with the highest score in each cluster
0102   ///
0103   /// @param clusters is a map of clusters, each cluster correspond to a vector of track ID
0104   /// @param tracks is the input track container
0105   /// @return a vector of trackID corresponding tho the good tracks
0106   template <TrackContainerFrontend track_container_t>
0107   std::vector<std::size_t> solveAmbiguity(
0108       std::unordered_map<std::size_t, std::vector<std::size_t>>& clusters,
0109       const track_container_t& tracks) const {
0110     std::vector<std::vector<float>> outputTensor =
0111         m_duplicateClassifier.inferScores(clusters, tracks);
0112     std::vector<std::size_t> goodTracks =
0113         m_duplicateClassifier.trackSelection(clusters, outputTensor);
0114 
0115     return goodTracks;
0116   }
0117 
0118  private:
0119   // Configuration
0120   Config m_cfg;
0121 
0122   // The neural network for duplicate classification, the network
0123   // implementation is chosen with the AmbiguityNetwork template parameter
0124   AmbiguityNetwork m_duplicateClassifier;
0125 
0126   /// Logging instance
0127   std::unique_ptr<const Logger> m_logger = nullptr;
0128 
0129   /// Private access to logging instance
0130   const Logger& logger() const { return *m_logger; }
0131 };
0132 
0133 }  // namespace Acts