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 <cstdint>
13#include <stdexcept>
14#include <utility>
15#include <vector>
16
17namespace ROOT {
18namespace Experimental {
19namespace Internal {
20
21/**
22Mapper of bin indices for slice operations.
23*/
25 /// The requested slice specifications
26 std::vector<RSliceSpec> fSliceSpecs;
27 /// The expected dimensionality of the mapped indices
29
30 static std::size_t ComputeMappedDimensionality(const std::vector<RSliceSpec> &sliceSpecs)
31 {
32 std::size_t dimensionality = 0;
33 for (auto &&spec : sliceSpecs) {
34 // A sum operation makes the dimension disappear.
35 if (spec.GetOperationSum() == nullptr) {
37 }
38 }
39 return dimensionality;
40 }
41
42public:
43 /// \param[in] sliceSpecs the slice specifications, must have size > 0
44 explicit RSliceBinIndexMapper(std::vector<RSliceSpec> sliceSpecs)
46 {
47 if (fSliceSpecs.empty()) {
48 throw std::invalid_argument("must have at least 1 slice specification");
49 }
50 }
51
52 const std::vector<RSliceSpec> &GetSliceSpecs() const { return fSliceSpecs; }
53 std::size_t GetMappedDimensionality() const { return fMappedDimensionality; }
54
55 /// Map a vector of RBinIndex according to the slice specifications.
56 ///
57 /// \param[in] original the original bin indices
58 /// \param[out] mapped the mapped bin indices
59 /// \return whether the mapping was successful or the bin content should be discarded
60 bool Map(const std::vector<RBinIndex> &original, std::vector<RBinIndex> &mapped) const
61 {
62 if (original.size() != fSliceSpecs.size()) {
63 throw std::invalid_argument("invalid number of original indices passed to RSliceBinIndexMapper::Map");
64 }
65 if (mapped.size() != fMappedDimensionality) {
66 throw std::invalid_argument("invalid size of mapped indices passed to RSliceBinIndexMapper::Map");
67 }
68
69 std::size_t mappedPos = 0;
70 for (std::size_t i = 0; i < original.size(); i++) {
72 if (index.IsInvalid()) {
73 throw std::invalid_argument("invalid bin index passed to RSliceBinIndexMapper::Map");
74 }
75
77 const auto &range = sliceSpec.GetRange();
78 bool contained = true;
79 if (!range.IsInvalid()) {
80 // Underflow and overflow indices map to themselves, but they may not actually be contained in the range.
81 // This is important for the sum operation below.
82 if (index.IsUnderflow()) {
83 contained = range.GetBegin().IsUnderflow();
84 } else if (index.IsOverflow()) {
85 contained = range.GetEnd().IsInvalid();
86 } else if (index.IsNormal()) {
87 const auto &begin = range.GetBegin();
88 const auto &end = range.GetEnd();
89 if (begin.IsNormal() && index < begin) {
91 contained = false;
92 } else if (end.IsNormal() && index >= end) {
94 contained = false;
95 } else if (begin.IsNormal()) {
96 // This normal bin is contained in the range. Its index must be shifted according to the begin of the
97 // range.
98 index -= begin.GetIndex();
99 assert(!index.IsInvalid());
100 }
101 }
102 }
103
104 if (auto *opRebin = sliceSpec.GetOperationRebin()) {
105 if (index.IsNormal()) {
106 index = RBinIndex(index.GetIndex() / opRebin->GetNGroup());
107 }
108 } else if (sliceSpec.GetOperationSum() != nullptr) {
109 // This dimension disappears. If there is a range and the index is not contained, discard it.
110 if (!contained) {
111 return false;
112 }
113 // Otherwise got to the next dimension.
114 continue;
115 }
116
118 mappedPos++;
119 }
120
121 // If we got here, the loop should have filled all mapped indices.
122 assert(mappedPos == mapped.size());
123 return true;
124 }
125};
126
127} // namespace Internal
128} // namespace Experimental
129} // namespace ROOT
130
131#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.