Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-11-29 09:17:20

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   /// Type alias for path seed consisting of track parameters and source links
0047   using PathSeed = std::pair<BoundTrackParameters, std::vector<SourceLink>>;
0048 
0049   /// @brief Delegate to estimate the IP parameters
0050   /// and the momentum direction at the reference tracking layer
0051   ///
0052   /// @arg Geometry context to use
0053   /// @arg Pivot source link
0054   ///
0055   /// @return Pair of the track parameters at the IP and
0056   /// the reference tracking layer
0057   using TrackEstimator =
0058       Delegate<std::pair<BoundTrackParameters, BoundTrackParameters>(
0059           const GeometryContext&, const SourceLink&)>;
0060 
0061   /// @brief Delegate to find the intersections for the given pivot
0062   /// source link
0063   ///
0064   /// @arg The geometry context to use
0065   /// @arg Track parameters at the reference tracking layer
0066   ///
0067   /// @return Vector of pairs of the geometry identifier
0068   /// and the local intersection point
0069   using IntersectionLookup =
0070       Delegate<std::vector<std::pair<GeometryIdentifier, Vector2>>(
0071           const GeometryContext&, const BoundTrackParameters&)>;
0072 
0073   /// @brief Delegate to provide the path width around
0074   /// the intersection point to pull the source links
0075   /// from the grid
0076   ///
0077   /// @arg The geometry context to use
0078   /// @arg The geometry identifier to use if the
0079   /// path width is varied across different tracking layers
0080   ///
0081   /// @return The path width in the bin0 and bin1 direction
0082   /// defined with respect to the surface normal
0083   using PathWidthLookup = Delegate<std::pair<double, double>(
0084       const GeometryContext&, const GeometryIdentifier&)>;
0085 
0086   /// @brief The nested configuration struct
0087   struct Config {
0088     /// Parameters estimator
0089     TrackEstimator trackEstimator;
0090     /// Intersection finder
0091     IntersectionLookup intersectionFinder;
0092     /// Path width provider
0093     PathWidthLookup pathWidthProvider;
0094     /// Reference layer IDs
0095     std::vector<GeometryIdentifier> refLayerIds;
0096   };
0097 
0098   /// @brief Constructor
0099   /// @param config Configuration for the path seeder
0100   explicit PathSeeder(const Config& config) : m_cfg(config) {};
0101 
0102   /// @brief Destructor
0103   ~PathSeeder() = default;
0104 
0105   /// @brief Extract the IP parameters and
0106   /// sort the source links into the seeds
0107   ///
0108   /// @param gctx The geometry context
0109   /// @param sourceLinkGridLookup The lookup table for the source links
0110   /// @param seedCollection The collection of seeds to fill
0111   template <Acts::detail::SourceLinkGrid grid_t, typename container_t>
0112   void findSeeds(const GeometryContext& gctx,
0113                  const std::unordered_map<GeometryIdentifier, grid_t>&
0114                      sourceLinkGridLookup,
0115                  container_t& seedCollection) const {
0116     // Create the seeds
0117     for (auto& refGeoId : m_cfg.refLayerIds) {
0118       auto refGrid = sourceLinkGridLookup.at(refGeoId);
0119 
0120       for (auto it = refGrid.begin(); it != refGrid.end(); it++) {
0121         std::vector<SourceLink> pivotSourceLinks = *it;
0122 
0123         for (const auto& pivot : pivotSourceLinks) {
0124           // Get the IP parameters
0125           auto [ipParameters, refLayerParameters] =
0126               m_cfg.trackEstimator(gctx, pivot);
0127 
0128           // Intersect with the surfaces
0129           std::vector<std::pair<GeometryIdentifier, Vector2>> intersections =
0130               m_cfg.intersectionFinder(gctx, refLayerParameters);
0131 
0132           // Continue if no intersections
0133           if (intersections.empty()) {
0134             continue;
0135           }
0136 
0137           // Iterate over the intersections
0138           // and get the source links
0139           // in the subsequent layers
0140           std::vector<SourceLink> seedSourceLinks;
0141           for (auto& [geoId, refPoint] : intersections) {
0142             // Get the path width
0143             auto [pathWidth0, pathWidth1] =
0144                 m_cfg.pathWidthProvider(gctx, geoId);
0145 
0146             // Get the bounds of the path
0147             double top0 = refPoint[0] + pathWidth0;
0148             double bot0 = refPoint[0] - pathWidth0;
0149             double top1 = refPoint[1] + pathWidth1;
0150             double bot1 = refPoint[1] - pathWidth1;
0151 
0152             // Get the lookup table for the source links
0153             auto grid = sourceLinkGridLookup.at(geoId);
0154 
0155             // Get the range of bins to search for source links
0156             auto botLeftBin = grid.localBinsFromPosition(Vector2(bot0, bot1));
0157             auto topRightBin = grid.localBinsFromPosition(Vector2(top0, top1));
0158 
0159             // Get the source links from the lookup table
0160             // by iterating over the bin ranges
0161             auto currentBin = botLeftBin;
0162             while (currentBin.at(1) <= topRightBin.at(1)) {
0163               while (currentBin.at(0) <= topRightBin.at(0)) {
0164                 auto sourceLinksToAdd = grid.atLocalBins(currentBin);
0165 
0166                 seedSourceLinks.insert(seedSourceLinks.end(),
0167                                        sourceLinksToAdd.begin(),
0168                                        sourceLinksToAdd.end());
0169 
0170                 currentBin.at(0)++;
0171               }
0172               currentBin.at(1)++;
0173               currentBin.at(0) = botLeftBin.at(0);
0174             }
0175           }
0176           PathSeed seed = {ipParameters, seedSourceLinks};
0177 
0178           // Add the seed to the collection
0179           Acts::detail::pushBackOrInsertAtEnd(seedCollection, seed);
0180         }
0181       }
0182     }
0183   }
0184 
0185  private:
0186   Config m_cfg;
0187 };
0188 
0189 }  // namespace Acts