Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-17 07:59:02

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/Definitions/Common.hpp"
0013 #include "Acts/Geometry/GeometryContext.hpp"
0014 #include "Acts/Geometry/Polyhedron.hpp"
0015 #include "Acts/Utilities/Enumerate.hpp"
0016 #include "Acts/Utilities/GridAccessHelpers.hpp"
0017 #include "Acts/Utilities/Helpers.hpp"
0018 #include "Acts/Utilities/IAxis.hpp"
0019 #include "Acts/Utilities/Logger.hpp"
0020 
0021 #include <algorithm>
0022 #include <array>
0023 #include <set>
0024 #include <string>
0025 #include <vector>
0026 
0027 namespace Acts {
0028 
0029 /// @brief Helper method to generate completely populated bin sequences
0030 /// that respect the boundary type of the axis
0031 ///
0032 /// @param minMaxBins estimated bin range (aka binning boundary box)
0033 /// @param expand the parameter to expand the view (extra window)
0034 /// @param nBins the maximum number of bins on this axis
0035 /// @param type the boundary type of the axis (for correct bin closure)
0036 ///
0037 /// @note for closed binning a span over half the bins flips direction
0038 ///
0039 /// @return a vector of bins to be filled
0040 std::vector<std::size_t> binSequence(std::array<std::size_t, 2u> minMaxBins,
0041                                      std::size_t expand, std::size_t nBins,
0042                                      Acts::AxisBoundaryType type);
0043 
0044 /// @brief Helper method to fill local bins given a set of query points
0045 /// bin in between the extra points are filled, and a possible expansion
0046 /// of the bin window can be chosen
0047 ///
0048 /// @tparam grid_type the type of the grid that determines locall binning
0049 ///
0050 /// @param grid the grid used for this
0051 /// @param queries the grid positions for the bin queries
0052 /// @param expansion are the additional (configured) number of bins to expand
0053 /// the view
0054 ///
0055 /// @return a set of unique indices
0056 template <typename grid_type>
0057 std::set<typename grid_type::index_t> localIndices(
0058     const grid_type& grid,
0059     const std::vector<typename grid_type::point_t>& queries,
0060     const std::vector<std::size_t>& expansion = {}) {
0061   // Return indices
0062   std::set<typename grid_type::index_t> lIndices;
0063 
0064   if (queries.empty()) {
0065     throw std::runtime_error("IndexedSurfaceGridFiller: no query point given.");
0066   }
0067 
0068   if (!expansion.empty() && expansion.size() != grid_type::DIM) {
0069     throw std::runtime_error(
0070         "IndexedSurfaceGridFiller: wrong dimension of bin expansion given.");
0071   }
0072 
0073   /// These are the axis bounds type parameters - for correct bin sequences
0074   std::array<Acts::AxisBoundaryType, grid_type::DIM> axisTypes{};
0075   std::array<std::size_t, grid_type::DIM> axisBins{};
0076   // Fill the axis types
0077   for (auto [ia, a] : enumerate(grid.axes())) {
0078     axisTypes[ia] = a->getBoundaryType();
0079     axisBins[ia] = a->getNBins();
0080   }
0081 
0082   // Initialize the bin ranges
0083   std::array<std::array<std::size_t, 2u>, grid_type::DIM> binRanges = {};
0084   for (auto& br : binRanges) {
0085     br[0u] = std::numeric_limits<std::size_t>::max();
0086     br[1u] = 0u;
0087   }
0088   // Bin range bounding box - estimated from the query points
0089   for (const auto& q : queries) {
0090     auto qbin = grid.localBinsFromPosition(q);
0091     for (std::size_t ib = 0; ib < grid_type::DIM; ++ib) {
0092       auto iqb = qbin[ib];
0093       binRanges[ib][0u] = std::min(iqb, binRanges[ib][0u]);
0094       binRanges[ib][1u] = std::max(iqb, binRanges[ib][1u]);
0095     }
0096   }
0097   // Fill the bins - 1D case
0098   if constexpr (grid_type::DIM == 1u) {
0099     // Take the expansion if available & generate the local bin sequence
0100     std::size_t expand = expansion.empty() ? 0u : expansion[0u];
0101     auto localBins0 =
0102         binSequence(binRanges[0u], expand, axisBins[0u], axisTypes[0u]);
0103     for (auto l0 : localBins0) {
0104       typename grid_type::index_t b;
0105       b[0u] = l0;
0106       lIndices.insert(b);
0107     }
0108   }
0109   // Fill the bins - 2D case
0110   if constexpr (grid_type::DIM == 2u) {
0111     // Take the expansion if available & generate the local bin sequence
0112     std::size_t expand = expansion.empty() ? 0u : expansion[0u];
0113     auto localBins0 =
0114         binSequence(binRanges[0u], expand, axisBins[0u], axisTypes[0u]);
0115     expand = expansion.empty() ? 0u : expansion[1u];
0116     auto localBins1 =
0117         binSequence(binRanges[1u], expand, axisBins[1u], axisTypes[1u]);
0118     for (auto l0 : localBins0) {
0119       for (auto l1 : localBins1) {
0120         typename grid_type::index_t b;
0121         b[0u] = l0;
0122         b[1u] = l1;
0123         lIndices.insert(b);
0124       }
0125     }
0126   }
0127   return lIndices;
0128 }
0129 
0130 /// @brief Helper method to screen output the local bins
0131 ///
0132 /// @tparam local_bin the type of the local bins
0133 ///
0134 /// @param lbins the local bins
0135 ///
0136 /// @return a string containing the local bins ordered in a set
0137 template <typename local_bin>
0138 std::string outputIndices(const std::set<local_bin>& lbins) {
0139   std::string rString;
0140   for (auto [ilb, lb] : Acts::enumerate(lbins)) {
0141     if (ilb == 0) {
0142       rString = "bins: [";
0143     } else {
0144       rString += ", [";
0145     }
0146     for (auto [ib, b] : Acts::enumerate(lb)) {
0147       if (ib != 0u) {
0148         rString += ", ";
0149       }
0150       rString += std::to_string(b);
0151     }
0152     rString += "]";
0153   }
0154   return rString;
0155 }
0156 
0157 /// A helper class that fills surfaces into predefined grids
0158 struct IndexGridFiller {
0159   /// Bin expansion where needed
0160   std::vector<std::size_t> binExpansion = {};
0161 
0162   /// Screen output logger
0163   std::unique_ptr<const Logger> oLogger =
0164       getDefaultLogger("IndexGridFiller", Logging::INFO);
0165 
0166   /// @brief This method takes a collection of objects and fills them
0167   /// into an index grid - it uses a reference generator for grid query points
0168   /// and then completes the bins in between.
0169   ///
0170   /// It also allows for expanding the fill view.
0171   ///
0172   /// @tparam index_grid the type of the index grid
0173   /// @tparam indexed_objects the type of the object container
0174   /// @tparam reference_generator the generator for reference points to be filled
0175   ///
0176   /// @param gctx the geometry context of the operation
0177   /// @param iGrid [in,out] the index grid object to be filled
0178   /// @param iObjects the object container to be indexed
0179   /// @param rGenerator the reference point generator for position queries
0180   /// @param aToAll the indices that are assigned to all bins
0181   ///
0182   /// @note as this is a Detector module, the objects within the indexed_objects container
0183   /// are assumed to have pointer semantics
0184   ///
0185   template <typename index_grid, typename indexed_objects,
0186             typename reference_generator>
0187   void fill(
0188       const GeometryContext& gctx, index_grid& iGrid,
0189       const indexed_objects& iObjects, const reference_generator& rGenerator,
0190       const typename index_grid::grid_type::value_type& aToAll = {}) const {
0191     // Loop over the surfaces to be filled
0192     for (auto [io, o] : enumerate(iObjects)) {
0193       // Exclude indices that should be handled differently
0194       if (rangeContainsValue(aToAll, io)) {
0195         continue;
0196       }
0197       // Get the reference positions
0198       auto refs = rGenerator.references(gctx, *o);
0199       std::vector<typename index_grid::grid_type::point_t> gridQueries;
0200       gridQueries.reserve(refs.size());
0201       for (const auto& ref : refs) {
0202         // Cast the transform according to the grid binning
0203         gridQueries.push_back(
0204             GridAccessHelpers::castPosition<decltype(iGrid.grid)>(
0205                 iGrid.transform * ref, iGrid.casts));
0206       }
0207       ACTS_DEBUG(gridQueries.size() << " reference points generated.");
0208       auto lIndices = localIndices<decltype(iGrid.grid)>(
0209           iGrid.grid, gridQueries, binExpansion);
0210       ACTS_DEBUG(lIndices.size() << " indices assigned.");
0211       if (oLogger->level() <= Logging::VERBOSE) {
0212         ACTS_VERBOSE("- list of indices: " << outputIndices(lIndices));
0213       }
0214       // Now fill the surface indices
0215       for (const auto& li : lIndices) {
0216         auto& bContent = iGrid.grid.atLocalBins(li);
0217         if (!rangeContainsValue(bContent, io)) {
0218           bContent.push_back(io);
0219         }
0220       }
0221     }
0222 
0223     // Assign the indices into all
0224     if (!aToAll.empty()) {
0225       assignToAll(iGrid, aToAll);
0226     }
0227   }
0228 
0229   /// Helper method to fill a dedicated list of indices into the entire grid
0230   ///
0231   /// This is useful if e.g. certain objects are to be attempted in any case,
0232   /// regardless of their binning.
0233   ///
0234   template <typename index_grid, typename indices>
0235   void assignToAll(index_grid& iGrid, const indices& idcs) const {
0236     for (std::size_t gi = 0; gi < iGrid.grid.size(true); ++gi) {
0237       auto& bContent = iGrid.grid.at(gi);
0238       for (const auto& io : idcs) {
0239         if (!rangeContainsValue(bContent, io)) {
0240           bContent.push_back(io);
0241         }
0242       }
0243     }
0244   }
0245 
0246   /// Access to the logger
0247   ///
0248   /// @return a const reference to the logger
0249   const Logger& logger() const { return (*oLogger); }
0250 };
0251 
0252 }  // namespace Acts