![]() |
|
|||
File indexing completed on 2025-07-01 07:52:40
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/GridIterator.hpp" 0012 #include "Acts/Utilities/IAxis.hpp" 0013 #include "Acts/Utilities/Interpolation.hpp" 0014 #include "Acts/Utilities/TypeTag.hpp" 0015 #include "Acts/Utilities/detail/grid_helper.hpp" 0016 #include "Acts/Utilities/detail/interpolation_impl.hpp" 0017 0018 #include <any> 0019 #include <array> 0020 #include <tuple> 0021 #include <type_traits> 0022 #include <typeinfo> 0023 #include <utility> 0024 #include <vector> 0025 0026 #include <boost/container/small_vector.hpp> 0027 0028 namespace Acts { 0029 0030 namespace detail { 0031 0032 template <typename T, bool isConst> 0033 class AnyGridViewBase; 0034 0035 } // namespace detail 0036 0037 /// Base class for all grid types 0038 class IGrid { 0039 public: 0040 virtual ~IGrid() = default; 0041 0042 /// Get a dynamically sized vector of axis objects for inspection 0043 /// @return a vector of axis pointers 0044 virtual boost::container::small_vector<const IAxis*, 3> axes() const = 0; 0045 0046 /// @brief Get the number of dimensions of the grid 0047 /// @return The number of dimensions of the grid 0048 virtual std::size_t dimensions() const = 0; 0049 0050 /// @brief Get the type of the values stored in the grid 0051 /// @return The type of the values stored in the grid 0052 virtual std::type_info const& valueType() const = 0; 0053 0054 /// Type-erased interface to access the contents of the grid 0055 /// 0056 /// @note This interface has non-negligible runtime overhead due to packing 0057 /// and unpacking from/to @c std::any and the dynamically sized index and 0058 /// point types. **USE WITH CARE!** 0059 /// 0060 /// @{ 0061 using AnyIndexType = boost::container::small_vector<std::size_t, 3>; 0062 using AnyPointType = boost::container::small_vector<double, 3>; 0063 0064 /// @brief Get the lower left edge of a bin for a given set of indices 0065 /// @param indices The indices to get the lower left edge of the bin for 0066 /// @return The lower left edge of the bin 0067 virtual AnyPointType lowerLeftBinEdgeAny(AnyIndexType indices) const = 0; 0068 0069 /// @brief Get the upper right edge of a bin for a given set of indices 0070 /// @param indices The indices to get the upper right edge of the bin for 0071 /// @return The upper right edge of the bin 0072 virtual AnyPointType upperRightBinEdgeAny(AnyIndexType indices) const = 0; 0073 0074 /// @brief Get the center of a bin for a given set of indices 0075 /// @param indices The indices to get the center of the bin for 0076 /// @return The center of the bin 0077 virtual AnyPointType binCenterAny(AnyIndexType indices) const = 0; 0078 0079 /// @brief Get the number of local bins for a given set of indices 0080 /// @return The number of local bins 0081 virtual AnyIndexType numLocalBinsAny() const = 0; 0082 0083 /// @} 0084 0085 /// Helper to print out the grid 0086 /// @param os the output stream 0087 /// @param grid the grid to print 0088 /// @return the output stream 0089 friend std::ostream& operator<<(std::ostream& os, const IGrid& grid) { 0090 grid.toStream(os); 0091 return os; 0092 } 0093 0094 friend bool operator==(const IGrid& lhs, const IGrid& rhs) { 0095 auto lhsAxes = lhs.axes(); 0096 auto rhsAxes = rhs.axes(); 0097 return lhsAxes.size() == rhsAxes.size() && 0098 std::equal(lhsAxes.begin(), lhsAxes.end(), rhsAxes.begin(), 0099 [](const IAxis* a, const IAxis* b) { return *a == *b; }); 0100 } 0101 0102 protected: 0103 virtual void toStream(std::ostream& os) const = 0; 0104 0105 /// @brief Get the value of a bin for a given set of indices 0106 /// @param indices The indices to get the value of the bin for 0107 /// @return The value of the bin: the @c std::any contains a const pointer to 0108 /// the value 0109 virtual std::any atLocalBinsAny(AnyIndexType indices) const = 0; 0110 0111 /// @brief Get the value of a bin for a given set of indices 0112 /// @param indices The indices to get the value of the bin for 0113 /// @return The value of the bin: the @c std::any contains a pointer to the 0114 /// value 0115 virtual std::any atLocalBinsAny(AnyIndexType indices) = 0; 0116 0117 template <typename T, bool isConst> 0118 friend class detail::AnyGridViewBase; 0119 }; 0120 0121 /// @brief class for describing a regular multi-dimensional grid 0122 /// 0123 /// @tparam T type of values stored inside the bins of the grid 0124 /// @tparam Axes parameter pack of axis types defining the grid 0125 /// 0126 /// Class describing a multi-dimensional, regular grid which can store objects 0127 /// in its multi-dimensional bins. Bins are hyper-boxes and can be accessed 0128 /// either by global bin index, local bin indices or position. 0129 /// 0130 /// @note @c T must be default-constructible. 0131 /// @note @c T must not be @c bool, because @c std::vector<bool> is special 0132 /// and does not return references to its elements. 0133 template <typename T, class... Axes> 0134 requires(std::is_default_constructible_v<T> && !std::is_same_v<T, bool>) 0135 class Grid final : public IGrid { 0136 public: 0137 /// number of dimensions of the grid 0138 static constexpr std::size_t DIM = sizeof...(Axes); 0139 0140 /// type of values stored 0141 using value_type = T; 0142 /// reference type to values stored 0143 using reference = value_type&; 0144 /// constant reference type to values stored 0145 using const_reference = const value_type&; 0146 /// type for points in d-dimensional grid space 0147 using point_t = std::array<double, DIM>; 0148 /// index type using local bin indices along each axis 0149 using index_t = std::array<std::size_t, DIM>; 0150 /// global iterator type 0151 using global_iterator_t = GridGlobalIterator<T, Axes...>; 0152 /// local iterator type 0153 using local_iterator_t = GridLocalIterator<T, Axes...>; 0154 0155 /// @brief Constructor from const axis tuple, this will allow 0156 /// creating a grid with a different value type from a template 0157 /// grid object. 0158 /// 0159 /// @param axes 0160 explicit Grid(const std::tuple<Axes...>& axes) : m_axes(axes) { 0161 m_values.resize(size()); 0162 } 0163 0164 /// @brief Move constructor from axis tuple 0165 /// @param axes 0166 explicit Grid(std::tuple<Axes...>&& axes) : m_axes(std::move(axes)) { 0167 m_values.resize(size()); 0168 } 0169 0170 /// @brief constructor from parameters pack of axes 0171 /// @param axes 0172 explicit Grid(Axes&&... axes) : m_axes(std::forward_as_tuple(axes...)) { 0173 m_values.resize(size()); 0174 } 0175 0176 /// @brief constructor from parameters pack of axes 0177 /// @param axes 0178 explicit Grid(const Axes&... axes) : m_axes(std::tuple(axes...)) { 0179 m_values.resize(size()); 0180 } 0181 0182 /// @brief constructor from parameters pack of axes and type tag 0183 /// @param axes 0184 explicit Grid(TypeTag<T> /*tag*/, Axes&&... axes) 0185 : m_axes(std::forward_as_tuple(axes...)) { 0186 m_values.resize(size()); 0187 } 0188 0189 /// @brief constructor from parameters pack of axes and type tag 0190 /// @param axes 0191 explicit Grid(TypeTag<T> /*tag*/, const Axes&... axes) 0192 : m_axes(std::tuple(axes...)) { 0193 m_values.resize(size()); 0194 } 0195 0196 // Grid(TypeTag<T> /*tag*/, Axes&... axes) = delete; 0197 0198 /// @brief access value stored in bin for a given point 0199 /// 0200 /// @tparam Point any type with point semantics supporting component access 0201 /// through @c operator[] 0202 /// @param [in] point point used to look up the corresponding bin in the 0203 /// grid 0204 /// @return reference to value stored in bin containing the given point 0205 /// 0206 /// @pre The given @c Point type must represent a point in d (or higher) 0207 /// dimensions where d is dimensionality of the grid. 0208 /// 0209 /// @note The look-up considers under-/overflow bins along each axis. 0210 /// Therefore, the look-up will never fail. 0211 // 0212 template <class Point> 0213 reference atPosition(const Point& point) { 0214 return m_values.at(globalBinFromPosition(point)); 0215 } 0216 0217 /// @brief access value stored in bin for a given point 0218 /// 0219 /// @tparam Point any type with point semantics supporting component access 0220 /// through @c operator[] 0221 /// @param [in] point point used to look up the corresponding bin in the 0222 /// grid 0223 /// @return const-reference to value stored in bin containing the given 0224 /// point 0225 /// 0226 /// @pre The given @c Point type must represent a point in d (or higher) 0227 /// dimensions where d is dimensionality of the grid. 0228 /// 0229 /// @note The look-up considers under-/overflow bins along each axis. 0230 /// Therefore, the look-up will never fail. 0231 template <class Point> 0232 const_reference atPosition(const Point& point) const { 0233 return m_values.at(globalBinFromPosition(point)); 0234 } 0235 0236 /// @brief access value stored in bin with given global bin number 0237 /// 0238 /// @param [in] bin global bin number 0239 /// @return reference to value stored in bin containing the given 0240 /// point 0241 reference at(std::size_t bin) { return m_values.at(bin); } 0242 0243 /// @brief access value stored in bin with given global bin number 0244 /// 0245 /// @param [in] bin global bin number 0246 /// @return const-reference to value stored in bin containing the given 0247 /// point 0248 const_reference at(std::size_t bin) const { return m_values.at(bin); } 0249 0250 /// @brief access value stored in bin with given local bin numbers 0251 /// 0252 /// @param [in] localBins local bin indices along each axis 0253 /// @return reference to value stored in bin containing the given 0254 /// point 0255 /// 0256 /// @pre All local bin indices must be a valid index for the corresponding 0257 /// axis (including the under-/overflow bin for this axis). 0258 reference atLocalBins(const index_t& localBins) { 0259 return m_values.at(globalBinFromLocalBins(localBins)); 0260 } 0261 0262 /// @copydoc Acts::IGrid::atLocalBinsAny 0263 std::any atLocalBinsAny(AnyIndexType indices) const override { 0264 const_reference cref = atLocalBins(toIndexType(indices)); 0265 return &cref; 0266 } 0267 0268 /// @brief access value stored in bin with given local bin numbers 0269 /// 0270 /// @param [in] localBins local bin indices along each axis 0271 /// @return const-reference to value stored in bin containing the given 0272 /// point 0273 /// 0274 /// @pre All local bin indices must be a valid index for the corresponding 0275 /// axis (including the under-/overflow bin for this axis). 0276 const_reference atLocalBins(const index_t& localBins) const { 0277 return m_values.at(globalBinFromLocalBins(localBins)); 0278 } 0279 0280 /// @copydoc Acts::IGrid::atLocalBinsAny 0281 std::any atLocalBinsAny(AnyIndexType indices) override { 0282 reference ref = atLocalBins(toIndexType(indices)); 0283 return &ref; 0284 } 0285 0286 /// @brief get global bin indices for closest points on grid 0287 /// 0288 /// @tparam Point any type with point semantics supporting component access 0289 /// through @c operator[] 0290 /// @param [in] position point of interest 0291 /// @return Iterable thatemits the indices of bins whose lower-left corners 0292 /// are the closest points on the grid to the input. 0293 /// 0294 /// @pre The given @c Point type must represent a point in d (or higher) 0295 /// dimensions where d is dimensionality of the grid. It must lie 0296 /// within the grid range (i.e. not within a under-/overflow bin). 0297 template <class Point> 0298 detail::GlobalNeighborHoodIndices<DIM> closestPointsIndices( 0299 const Point& position) const { 0300 return rawClosestPointsIndices(localBinsFromPosition(position)); 0301 } 0302 0303 /// @brief dimensionality of grid 0304 /// 0305 /// @return number of axes spanning the grid 0306 std::size_t dimensions() const override { return DIM; } 0307 0308 /// @copydoc Acts::IGrid::valueType 0309 const std::type_info& valueType() const override { return typeid(T); } 0310 0311 /// @brief get center position of bin with given local bin numbers 0312 /// 0313 /// @param [in] localBins local bin indices along each axis 0314 /// @return center position of bin 0315 /// 0316 /// @pre All local bin indices must be a valid index for the corresponding 0317 /// axis (excluding the under-/overflow bins for each axis). 0318 point_t binCenter(const index_t& localBins) const { 0319 return detail::grid_helper::getBinCenter(localBins, m_axes); 0320 } 0321 0322 AnyPointType binCenterAny(AnyIndexType indices) const override { 0323 return toAnyPointType(binCenter(toIndexType(indices))); 0324 } 0325 0326 /// @brief determine global index for bin containing the given point 0327 /// 0328 /// @tparam Point any type with point semantics supporting component access 0329 /// through @c operator[] 0330 /// 0331 /// @param [in] point point to look up in the grid 0332 /// @return global index for bin containing the given point 0333 /// 0334 /// @pre The given @c Point type must represent a point in d (or higher) 0335 /// dimensions where d is dimensionality of the grid. 0336 /// @note This could be a under-/overflow bin along one or more axes. 0337 template <class Point> 0338 std::size_t globalBinFromPosition(const Point& point) const { 0339 return globalBinFromLocalBins(localBinsFromPosition(point)); 0340 } 0341 0342 /// @brief determine global bin index from local bin indices along each axis 0343 /// 0344 /// @param [in] localBins local bin indices along each axis 0345 /// @return global index for bin defined by the local bin indices 0346 /// 0347 /// @pre All local bin indices must be a valid index for the corresponding 0348 /// axis (including the under-/overflow bin for this axis). 0349 std::size_t globalBinFromLocalBins(const index_t& localBins) const { 0350 return detail::grid_helper::getGlobalBin(localBins, m_axes); 0351 } 0352 0353 /// @brief determine global bin index of the bin with the lower left edge 0354 /// closest to the given point for each axis 0355 /// 0356 /// @tparam Point any type with point semantics supporting component access 0357 /// through @c operator[] 0358 /// 0359 /// @param [in] point point to look up in the grid 0360 /// @return global index for bin containing the given point 0361 /// 0362 /// @pre The given @c Point type must represent a point in d (or higher) 0363 /// dimensions where d is dimensionality of the grid. 0364 /// @note This could be a under-/overflow bin along one or more axes. 0365 template <class Point> 0366 std::size_t globalBinFromFromLowerLeftEdge(const Point& point) const { 0367 return globalBinFromLocalBins(localBinsFromLowerLeftEdge(point)); 0368 } 0369 0370 /// @brief determine local bin index for each axis from the given point 0371 /// 0372 /// @tparam Point any type with point semantics supporting component access 0373 /// through @c operator[] 0374 /// 0375 /// @param [in] point point to look up in the grid 0376 /// @return array with local bin indices along each axis (in same order as 0377 /// given @c axes object) 0378 /// 0379 /// @pre The given @c Point type must represent a point in d (or higher) 0380 /// dimensions where d is dimensionality of the grid. 0381 /// @note This could be a under-/overflow bin along one or more axes. 0382 template <class Point> 0383 index_t localBinsFromPosition(const Point& point) const { 0384 return detail::grid_helper::getLocalBinIndices(point, m_axes); 0385 } 0386 0387 /// @brief determine local bin index for each axis from global bin index 0388 /// 0389 /// @param [in] bin global bin index 0390 /// @return array with local bin indices along each axis (in same order as 0391 /// given @c axes object) 0392 /// 0393 /// @note Local bin indices can contain under-/overflow bins along the 0394 /// corresponding axis. 0395 index_t localBinsFromGlobalBin(std::size_t bin) const { 0396 return detail::grid_helper::getLocalBinIndices(bin, m_axes); 0397 } 0398 0399 /// @brief determine local bin index of the bin with the lower left edge 0400 /// closest to the given point for each axis 0401 /// 0402 /// @tparam Point any type with point semantics supporting component access 0403 /// through @c operator[] 0404 /// 0405 /// @param [in] point point to look up in the grid 0406 /// @return array with local bin indices along each axis (in same order as 0407 /// given @c axes object) 0408 /// 0409 /// @pre The given @c Point type must represent a point in d (or higher) 0410 /// dimensions where d is dimensionality of the grid. 0411 /// @note This could be a under-/overflow bin along one or more axes. 0412 template <class Point> 0413 index_t localBinsFromLowerLeftEdge(const Point& point) const { 0414 Point shiftedPoint; 0415 point_t width = detail::grid_helper::getWidth(m_axes); 0416 for (std::size_t i = 0; i < DIM; i++) { 0417 shiftedPoint[i] = point[i] + width[i] / 2; 0418 } 0419 return detail::grid_helper::getLocalBinIndices(shiftedPoint, m_axes); 0420 } 0421 0422 /// @brief retrieve lower-left bin edge from set of local bin indices 0423 /// 0424 /// @param [in] localBins local bin indices along each axis 0425 /// @return generalized lower-left bin edge position 0426 /// 0427 /// @pre @c localBins must only contain valid bin indices (excluding 0428 /// underflow bins). 0429 point_t lowerLeftBinEdge(const index_t& localBins) const { 0430 return detail::grid_helper::getLowerLeftBinEdge(localBins, m_axes); 0431 } 0432 0433 /// @copydoc Acts::IGrid::lowerLeftBinEdgeAny 0434 AnyPointType lowerLeftBinEdgeAny(AnyIndexType indices) const override { 0435 return toAnyPointType(lowerLeftBinEdge(toIndexType(indices))); 0436 } 0437 0438 /// @brief retrieve upper-right bin edge from set of local bin indices 0439 /// 0440 /// @param [in] localBins local bin indices along each axis 0441 /// @return generalized upper-right bin edge position 0442 /// 0443 /// @pre @c localBins must only contain valid bin indices (excluding 0444 /// overflow bins). 0445 point_t upperRightBinEdge(const index_t& localBins) const { 0446 return detail::grid_helper::getUpperRightBinEdge(localBins, m_axes); 0447 } 0448 0449 /// @copydoc Acts::IGrid::upperRightBinEdgeAny 0450 AnyPointType upperRightBinEdgeAny(AnyIndexType indices) const override { 0451 return toAnyPointType(upperRightBinEdge(toIndexType(indices))); 0452 } 0453 0454 /// @brief get bin width along each specific axis 0455 /// 0456 /// @return array giving the bin width alonf all axes 0457 point_t binWidth() const { return detail::grid_helper::getWidth(m_axes); } 0458 0459 /// @brief get number of bins along each specific axis 0460 /// 0461 /// @return array giving the number of bins along all axes 0462 /// 0463 /// @note Not including under- and overflow bins 0464 index_t numLocalBins() const { return detail::grid_helper::getNBins(m_axes); } 0465 0466 /// @copydoc Acts::IGrid::numLocalBinsAny 0467 AnyIndexType numLocalBinsAny() const override { 0468 return toAnyIndexType(numLocalBins()); 0469 } 0470 0471 /// @brief get the minimum value of all axes of one grid 0472 /// 0473 /// @return array returning the minima of all given axes 0474 point_t minPosition() const { return detail::grid_helper::getMin(m_axes); } 0475 0476 /// @brief get the maximum value of all axes of one grid 0477 /// 0478 /// @return array returning the maxima of all given axes 0479 point_t maxPosition() const { return detail::grid_helper::getMax(m_axes); } 0480 0481 /// @brief set all overflow and underflow bins to a certain value 0482 /// 0483 /// @param [in] value value to be inserted in every overflow and underflow 0484 /// bin of the grid. 0485 /// 0486 void setExteriorBins(const value_type& value) { 0487 for (std::size_t index : detail::grid_helper::exteriorBinIndices(m_axes)) { 0488 at(index) = value; 0489 } 0490 } 0491 0492 /// @brief interpolate grid values to given position 0493 /// 0494 /// @tparam Point type specifying geometric positions 0495 /// @tparam U dummy template parameter identical to @c T 0496 /// 0497 /// @param [in] point location to which to interpolate grid values. The 0498 /// position must be within the grid dimensions and not 0499 /// lie in an under-/overflow bin along any axis. 0500 /// 0501 /// @return interpolated value at given position 0502 /// 0503 /// @pre The given @c Point type must represent a point in d (or higher) 0504 /// dimensions where d is dimensionality of the grid. 0505 /// 0506 /// @note This function is available only if the following conditions are 0507 /// fulfilled: 0508 /// - Given @c U and @c V of value type @c T as well as two @c double 0509 /// @c a and @c b, then the following must be a valid expression <tt>a * U + b 0510 /// * V</tt> yielding an object which is (implicitly) convertible to @c T. 0511 /// - @c Point must represent a d-dimensional position and support 0512 /// coordinate access using @c operator[] which should return a @c 0513 /// double (or a value which is implicitly convertible). Coordinate 0514 /// indices must start at 0. 0515 /// @note Bin values are interpreted as being the field values at the 0516 /// lower-left corner of the corresponding hyper-box. 0517 template <class Point> 0518 T interpolate(const Point& point) const 0519 requires(Concepts::interpolatable<T, Point, std::array<double, DIM>, 0520 std::array<double, DIM>>) 0521 { 0522 // there are 2^DIM corner points used during the interpolation 0523 constexpr std::size_t nCorners = 1 << DIM; 0524 0525 // construct vector of pairs of adjacent bin centers and values 0526 std::array<value_type, nCorners> neighbors{}; 0527 0528 // get local indices for current bin 0529 // value of bin is interpreted as being the field value at its lower left 0530 // corner 0531 const auto& llIndices = localBinsFromPosition(point); 0532 0533 // get global indices for all surrounding corner points 0534 const auto& closestIndices = rawClosestPointsIndices(llIndices); 0535 0536 // get values on grid points 0537 std::size_t i = 0; 0538 for (std::size_t index : closestIndices) { 0539 neighbors.at(i++) = at(index); 0540 } 0541 0542 return Acts::interpolate(point, lowerLeftBinEdge(llIndices), 0543 upperRightBinEdge(llIndices), neighbors); 0544 } 0545 0546 /// @brief check whether given point is inside grid limits 0547 /// 0548 /// @return @c true if \f$\text{xmin_i} \le x_i < \text{xmax}_i \forall i=0, 0549 /// \dots, d-1\f$, otherwise @c false 0550 /// 0551 /// @pre The given @c Point type must represent a point in d (or higher) 0552 /// dimensions where d is dimensionality of the grid. 0553 /// 0554 /// @post If @c true is returned, the global bin containing the given point 0555 /// is a valid bin, i.e. it is neither a underflow nor an overflow bin 0556 /// along any axis. 0557 template <class Point> 0558 bool isInside(const Point& position) const { 0559 return detail::grid_helper::isInside(position, m_axes); 0560 } 0561 0562 /// @brief get global bin indices for neighborhood 0563 /// 0564 /// @param [in] localBins center bin defined by local bin indices along each 0565 /// axis 0566 /// @param [in] size size of neighborhood determining how many adjacent 0567 /// bins along each axis are considered 0568 /// @return set of global bin indices for all bins in neighborhood 0569 /// 0570 /// @note Over-/underflow bins are included in the neighborhood. 0571 /// @note The @c size parameter sets the range by how many units each local 0572 /// bin index is allowed to be varied. All local bin indices are 0573 /// varied independently, that is diagonal neighbors are included. 0574 /// Ignoring the truncation of the neighborhood size reaching beyond 0575 /// over-/underflow bins, the neighborhood is of size \f$2 \times 0576 /// \text{size}+1\f$ along each dimension. 0577 detail::GlobalNeighborHoodIndices<DIM> neighborHoodIndices( 0578 const index_t& localBins, std::size_t size = 1u) const { 0579 return detail::grid_helper::neighborHoodIndices(localBins, size, m_axes); 0580 } 0581 0582 /// @brief get global bin indices for neighborhood 0583 /// 0584 /// @param [in] localBins center bin defined by local bin indices along 0585 /// each axis. If size is negative, center bin 0586 /// is not returned. 0587 /// @param [in] sizePerAxis size of neighborhood for each axis, how many 0588 /// adjacent bins along each axis are considered 0589 /// @return set of global bin indices for all bins in neighborhood 0590 /// 0591 /// @note Over-/underflow bins are included in the neighborhood. 0592 /// @note The @c size parameter sets the range by how many units each local 0593 /// bin index is allowed to be varied. All local bin indices are 0594 /// varied independently, that is diagonal neighbors are included. 0595 /// Ignoring the truncation of the neighborhood size reaching beyond 0596 /// over-/underflow bins, the neighborhood is of size \f$2 \times 0597 /// \text{size}+1\f$ along each dimension. 0598 detail::GlobalNeighborHoodIndices<DIM> neighborHoodIndices( 0599 const index_t& localBins, 0600 std::array<std::pair<int, int>, DIM>& sizePerAxis) const { 0601 return detail::grid_helper::neighborHoodIndices(localBins, sizePerAxis, 0602 m_axes); 0603 } 0604 0605 /// @brief total number of bins 0606 /// 0607 /// @return total number of bins in the grid 0608 /// 0609 /// @note This number contains under-and overflow bins along all axes. 0610 std::size_t size(bool fullCounter = true) const { 0611 index_t nBinsArray = numLocalBins(); 0612 std::size_t current_size = 1; 0613 // add under-and overflow bins for each axis and multiply all bins 0614 if (fullCounter) { 0615 for (const auto& value : nBinsArray) { 0616 current_size *= value + 2; 0617 } 0618 } 0619 // ignore under-and overflow bins for each axis and multiply all bins 0620 else { 0621 for (const auto& value : nBinsArray) { 0622 current_size *= value; 0623 } 0624 } 0625 return current_size; 0626 } 0627 0628 /// @brief Convenience function to convert the type of the grid 0629 /// to hold another object type. 0630 /// 0631 /// @tparam U the new grid value type 0632 /// 0633 /// @return a new grid with the same axes and a different value type 0634 template <typename U> 0635 Grid<U, Axes...> convertType() const { 0636 Grid<U, Axes...> cGrid(m_axes); 0637 return cGrid; 0638 } 0639 0640 /// @brief Convenience function to convert the type of the grid 0641 /// to hold another object type. 0642 /// 0643 /// @tparam converter_t the converter type 0644 /// 0645 /// This is designed to be most flexible with a converter object 0646 /// as a visitor. If needed, such a visitor could also use 0647 /// caching or other techniques to speed up the conversion. 0648 /// 0649 /// @param cVisitor the converter object as visitor 0650 /// 0651 /// @return a new grid with the same axes and a different value type 0652 template <typename converter_t> 0653 Grid<typename converter_t::value_type, Axes...> convertGrid( 0654 converter_t& cVisitor) const { 0655 Grid<typename converter_t::value_type, Axes...> cGrid(m_axes); 0656 // Loop through the values and convert them 0657 for (std::size_t i = 0; i < size(); i++) { 0658 cGrid.at(i) = cVisitor(at(i)); 0659 } 0660 return cGrid; 0661 } 0662 0663 /// @brief get the axes as a tuple 0664 const std::tuple<Axes...>& axesTuple() const { return m_axes; } 0665 0666 /// @brief get the axes as an array of IAxis pointers 0667 boost::container::small_vector<const IAxis*, 3> axes() const override { 0668 boost::container::small_vector<const IAxis*, 3> result; 0669 auto axes = detail::grid_helper::getAxes(m_axes); 0670 std::copy(axes.begin(), axes.end(), std::back_inserter(result)); 0671 return result; 0672 } 0673 0674 /// begin iterator for global bins 0675 global_iterator_t begin() const { return global_iterator_t(*this, 0); } 0676 0677 /// end iterator for global bins 0678 global_iterator_t end() const { return global_iterator_t(*this, size()); } 0679 0680 /// @brief begin iterator for local bins 0681 /// 0682 /// @param navigator is local navigator for the grid 0683 local_iterator_t begin( 0684 const std::array<std::vector<std::size_t>, DIM>& navigator) const { 0685 std::array<std::size_t, DIM> localBin{}; 0686 return local_iterator_t(*this, std::move(localBin), navigator); 0687 } 0688 0689 /// @brief end iterator for local bins 0690 /// 0691 /// @param navigator is local navigator for the grid 0692 local_iterator_t end( 0693 const std::array<std::vector<std::size_t>, DIM>& navigator) const { 0694 std::array<std::size_t, DIM> endline{}; 0695 for (std::size_t i(0ul); i < DIM; ++i) { 0696 endline[i] = navigator[i].size(); 0697 } 0698 return local_iterator_t(*this, std::move(endline), navigator); 0699 } 0700 0701 protected: 0702 void toStream(std::ostream& os) const override { 0703 printAxes(os, std::make_index_sequence<sizeof...(Axes)>()); 0704 } 0705 0706 private: 0707 /// set of axis defining the multi-dimensional grid 0708 std::tuple<Axes...> m_axes; 0709 /// linear value store for each bin 0710 std::vector<T> m_values; 0711 0712 // Part of closestPointsIndices that goes after local bins resolution. 0713 // Used as an interpolation performance optimization, but not exposed as it 0714 // doesn't make that much sense from an API design standpoint. 0715 detail::GlobalNeighborHoodIndices<DIM> rawClosestPointsIndices( 0716 const index_t& localBins) const { 0717 return detail::grid_helper::closestPointsIndices(localBins, m_axes); 0718 } 0719 0720 template <std::size_t... Is> 0721 void printAxes(std::ostream& os, std::index_sequence<Is...> /*s*/) const { 0722 auto printOne = [&os, this]<std::size_t index>( 0723 std::integral_constant<std::size_t, index>) { 0724 if constexpr (index > 0) { 0725 os << ", "; 0726 } 0727 os << std::get<index>(m_axes); 0728 }; 0729 (printOne(std::integral_constant<std::size_t, Is>()), ...); 0730 } 0731 0732 static AnyIndexType toAnyIndexType(const index_t& indices) { 0733 AnyIndexType anyIndices; 0734 anyIndices.reserve(indices.size()); 0735 std::ranges::copy(indices, std::back_inserter(anyIndices)); 0736 return anyIndices; 0737 } 0738 0739 static AnyPointType toAnyPointType(const point_t& point) { 0740 AnyPointType anyPoint; 0741 anyPoint.reserve(point.size()); 0742 std::ranges::copy(point, std::back_inserter(anyPoint)); 0743 return anyPoint; 0744 } 0745 0746 static index_t toIndexType(const AnyIndexType& indices) { 0747 if (indices.size() != DIM) { 0748 throw std::invalid_argument("Invalid number of indices"); 0749 } 0750 index_t concrete; 0751 std::ranges::copy(indices, concrete.begin()); 0752 return concrete; 0753 } 0754 }; 0755 0756 template <typename T, class... Axes> 0757 Grid(TypeTag<T> /*type*/, Axes&&... axes) -> Grid<T, Axes...>; 0758 0759 template <typename T, class... Axes> 0760 Grid(TypeTag<T> /*type*/, Axes&... axes) -> Grid<T, Axes...>; 0761 0762 } // namespace Acts
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |