Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-16 08:16:42

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/Algebra.hpp"
0012 #include "Acts/EventData/SpacePointContainer.hpp"
0013 #include "Acts/Seeding/BinnedGroup.hpp"
0014 #include "Acts/Utilities/Logger.hpp"
0015 #include "Acts/Utilities/RangeXD.hpp"
0016 
0017 #include <algorithm>
0018 #include <cstdint>
0019 #include <limits>
0020 #include <memory>
0021 #include <optional>
0022 #include <tuple>
0023 #include <vector>
0024 
0025 namespace Acts::detail {
0026 
0027 /// CRTP base class for the space point grids used in seeding. It owns the
0028 /// grid and the binned group and implements the functionality that is
0029 /// independent of the grid coordinate system. The derived class constructs
0030 /// the axes and hands the grid over via `initializeGrid`, and maps a space
0031 /// point onto the grid axes by implementing
0032 /// `insert(const ConstSpacePointProxy&)`, which is used by `extend`.
0033 /// @tparam derived_t The deriving space point grid class
0034 /// @tparam grid_t The underlying grid type
0035 template <typename derived_t, typename grid_t>
0036 class SpacePointGridBase {
0037  public:
0038   /// Space point index type used in the grid.
0039   using SpacePointIndex = std::uint32_t;
0040   /// Type alias for bin container holding space point indices
0041   using BinType = std::vector<SpacePointIndex>;
0042   /// Type of the underlying grid
0043   using GridType = grid_t;
0044   /// Type alias for binned group over the grid
0045   using BinnedGroupType = BinnedGroup<GridType>;
0046   /// Type of the grid axis along dimension @p index. Derived classes should
0047   /// spell their named axis aliases in terms of this, so that they cannot
0048   /// drift from the grid type.
0049   /// @tparam index The grid dimension to query
0050   template <std::size_t index>
0051   using AxisTypeAt =
0052       std::tuple_element_t<index, typename GridType::multi_axis_t::AxesTuple>;
0053 
0054   /// Clear the grid and drop all state. The object will behave like a newly
0055   /// constructed one.
0056   void clear() {
0057     for (std::size_t i = 0; i < grid().size(); ++i) {
0058       grid().at(i).clear();
0059     }
0060     m_counter = 0;
0061   }
0062 
0063   /// Get the bin index for a position on the grid axes.
0064   /// @param position The position of the space point on the grid axes
0065   /// @return The index of the bin in which the space point is located, or
0066   ///         `std::nullopt` if the space point is outside the grid bounds.
0067   std::optional<std::size_t> binIndex(const Vector3& position) const {
0068     if (!grid().multiAxis().isInside(position)) {
0069       return std::nullopt;
0070     }
0071     return grid().multiAxis().getGlobalBinFromPoint(position);
0072   }
0073 
0074   /// Insert a space point into the grid.
0075   /// @param index The index of the space point to insert
0076   /// @param position The position of the space point on the grid axes
0077   /// @return The index of the bin in which the space point was inserted, or
0078   ///         `std::nullopt` if the space point is outside the grid bounds.
0079   std::optional<std::size_t> insert(SpacePointIndex index,
0080                                     const Vector3& position) {
0081     const std::optional<std::size_t> gridIndex = binIndex(position);
0082     if (gridIndex.has_value()) {
0083       grid().at(*gridIndex).push_back(index);
0084       ++m_counter;
0085     }
0086     return gridIndex;
0087   }
0088 
0089   /// Fill the grid with space points from the container.
0090   /// @param spacePoints The space point container to fill the grid with
0091   void extend(const SpacePointContainer::ConstRange& spacePoints) {
0092     ACTS_VERBOSE("Inserting " << spacePoints.size()
0093                               << " space points to the grid");
0094 
0095     for (const ConstSpacePointProxy& sp : spacePoints) {
0096       derived().insert(sp);
0097     }
0098   }
0099 
0100   /// Mutable bin access by index.
0101   /// @param index The index of the bin to access
0102   /// @return Mutable reference to the bin at the specified index
0103   BinType& at(std::size_t index) { return grid().at(index); }
0104   /// Const bin access by index.
0105   /// @param index The index of the bin to access
0106   /// @return Const reference to the bin at the specified index
0107   const BinType& at(std::size_t index) const { return grid().at(index); }
0108 
0109   /// Mutable grid access.
0110   /// @return Mutable reference to the grid
0111   GridType& grid() { return *m_grid; }
0112   /// Const grid access.
0113   /// @return Const reference to the grid
0114   const GridType& grid() const { return *m_grid; }
0115 
0116   /// Access to the binned group.
0117   /// @return Reference to the binned group
0118   const BinnedGroupType& binnedGroup() const { return *m_binnedGroup; }
0119 
0120   /// Get the number of space points in the grid.
0121   /// @return The number of space points in the grid
0122   std::size_t numberOfSpacePoints() const { return m_counter; }
0123 
0124   /// Get the number of bins in the grid.
0125   /// @return The number of bins in the grid
0126   std::size_t numberOfBins() const { return grid().size(); }
0127 
0128  protected:
0129   /// Construct the base with a logger. The grid has to be handed over with
0130   /// `initializeGrid` afterwards.
0131   /// @param logger Logger instance for debugging output
0132   explicit SpacePointGridBase(std::unique_ptr<const Logger> logger)
0133       : m_logger(std::move(logger)) {}
0134 
0135   ~SpacePointGridBase() = default;
0136 
0137   /// Take ownership of the fully constructed grid and set up the binned
0138   /// group. Has to be called exactly once by the derived constructor.
0139   /// @param grid The grid to take ownership of
0140   /// @param bottomBinFinder Bin finder for bottom space points
0141   /// @param topBinFinder Bin finder for top space points
0142   /// @param navigation Navigation structure for the grid
0143   void initializeGrid(
0144       GridType&& grid, const GridBinFinder<GridType::DIM>& bottomBinFinder,
0145       const GridBinFinder<GridType::DIM>& topBinFinder,
0146       std::array<std::vector<std::size_t>, GridType::DIM> navigation) {
0147     m_binnedGroup.emplace(std::move(grid), bottomBinFinder, topBinFinder,
0148                           std::move(navigation));
0149     m_grid = &m_binnedGroup->grid();
0150   }
0151 
0152   /// Sort the space points in each bin by the given projection.
0153   /// @param spacePoints The space point container the stored indices refer to
0154   /// @param projection Callable mapping a space point proxy to its sort key
0155   template <typename projection_t>
0156   void sortBinsBy(const SpacePointContainer& spacePoints,
0157                   const projection_t& projection) {
0158     ACTS_VERBOSE("Sorting the grid");
0159 
0160     for (std::size_t i = 0; i < grid().size(); ++i) {
0161       BinType& bin = grid().at(i);
0162       std::ranges::sort(bin, {}, [&](SpacePointIndex spIndex) {
0163         return projection(spacePoints[spIndex]);
0164       });
0165     }
0166 
0167     ACTS_VERBOSE(
0168         "Number of space points inserted (within grid range): " << m_counter);
0169   }
0170 
0171   /// Compute the range of the projection values in the grid. This requires
0172   /// the bins to be sorted by the same projection with `sortBinsBy`.
0173   /// @param spacePoints The space point container the stored indices refer to
0174   /// @param projection Callable mapping a space point proxy to its sort key
0175   /// @return The range of projection values in the grid
0176   template <typename projection_t>
0177   Range1D<float> computeRange(const SpacePointContainer& spacePoints,
0178                               const projection_t& projection) const {
0179     float minRange = std::numeric_limits<float>::max();
0180     float maxRange = std::numeric_limits<float>::lowest();
0181     for (const BinType& bin : grid()) {
0182       if (bin.empty()) {
0183         continue;
0184       }
0185       auto first = spacePoints[bin.front()];
0186       auto last = spacePoints[bin.back()];
0187       minRange = std::min(projection(first), minRange);
0188       maxRange = std::max(projection(last), maxRange);
0189     }
0190     return {minRange, maxRange};
0191   }
0192 
0193   /// Access to the logger.
0194   /// @return Reference to the logger
0195   const Logger& logger() const { return *m_logger; }
0196 
0197  private:
0198   derived_t& derived() { return static_cast<derived_t&>(*this); }
0199 
0200   std::unique_ptr<const Logger> m_logger;
0201 
0202   GridType* m_grid{};
0203   std::optional<BinnedGroupType> m_binnedGroup;
0204 
0205   std::size_t m_counter{};
0206 };
0207 
0208 }  // namespace Acts::detail