|
|
|||
File indexing completed on 2026-09-04 08:20:08
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/Axis.hpp" 0012 #include "Acts/Utilities/Enumerate.hpp" 0013 #include "Acts/Utilities/GridIterator.hpp" 0014 #include "Acts/Utilities/IGrid.hpp" 0015 #include "Acts/Utilities/Interpolation.hpp" 0016 #include "Acts/Utilities/MultiAxis.hpp" 0017 #include "Acts/Utilities/TypeTag.hpp" 0018 #include "Acts/Utilities/detail/MultiAxisHelper.hpp" 0019 0020 #include <algorithm> 0021 #include <array> 0022 #include <tuple> 0023 #include <type_traits> 0024 #include <typeinfo> 0025 #include <utility> 0026 #include <vector> 0027 0028 namespace Acts { 0029 0030 /// class for describing a regular multi-dimensional grid 0031 /// 0032 /// @tparam T type of values stored inside the bins of the grid 0033 /// @tparam Axes parameter pack of axis types defining the grid 0034 /// 0035 /// Class describing a multi-dimensional, regular grid which can store objects 0036 /// in its multi-dimensional bins. Bins are hyper-boxes and can be accessed 0037 /// either by global bin index, local bin indices or position. 0038 /// 0039 /// @note @c T must be default-constructible. 0040 /// @note @c T must not be @c bool, because @c std::vector<bool> is special 0041 /// and does not return references to its elements. 0042 template <typename T, class... Axes> 0043 requires(std::is_default_constructible_v<T> && !std::is_same_v<T, bool>) 0044 class Grid final : public IGrid { 0045 public: 0046 /// number of dimensions of the grid 0047 static constexpr std::size_t DIM = sizeof...(Axes); 0048 0049 /// multi axis type 0050 using multi_axis_t = MultiAxis<Axes...>; 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 /// 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 /// 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 /// 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 /// 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 /// 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 /// 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 /// Move constructor from axis tuple 0108 /// @param axes 0109 explicit Grid(multi_axis_t axes) : m_axes(std::move(axes)) { 0110 m_values.resize(size()); 0111 } 0112 0113 /// constructor from parameters pack of axes and type tag 0114 /// @param axes 0115 explicit Grid(TypeTag<T> /*tag*/, multi_axis_t axes) 0116 : m_axes(std::move(axes)) { 0117 m_values.resize(size()); 0118 } 0119 0120 /// access value stored in bin for a given point 0121 /// 0122 /// @tparam Point any type with point semantics supporting component access 0123 /// through @c operator[] 0124 /// @param point point used to look up the corresponding bin in the 0125 /// grid 0126 /// @return reference to value stored in bin containing the given point 0127 /// 0128 /// @pre The given @c Point type must represent a point in d (or higher) 0129 /// dimensions where d is dimensionality of the grid. 0130 /// 0131 /// @note The look-up considers under-/overflow bins along each axis. 0132 /// Therefore, the look-up will never fail. 0133 // 0134 template <class Point> 0135 reference atPosition(const Point& point) { 0136 return m_values.at(m_axes.getGlobalBinFromPoint(point)); 0137 } 0138 0139 /// access value stored in bin for a given point 0140 /// 0141 /// @tparam Point any type with point semantics supporting component access 0142 /// through @c operator[] 0143 /// @param point point used to look up the corresponding bin in the 0144 /// grid 0145 /// @return const-reference to value stored in bin containing the given 0146 /// point 0147 /// 0148 /// @pre The given @c Point type must represent a point in d (or higher) 0149 /// dimensions where d is dimensionality of the grid. 0150 /// 0151 /// @note The look-up considers under-/overflow bins along each axis. 0152 /// Therefore, the look-up will never fail. 0153 template <class Point> 0154 const_reference atPosition(const Point& point) const { 0155 return m_values.at(m_axes.getGlobalBinFromPoint(point)); 0156 } 0157 0158 /// access value stored in bin with given global bin number 0159 /// 0160 /// @param bin global bin number 0161 /// @return reference to value stored in bin containing the given 0162 /// point 0163 reference at(std::size_t bin) { return m_values.at(bin); } 0164 0165 /// access value stored in bin with given global bin number 0166 /// 0167 /// @param bin global bin number 0168 /// @return const-reference to value stored in bin containing the given 0169 /// point 0170 const_reference at(std::size_t bin) const { return m_values.at(bin); } 0171 0172 /// access value stored in bin with given local bin numbers 0173 /// 0174 /// @param localBins local bin indices along each axis 0175 /// @return reference to value stored in bin containing the given 0176 /// point 0177 /// 0178 /// @pre All local bin indices must be a valid index for the corresponding 0179 /// axis (including the under-/overflow bin for this axis). 0180 reference atLocalBins(const index_t& localBins) { 0181 return m_values.at(m_axes.getGlobalBinFromLocalBins(localBins)); 0182 } 0183 0184 /// access value stored in bin with given local bin numbers 0185 /// 0186 /// @param localBins local bin indices along each axis 0187 /// @return const-reference to value stored in bin containing the given 0188 /// point 0189 /// 0190 /// @pre All local bin indices must be a valid index for the corresponding 0191 /// axis (including the under-/overflow bin for this axis). 0192 const_reference atLocalBins(const index_t& localBins) const { 0193 return m_values.at(m_axes.getGlobalBinFromLocalBins(localBins)); 0194 } 0195 0196 /// @copydoc Acts::IGrid::atLocalBinsAny 0197 std::any atLocalBinsAny(const AnyIndexType& indices) const override { 0198 return &atLocalBins(toIndexType(indices)); 0199 } 0200 0201 /// @copydoc Acts::IGrid::atLocalBinsAny 0202 std::any atLocalBinsAny(const AnyIndexType& indices) override { 0203 return &atLocalBins(toIndexType(indices)); 0204 } 0205 0206 /// get global bin indices for closest points on grid 0207 /// 0208 /// @tparam Point any type with point semantics supporting component access 0209 /// through @c operator[] 0210 /// @param position point of interest 0211 /// @return Iterable thatemits the indices of bins whose lower-left corners 0212 /// are the closest points on the grid to the input. 0213 /// 0214 /// @pre The given @c Point type must represent a point in d (or higher) 0215 /// dimensions where d is dimensionality of the grid. It must lie 0216 /// within the grid range (i.e. not within a under-/overflow bin). 0217 /// @deprecated Use grid.multiAxis().getClosestPointsIndices(point) instead 0218 template <class Point> 0219 [[deprecated("Use grid.multiAxis().getClosestPointsIndices(point) instead")]] 0220 detail::FlatNeighborHoodIndices<DIM> closestPointsIndices( 0221 const Point& position) const { 0222 return m_axes.getClosestPointsIndices(position); 0223 } 0224 0225 /// dimensionality of grid 0226 /// 0227 /// @return number of axes spanning the grid 0228 std::size_t dimensions() const override { return DIM; } 0229 0230 /// Get the multi-axis object for the grid 0231 /// @return The multi-axis object for the grid 0232 const IMultiAxis& multiAxisAny() const override { return m_axes; } 0233 0234 /// Get the multi-axis object for the grid 0235 /// @return The multi-axis object for the grid 0236 const multi_axis_t& multiAxis() const { return m_axes; } 0237 0238 const IAxis& axis(std::size_t index) const override { 0239 return m_axes.getAxis(index); 0240 } 0241 0242 /// @copydoc Acts::IGrid::valueType 0243 const std::type_info& valueType() const override { return typeid(T); } 0244 0245 /// get center position of bin with given local bin numbers 0246 /// 0247 /// @param localBins local bin indices along each axis 0248 /// @return center position of bin 0249 /// 0250 /// @pre All local bin indices must be a valid index for the corresponding 0251 /// axis (excluding the under-/overflow bins for each axis). 0252 /// @deprecated Use grid.multiAxis().getBinCenter(localBins) instead 0253 [[deprecated("Use grid.multiAxis().getBinCenter(localBins) instead")]] 0254 point_t binCenter(const index_t& localBins) const { 0255 return m_axes.getBinCenter(localBins); 0256 } 0257 0258 /// determine global index for bin containing the given point 0259 /// 0260 /// @tparam Point any type with point semantics supporting component access 0261 /// through @c operator[] 0262 /// 0263 /// @param point point to look up in the grid 0264 /// @return global index for bin containing the given point 0265 /// 0266 /// @pre The given @c Point type must represent a point in d (or higher) 0267 /// dimensions where d is dimensionality of the grid. 0268 /// @note This could be a under-/overflow bin along one or more axes. 0269 /// @deprecated Use grid.multiAxis().getGlobalBinFromPoint(point) instead 0270 template <class Point> 0271 [[deprecated("Use grid.multiAxis().getGlobalBinFromPoint(point) instead")]] 0272 std::size_t globalBinFromPosition(const Point& point) const { 0273 return m_axes.getGlobalBinFromPoint(point); 0274 } 0275 0276 /// determine global bin index from local bin indices along each axis 0277 /// 0278 /// @param localBins local bin indices along each axis 0279 /// @return global index for bin defined by the local bin indices 0280 /// 0281 /// @pre All local bin indices must be a valid index for the corresponding 0282 /// axis (including the under-/overflow bin for this axis). 0283 /// @deprecated Use grid.multiAxis().getGlobalBinFromLocalBins(localBins) 0284 /// instead 0285 [[deprecated( 0286 "Use grid.multiAxis().getGlobalBinFromLocalBins(localBins) instead")]] 0287 std::size_t globalBinFromLocalBins(const index_t& localBins) const { 0288 return m_axes.getGlobalBinFromLocalBins(localBins); 0289 } 0290 0291 /// determine global bin index of the bin with the lower left edge 0292 /// closest to the given point for each axis 0293 /// 0294 /// @tparam Point any type with point semantics supporting component access 0295 /// through @c operator[] 0296 /// 0297 /// @param point point to look up in the grid 0298 /// @return global index for bin containing the given point 0299 /// 0300 /// @pre The given @c Point type must represent a point in d (or higher) 0301 /// dimensions where d is dimensionality of the grid. 0302 /// @note This could be a under-/overflow bin along one or more axes. 0303 /// @deprecated Use grid.multiAxis().getGlobalBinFromLowerLeftEdge(point) 0304 /// instead 0305 template <class Point> 0306 [[deprecated( 0307 "Use grid.multiAxis().getGlobalBinFromLowerLeftEdge(point) instead")]] 0308 std::size_t globalBinFromFromLowerLeftEdge(const Point& point) const { 0309 return m_axes.getGlobalBinFromLowerLeftEdge(point); 0310 } 0311 0312 /// determine local bin index for each axis from the given point 0313 /// 0314 /// @tparam Point any type with point semantics supporting component access 0315 /// through @c operator[] 0316 /// 0317 /// @param point point to look up in the grid 0318 /// @return array with local bin indices along each axis (in same order as 0319 /// given @c axes object) 0320 /// 0321 /// @pre The given @c Point type must represent a point in d (or higher) 0322 /// dimensions where d is dimensionality of the grid. 0323 /// @note This could be a under-/overflow bin along one or more axes. 0324 /// @deprecated Use grid.multiAxis().getLocalBinsFromPoint(point) instead 0325 template <class Point> 0326 [[deprecated("Use grid.multiAxis().getLocalBinsFromPoint(point) instead")]] 0327 index_t localBinsFromPosition(const Point& point) const { 0328 return m_axes.getLocalBinsFromPoint(point); 0329 } 0330 0331 /// determine local bin index for each axis from global bin index 0332 /// 0333 /// @param bin global bin index 0334 /// @return array with local bin indices along each axis (in same order as 0335 /// given @c axes object) 0336 /// 0337 /// @note Local bin indices can contain under-/overflow bins along the 0338 /// corresponding axis. 0339 /// @deprecated Use grid.multiAxis().getLocalBinsFromGlobalBin(bin) instead 0340 [[deprecated("Use grid.multiAxis().getLocalBinsFromGlobalBin(bin) instead")]] 0341 index_t localBinsFromGlobalBin(std::size_t bin) const { 0342 return m_axes.getLocalBinsFromGlobalBin(bin); 0343 } 0344 0345 /// determine local bin index of the bin with the lower left edge 0346 /// closest to the given point for each axis 0347 /// 0348 /// @tparam Point any type with point semantics supporting component access 0349 /// through @c operator[] 0350 /// 0351 /// @param point point to look up in the grid 0352 /// @return array with local bin indices along each axis (in same order as 0353 /// given @c axes object) 0354 /// 0355 /// @pre The given @c Point type must represent a point in d (or higher) 0356 /// dimensions where d is dimensionality of the grid. 0357 /// @note This could be a under-/overflow bin along one or more axes. 0358 /// @deprecated Use grid.multiAxis().getLocalBinsFromLowerLeftEdge(point) 0359 /// instead 0360 template <class Point> 0361 [[deprecated( 0362 "Use grid.multiAxis().getLocalBinsFromLowerLeftEdge(point) instead")]] 0363 index_t localBinsFromLowerLeftEdge(const Point& point) const { 0364 return m_axes.getLocalBinsFromLowerLeftEdge(point); 0365 } 0366 0367 /// retrieve lower-left bin edge from set of local bin indices 0368 /// 0369 /// @param localBins local bin indices along each axis 0370 /// @return generalized lower-left bin edge position 0371 /// 0372 /// @pre @c localBins must only contain valid bin indices (excluding 0373 /// underflow bins). 0374 /// @deprecated Use grid.multiAxis().getLowerLeftBinEdge(localBins) instead 0375 [[deprecated("Use grid.multiAxis().getLowerLeftBinEdge(localBins) instead")]] 0376 point_t lowerLeftBinEdge(const index_t& localBins) const { 0377 return m_axes.getLowerLeftBinEdge(localBins); 0378 } 0379 0380 /// retrieve upper-right bin edge from set of local bin indices 0381 /// 0382 /// @param localBins local bin indices along each axis 0383 /// @return generalized upper-right bin edge position 0384 /// 0385 /// @pre @c localBins must only contain valid bin indices (excluding 0386 /// overflow bins). 0387 /// @deprecated Use grid.multiAxis().getUpperRightBinEdge(localBins) instead 0388 [[deprecated("Use grid.multiAxis().getUpperRightBinEdge(localBins) instead")]] 0389 point_t upperRightBinEdge(const index_t& localBins) const { 0390 return m_axes.getUpperRightBinEdge(localBins); 0391 } 0392 0393 /// get bin width along each specific axis 0394 /// 0395 /// @return array giving the bin width alonf all axes 0396 /// @deprecated Use grid.multiAxis().getBinWidth({}) instead 0397 [[deprecated("Use grid.multiAxis().getBinWidth({}) instead")]] 0398 point_t binWidth() const { 0399 return m_axes.getBinWidth({}); 0400 } 0401 0402 /// get number of bins along each specific axis 0403 /// 0404 /// @return array giving the number of bins along all axes 0405 /// 0406 /// @note Not including under- and overflow bins 0407 /// @deprecated Use grid.multiAxis().getNBins() instead 0408 [[deprecated("Use grid.multiAxis().getNBins() instead")]] 0409 index_t numLocalBins() const { 0410 return m_axes.getNBins(); 0411 } 0412 0413 /// get the minimum value of all axes of one grid 0414 /// 0415 /// @return array returning the minima of all given axes 0416 /// @deprecated Use grid.multiAxis().getMinPoint() instead 0417 [[deprecated("Use grid.multiAxis().getMinPoint() instead")]] 0418 point_t minPosition() const { 0419 return m_axes.getMinPoint(); 0420 } 0421 0422 /// get the maximum value of all axes of one grid 0423 /// 0424 /// @return array returning the maxima of all given axes 0425 /// @deprecated Use grid.multiAxis().getMaxPoint() instead 0426 [[deprecated("Use grid.multiAxis().getMaxPoint() instead")]] 0427 point_t maxPosition() const { 0428 return m_axes.getMaxPoint(); 0429 } 0430 0431 /// set all overflow and underflow bins to a certain value 0432 /// 0433 /// @param value value to be inserted in every overflow and underflow 0434 /// bin of the grid. 0435 /// 0436 void setExteriorBins(const value_type& value) { 0437 for (std::size_t index : 0438 detail::MultiAxisHelper::exteriorBinIndices(m_axes.getAxesTuple())) { 0439 at(index) = value; 0440 } 0441 } 0442 0443 /// interpolate grid values to given position 0444 /// 0445 /// @tparam Point type specifying geometric positions 0446 /// @tparam U dummy template parameter identical to @c T 0447 /// 0448 /// @param point location to which to interpolate grid values. The 0449 /// position must be within the grid dimensions and not 0450 /// lie in an under-/overflow bin along any axis. 0451 /// 0452 /// @return interpolated value at given position 0453 /// 0454 /// @pre The given @c Point type must represent a point in d (or higher) 0455 /// dimensions where d is dimensionality of the grid. 0456 /// 0457 /// @note This function is available only if the following conditions are 0458 /// fulfilled: 0459 /// - Given @c U and @c V of value type @c T as well as two @c double 0460 /// @c a and @c b, then the following must be a valid expression <tt>a * U + b 0461 /// * V</tt> yielding an object which is (implicitly) convertible to @c T. 0462 /// - @c Point must represent a d-dimensional position and support 0463 /// coordinate access using @c operator[] which should return a @c 0464 /// double (or a value which is implicitly convertible). Coordinate 0465 /// indices must start at 0. 0466 /// @note Bin values are interpreted as being the field values at the 0467 /// lower-left corner of the corresponding hyper-box. 0468 template <class Point> 0469 T interpolate(const Point& point) const { 0470 // get local indices for current bin 0471 // value of bin is interpreted as being the field value at its lower left 0472 // corner 0473 const auto llIndices = m_axes.getLocalBinsFromPoint(point); 0474 0475 // get global indices for all surrounding corner points 0476 const auto closestIndices = 0477 m_axes.getNeighborHoodIndices(llIndices, {0, 1}); 0478 0479 // there are 2^DIM corner points used during the interpolation 0480 constexpr std::size_t nCorners = 1 << DIM; 0481 0482 // construct vector of pairs of adjacent bin centers and values 0483 std::array<value_type, nCorners> neighbors{}; 0484 0485 // get values on grid points 0486 std::size_t i = 0; 0487 for (const auto index : closestIndices) { 0488 neighbors.at(i) = at(index); 0489 ++i; 0490 } 0491 0492 return Acts::interpolate(point, m_axes.getLowerLeftBinEdge(llIndices), 0493 m_axes.getUpperRightBinEdge(llIndices), neighbors); 0494 } 0495 0496 /// check whether given point is inside grid limits 0497 /// 0498 /// @param position Point to check for inclusion within grid boundaries 0499 /// @return @c true if \f$\text{xmin_i} \le x_i < \text{xmax}_i \forall i=0, 0500 /// \dots, d-1\f$, otherwise @c false 0501 /// 0502 /// @pre The given @c Point type must represent a point in d (or higher) 0503 /// dimensions where d is dimensionality of the grid. 0504 /// 0505 /// @post If @c true is returned, the global bin containing the given point 0506 /// is a valid bin, i.e. it is neither a underflow nor an overflow bin 0507 /// along any axis. 0508 /// @deprecated Use grid.multiAxis().isInside(position) instead 0509 template <class Point> 0510 [[deprecated("Use grid.multiAxis().isInside(position) instead")]] 0511 bool isInside(const Point& position) const { 0512 return m_axes.isInside(position); 0513 } 0514 0515 /// get global bin indices for neighborhood 0516 /// 0517 /// @param localBins center bin defined by local bin indices along each 0518 /// axis 0519 /// @param size size of neighborhood determining how many adjacent 0520 /// bins along each axis are considered 0521 /// @return set of global bin indices for all bins in neighborhood 0522 /// 0523 /// @note Over-/underflow bins are included in the neighborhood. 0524 /// @note The @c size parameter sets the range by how many units each local 0525 /// bin index is allowed to be varied. All local bin indices are 0526 /// varied independently, that is diagonal neighbors are included. 0527 /// Ignoring the truncation of the neighborhood size reaching beyond 0528 /// over-/underflow bins, the neighborhood is of size \f$2 \times 0529 /// \text{size}+1\f$ along each dimension. 0530 /// @deprecated Use grid.multiAxis().getNeighborHoodIndices(localBins, size) 0531 /// instead 0532 [[deprecated( 0533 "Use grid.multiAxis().getNeighborHoodIndices(localBins, size) instead")]] 0534 detail::FlatNeighborHoodIndices<DIM> neighborHoodIndices( 0535 const index_t& localBins, std::size_t size = 1u) const { 0536 return m_axes.getNeighborHoodIndices(localBins, size); 0537 } 0538 0539 /// get global bin indices for neighborhood 0540 /// 0541 /// @param localBins center bin defined by local bin indices along 0542 /// each axis. If size is negative, center bin 0543 /// is not returned. 0544 /// @param sizePerAxis size of neighborhood for each axis, how many 0545 /// adjacent bins along each axis are considered 0546 /// @return set of global bin indices for all bins in neighborhood 0547 /// 0548 /// @note Over-/underflow bins are included in the neighborhood. 0549 /// @note The @c size parameter sets the range by how many units each local 0550 /// bin index is allowed to be varied. All local bin indices are 0551 /// varied independently, that is diagonal neighbors are included. 0552 /// Ignoring the truncation of the neighborhood size reaching beyond 0553 /// over-/underflow bins, the neighborhood is of size \f$2 \times 0554 /// \text{size}+1\f$ along each dimension. 0555 /// @deprecated Use grid.multiAxis().getNeighborHoodIndices(localBins, 0556 /// sizePerAxis) instead 0557 [[deprecated( 0558 "Use grid.multiAxis().getNeighborHoodIndices(localBins, sizePerAxis) " 0559 "instead")]] 0560 detail::FlatNeighborHoodIndices<DIM> neighborHoodIndices( 0561 const index_t& localBins, 0562 std::array<std::pair<int, int>, DIM>& sizePerAxis) const { 0563 return m_axes.getNeighborHoodIndices(localBins, sizePerAxis); 0564 } 0565 0566 /// total number of bins 0567 /// 0568 /// @param fullCounter Whether to include under-and overflow bins in the count 0569 /// @return total number of bins in the grid 0570 /// 0571 /// @note This number contains under-and overflow bins along all axes. 0572 std::size_t size(bool fullCounter = true) const { 0573 return m_axes.getNTotalBins(fullCounter); 0574 } 0575 0576 /// Convenience function to convert the type of the grid 0577 /// to hold another object type. 0578 /// 0579 /// @tparam U the new grid value type 0580 /// 0581 /// @return a new grid with the same axes and a different value type 0582 template <typename U> 0583 Grid<U, Axes...> convertType() const { 0584 Grid<U, Axes...> cGrid(m_axes); 0585 return cGrid; 0586 } 0587 0588 /// Convenience function to convert the type of the grid 0589 /// to hold another object type. 0590 /// 0591 /// @tparam converter_t the converter type 0592 /// 0593 /// This is designed to be most flexible with a converter object 0594 /// as a visitor. If needed, such a visitor could also use 0595 /// caching or other techniques to speed up the conversion. 0596 /// 0597 /// @param cVisitor the converter object as visitor 0598 /// 0599 /// @return a new grid with the same axes and a different value type 0600 template <typename converter_t> 0601 Grid<typename converter_t::value_type, Axes...> convertGrid( 0602 converter_t& cVisitor) const { 0603 Grid<typename converter_t::value_type, Axes...> cGrid(m_axes); 0604 // Loop through the values and convert them 0605 for (std::size_t i = 0; i < size(); i++) { 0606 cGrid.at(i) = cVisitor(at(i)); 0607 } 0608 return cGrid; 0609 } 0610 0611 /// get the axes as a tuple 0612 /// @return Reference to the tuple containing all grid axes 0613 /// @deprecated Use grid.multiAxis().getAxesTuple() instead 0614 [[deprecated("Use grid.multiAxis().getAxesTuple() instead")]] 0615 const std::tuple<Axes...>& axesTuple() const { 0616 return m_axes.getAxesTuple(); 0617 } 0618 0619 /// get the axes as an array of IAxis pointers 0620 /// @return Vector containing pointers to all grid axes 0621 AnyAxesVector axes() const override { return m_axes.getAnyAxesVector(); } 0622 0623 /// begin iterator for global bins 0624 /// @return Iterator pointing to the first global bin 0625 global_iterator_t begin() const { return global_iterator_t(*this, 0); } 0626 0627 /// end iterator for global bins 0628 /// @return Iterator pointing one past the last global bin 0629 global_iterator_t end() const { return global_iterator_t(*this, size()); } 0630 0631 /// begin iterator for local bins 0632 /// 0633 /// @param navigator is local navigator for the grid 0634 /// @return Iterator pointing to the first local bin 0635 local_iterator_t begin( 0636 const std::array<std::vector<std::size_t>, DIM>& navigator) const { 0637 std::array<std::size_t, DIM> localBin{}; 0638 return local_iterator_t(*this, std::move(localBin), navigator); 0639 } 0640 0641 /// end iterator for local bins 0642 /// 0643 /// @param navigator is local navigator for the grid 0644 /// @return Iterator pointing one past the last local bin 0645 local_iterator_t end( 0646 const std::array<std::vector<std::size_t>, DIM>& navigator) const { 0647 std::array<std::size_t, DIM> endline{}; 0648 for (std::size_t i(0ul); i < DIM; ++i) { 0649 endline[i] = navigator[i].size(); 0650 } 0651 return local_iterator_t(*this, std::move(endline), navigator); 0652 } 0653 0654 protected: 0655 void toStream(std::ostream& os) const override { os << m_axes; } 0656 0657 private: 0658 /// multi axis for the grid 0659 multi_axis_t m_axes; 0660 /// linear value store for each bin 0661 std::vector<T> m_values; 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 /// @brief Helper method to create a 1D grid from a single type-erased axis 0684 /// 0685 /// @tparam payload_t the grid payload type 0686 /// 0687 /// @param a the axis 0688 /// 0689 /// @return an IGrid unique ptr and hence transfers ownership 0690 template <typename payload_t> 0691 std::unique_ptr<IGrid> makeGrid(const IAxis& a) { 0692 return a.visit( 0693 [&]<typename AxisTypeA>(const AxisTypeA& axis) -> std::unique_ptr<IGrid> { 0694 using GridType = Grid<payload_t, AxisTypeA>; 0695 return std::make_unique<GridType>(axis); 0696 }); 0697 } 0698 0699 /// @brief Helper method to create a 2D grid from two type-erased axes 0700 /// 0701 /// @tparam payload_t the grid payload type 0702 /// 0703 /// @param a the first axis 0704 /// @param b the second axis 0705 /// 0706 /// @return an IGrid unique ptr and hence transfers ownership 0707 template <typename payload_t> 0708 std::unique_ptr<IGrid> makeGrid(const IAxis& a, const IAxis& b) { 0709 return a.visit([&]<typename AxisTypeA>( 0710 const AxisTypeA& axisA) -> std::unique_ptr<IGrid> { 0711 return b.visit([&]<typename AxisTypeB>( 0712 const AxisTypeB& axisB) -> std::unique_ptr<IGrid> { 0713 using GridType = Grid<payload_t, AxisTypeA, AxisTypeB>; 0714 return std::make_unique<GridType>(axisA, axisB); 0715 }); 0716 }); 0717 } 0718 0719 } // 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 |
|