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