Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RSliceBinIndexMapper.hxx
Go to the documentation of this file.
1/// \file
2/// \warning This is part of the %ROOT 7 prototype! It will change without notice. It might trigger earthquakes.
3/// Feedback is welcome!
4
5#ifndef ROOT_RSliceBinIndexMapper
6#define ROOT_RSliceBinIndexMapper
7
8#include "RBinIndex.hxx"
9#include "RBinIndexRange.hxx"
10#include "RSliceSpec.hxx"
11
12#include <cassert>
13#include <cstddef>
14#include <stdexcept>
15#include <utility>
16#include <vector>
17
18namespace ROOT {
19namespace Experimental {
20namespace Internal {
21
22/**
23Mapper of bin indices for slice operations.
24*/
26 /// The requested slice specifications
27 std::vector<RSliceSpec> fSliceSpecs;
28 /// The expected dimensionality of the mapped indices
30
31 static std::size_t ComputeMappedDimensionality(const std::vector<RSliceSpec> &sliceSpecs)
32 {
33 std::size_t dimensionality = 0;
34 for (auto &&spec : sliceSpecs) {
35 // A sum operation makes the dimension disappear.
36 if (spec.GetOperationSum() == nullptr) {
38 }
39 }
40 return dimensionality;
41 }
42
43public:
44 /// \param[in] sliceSpecs the slice specifications, must have size > 0
45 explicit RSliceBinIndexMapper(std::vector<RSliceSpec> sliceSpecs)
47 {
48 if (fSliceSpecs.empty()) {
49 throw std::invalid_argument("must have at least 1 slice specification");
50 }
51 }
52
53 const std::vector<RSliceSpec> &GetSliceSpecs() const { return fSliceSpecs; }
54 std::size_t GetMappedDimensionality() const { return fMappedDimensionality; }
55
56 /// Map a vector of RBinIndex according to the slice specifications.
57 ///
58 /// \param[in] original the original bin indices
59 /// \param[out] mapped the mapped bin indices
60 /// \return whether the mapping was successful or the bin content should be discarded
61 bool Map(const std::vector<RBinIndex> &original, std::vector<RBinIndex> &mapped) const
62 {
63 if (original.size() != fSliceSpecs.size()) {
64 throw std::invalid_argument("invalid number of original indices passed to RSliceBinIndexMapper::Map");
65 }
66 if (mapped.size() != fMappedDimensionality) {
67 throw std::invalid_argument("invalid size of mapped indices passed to RSliceBinIndexMapper::Map");
68 }
69
70 std::size_t mappedPos = 0;
71 for (std::size_t i = 0; i < original.size(); i++) {
73 if (index.IsInvalid()) {
74 throw std::invalid_argument("invalid bin index passed to RSliceBinIndexMapper::Map");
75 }
76
78 const auto &range = sliceSpec.GetRange();
79 bool contained = true;
80 if (!range.IsInvalid()) {
81 // Underflow and overflow indices map to themselves, but they may not actually be contained in the range.
82 // This is important for the sum operation below.
83 if (index.IsUnderflow()) {
84 contained = range.GetBegin().IsUnderflow();
85 } else if (index.IsOverflow()) {
86 contained = range.GetEnd().IsInvalid();
87 } else if (index.IsNormal()) {
88 const auto &begin = range.GetBegin();
89 const auto &end = range.GetEnd();
90 if (begin.IsNormal() && index < begin) {
92 contained = false;
93 } else if (end.IsNormal() && index >= end) {
95 contained = false;
96 } else if (begin.IsNormal()) {
97 // This normal bin is contained in the range. Its index must be shifted according to the begin of the
98 // range.
99 index -= begin.GetIndex();
100 assert(!index.IsInvalid());
101 }
102 }
103 }
104
105 if (auto *opRebin = sliceSpec.GetOperationRebin()) {
106 if (index.IsNormal()) {
107 index = RBinIndex(index.GetIndex() / opRebin->GetNGroup());
108 }
109 } else if (sliceSpec.GetOperationSum() != nullptr) {
110 // This dimension disappears. If there is a range and the index is not contained, discard it.
111 if (!contained) {
112 return false;
113 }
114 // Otherwise got to the next dimension.
115 continue;
116 }
117
119 mappedPos++;
120 }
121
122 // If we got here, the loop should have filled all mapped indices.
123 assert(mappedPos == mapped.size());
124 return true;
125 }
126};
127
128} // namespace Internal
129} // namespace Experimental
130} // namespace ROOT
131
132#endif
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Mapper of bin indices for slice operations.
bool Map(const std::vector< RBinIndex > &original, std::vector< RBinIndex > &mapped) const
Map a vector of RBinIndex according to the slice specifications.
RSliceBinIndexMapper(std::vector< RSliceSpec > sliceSpecs)
const std::vector< RSliceSpec > & GetSliceSpecs() const
std::size_t fMappedDimensionality
The expected dimensionality of the mapped indices.
std::vector< RSliceSpec > fSliceSpecs
The requested slice specifications.
static std::size_t ComputeMappedDimensionality(const std::vector< RSliceSpec > &sliceSpecs)
A bin index with special values for underflow and overflow bins.
Definition RBinIndex.hxx:23
static RBinIndex Overflow()
static RBinIndex Underflow()
Specification of a slice operation along one dimension.