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