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 "RBinIndex.hxx"
10#include "RRegularAxis.hxx"
11#include "RVariableBinAxis.hxx"
12
13#include <array>
14#include <cassert>
15#include <cstddef>
16#include <stdexcept>
17#include <tuple>
18#include <utility>
19#include <variant>
20#include <vector>
21
22class TBuffer;
23
24namespace ROOT {
25namespace Experimental {
26
27/// Variant of all supported axis types.
28using RAxisVariant = std::variant<RRegularAxis, RVariableBinAxis>;
29
30// forward declaration for friend declaration
31template <typename T>
32class RHistEngine;
33
34namespace Internal {
35
36/**
37Bin configurations for all dimensions of a histogram.
38*/
39class RAxes final {
40 template <typename T>
41 friend class ::ROOT::Experimental::RHistEngine;
42
43 std::vector<RAxisVariant> fAxes;
44
45public:
46 /// \param[in] axes the axis objects, must have size > 0
47 explicit RAxes(std::vector<RAxisVariant> axes) : fAxes(std::move(axes))
48 {
49 if (fAxes.empty()) {
50 throw std::invalid_argument("must have at least 1 axis object");
51 }
52 }
53
54 std::size_t GetNDimensions() const { return fAxes.size(); }
55 const std::vector<RAxisVariant> &Get() const { return fAxes; }
56
57 friend bool operator==(const RAxes &lhs, const RAxes &rhs) { return lhs.fAxes == rhs.fAxes; }
58 friend bool operator!=(const RAxes &lhs, const RAxes &rhs) { return !(lhs == rhs); }
59
60 /// Compute the total number of bins for all axes.
61 ///
62 /// It is the product of each dimension's total number of bins.
63 ///
64 /// \return the total number of bins
65 std::size_t ComputeTotalNBins() const
66 {
67 std::size_t totalNBins = 1;
68 for (auto &&axis : fAxes) {
69 if (auto *regular = std::get_if<RRegularAxis>(&axis)) {
70 totalNBins *= regular->GetTotalNBins();
71 } else if (auto *variable = std::get_if<RVariableBinAxis>(&axis)) {
72 totalNBins *= variable->GetTotalNBins();
73 } else {
74 throw std::logic_error("unimplemented axis type"); // GCOVR_EXCL_LINE
75 }
76 }
77 return totalNBins;
78 }
79
80private:
81 template <std::size_t I, std::size_t N, typename... A>
82 RLinearizedIndex ComputeGlobalIndexImpl(std::size_t index, const std::tuple<A...> &args) const
83 {
84 const auto &axis = fAxes[I];
86 if (auto *regular = std::get_if<RRegularAxis>(&axis)) {
87 index *= regular->GetTotalNBins();
88 linIndex = regular->ComputeLinearizedIndex(std::get<I>(args));
89 } else if (auto *variable = std::get_if<RVariableBinAxis>(&axis)) {
90 index *= variable->GetTotalNBins();
91 linIndex = variable->ComputeLinearizedIndex(std::get<I>(args));
92 } else {
93 throw std::logic_error("unimplemented axis type"); // GCOVR_EXCL_LINE
94 }
95 if (!linIndex.fValid) {
96 return {0, false};
97 }
98 index += linIndex.fIndex;
99 if constexpr (I + 1 < N) {
101 }
102 return {index, true};
103 }
104
105 template <std::size_t N, typename... A>
106 RLinearizedIndex ComputeGlobalIndexImpl(const std::tuple<A...> &args) const
107 {
108 return ComputeGlobalIndexImpl<0, N>(0, args);
109 }
110
111public:
112 /// Compute the global index for all axes.
113 ///
114 /// \param[in] args the arguments
115 /// \return the global index that may be invalid
116 template <typename... A>
117 RLinearizedIndex ComputeGlobalIndex(const std::tuple<A...> &args) const
118 {
119 if (sizeof...(A) != fAxes.size()) {
120 throw std::invalid_argument("invalid number of arguments to ComputeGlobalIndex");
121 }
122 return ComputeGlobalIndexImpl<sizeof...(A)>(args);
123 }
124
125 /// Compute the global index for all axes.
126 ///
127 /// \param[in] indices the array of RBinIndex
128 /// \return the global index that may be invalid
129 template <std::size_t N>
130 RLinearizedIndex ComputeGlobalIndex(const std::array<RBinIndex, N> &indices) const
131 {
132 if (N != fAxes.size()) {
133 throw std::invalid_argument("invalid number of indices passed to ComputeGlobalIndex");
134 }
135 std::size_t globalIndex = 0;
136 for (std::size_t i = 0; i < N; i++) {
137 const auto &index = indices[i];
138 const auto &axis = fAxes[i];
140 if (auto *regular = std::get_if<RRegularAxis>(&axis)) {
141 globalIndex *= regular->GetTotalNBins();
142 linIndex = regular->GetLinearizedIndex(index);
143 } else if (auto *variable = std::get_if<RVariableBinAxis>(&axis)) {
144 globalIndex *= variable->GetTotalNBins();
145 linIndex = variable->GetLinearizedIndex(index);
146 } else {
147 throw std::logic_error("unimplemented axis type"); // GCOVR_EXCL_LINE
148 }
149 if (!linIndex.fValid) {
150 return {0, false};
151 }
152 globalIndex += linIndex.fIndex;
153 }
154 return {globalIndex, true};
155 }
156
157 /// %ROOT Streamer function to throw when trying to store an object of this class.
158 void Streamer(TBuffer &) { throw std::runtime_error("unable to store RAxes"); }
159};
160
161} // namespace Internal
162} // namespace Experimental
163} // namespace ROOT
164
165#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:39
friend bool operator==(const RAxes &lhs, const RAxes &rhs)
Definition RAxes.hxx:57
std::size_t GetNDimensions() const
Definition RAxes.hxx:54
friend bool operator!=(const RAxes &lhs, const RAxes &rhs)
Definition RAxes.hxx:58
RLinearizedIndex ComputeGlobalIndexImpl(std::size_t index, const std::tuple< A... > &args) const
Definition RAxes.hxx:82
RLinearizedIndex ComputeGlobalIndex(const std::tuple< A... > &args) const
Compute the global index for all axes.
Definition RAxes.hxx:117
std::size_t ComputeTotalNBins() const
Compute the total number of bins for all axes.
Definition RAxes.hxx:65
RLinearizedIndex ComputeGlobalIndexImpl(const std::tuple< A... > &args) const
Definition RAxes.hxx:106
RAxes(std::vector< RAxisVariant > axes)
Definition RAxes.hxx:47
void Streamer(TBuffer &)
ROOT Streamer function to throw when trying to store an object of this class.
Definition RAxes.hxx:158
RLinearizedIndex ComputeGlobalIndex(const std::array< RBinIndex, N > &indices) const
Compute the global index for all axes.
Definition RAxes.hxx:130
std::vector< RAxisVariant > fAxes
Definition RAxes.hxx:43
const std::vector< RAxisVariant > & Get() const
Definition RAxes.hxx:55
A histogram data structure to bin data along multiple dimensions.
Buffer base class used for serializing objects.
Definition TBuffer.h:43
#define I(x, y, z)
std::variant< RRegularAxis, RVariableBinAxis > RAxisVariant
Variant of all supported axis types.
Definition RAxes.hxx:28
A linearized index that can be invalid.