Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RAxes.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_RAxes
6#define ROOT_RAxes
7
8#include "RAxisVariant.hxx"
9#include "RBinIndex.hxx"
11#include "RBinIndexRange.hxx"
12#include "RCategoricalAxis.hxx"
13#include "RLinearizedIndex.hxx"
14#include "RRegularAxis.hxx"
15#include "RVariableBinAxis.hxx"
16
17#include <array>
18#include <cstddef>
19#include <cstdint>
20#include <stdexcept>
21#include <tuple>
22#include <type_traits>
23#include <utility>
24#include <vector>
25
26class TBuffer;
27
28namespace ROOT {
29namespace Experimental {
30
31// forward declaration for friend declaration
32template <typename T>
33class RHistEngine;
34
35namespace Internal {
36
37/**
38Bin configurations for all dimensions of a histogram.
39*/
40class RAxes final {
41 template <typename T>
42 friend class ::ROOT::Experimental::RHistEngine;
43
44 std::vector<RAxisVariant> fAxes;
45
46public:
47 /// \param[in] axes the axis objects, must have size > 0
48 explicit RAxes(std::vector<RAxisVariant> axes) : fAxes(std::move(axes))
49 {
50 if (fAxes.empty()) {
51 throw std::invalid_argument("must have at least 1 axis object");
52 }
53 }
54
55 std::size_t GetNDimensions() const { return fAxes.size(); }
56 const std::vector<RAxisVariant> &Get() const { return fAxes; }
57
58 friend bool operator==(const RAxes &lhs, const RAxes &rhs) { return lhs.fAxes == rhs.fAxes; }
59 friend bool operator!=(const RAxes &lhs, const RAxes &rhs) { return !(lhs == rhs); }
60
61 /// Compute the total number of bins for all axes.
62 ///
63 /// It is the product of each dimension's total number of bins.
64 ///
65 /// \return the total number of bins
66 std::uint64_t ComputeTotalNBins() const
67 {
68 std::uint64_t totalNBins = 1;
69 for (auto &&axis : fAxes) {
70 totalNBins *= axis.GetTotalNBins();
71 }
72 return totalNBins;
73 }
74
75private:
76 template <std::size_t I, std::size_t N, typename... A>
77 RLinearizedIndex ComputeGlobalIndexImpl(std::size_t index, const std::tuple<A...> &args) const
78 {
79 using ArgumentType = std::tuple_element_t<I, std::tuple<A...>>;
80 const auto &axis = fAxes[I];
82 if (auto *regular = axis.GetRegularAxis()) {
83 if constexpr (std::is_convertible_v<ArgumentType, RRegularAxis::ArgumentType>) {
84 index *= regular->GetTotalNBins();
85 linIndex = regular->ComputeLinearizedIndex(std::get<I>(args));
86 } else {
87 throw std::invalid_argument("invalid type of argument");
88 }
89 } else if (auto *variable = axis.GetVariableBinAxis()) {
90 if constexpr (std::is_convertible_v<ArgumentType, RVariableBinAxis::ArgumentType>) {
91 index *= variable->GetTotalNBins();
92 linIndex = variable->ComputeLinearizedIndex(std::get<I>(args));
93 } else {
94 throw std::invalid_argument("invalid type of argument");
95 }
96 } else if (auto *categorical = axis.GetCategoricalAxis()) {
97 if constexpr (std::is_convertible_v<ArgumentType, RCategoricalAxis::ArgumentType>) {
98 index *= categorical->GetTotalNBins();
99 linIndex = categorical->ComputeLinearizedIndex(std::get<I>(args));
100 } else {
101 throw std::invalid_argument("invalid type of argument");
102 }
103 } else {
104 throw std::logic_error("unimplemented axis type"); // GCOVR_EXCL_LINE
105 }
106 if (!linIndex.fValid) {
107 return {0, false};
108 }
109 index += linIndex.fIndex;
110 if constexpr (I + 1 < N) {
112 }
113 return {index, true};
114 }
115
116 template <std::size_t N, typename... A>
117 RLinearizedIndex ComputeGlobalIndexImpl(const std::tuple<A...> &args) const
118 {
119 return ComputeGlobalIndexImpl<0, N>(0, args);
120 }
121
122public:
123 /// Compute the global index for all axes.
124 ///
125 /// Throws an exception if the number of arguments does not match the axis configuration, or if an argument cannot be
126 /// converted for the axis type at run-time.
127 ///
128 /// \param[in] args the arguments
129 /// \return the global index that may be invalid
130 template <typename... A>
131 RLinearizedIndex ComputeGlobalIndex(const std::tuple<A...> &args) const
132 {
133 if (sizeof...(A) != fAxes.size()) {
134 throw std::invalid_argument("invalid number of arguments to ComputeGlobalIndex");
135 }
136 return ComputeGlobalIndexImpl<sizeof...(A)>(args);
137 }
138
139private:
140 template <typename Container>
142 {
143 const auto N = indices.size();
144 if (N != fAxes.size()) {
145 throw std::invalid_argument("invalid number of indices passed to ComputeGlobalIndex");
146 }
147 std::uint64_t globalIndex = 0;
148 for (std::size_t i = 0; i < N; i++) {
149 const auto &index = indices[i];
150 const auto &axis = fAxes[i];
152 if (auto *regular = axis.GetRegularAxis()) {
153 globalIndex *= regular->GetTotalNBins();
154 linIndex = regular->GetLinearizedIndex(index);
155 } else if (auto *variable = axis.GetVariableBinAxis()) {
156 globalIndex *= variable->GetTotalNBins();
157 linIndex = variable->GetLinearizedIndex(index);
158 } else if (auto *categorical = axis.GetCategoricalAxis()) {
159 globalIndex *= categorical->GetTotalNBins();
160 linIndex = categorical->GetLinearizedIndex(index);
161 } else {
162 throw std::logic_error("unimplemented axis type"); // GCOVR_EXCL_LINE
163 }
164 if (!linIndex.fValid) {
165 return {0, false};
166 }
167 globalIndex += linIndex.fIndex;
168 }
169 return {globalIndex, true};
170 }
171
172public:
173 /// Compute the global index for all axes.
174 ///
175 /// \param[in] indices the array of RBinIndex
176 /// \return the global index that may be invalid
177 template <std::size_t N>
178 RLinearizedIndex ComputeGlobalIndex(const std::array<RBinIndex, N> &indices) const
179 {
181 }
182
183 /// Compute the global index for all axes.
184 ///
185 /// \param[in] indices the vector of RBinIndex
186 /// \return the global index that may be invalid
187 RLinearizedIndex ComputeGlobalIndex(const std::vector<RBinIndex> &indices) const
188 {
190 }
191
192 /// Get the multidimensional range of all bins.
193 ///
194 /// \return the multidimensional range
196 {
197 std::vector<RBinIndexRange> ranges;
198 for (auto &&axis : fAxes) {
199 ranges.push_back(axis.GetFullRange());
200 }
201 return RBinIndexMultiDimRange(std::move(ranges));
202 }
203
204 /// %ROOT Streamer function to throw when trying to store an object of this class.
205 void Streamer(TBuffer &) { throw std::runtime_error("unable to store RAxes"); }
206};
207
208} // namespace Internal
209} // namespace Experimental
210} // namespace ROOT
211
212#endif
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define N
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
Bin configurations for all dimensions of a histogram.
Definition RAxes.hxx:40
friend bool operator==(const RAxes &lhs, const RAxes &rhs)
Definition RAxes.hxx:58
std::size_t GetNDimensions() const
Definition RAxes.hxx:55
friend bool operator!=(const RAxes &lhs, const RAxes &rhs)
Definition RAxes.hxx:59
RLinearizedIndex ComputeGlobalIndexImpl(std::size_t index, const std::tuple< A... > &args) const
Definition RAxes.hxx:77
RLinearizedIndex ComputeGlobalIndex(const std::tuple< A... > &args) const
Compute the global index for all axes.
Definition RAxes.hxx:131
RBinIndexMultiDimRange GetFullMultiDimRange() const
Get the multidimensional range of all bins.
Definition RAxes.hxx:195
RLinearizedIndex ComputeGlobalIndexImpl(const std::tuple< A... > &args) const
Definition RAxes.hxx:117
std::uint64_t ComputeTotalNBins() const
Compute the total number of bins for all axes.
Definition RAxes.hxx:66
RAxes(std::vector< RAxisVariant > axes)
Definition RAxes.hxx:48
RLinearizedIndex ComputeGlobalIndexImpl(const Container &indices) const
Definition RAxes.hxx:141
RLinearizedIndex ComputeGlobalIndex(const std::vector< RBinIndex > &indices) const
Compute the global index for all axes.
Definition RAxes.hxx:187
void Streamer(TBuffer &)
ROOT Streamer function to throw when trying to store an object of this class.
Definition RAxes.hxx:205
RLinearizedIndex ComputeGlobalIndex(const std::array< RBinIndex, N > &indices) const
Compute the global index for all axes.
Definition RAxes.hxx:178
std::vector< RAxisVariant > fAxes
Definition RAxes.hxx:44
const std::vector< RAxisVariant > & Get() const
Definition RAxes.hxx:56
A multidimensional range of bin indices.
Buffer base class used for serializing objects.
Definition TBuffer.h:43
#define I(x, y, z)
A linearized index that can be invalid.