Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-14 08:10:41

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/EventData/SourceLink.hpp"
0012 #include "Acts/EventData/TrackParameters.hpp"
0013 #include "Acts/Seeding/detail/UtilityFunctions.hpp"
0014 #include "Acts/Utilities/Delegate.hpp"
0015 #include "Acts/Utilities/GridIterator.hpp"
0016 
0017 namespace Acts {
0018 
0019 /// @brief Seeding algorigthm that extracts
0020 /// the IP parameters and sorts the source links
0021 /// into possible track candidates
0022 ///
0023 /// The algorithm to convert the given source links
0024 /// into seeds -- pairs of IP parameters and the corresponding
0025 /// source links -- as follows: First the source links
0026 /// are sorted into a user-defined grid. Then, iteration over the source links
0027 /// is performed. If a source link is attached to a surface that is
0028 /// in the reference tracking layer, as defined by the user, the IP parameters
0029 /// are estimated and the tracking layers are intersected to construct the
0030 /// core of the "Path". The source links in the subsequent layers are then
0031 /// added to the seed if they lie within the path width of the core.
0032 /// Both the list of source links and the IP parameters are stored in the seed
0033 /// struct.
0034 ///
0035 /// @tparam axis_t Type of the axis to bin
0036 /// the source links
0037 ///
0038 /// @note The algorithm is designed to be used in the
0039 /// context of a telescope-style geometry. The surfaces
0040 /// are assumed to be planar.
0041 ///
0042 /// @note Handling of the rotated surfaces has to happen
0043 /// in the user-defined delegate functions.
0044 class PathSeeder {
0045  public:
0046   using PathSeed = std::pair<BoundTrackParameters, std::vector<SourceLink>>;
0047 
0048   /// @brief Delegate to estimate the IP parameters
0049   /// and the momentum direction at the reference tracking layer
0050   ///
0051   /// @arg Geometry context to use
0052   /// @arg Pivot source link
0053   ///
0054   /// @return Pair of the track parameters at the IP and
0055   /// the reference tracking layer
0056   using TrackEstimator =
0057       Delegate<std::pair<BoundTrackParameters, BoundTrackParameters>(
0058           const GeometryContext&, const SourceLink&)>;
0059 
0060   /// @brief Delegate to find the intersections for the given pivot
0061   /// source link
0062   ///
0063   /// @arg The geometry context to use
0064   /// @arg Track parameters at the reference tracking layer
0065   ///
0066   /// @return Vector of pairs of the geometry identifier
0067   /// and the local intersection point
0068   using IntersectionLookup =
0069       Delegate<std::vector<std::pair<GeometryIdentifier, Vector2>>(
0070           const GeometryContext&, const BoundTrackParameters&)>;
0071 
0072   /// @brief Delegate to provide the path width around
0073   /// the intersection point to pull the source links
0074   /// from the grid
0075   ///
0076   /// @arg The geometry context to use
0077   /// @arg The geometry identifier to use if the
0078   /// path width is varied across different tracking layers
0079   ///
0080   /// @return The path width in the bin0 and bin1 direction
0081   /// defined with respect to the surface normal
0082   using PathWidthLookup = Delegate<std::pair<double, double>(
0083       const GeometryContext&, const GeometryIdentifier&)>;
0084 
0085   /// @brief The nested configuration struct
0086   struct Config {
0087     /// Parameters estimator
0088     TrackEstimator trackEstimator;
0089     /// Intersection finder
0090     IntersectionLookup intersectionFinder;
0091     /// Path width provider
0092     PathWidthLookup pathWidthProvider;
0093     /// Reference layer IDs
0094     std::vector<GeometryIdentifier> refLayerIds;
0095   };
0096 
0097   /// @brief Constructor
0098   explicit PathSeeder(const Config& config) : m_cfg(config) {};
0099 
0100   /// @brief Destructor
0101   ~PathSeeder() = default;
0102 
0103   /// @brief Extract the IP parameters and
0104   /// sort the source links into the seeds
0105   ///
0106   /// @param gctx The geometry context
0107   /// @param sourceLinkGridLookup The lookup table for the source links
0108   /// @param seedCollection The collection of seeds to fill
0109   template <Acts::detail::SourceLinkGrid grid_t, typename container_t>
0110   void findSeeds(const GeometryContext& gctx,
0111                  const std::unordered_map<GeometryIdentifier, grid_t>&
0112                      sourceLinkGridLookup,
0113                  container_t& seedCollection) const {
0114     // Create the seeds
0115     for (auto& refGeoId : m_cfg.refLayerIds) {
0116       auto refGrid = sourceLinkGridLookup.at(refGeoId);
0117 
0118       for (auto it = refGrid.begin(); it != refGrid.end(); it++) {
0119         std::vector<SourceLink> pivotSourceLinks = *it;
0120 
0121         for (const auto& pivot : pivotSourceLinks) {
0122           // Get the IP parameters
0123           auto [ipParameters, refLayerParameters] =
0124               m_cfg.trackEstimator(gctx, pivot);
0125 
0126           // Intersect with the surfaces
0127           std::vector<std::pair<GeometryIdentifier, Vector2>> intersections =
0128               m_cfg.intersectionFinder(gctx, refLayerParameters);
0129 
0130           // Continue if no intersections
0131           if (intersections.empty()) {
0132             continue;
0133           }
0134 
0135           // Iterate over the intersections
0136           // and get the source links
0137           // in the subsequent layers
0138           std::vector<SourceLink> seedSourceLinks;
0139           for (auto& [geoId, refPoint] : intersections) {
0140             // Get the path width
0141             auto [pathWidth0, pathWidth1] =
0142                 m_cfg.pathWidthProvider(gctx, geoId);
0143 
0144             // Get the bounds of the path
0145             double top0 = refPoint[0] + pathWidth0;
0146             double bot0 = refPoint[0] - pathWidth0;
0147             double top1 = refPoint[1] + pathWidth1;
0148             double bot1 = refPoint[1] - pathWidth1;
0149 
0150             // Get the lookup table for the source links
0151             auto grid = sourceLinkGridLookup.at(geoId);
0152 
0153             // Get the range of bins to search for source links
0154             auto botLeftBin = grid.localBinsFromPosition(Vector2(bot0, bot1));
0155             auto topRightBin = grid.localBinsFromPosition(Vector2(top0, top1));
0156 
0157             // Get the source links from the lookup table
0158             // by iterating over the bin ranges
0159             auto currentBin = botLeftBin;
0160             while (currentBin.at(1) <= topRightBin.at(1)) {
0161               while (currentBin.at(0) <= topRightBin.at(0)) {
0162                 auto sourceLinksToAdd = grid.atLocalBins(currentBin);
0163 
0164                 seedSourceLinks.insert(seedSourceLinks.end(),
0165                                        sourceLinksToAdd.begin(),
0166                                        sourceLinksToAdd.end());
0167 
0168                 currentBin.at(0)++;
0169               }
0170               currentBin.at(1)++;
0171               currentBin.at(0) = botLeftBin.at(0);
0172             }
0173           }
0174           PathSeed seed = {ipParameters, seedSourceLinks};
0175 
0176           // Add the seed to the collection
0177           Acts::detail::pushBackOrInsertAtEnd(seedCollection, seed);
0178         }
0179       }
0180     }
0181   }
0182 
0183  private:
0184   Config m_cfg;
0185 };
0186 
0187 }  // namespace Acts