Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RHistEngine.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_RHistEngine
6#define ROOT_RHistEngine
7
8#include "RAxes.hxx"
9#include "RBinIndex.hxx"
10#include "RLinearizedIndex.hxx"
11#include "RRegularAxis.hxx"
12
13#include <array>
14#include <cassert>
15#include <stdexcept>
16#include <tuple>
17#include <utility>
18#include <vector>
19
20class TBuffer;
21
22namespace ROOT {
23namespace Experimental {
24
25/**
26A histogram data structure to bin data along multiple dimensions.
27
28Every call to \ref Fill(const A &... args) "Fill" bins the data according to the axis configuration and increments the
29bin content:
30\code
31ROOT::Experimental::RHistEngine<int> hist(10, 5, 15);
32hist.Fill(8.5);
33// hist.GetBinContent(ROOT::Experimental::RBinIndex(3)) will return 1
34\endcode
35
36The class is templated on the bin content type. For counting, as in the example above, it may be an integer type such as
37`int` or `long`. Narrower types such as `unsigned char` or `short` are supported, but may overflow due to their limited
38range and must be used with care. For weighted filling, the bin content type must be a floating-point type such as
39`float` or `double`. Note that `float` has a limited significant precision of 24 bits.
40
41An object can have arbitrary dimensionality determined at run-time. The axis configuration is passed as a vector of
42RAxisVariant:
43\code
44std::vector<ROOT::Experimental::RAxisVariant> axes;
45axes.push_back(ROOT::Experimental::RRegularAxis(10, 5, 15));
46axes.push_back(ROOT::Experimental::RVariableBinAxis({1, 10, 100, 1000}));
47ROOT::Experimental::RHistEngine<int> hist(axes);
48// hist.GetNDimensions() will return 2
49\endcode
50
51\warning This is part of the %ROOT 7 prototype! It will change without notice. It might trigger earthquakes.
52Feedback is welcome!
53*/
54template <typename BinContentType>
56 /// The axis configuration for this histogram. Relevant methods are forwarded from the public interface.
58 /// The bin contents for this histogram
59 std::vector<BinContentType> fBinContents;
60
61public:
62 /// Construct a histogram engine.
63 ///
64 /// \param[in] axes the axis objects, must have size > 0
65 explicit RHistEngine(std::vector<RAxisVariant> axes) : fAxes(std::move(axes))
66 {
68 }
69
70 /// Construct a one-dimensional histogram engine with a regular axis.
71 ///
72 /// \param[in] nNormalBins the number of normal bins, must be > 0
73 /// \param[in] low the lower end of the axis interval (inclusive)
74 /// \param[in] high the upper end of the axis interval (exclusive), must be > low
75 /// \par See also
76 /// the \ref RRegularAxis::RRegularAxis(std::size_t nNormalBins, double low, double high, bool enableFlowBins)
77 /// "constructor of RRegularAxis"
78 RHistEngine(std::size_t nNormalBins, double low, double high) : RHistEngine({RRegularAxis(nNormalBins, low, high)})
79 {
80 }
81
82 // Copy constructor and assignment operator are deleted to avoid surprises.
87 ~RHistEngine() = default;
88
89 const std::vector<RAxisVariant> &GetAxes() const { return fAxes.Get(); }
90 std::size_t GetNDimensions() const { return fAxes.GetNDimensions(); }
91 std::size_t GetTotalNBins() const { return fBinContents.size(); }
92
93 /// Get the content of a single bin.
94 ///
95 /// \code
96 /// ROOT::Experimental::RHistEngine<int> hist({/* two dimensions */});
97 /// std::array<ROOT::Experimental::RBinIndex, 2> indices = {3, 5};
98 /// int content = hist.GetBinContent(indices);
99 /// \endcode
100 ///
101 /// \note Compared to TH1 conventions, the first normal bin has index 0 and underflow and overflow bins are special
102 /// values. See also the class documentation of RBinIndex.
103 ///
104 /// Throws an exception if the number of indices does not match the axis configuration or the bin is not found.
105 ///
106 /// \param[in] indices the array of indices for each axis
107 /// \return the bin content
108 /// \par See also
109 /// the \ref GetBinContent(const A &... args) const "variadic function template overload" accepting arguments
110 /// directly
111 template <std::size_t N>
112 const BinContentType &GetBinContent(const std::array<RBinIndex, N> &indices) const
113 {
114 // We could rely on RAxes::ComputeGlobalIndex to check the number of arguments, but its exception message might
115 // be confusing for users.
116 if (N != GetNDimensions()) {
117 throw std::invalid_argument("invalid number of indices passed to GetBinContent");
118 }
120 if (!index.fValid) {
121 throw std::invalid_argument("bin not found in GetBinContent");
122 }
123 assert(index.fIndex < fBinContents.size());
124 return fBinContents[index.fIndex];
125 }
126
127 /// Get the content of a single bin.
128 ///
129 /// \code
130 /// ROOT::Experimental::RHistEngine<int> hist({/* two dimensions */});
131 /// int content = hist.GetBinContent(ROOT::Experimental::RBinIndex(3), ROOT::Experimental::RBinIndex(5));
132 /// // ... or construct the RBinIndex arguments implicitly from integers:
133 /// content = hist.GetBinContent(3, 5);
134 /// \endcode
135 ///
136 /// \note Compared to TH1 conventions, the first normal bin has index 0 and underflow and overflow bins are special
137 /// values. See also the class documentation of RBinIndex.
138 ///
139 /// Throws an exception if the number of arguments does not match the axis configuration or the bin is not found.
140 ///
141 /// \param[in] args the arguments for each axis
142 /// \return the bin content
143 /// \par See also
144 /// the \ref GetBinContent(const std::array<RBinIndex, N> &indices) const "function overload" accepting
145 /// `std::array`
146 template <typename... A>
147 const BinContentType &GetBinContent(const A &...args) const
148 {
149 std::array<RBinIndex, sizeof...(A)> indices{args...};
150 return GetBinContent(indices);
151 }
152
153 /// Fill an entry into the histogram.
154 ///
155 /// \code
156 /// ROOT::Experimental::RHistEngine<int> hist({/* two dimensions */});
157 /// auto args = std::make_tuple(8.5, 10.5);
158 /// hist.Fill(args);
159 /// \endcode
160 ///
161 /// If one of the arguments is outside the corresponding axis and flow bins are disabled, the entry will be silently
162 /// discarded.
163 ///
164 /// Throws an exception if the number of arguments does not match the axis configuration.
165 ///
166 /// \param[in] args the arguments for each axis
167 /// \par See also
168 /// the \ref Fill(const A &... args) "variadic function template overload" accepting arguments directly
169 template <typename... A>
170 void Fill(const std::tuple<A...> &args)
171 {
172 // We could rely on RAxes::ComputeGlobalIndex to check the number of arguments, but its exception message might
173 // be confusing for users.
174 if (sizeof...(A) != GetNDimensions()) {
175 throw std::invalid_argument("invalid number of arguments to Fill");
176 }
178 if (index.fValid) {
179 assert(index.fIndex < fBinContents.size());
180 fBinContents[index.fIndex]++;
181 }
182 }
183
184 /// Fill an entry into the histogram.
185 ///
186 /// \code
187 /// ROOT::Experimental::RHistEngine<int> hist({/* two dimensions */});
188 /// hist.Fill(8.5, 10.5);
189 /// \endcode
190 ///
191 /// If one of the arguments is outside the corresponding axis and flow bins are disabled, the entry will be silently
192 /// discarded.
193 ///
194 /// Throws an exception if the number of arguments does not match the axis configuration.
195 ///
196 /// \param[in] args the arguments for each axis
197 /// \par See also
198 /// the \ref Fill(const std::tuple<A...> &args) "function overload" accepting `std::tuple`
199 template <typename... A>
200 void Fill(const A &...args)
201 {
202 Fill(std::forward_as_tuple(args...));
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 RHistEngine"); }
207};
208
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:34
std::size_t GetNDimensions() const
Definition RAxes.hxx:46
std::size_t ComputeTotalNBins() const
Compute the total number of bins for all axes.
Definition RAxes.hxx:56
RLinearizedIndex ComputeGlobalIndex(std::size_t index, const std::tuple< A... > &args) const
Definition RAxes.hxx:73
const std::vector< RAxisVariant > & Get() const
Definition RAxes.hxx:47
A bin index with special values for underflow and overflow bins.
Definition RBinIndex.hxx:22
A histogram data structure to bin data along multiple dimensions.
void Fill(const A &...args)
Fill an entry into the histogram.
const std::vector< RAxisVariant > & GetAxes() const
RHistEngine< BinContentType > & operator=(const RHistEngine< BinContentType > &)=delete
std::size_t GetTotalNBins() const
void Fill(const std::tuple< A... > &args)
Fill an entry into the histogram.
RHistEngine< BinContentType > & operator=(RHistEngine< BinContentType > &&)=default
const BinContentType & GetBinContent(const std::array< RBinIndex, N > &indices) const
Get the content of a single bin.
const BinContentType & GetBinContent(const A &...args) const
Get the content of a single bin.
RHistEngine(const RHistEngine< BinContentType > &)=delete
RHistEngine(std::size_t nNormalBins, double low, double high)
Construct a one-dimensional histogram engine with a regular axis.
std::size_t GetNDimensions() const
RHistEngine(std::vector< RAxisVariant > axes)
Construct a histogram engine.
Internal::RAxes fAxes
The axis configuration for this histogram. Relevant methods are forwarded from the public interface.
RHistEngine(RHistEngine< BinContentType > &&)=default
void Streamer(TBuffer &)
ROOT Streamer function to throw when trying to store an object of this class.
std::vector< BinContentType > fBinContents
The bin contents for this histogram.
A regular axis with equidistant bins in the interval .
Buffer base class used for serializing objects.
Definition TBuffer.h:43
Namespace for new ROOT classes and functions.
A linearized index that can be invalid.