Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-27 08:32:54

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/Utilities/Helpers.hpp"
0012 #include "Acts/Utilities/IMultiAxis.hpp"
0013 
0014 #include <algorithm>
0015 
0016 namespace Acts {
0017 
0018 /// @brief Multi-dimensional binning defined by a product of one-dimensional
0019 /// axes
0020 ///
0021 /// This class stores a fixed set of concrete @c Axis objects in a tuple and
0022 /// implements the @c IMultiAxisXD interface for the resulting grid. The grid
0023 /// dimension and the concrete axis types (binning and boundary types) are
0024 /// fixed at compile time, while the @c IMultiAxis base allows handling
0025 /// different multi-axes through a common pointer. The grid index conventions
0026 /// (per-axis local bin indices starting at @c 1, under-/overflow bins at @c 0
0027 /// and <tt>nBins + 1</tt>, and flattened global bin indices including those
0028 /// under-/overflow bins) are described on @c IMultiAxis.
0029 ///
0030 /// @tparam Axes parameter pack of concrete @c Axis types spanning the grid
0031 template <AxisConcept... Axes>
0032 class MultiAxis : public IMultiAxisXD<sizeof...(Axes)> {
0033  public:
0034   /// Base interface for this multi-axis' dimension
0035   using Base = IMultiAxisXD<sizeof...(Axes)>;
0036 
0037   /// Dimension of the grid (number of axes)
0038   static constexpr std::size_t DIM = Base::DIM;
0039   /// Flattened global bin index across all axes
0040   using GlobalBin = typename Base::GlobalBin;
0041   /// Statically sized multi-index holding one local bin index per axis
0042   using LocalBins = typename Base::LocalBins;
0043   /// Statically sized point holding one coordinate per axis
0044   using Point = typename Base::Point;
0045 
0046   /// Tuple type holding the concrete axes
0047   using AxesTuple = std::tuple<Axes...>;
0048 
0049   /// Construct from a tuple of axes (copy)
0050   /// @param axes tuple of axes spanning the grid
0051   explicit MultiAxis(const std::tuple<Axes...>& axes) : m_axes(axes) {}
0052 
0053   /// Construct from a tuple of axes (move)
0054   /// @param axes tuple of axes spanning the grid
0055   explicit MultiAxis(std::tuple<Axes...>&& axes) : m_axes(std::move(axes)) {}
0056 
0057   /// Construct from individual axes (forwarding)
0058   /// @param axes axes spanning the grid
0059   explicit MultiAxis(Axes&&... axes) : m_axes(std::forward_as_tuple(axes...)) {}
0060 
0061   /// Construct from individual axes (copy)
0062   /// @param axes axes spanning the grid
0063   explicit MultiAxis(const Axes&... axes) : m_axes(std::tuple(axes...)) {}
0064 
0065   /// @copydoc IMultiAxisXD::getAxis(std::size_t) const
0066   const IAxis& getAxis(std::size_t i) const final {
0067     return template_switch_lambda<0, DIM - 1>(
0068         i, [this]<typename T>(T) -> const IAxis& {
0069           constexpr std::size_t iValue = T::value;
0070           return std::get<iValue>(m_axes);
0071         });
0072   }
0073 
0074   /// Get the tuple of concrete axes
0075   /// @return const reference to the stored axes tuple
0076   const AxesTuple& getAxesTuple() const { return m_axes; }
0077 
0078   /// @copydoc IMultiAxisXD::getNBins() const
0079   LocalBins getNBins() const final {
0080     return detail::MultiAxisHelper::getNBins(m_axes);
0081   }
0082 
0083   /// @copydoc IMultiAxisXD::getMinPoint() const
0084   Point getMinPoint() const final {
0085     return detail::MultiAxisHelper::getMin(m_axes);
0086   }
0087 
0088   /// @copydoc IMultiAxisXD::getMaxPoint() const
0089   Point getMaxPoint() const final {
0090     return detail::MultiAxisHelper::getMax(m_axes);
0091   }
0092 
0093   /// @copydoc IMultiAxisXD::isInside(const Point&) const
0094   bool isInside(const Point& point) const final {
0095     return detail::MultiAxisHelper::isInside(point, m_axes);
0096   }
0097 
0098   /// @copydoc IMultiAxisXD::getLowerLeftBinEdge(const LocalBins&) const
0099   Point getLowerLeftBinEdge(const LocalBins& localBins) const final {
0100     return detail::MultiAxisHelper::getLowerLeftBinEdge(localBins, m_axes);
0101   }
0102 
0103   /// @copydoc IMultiAxisXD::getUpperRightBinEdge(const LocalBins&) const
0104   Point getUpperRightBinEdge(const LocalBins& localBins) const final {
0105     return detail::MultiAxisHelper::getUpperRightBinEdge(localBins, m_axes);
0106   }
0107 
0108   /// @copydoc IMultiAxisXD::getBinCenter(const LocalBins&) const
0109   Point getBinCenter(const LocalBins& localBins) const final {
0110     return detail::MultiAxisHelper::getBinCenter(localBins, m_axes);
0111   }
0112 
0113   /// @copydoc IMultiAxisXD::getBinWidth(const LocalBins&) const
0114   Point getBinWidth(const LocalBins& localBins) const final {
0115     return detail::MultiAxisHelper::getBinWidth(localBins, m_axes);
0116   }
0117 
0118   /// @copydoc IMultiAxisXD::getGlobalBinFromPoint(const Point&) const
0119   GlobalBin getGlobalBinFromPoint(const Point& point) const final {
0120     return getGlobalBinFromLocalBins(getLocalBinsFromPoint(point));
0121   }
0122 
0123   /// @copydoc IMultiAxisXD::getGlobalBinFromLocalBins(const LocalBins&) const
0124   GlobalBin getGlobalBinFromLocalBins(const LocalBins& localBins) const final {
0125     return detail::MultiAxisHelper::getGlobalBinFromLocalBins(localBins,
0126                                                               m_axes);
0127   }
0128 
0129   /// @copydoc IMultiAxisXD::getLocalBinsFromPoint(const Point&) const
0130   LocalBins getLocalBinsFromPoint(const Point& point) const final {
0131     return detail::MultiAxisHelper::getLocalBinsFromPoint(point, m_axes);
0132   }
0133 
0134   /// Determine the multi-index of local bin indices for a given point, where
0135   /// the point is interpreted as being shifted by half a bin width along each
0136   /// axis.
0137   /// @param point coordinates to look up, one per axis
0138   /// @return local bin indices along each axis (may be under-/overflow bins)
0139   LocalBins getLocalBinsFromLowerLeftEdge(const Point& point) const {
0140     return detail::MultiAxisHelper::getLocalBinsFromLowerLeftEdge(
0141         point, m_axes.getAxesTuple());
0142   }
0143 
0144   /// @copydoc IMultiAxisXD::getLocalBinsFromGlobalBin(GlobalBin) const
0145   LocalBins getLocalBinsFromGlobalBin(GlobalBin globalBin) const final {
0146     return detail::MultiAxisHelper::getLocalBinsFromGlobalBin(globalBin,
0147                                                               m_axes);
0148   }
0149 
0150   /// @copydoc IMultiAxisXD::getNeighborHoodIndices(const LocalBins&, std::size_t) const
0151   detail::FlatNeighborHoodIndices<DIM> getNeighborHoodIndices(
0152       const LocalBins& localBins, std::size_t size = 1u) const final {
0153     return detail::MultiAxisHelper::neighborHoodIndices(localBins, size,
0154                                                         m_axes);
0155   }
0156 
0157   /// @copydoc IMultiAxisXD::getNeighborHoodIndices(const LocalBins&, const std::pair<int, int>&) const
0158   detail::FlatNeighborHoodIndices<DIM> getNeighborHoodIndices(
0159       const LocalBins& localBins, const std::pair<int, int>& size) const final {
0160     return detail::MultiAxisHelper::neighborHoodIndices(localBins, size,
0161                                                         m_axes);
0162   }
0163 
0164   /// @copydoc IMultiAxisXD::getNeighborHoodIndices(const LocalBins&, const std::array<std::pair<int, int>, DIM>&) const
0165   detail::FlatNeighborHoodIndices<DIM> getNeighborHoodIndices(
0166       const LocalBins& localBins,
0167       const std::array<std::pair<int, int>, DIM>& sizePerAxis) const final {
0168     return detail::MultiAxisHelper::neighborHoodIndices(localBins, sizePerAxis,
0169                                                         m_axes);
0170   }
0171 
0172   /// @copydoc IMultiAxisXD::getClosestPointsIndices(const LocalBins&) const
0173   detail::FlatNeighborHoodIndices<DIM> getClosestPointsIndices(
0174       const LocalBins& localBins) const override {
0175     return getNeighborHoodIndices(localBins, {0, 1});
0176   }
0177 
0178   /// @copydoc IMultiAxisXD::getClosestPointsIndices(const Point&) const
0179   detail::FlatNeighborHoodIndices<DIM> getClosestPointsIndices(
0180       const Point& point) const override {
0181     return getNeighborHoodIndices(getLocalBinsFromPoint(point), {0, 1});
0182   }
0183 
0184  private:
0185   /// tuple of concrete axes spanning the grid
0186   std::tuple<Axes...> m_axes;
0187 };
0188 
0189 }  // namespace Acts