6#ifndef YODA_BinnedStorage_H
7#define YODA_BinnedStorage_H
26 using BinType = std::decay_t<decltype(*std::declval<VecT>().begin())>;
31 : _bins(bins), _hiddenBins(hiddenBins) {}
34 : _bins(std::move(other._bins)), _hiddenBins(std::move(other._hiddenBins)) {}
39 size_t size()
const {
return _bins.size() - _hiddenBins.size(); }
48 std::vector<size_t> _hiddenBins;
51 template<
typename VecT>
54 using IterT = std::conditional_t<std::is_const<VecT>::value,
55 typename VecT::const_iterator,
56 typename VecT::iterator>;
60 const std::vector<size_t>& hiddenBins)
62 hiddenCurrPtr(hiddenBins.
begin()),
63 hiddenEndPtr(hiddenBins.
end()),
64 binsEndPtr(bins.
end()) {
66 if (hiddenCurrPtr != hiddenEndPtr && 0 == *hiddenCurrPtr){
78 binsEndPtr(bins.
end()) {}
86 while (_ptr != binsEndPtr &&
87 hiddenCurrPtr != hiddenEndPtr &&
88 currBinIdx == *hiddenCurrPtr) {
98 return _ptr != other._ptr;
101 typename std::iterator_traits<IterT>::reference
operator*() noexcept {
return *_ptr; }
105 std::vector<size_t>::const_iterator hiddenCurrPtr;
106 std::vector<size_t>::const_iterator hiddenEndPtr;
108 size_t currBinIdx = 0;
113 template <
typename BinContentT,
typename... AxisT>
154 BinnedStorage(std::vector<AxisT>&&... edges) : _binning(std::move(edges)...) {
159 BinnedStorage(std::initializer_list<AxisT>&&... edges) : _binning(std::vector<AxisT>{edges}...) {
159 BinnedStorage(std::initializer_list<AxisT>&&... edges) : _binning(std::vector<AxisT>{edges}...) {
…}
189 size_t dim() const noexcept {
190 return sizeof...(AxisT) + 1;
189 size_t dim() const noexcept {
…}
201 return _bins.at(idx);
206 return _bins.at(idx);
210 BinT&
bin(
const std::array<
size_t,
sizeof...(AxisT)>& idxLocal)
noexcept {
211 return bin( _binning.localToGlobalIndex(idxLocal) );
210 BinT&
bin(
const std::array<
size_t,
sizeof...(AxisT)>& idxLocal)
noexcept {
…}
215 const BinT&
bin(
const std::array<
size_t,
sizeof...(AxisT)>& idxLocal)
const noexcept {
216 return bin( _binning.localToGlobalIndex(idxLocal) );
215 const BinT&
bin(
const std::array<
size_t,
sizeof...(AxisT)>& idxLocal)
const noexcept {
…}
221 const size_t binIdx = _binning.globalIndexAt(coords);
227 const size_t binIdx = _binning.globalIndexAt(coords);
235 const size_t binIdx = _binning.globalIndexAt(coords);
236 _bins[binIdx] = std::move(content);
241 const size_t binIdx = _binning.globalIndexAt(coords);
242 _bins[binIdx] = content;
248 void set(
const size_t binIdx, BinContentT&& content)
noexcept {
249 _bins[binIdx] = std::move(content);
248 void set(
const size_t binIdx, BinContentT&& content)
noexcept {
…}
253 void set(
const size_t binIdx,
const BinContentT& content)
noexcept {
254 _bins[binIdx] = content;
253 void set(
const size_t binIdx,
const BinContentT& content)
noexcept {
…}
259 std::vector<size_t>
calcIndicesToSkip(
const bool includeOverflows,
const bool includeMaskedBins)
const noexcept {
262 if (!_binning.numBins(!includeOverflows, !includeMaskedBins))
return {};
264 std::vector<size_t> indicesToSkip;
267 auto appendIndicesVec = [&indicesToSkip](std::vector<size_t>&& indicesVec) {
268 indicesToSkip.insert(std::end(indicesToSkip),
269 std::make_move_iterator(std::begin(indicesVec)),
270 std::make_move_iterator(std::end(indicesVec)));
275 if(!includeOverflows) {
276 appendIndicesVec(_binning.calcOverflowBinsIndices());
279 if (!includeMaskedBins) {
280 appendIndicesVec(_binning.maskedBins());
284 std::sort(indicesToSkip.begin(), indicesToSkip.end());
285 indicesToSkip.erase( std::unique(indicesToSkip.begin(), indicesToSkip.end()),
286 indicesToSkip.end() );
288 return indicesToSkip;
259 std::vector<size_t>
calcIndicesToSkip(
const bool includeOverflows,
const bool includeMaskedBins)
const noexcept {
…}
299 const bool includeMaskedBins =
false) noexcept {
310 const bool includeMaskedBins =
false) const noexcept {
327 return _binning.dim();
331 size_t numBins(
const bool includeOverflows =
false,
const bool includeMaskedBins =
false) const noexcept {
332 return _binning.numBins(includeOverflows, includeMaskedBins);
331 size_t numBins(
const bool includeOverflows =
false,
const bool includeMaskedBins =
false) const noexcept {
…}
339 size_t numBinsAt(
const size_t axisN,
const bool includeOverflows =
false) const noexcept {
340 size_t nOverflows = includeOverflows? 0 : _binning.countOverflowBins(axisN);
341 return _binning.numBinsAt(axisN) - nOverflows;
339 size_t numBinsAt(
const size_t axisN,
const bool includeOverflows =
false) const noexcept {
…}
356 void maskBins(
const std::vector<size_t>& indicesToMask,
const bool status =
true) noexcept {
357 _binning.maskBins(indicesToMask, status);
356 void maskBins(
const std::vector<size_t>& indicesToMask,
const bool status =
true) noexcept {
…}
361 void maskBin(
const size_t indexToMask,
const bool status =
true) noexcept {
362 _binning.maskBin(indexToMask, status);
361 void maskBin(
const size_t indexToMask,
const bool status =
true) noexcept {
…}
366 void maskSlice(
const size_t dim,
const size_t idx,
const bool status =
true) {
367 _binning.maskSlice(
dim, idx, status);
366 void maskSlice(
const size_t dim,
const size_t idx,
const bool status =
true) {
…}
372 _binning.maskBinAt(coords, status);
375 bool isMasked(
const size_t binIndex)
const noexcept {
376 return _binning.isMasked(binIndex);
380 return _binning.maskedBins();
384 return _binning.isVisible(binIndex);
398 template <
size_t... AxisNs,
class RetT =
void>
400 std::decay_t<
decltype(AxisNs, std::declval<std::pair<size_t, size_t>>())>... mergeRanges)
401 noexcept -> std::enable_if_t<MetaUtils::is_detected_v<MetaUtils::operatorTraits::addition_assignment_t, BinContentT>, RetT>
403 auto mergeStorageBins =
404 [&
binning = BaseT::_binning, &binStorage = BaseT::_bins](
auto I,
const auto& mergeRangePair){
405 assert(mergeRangePair.first < mergeRangePair.second);
407 auto append = [&binStorage](
const auto& pivotBinsIndices,
const auto& binsIndicesToMerge){
408 assert(pivotBinsIndices.size() == binsIndicesToMerge.size());
416 for (
size_t i = 0; i < pivotBinsIndices.size(); ++i) {
417 auto& pivotBin = binStorage[pivotBinsIndices[i]];
418 pivotBin += std::move(binStorage[binsIndicesToMerge[i]]);
422 std::remove_if(binStorage.begin(), binStorage.end(), [&](
const auto& b) {
423 return std::find(binsIndicesToMerge.begin(), binsIndicesToMerge.end(), b.index()) != binsIndicesToMerge.end();
424 }), binStorage.end());
427 ssize_t nBinRowsToBeMerged = mergeRangePair.second - mergeRangePair.first;
429 size_t currBinRowIdx = mergeRangePair.first;
430 size_t nextBinRowIdx = mergeRangePair.first + 1;
433 while (nBinRowsToBeMerged--) {
437 binning.template mergeBins<I>({currBinRowIdx, nextBinRowIdx});
441 ((void)mergeStorageBins(std::integral_constant<size_t, AxisNs>(), mergeRanges), ...);
450 template<
size_t axisN,
template<
typename...>
typename BinnedT,
typename Func,
451 typename = std::enable_if_t< (axisN <
sizeof...(AxisT) &&
sizeof...(AxisT)>=2) >>
455 auto binnedSlice = _mkBinnedT<BinnedT>(_binning.template _getAxesExcept<axisN>());
456 std::vector<
decltype(binnedSlice)> rtn(vecN, binnedSlice);
457 for (
size_t i = 0; i < vecN; ++i) {
459 auto mkSlice = [&oldBins = _bins, &how2add, &binnedSlice = rtn[i]](
const auto& indicesToCopy) {
460 assert(binnedSlice.numBins(
true) == indicesToCopy.size());
464 for (
size_t i = 0; i < binnedSlice.numBins(
true); ++i) {
465 auto& pivotBin = binnedSlice.bin(i);
466 auto& binToCopy = oldBins[indicesToCopy[i]];
467 how2add(pivotBin, binToCopy);
473 mkSlice(_binning.sliceIndices(axisN, i + !includeOverflows));
482 if (
this != &other) {
483 _binning = other._binning;
491 if (
this != &other) {
492 _binning = std::move(other._binning);
503 return _binning.isCompatible(other._binning);
514 std::vector<size_t> _global2local(
size_t idx)
const noexcept {
515 const auto& indices = _binning.globalToLocalIndices(idx);
516 return std::vector<size_t>(indices.begin(), indices.end());
520 size_t _local2global(
const std::vector<size_t>& indices)
const {
521 assert(indices.size() ==
sizeof...(AxisT));
522 std::array<size_t,
sizeof...(AxisT)> arr;
523 std::copy_n(std::make_move_iterator(indices.begin()),
sizeof...(AxisT), arr.begin());
524 return _binning.localToGlobalIndex(arr);
537 _bins.reserve(_binning.numBins());
539 for (
size_t i = 0; i < _binning.numBins(); ++i) {
540 _bins.emplace_back(i, _binning);
546 _bins.reserve(_binning.numBins());
547 for (
const auto& b :
bins) {
548 _bins.emplace_back(b, _binning);
554 _bins.reserve(_binning.numBins());
555 for (
auto&& b :
bins) {
556 _bins.emplace_back(std::move(b), _binning);
561 template<
template<
typename...>
typename BinnedT,
class... newAxes,
size_t... As>
562 auto _mkBinnedT_aux(
const std::tuple<newAxes...>& t, std::index_sequence<As...>)
const {
563 return BinnedT<
typename newAxes::EdgeT...>(std::get<As>(t)...);
567 template <
template<
typename...>
typename BinnedT,
class... newAxes>
568 auto _mkBinnedT(
const std::tuple<newAxes...>& t)
const {
569 return _mkBinnedT_aux<BinnedT>(t, std::make_index_sequence<
sizeof...(newAxes)>{});
Discrete axis with edges of non-floating-point-type.
generic Bin version that derives from BinBase
BinnedStorage, stores the bins and coordinates access to them.
void maskBin(const size_t indexToMask, const bool status=true) noexcept
Mask a bin at a given index.
BinT & bin(size_t idx) noexcept
Returns reference to the bin at idx.
std::vector< BinT > BinsVecT
BinnedStorage(std::initializer_list< AxisT > &&... edges)
Constructs binning from an adapter and Rvalue initializer lists of axes' edges.
void maskBinAt(typename BinningT::EdgeTypesTuple &&coords, const bool status=true) noexcept
Mask a bin at a given set of corrdinates.
void maskBins(const std::vector< size_t > &indicesToMask, const bool status=true) noexcept
Mask a range of bins.
size_t numBinsAt(const size_t axisN, const bool includeOverflows=false) const noexcept
Number of bins in the BinnedStorage.
const BinsVecWrapper< const BinsVecT > bins(const bool includeOverflows=false, const bool includeMaskedBins=false) const noexcept
Const version.
auto mkBinnedSlices(Func &&how2add, const bool includeOverflows=false) const
Split this BinnedStorage into a vector of BinnedStorages along axisN.
void set(const size_t binIdx, const BinContentT &content) noexcept
Sets the bin corresponding to binIndex with content.
size_t numBins(const bool includeOverflows=false, const bool includeMaskedBins=false) const noexcept
Number of bins in the BinnedStorage.
Binning< std::decay_t< decltype(std::declval< Axis< AxisT > >())>... > BinningT
Convenience alias to be used in constructor.
void set(typename BinningT::EdgeTypesTuple &&coords, const BinContentT &content) noexcept
Sets the bin corresponding to coords with content.
BinnedStorage(const BinningT &binning)
Constructs BinnedStorage from Binning.
bool operator==(const BinnedStorage &other) const noexcept
Compares BinnedStorages for equality, e.g. dimensions of underlying binnings and all axes edges are e...
void set(typename BinningT::EdgeTypesTuple &&coords, BinContentT &&content) noexcept
Sets the bin corresponding to coords with an rvalue content.
BinnedStorage(const Axis< AxisT > &... axes)
Constructs binning from an adapter and a sequence of axes.
BinnedStorage(std::vector< AxisT > &&... edges)
Constructs binning from an adapter and Rvalue vectors of axes' edges.
const BinT & bin(const std::array< size_t, sizeof...(AxisT)> &idxLocal) const noexcept
Bin access using local bin indices.
void fillBins() noexcept
Fills bins with wrapped BinContent objects.
BinnedStorage(const std::vector< AxisT > &... edges)
Constructs binning from an adapter and vectors of axes' edges.
BinnedStorage & operator=(const BinnedStorage &other) noexcept
Copy assignment.
size_t binDim() const noexcept
Returns dimension of binning.
bool isMasked(const size_t binIndex) const noexcept
BinnedStorage(BinningT &&binning)
Constructs BinnedStorage from Binning. Rvalue.
const BinT & binAt(typename BinningT::EdgeTypesTuple &&coords) const noexcept
Returns reference to the bin at coordinates (const version).
void maskSlice(const size_t dim, const size_t idx, const bool status=true)
Mask a slice of the binning at local bin index idx along axis dimesnion dim.
Bin< sizeof...(AxisT), BinContentT, BinningT > BinT
BinnedStorage(const BinnedStorage &other)
Copy constructor.
BinnedStorage(Axis< AxisT > &&... axes)
Constructs binning from an adapter and a sequence of Rvalue axes.
void clearBins() noexcept
Deletes all bins and creates empty new ones.
BinsVecWrapper< BinsVecT > bins(const bool includeOverflows=false, const bool includeMaskedBins=false) noexcept
Returns bins vector wrapper, which skips masked elements when iterated over.
const BinT & bin(size_t idx) const noexcept
Returns Bin at idx.
void reset() noexcept
Reset the BinnedStorage.
auto mergeBins(std::decay_t< decltype(AxisNs, std::declval< std::pair< size_t, size_t > >())>... mergeRanges) noexcept -> std::enable_if_t< MetaUtils::is_detected_v< MetaUtils::operatorTraits::addition_assignment_t, BinContentT >, RetT >
Merge bins from A to B at G axis.
void fillBins(const BinsVecT &bins) noexcept
size_t dim() const noexcept
Total dimension of the object ( = number of axes + content)
BinnedStorage()
Nullary constructor for unique pointers etc.
BinnedStorage(BinnedStorage &&other)
Move constructor.
BinT & bin(const std::array< size_t, sizeof...(AxisT)> &idxLocal) noexcept
Bin access using local bin indices.
const BinningT & binning() const noexcept
Returns dimension underlying binning object reference.
std::vector< size_t > maskedBins() const noexcept
BinT & binAt(typename BinningT::EdgeTypesTuple &&coords) noexcept
Returns reference to the bin at coordinates.
bool isVisible(const size_t binIndex) const noexcept
void fillBins(BinsVecT &&bins) noexcept
std::vector< size_t > calcIndicesToSkip(const bool includeOverflows, const bool includeMaskedBins) const noexcept
Calculates indices of bins which are marked or located in the overflow.
void set(const size_t binIdx, BinContentT &&content) noexcept
Sets the bin corresponding to binIndex with an rvalue content.
bool operator!=(const BinnedStorage &other) const noexcept
Compares BinnedStorages for inequality.
std::integral_constant< size_t, sizeof...(AxisT)> BinDimension
decltype(std::tuple_cat(std::declval< std::tuple< typename Axes::EdgeT > >()...)) EdgeTypesTuple
std::vector< size_t > sliceIndices(std::vector< std::pair< size_t, std::vector< size_t > > >) const noexcept
Calculates indices of bins located in the specified slices.
myIt(VecT &bins, const std::vector< size_t > &hiddenBins)
std::iterator_traits< IterT >::reference operator*() noexcept
bool operator!=(const myIt &other) const noexcept
myIt operator++() noexcept
Vector wrapper used to interact with bins vectors. Able to hide overflow and hidden bins.
BinsVecWrapper(BinsVecWrapper &&other)
std::decay_t< decltype(*std::declval< VecT >().begin())> BinType
BinType & operator[](size_t index)
BinsVecWrapper(VecT &bins, const std::vector< size_t > &hiddenBins)
HiddenBins std::vector<size_t> must be sorted.
const BinType & operator[](size_t index) const
Anonymous namespace to limit visibility.