Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RHist.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_RHist
6#define ROOT_RHist
7
8#include "RAxisVariant.hxx"
9#include "RBinIndex.hxx"
10#include "RCategoricalAxis.hxx"
11#include "RHistEngine.hxx"
12#include "RHistStats.hxx"
13#include "RRegularAxis.hxx"
14#include "RWeight.hxx"
15
16#include <array>
17#include <cstddef>
18#include <cstdint>
19#include <stdexcept>
20#include <tuple>
21#include <utility>
22#include <variant>
23#include <vector>
24
25class TBuffer;
26
27namespace ROOT {
28namespace Experimental {
29
30// forward declaration for friend declaration
31template <typename BinContentType>
32class RHistFillContext;
33
34/**
35A histogram for aggregation of data along multiple dimensions.
36
37Every call to \ref Fill(const A &... args) "Fill" increments the bin content and is reflected in global statistics:
38\code
39ROOT::Experimental::RHist<int> hist(10, {5, 15});
40hist.Fill(8.5);
41// hist.GetBinContent(ROOT::Experimental::RBinIndex(3)) will return 1
42\endcode
43
44The class is templated on the bin content type. For counting, as in the example above, it may be an integral type such
45as `int` or `long`. Narrower types such as `unsigned char` or `short` are supported, but may overflow due to their
46limited range and must be used with care. For weighted filling, the bin content type must not be an integral type, but
47a floating-point type such as `float` or `double`, or the special type RBinWithError. Note that `float` has a limited
48significand precision of 24 bits.
49
50An object can have arbitrary dimensionality determined at run-time. The axis configuration is passed as a vector of
51RAxisVariant:
52\code
53std::vector<ROOT::Experimental::RAxisVariant> axes;
54axes.push_back(ROOT::Experimental::RRegularAxis(10, 5, 15));
55axes.push_back(ROOT::Experimental::RVariableBinAxis({1, 10, 100, 1000}));
56ROOT::Experimental::RHist<int> hist(axes);
57// hist.GetNDimensions() will return 2
58\endcode
59
60\warning This is part of the %ROOT 7 prototype! It will change without notice. It might trigger earthquakes.
61Feedback is welcome!
62*/
63template <typename BinContentType>
64class RHist final {
65 friend class RHistFillContext<BinContentType>;
66
67 /// The histogram engine including the bin contents.
69 /// The global histogram statistics.
71
72 /// Private constructor based off an engine.
74
75public:
76 /// Construct a histogram.
77 ///
78 /// \param[in] axes the axis objects, must have size > 0
79 explicit RHist(std::vector<RAxisVariant> axes) : fEngine(std::move(axes)), fStats(fEngine.GetNDimensions())
80 {
81 // The axes parameter was moved, use from the engine.
82 const auto &engineAxes = fEngine.GetAxes();
83 for (std::size_t i = 0; i < engineAxes.size(); i++) {
84 if (engineAxes[i].GetCategoricalAxis() != nullptr) {
86 }
87 }
88 }
89
90 /// Construct a histogram.
91 ///
92 /// Note that there is no perfect forwarding of the axis objects. If that is needed, use the
93 /// \ref RHist(std::vector<RAxisVariant> axes) "overload accepting a std::vector".
94 ///
95 /// \param[in] axes the axis objects, must have size > 0
96 explicit RHist(std::initializer_list<RAxisVariant> axes) : RHist(std::vector(axes)) {}
97
98 /// Construct a histogram.
99 ///
100 /// Note that there is no perfect forwarding of the axis objects. If that is needed, use the
101 /// \ref RHist(std::vector<RAxisVariant> axes) "overload accepting a std::vector".
102 ///
103 /// \param[in] axis1 the first axis object
104 /// \param[in] axes the remaining axis objects
105 template <typename... Axes>
106 explicit RHist(const RAxisVariant &axis1, const Axes &...axes) : RHist(std::vector<RAxisVariant>{axis1, axes...})
107 {
108 }
109
110 /// Construct a one-dimensional histogram with a regular axis.
111 ///
112 /// \param[in] nNormalBins the number of normal bins, must be > 0
113 /// \param[in] interval the axis interval (lower end inclusive, upper end exclusive)
114 /// \par See also
115 /// the \ref RRegularAxis::RRegularAxis(std::uint64_t nNormalBins, std::pair<double, double> interval, bool
116 /// enableFlowBins) "constructor of RRegularAxis"
117 RHist(std::uint64_t nNormalBins, std::pair<double, double> interval)
119 {
120 }
121
122 /// The copy constructor is deleted.
123 ///
124 /// Copying all bin contents can be an expensive operation, depending on the number of bins. If required, users can
125 /// explicitly call Clone().
126 RHist(const RHist &) = delete;
127 /// Efficiently move construct a histogram.
128 ///
129 /// After this operation, the moved-from object is invalid.
130 RHist(RHist &&) = default;
131
132 /// The copy assignment operator is deleted.
133 ///
134 /// Copying all bin contents can be an expensive operation, depending on the number of bins. If required, users can
135 /// explicitly call Clone().
136 RHist &operator=(const RHist &) = delete;
137 /// Efficiently move a histogram.
138 ///
139 /// After this operation, the moved-from object is invalid.
140 RHist &operator=(RHist &&) = default;
141
142 ~RHist() = default;
143
145 const RHistStats &GetStats() const { return fStats; }
146
147 const std::vector<RAxisVariant> &GetAxes() const { return fEngine.GetAxes(); }
148 std::size_t GetNDimensions() const { return fEngine.GetNDimensions(); }
149 std::uint64_t GetTotalNBins() const { return fEngine.GetTotalNBins(); }
150
151 std::uint64_t GetNEntries() const { return fStats.GetNEntries(); }
152 /// \copydoc RHistStats::ComputeNEffectiveEntries()
154 /// \copydoc RHistStats::ComputeMean()
155 double ComputeMean(std::size_t dim = 0) const { return fStats.ComputeMean(dim); }
156 /// \copydoc RHistStats::ComputeStdDev()
157 double ComputeStdDev(std::size_t dim = 0) const { return fStats.ComputeStdDev(dim); }
158
159 /// Get the content of a single bin.
160 ///
161 /// \code
162 /// ROOT::Experimental::RHist<int> hist({/* two dimensions */});
163 /// std::array<ROOT::Experimental::RBinIndex, 2> indices = {3, 5};
164 /// int content = hist.GetBinContent(indices);
165 /// \endcode
166 ///
167 /// \note Compared to TH1 conventions, the first normal bin has index 0 and underflow and overflow bins are special
168 /// values. See also the class documentation of RBinIndex.
169 ///
170 /// Throws an exception if the number of indices does not match the axis configuration or the bin is not found.
171 ///
172 /// \param[in] indices the array of indices for each axis
173 /// \return the bin content
174 /// \par See also
175 /// the \ref GetBinContent(const A &... args) const "variadic function template overload" accepting arguments
176 /// directly
177 template <std::size_t N>
178 const BinContentType &GetBinContent(const std::array<RBinIndex, N> &indices) const
179 {
180 return fEngine.GetBinContent(indices);
181 }
182
183 /// Get the content of a single bin.
184 ///
185 /// \code
186 /// ROOT::Experimental::RHist<int> hist({/* two dimensions */});
187 /// int content = hist.GetBinContent(ROOT::Experimental::RBinIndex(3), ROOT::Experimental::RBinIndex(5));
188 /// // ... or construct the RBinIndex arguments implicitly from integers:
189 /// content = hist.GetBinContent(3, 5);
190 /// \endcode
191 ///
192 /// \note Compared to TH1 conventions, the first normal bin has index 0 and underflow and overflow bins are special
193 /// values. See also the class documentation of RBinIndex.
194 ///
195 /// Throws an exception if the number of arguments does not match the axis configuration or the bin is not found.
196 ///
197 /// \param[in] args the arguments for each axis
198 /// \return the bin content
199 /// \par See also
200 /// the \ref GetBinContent(const std::array<RBinIndex, N> &indices) const "function overload" accepting
201 /// `std::array`
202 template <typename... A>
203 const BinContentType &GetBinContent(const A &...args) const
204 {
205 return fEngine.GetBinContent(args...);
206 }
207
208 /// Add all bin contents and statistics of another histogram.
209 ///
210 /// Throws an exception if the axes configurations are not identical.
211 ///
212 /// \param[in] other another histogram
213 void Add(const RHist &other)
214 {
215 fEngine.Add(other.fEngine);
216 fStats.Add(other.fStats);
217 }
218
219 /// Add all bin contents and statistics of another histogram using atomic instructions.
220 ///
221 /// Throws an exception if the axes configurations are not identical.
222 ///
223 /// \param[in] other another histogram that must not be modified during the operation
224 void AddAtomic(const RHist &other)
225 {
226 fEngine.AddAtomic(other.fEngine);
227 fStats.AddAtomic(other.fStats);
228 }
229
230 /// Clear all bin contents and statistics.
231 void Clear()
232 {
233 fEngine.Clear();
234 fStats.Clear();
235 }
236
237 /// Clone this histogram.
238 ///
239 /// Copying all bin contents can be an expensive operation, depending on the number of bins.
240 ///
241 /// \return the cloned object
242 RHist Clone() const
243 {
244 RHist h(fEngine.Clone());
245 h.fStats = fStats;
246 return h;
247 }
248
249 /// Fill an entry into the histogram.
250 ///
251 /// \code
252 /// ROOT::Experimental::RHist<int> hist({/* two dimensions */});
253 /// auto args = std::make_tuple(8.5, 10.5);
254 /// hist.Fill(args);
255 /// \endcode
256 ///
257 /// If one of the arguments is outside the corresponding axis and flow bins are disabled, the entry will be silently
258 /// discarded.
259 ///
260 /// Throws an exception if the number of arguments does not match the axis configuration, or if an argument cannot be
261 /// converted for the axis type at run-time.
262 ///
263 /// \param[in] args the arguments for each axis
264 /// \par See also
265 /// the \ref Fill(const A &... args) "variadic function template overload" accepting arguments directly and the
266 /// \ref Fill(const std::tuple<A...> &args, RWeight weight) "overload for weighted filling"
267 template <typename... A>
268 void Fill(const std::tuple<A...> &args)
269 {
270 fEngine.Fill(args);
271 fStats.Fill(args);
272 }
273
274 /// Fill an entry into the histogram with a weight.
275 ///
276 /// This overload is not available for integral bin content types (see \ref RHistEngine::SupportsWeightedFilling).
277 ///
278 /// \code
279 /// ROOT::Experimental::RHist<float> hist({/* two dimensions */});
280 /// auto args = std::make_tuple(8.5, 10.5);
281 /// hist.Fill(args, ROOT::Experimental::RWeight(0.8));
282 /// \endcode
283 ///
284 /// If one of the arguments is outside the corresponding axis and flow bins are disabled, the entry will be silently
285 /// discarded.
286 ///
287 /// Throws an exception if the number of arguments does not match the axis configuration, or if an argument cannot be
288 /// converted for the axis type at run-time.
289 ///
290 /// \param[in] args the arguments for each axis
291 /// \param[in] weight the weight for this entry
292 /// \par See also
293 /// the \ref Fill(const A &... args) "variadic function template overload" accepting arguments directly and the
294 /// \ref Fill(const std::tuple<A...> &args) "overload for unweighted filling"
295 template <typename... A>
296 void Fill(const std::tuple<A...> &args, RWeight weight)
297 {
298 fEngine.Fill(args, weight);
299 fStats.Fill(args, weight);
300 }
301
302 /// Fill an entry into the histogram.
303 ///
304 /// \code
305 /// ROOT::Experimental::RHist<int> hist({/* two dimensions */});
306 /// hist.Fill(8.5, 10.5);
307 /// \endcode
308 ///
309 /// For weighted filling, pass an RWeight as the last argument:
310 /// \code
311 /// ROOT::Experimental::RHist<float> hist({/* two dimensions */});
312 /// hist.Fill(8.5, 10.5, ROOT::Experimental::RWeight(0.8));
313 /// \endcode
314 /// This is not available for integral bin content types (see \ref RHistEngine::SupportsWeightedFilling).
315 ///
316 /// If one of the arguments is outside the corresponding axis and flow bins are disabled, the entry will be silently
317 /// discarded.
318 ///
319 /// Throws an exception if the number of arguments does not match the axis configuration, or if an argument cannot be
320 /// converted for the axis type at run-time.
321 ///
322 /// \param[in] args the arguments for each axis
323 /// \par See also
324 /// the function overloads accepting `std::tuple` \ref Fill(const std::tuple<A...> &args) "for unweighted filling"
325 /// and \ref Fill(const std::tuple<A...> &args, RWeight) "for weighted filling"
326 template <typename... A>
327 void Fill(const A &...args)
328 {
329 static_assert(sizeof...(A) >= 1, "need at least one argument to Fill");
330 if constexpr (sizeof...(A) >= 1) {
331 fEngine.Fill(args...);
332 fStats.Fill(args...);
333 }
334 }
335
336 /// Scale all histogram bin contents and statistics.
337 ///
338 /// This method is not available for integral bin content types.
339 ///
340 /// \param[in] factor the scale factor
341 void Scale(double factor)
342 {
343 fEngine.Scale(factor);
344 fStats.Scale(factor);
345 }
346
347 /// %ROOT Streamer function to throw when trying to store an object of this class.
348 void Streamer(TBuffer &) { throw std::runtime_error("unable to store RHist"); }
349};
350
351} // namespace Experimental
352} // namespace ROOT
353
354#endif
#define h(i)
Definition RSha256.hxx:106
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
A variant of all supported axis types.
A context to concurrently fill an RHist.
Histogram statistics of unbinned values.
void Add(const RHistStats &other)
Add all entries from another statistics object.
void Clear()
Clear this statistics object.
void AddAtomic(const RHistStats &other)
Add all entries from another statistics object using atomic instructions.
void Scale(double factor)
Scale the histogram statistics.
void Fill(const std::tuple< A... > &args)
Fill an entry into this statistics object.
double ComputeNEffectiveEntries() const
Compute the number of effective entries.
void DisableDimension(std::size_t dim)
Disable one dimension of this statistics object.
std::uint64_t GetNEntries() const
double ComputeMean(std::size_t dim=0) const
Compute the arithmetic mean of unbinned values.
double ComputeStdDev(std::size_t dim=0) const
Compute the standard deviation of unbinned values.
A histogram for aggregation of data along multiple dimensions.
Definition RHist.hxx:64
RHist(const RHist &)=delete
The copy constructor is deleted.
double ComputeMean(std::size_t dim=0) const
Compute the arithmetic mean of unbinned values.
Definition RHist.hxx:155
RHist(std::uint64_t nNormalBins, std::pair< double, double > interval)
Construct a one-dimensional histogram with a regular axis.
Definition RHist.hxx:117
std::size_t GetNDimensions() const
Definition RHist.hxx:148
RHist Clone() const
Clone this histogram.
Definition RHist.hxx:242
RHist & operator=(RHist &&)=default
Efficiently move a histogram.
RHist(const RAxisVariant &axis1, const Axes &...axes)
Construct a histogram.
Definition RHist.hxx:106
void Scale(double factor)
Scale all histogram bin contents and statistics.
Definition RHist.hxx:341
RHist(std::initializer_list< RAxisVariant > axes)
Construct a histogram.
Definition RHist.hxx:96
void Fill(const std::tuple< A... > &args)
Fill an entry into the histogram.
Definition RHist.hxx:268
RHist & operator=(const RHist &)=delete
The copy assignment operator is deleted.
RHistStats fStats
The global histogram statistics.
Definition RHist.hxx:70
void AddAtomic(const RHist &other)
Add all bin contents and statistics of another histogram using atomic instructions.
Definition RHist.hxx:224
void Fill(const std::tuple< A... > &args, RWeight weight)
Fill an entry into the histogram with a weight.
Definition RHist.hxx:296
RHistEngine< BinContentType > fEngine
The histogram engine including the bin contents.
Definition RHist.hxx:68
double ComputeNEffectiveEntries() const
Compute the number of effective entries.
Definition RHist.hxx:153
std::uint64_t GetTotalNBins() const
Definition RHist.hxx:149
RHist(std::vector< RAxisVariant > axes)
Construct a histogram.
Definition RHist.hxx:79
const RHistStats & GetStats() const
Definition RHist.hxx:145
const RHistEngine< BinContentType > & GetEngine() const
Definition RHist.hxx:144
void Streamer(TBuffer &)
ROOT Streamer function to throw when trying to store an object of this class.
Definition RHist.hxx:348
void Fill(const A &...args)
Fill an entry into the histogram.
Definition RHist.hxx:327
double ComputeStdDev(std::size_t dim=0) const
Compute the standard deviation of unbinned values.
Definition RHist.hxx:157
RHist(RHist &&)=default
Efficiently move construct a histogram.
const BinContentType & GetBinContent(const std::array< RBinIndex, N > &indices) const
Get the content of a single bin.
Definition RHist.hxx:178
const std::vector< RAxisVariant > & GetAxes() const
Definition RHist.hxx:147
void Add(const RHist &other)
Add all bin contents and statistics of another histogram.
Definition RHist.hxx:213
RHist(RHistEngine< BinContentType > engine)
Private constructor based off an engine.
Definition RHist.hxx:73
const BinContentType & GetBinContent(const A &...args) const
Get the content of a single bin.
Definition RHist.hxx:203
void Clear()
Clear all bin contents and statistics.
Definition RHist.hxx:231
std::uint64_t GetNEntries() const
Definition RHist.hxx:151
A regular axis with equidistant bins in the interval .
Buffer base class used for serializing objects.
Definition TBuffer.h:43
A weight for filling histograms.
Definition RWeight.hxx:17