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"
11#include "RCategoricalAxis.hxx"
12#include "RHistEngine.hxx"
13#include "RHistStats.hxx"
14#include "RRegularAxis.hxx"
15#include "RWeight.hxx"
16
17#include <array>
18#include <cstddef>
19#include <cstdint>
20#include <stdexcept>
21#include <tuple>
22#include <utility>
23#include <variant>
24#include <vector>
25
26class TBuffer;
27
28namespace ROOT {
29namespace Experimental {
30
31// forward declaration for friend declaration
32template <typename BinContentType>
33class RHistFillContext;
34
35/**
36A histogram for aggregation of data along multiple dimensions.
37
38Every call to \ref Fill(const A &... args) "Fill" increments the bin content and is reflected in global statistics:
39\code
40ROOT::Experimental::RHist<int> hist(10, {5, 15});
41hist.Fill(8.5);
42// hist.GetBinContent(ROOT::Experimental::RBinIndex(3)) will return 1
43\endcode
44
45The class is templated on the bin content type. For counting, as in the example above, it may be an integral type such
46as `int` or `long`. Narrower types such as `unsigned char` or `short` are supported, but may overflow due to their
47limited range and must be used with care. For weighted filling, the bin content type must not be an integral type, but
48a floating-point type such as `float` or `double`, or the special type RBinWithError. Note that `float` has a limited
49significand precision of 24 bits.
50
51An object can have arbitrary dimensionality determined at run-time. The axis configuration is passed as a vector of
52RAxisVariant:
53\code
54std::vector<ROOT::Experimental::RAxisVariant> axes;
55axes.push_back(ROOT::Experimental::RRegularAxis(10, {5, 15}));
56axes.push_back(ROOT::Experimental::RVariableBinAxis({1, 10, 100, 1000}));
57ROOT::Experimental::RHist<int> hist(axes);
58// hist.GetNDimensions() will return 2
59\endcode
60
61\warning This is part of the %ROOT 7 prototype! It will change without notice. It might trigger earthquakes.
62Feedback is welcome!
63*/
64template <typename BinContentType>
65class RHist final {
66 // For conversion, all other template instantiations must be a friend.
67 template <typename U>
68 friend class RHist;
69
70 friend class RHistFillContext<BinContentType>;
71
72 /// The histogram engine including the bin contents.
74 /// The global histogram statistics.
76
77 /// Private constructor based off an engine.
79
80public:
81 /// Construct a histogram.
82 ///
83 /// \param[in] axes the axis objects, must have size > 0
84 explicit RHist(std::vector<RAxisVariant> axes) : fEngine(std::move(axes)), fStats(fEngine.GetNDimensions())
85 {
86 // The axes parameter was moved, use from the engine.
87 const auto &engineAxes = fEngine.GetAxes();
88 for (std::size_t i = 0; i < engineAxes.size(); i++) {
89 if (engineAxes[i].GetCategoricalAxis() != nullptr) {
91 }
92 }
93 }
94
95 /// Construct a histogram.
96 ///
97 /// Note that there is no perfect forwarding of the axis objects. If that is needed, use the
98 /// \ref RHist(std::vector<RAxisVariant> axes) "overload accepting a std::vector".
99 ///
100 /// \param[in] axes the axis objects, must have size > 0
101 explicit RHist(std::initializer_list<RAxisVariant> axes) : RHist(std::vector(axes)) {}
102
103 /// Construct a histogram.
104 ///
105 /// Note that there is no perfect forwarding of the axis objects. If that is needed, use the
106 /// \ref RHist(std::vector<RAxisVariant> axes) "overload accepting a std::vector".
107 ///
108 /// \param[in] axis1 the first axis object
109 /// \param[in] axes the remaining axis objects
110 template <typename... Axes>
111 explicit RHist(const RAxisVariant &axis1, const Axes &...axes) : RHist(std::vector<RAxisVariant>{axis1, axes...})
112 {
113 }
114
115 /// Construct a one-dimensional histogram with a regular axis.
116 ///
117 /// \param[in] nNormalBins the number of normal bins, must be > 0
118 /// \param[in] interval the axis interval (lower end inclusive, upper end exclusive)
119 /// \par See also
120 /// the \ref RRegularAxis::RRegularAxis(std::uint64_t nNormalBins, std::pair<double, double> interval, bool
121 /// enableFlowBins) "constructor of RRegularAxis"
122 RHist(std::uint64_t nNormalBins, std::pair<double, double> interval)
124 {
125 }
126
127 /// The copy constructor is deleted.
128 ///
129 /// Copying all bin contents can be an expensive operation, depending on the number of bins. If required, users can
130 /// explicitly call Clone().
131 RHist(const RHist &) = delete;
132 /// Efficiently move construct a histogram.
133 ///
134 /// After this operation, the moved-from object is invalid.
135 RHist(RHist &&) = default;
136
137 /// The copy assignment operator is deleted.
138 ///
139 /// Copying all bin contents can be an expensive operation, depending on the number of bins. If required, users can
140 /// explicitly call Clone().
141 RHist &operator=(const RHist &) = delete;
142 /// Efficiently move a histogram.
143 ///
144 /// After this operation, the moved-from object is invalid.
145 RHist &operator=(RHist &&) = default;
146
147 ~RHist() = default;
148
150 const RHistStats &GetStats() const { return fStats; }
151
152 const std::vector<RAxisVariant> &GetAxes() const { return fEngine.GetAxes(); }
153 std::size_t GetNDimensions() const { return fEngine.GetNDimensions(); }
154 std::uint64_t GetTotalNBins() const { return fEngine.GetTotalNBins(); }
155
156 std::uint64_t GetNEntries() const { return fStats.GetNEntries(); }
157 /// \copydoc RHistStats::ComputeNEffectiveEntries()
159 /// \copydoc RHistStats::ComputeMean()
160 double ComputeMean(std::size_t dim = 0) const { return fStats.ComputeMean(dim); }
161 /// \copydoc RHistStats::ComputeStdDev()
162 double ComputeStdDev(std::size_t dim = 0) const { return fStats.ComputeStdDev(dim); }
163
164 /// Get the content of a single bin.
165 ///
166 /// \code
167 /// ROOT::Experimental::RHist<int> hist({/* two dimensions */});
168 /// std::array<ROOT::Experimental::RBinIndex, 2> indices = {3, 5};
169 /// int content = hist.GetBinContent(indices);
170 /// \endcode
171 ///
172 /// \note Compared to TH1 conventions, the first normal bin has index 0 and underflow and overflow bins are special
173 /// values. See also the class documentation of RBinIndex.
174 ///
175 /// Throws an exception if the number of indices does not match the axis configuration or the bin is not found.
176 ///
177 /// \param[in] indices the array of indices for each axis
178 /// \return the bin content
179 /// \par See also
180 /// the \ref GetBinContent(const A &... args) const "variadic function template overload" accepting arguments
181 /// directly
182 template <std::size_t N>
183 const BinContentType &GetBinContent(const std::array<RBinIndex, N> &indices) const
184 {
185 return fEngine.GetBinContent(indices);
186 }
187
188 /// Get the content of a single bin.
189 ///
190 /// \code
191 /// ROOT::Experimental::RHist<int> hist({/* two dimensions */});
192 /// std::vector<ROOT::Experimental::RBinIndex> indices = {3, 5};
193 /// int content = hist.GetBinContent(indices);
194 /// \endcode
195 ///
196 /// \note Compared to TH1 conventions, the first normal bin has index 0 and underflow and overflow bins are special
197 /// values. See also the class documentation of RBinIndex.
198 ///
199 /// Throws an exception if the number of indices does not match the axis configuration or the bin is not found.
200 ///
201 /// \param[in] indices the array of indices for each axis
202 /// \return the bin content
203 /// \par See also
204 /// the \ref GetBinContent(const A &... args) const "variadic function template overload" accepting arguments
205 /// directly
206 const BinContentType &GetBinContent(const std::vector<RBinIndex> &indices) const
207 {
208 return fEngine.GetBinContent(indices);
209 }
210
211 /// Get the content of a single bin.
212 ///
213 /// \code
214 /// ROOT::Experimental::RHist<int> hist({/* two dimensions */});
215 /// int content = hist.GetBinContent(ROOT::Experimental::RBinIndex(3), ROOT::Experimental::RBinIndex(5));
216 /// // ... or construct the RBinIndex arguments implicitly from integers:
217 /// content = hist.GetBinContent(3, 5);
218 /// \endcode
219 ///
220 /// \note Compared to TH1 conventions, the first normal bin has index 0 and underflow and overflow bins are special
221 /// values. See also the class documentation of RBinIndex.
222 ///
223 /// Throws an exception if the number of arguments does not match the axis configuration or the bin is not found.
224 ///
225 /// \param[in] args the arguments for each axis
226 /// \return the bin content
227 /// \par See also
228 /// the function overloads accepting \ref GetBinContent(const std::array<RBinIndex, N> &indices) const "`std::array`"
229 /// or \ref GetBinContent(const std::vector<RBinIndex> &indices) const "`std::vector`"
230 template <typename... A>
231 const BinContentType &GetBinContent(const A &...args) const
232 {
233 return fEngine.GetBinContent(args...);
234 }
235
236 /// Get the multidimensional range of all bins.
237 ///
238 /// \return the multidimensional range
239 RBinIndexMultiDimRange GetFullMultiDimRange() const { return fEngine.GetFullMultiDimRange(); }
240
241 /// Set the content of a single bin.
242 ///
243 /// \code
244 /// ROOT::Experimental::RHist<int> hist({/* two dimensions */});
245 /// std::array<ROOT::Experimental::RBinIndex, 2> indices = {3, 5};
246 /// int value = /* ... */;
247 /// hist.SetBinContent(indices, value);
248 /// \endcode
249 ///
250 /// \note Compared to TH1 conventions, the first normal bin has index 0 and underflow and overflow bins are special
251 /// values. See also the class documentation of RBinIndex.
252 ///
253 /// Throws an exception if the number of indices does not match the axis configuration or the bin is not found.
254 ///
255 /// \warning Setting the bin content will taint the global histogram statistics. Attempting to access its values, for
256 /// example calling GetNEntries(), will throw exceptions.
257 ///
258 /// \param[in] indices the array of indices for each axis
259 /// \param[in] value the new value of the bin content
260 /// \par See also
261 /// the \ref SetBinContent(const A &... args) const "variadic function template overload" accepting arguments
262 /// directly
263 template <std::size_t N, typename V>
264 void SetBinContent(const std::array<RBinIndex, N> &indices, const V &value)
265 {
266 fEngine.SetBinContent(indices, value);
267 fStats.Taint();
268 }
269
270 /// Set the content of a single bin.
271 ///
272 /// \code
273 /// ROOT::Experimental::RHist<int> hist({/* two dimensions */});
274 /// int value = /* ... */;
275 /// hist.SetBinContent(ROOT::Experimental::RBinIndex(3), ROOT::Experimental::RBinIndex(5), value);
276 /// // ... or construct the RBinIndex arguments implicitly from integers:
277 /// hist.SetBinContent(3, 5, value);
278 /// \endcode
279 ///
280 /// \note Compared to TH1 conventions, the first normal bin has index 0 and underflow and overflow bins are special
281 /// values. See also the class documentation of RBinIndex.
282 ///
283 /// Throws an exception if the number of arguments does not match the axis configuration or the bin is not found.
284 ///
285 /// \warning Setting the bin content will taint the global histogram statistics. Attempting to access its values, for
286 /// example calling GetNEntries(), will throw exceptions.
287 ///
288 /// \param[in] args the arguments for each axis and the new value of the bin content
289 /// \par See also
290 /// the \ref SetBinContent(const std::array<RBinIndex, N> &indices, const V &value) const "function overload"
291 /// accepting `std::array`
292 template <typename... A>
293 void SetBinContent(const A &...args)
294 {
295 fEngine.SetBinContent(args...);
296 fStats.Taint();
297 }
298
299 /// Add all bin contents and statistics of another histogram.
300 ///
301 /// Throws an exception if the axes configurations are not identical.
302 ///
303 /// \param[in] other another histogram
304 void Add(const RHist &other)
305 {
306 fEngine.Add(other.fEngine);
307 fStats.Add(other.fStats);
308 }
309
310 /// Add all bin contents and statistics of another histogram using atomic instructions.
311 ///
312 /// Throws an exception if the axes configurations are not identical.
313 ///
314 /// \param[in] other another histogram that must not be modified during the operation
315 void AddAtomic(const RHist &other)
316 {
317 fEngine.AddAtomic(other.fEngine);
318 fStats.AddAtomic(other.fStats);
319 }
320
321 /// Clear all bin contents and statistics.
322 void Clear()
323 {
324 fEngine.Clear();
325 fStats.Clear();
326 }
327
328 /// Clone this histogram.
329 ///
330 /// Copying all bin contents can be an expensive operation, depending on the number of bins.
331 ///
332 /// \return the cloned object
333 RHist Clone() const
334 {
335 RHist h(fEngine.Clone());
336 h.fStats = fStats;
337 return h;
338 }
339
340 /// Convert this histogram to a different bin content type.
341 ///
342 /// There is no bounds checking to make sure that the converted values can be represented. Note that it is not
343 /// possible to convert to RBinWithError since the information about individual weights has been lost since filling.
344 ///
345 /// Converting all bin contents can be an expensive operation, depending on the number of bins.
346 ///
347 /// \return the converted object
348 template <typename U>
350 {
351 RHist<U> h(fEngine.template Convert<U>());
352 h.fStats = fStats;
353 return h;
354 }
355
356 /// Fill an entry into the histogram.
357 ///
358 /// \code
359 /// ROOT::Experimental::RHist<int> hist({/* two dimensions */});
360 /// auto args = std::make_tuple(8.5, 10.5);
361 /// hist.Fill(args);
362 /// \endcode
363 ///
364 /// If one of the arguments is outside the corresponding axis and flow bins are disabled, the entry will be silently
365 /// discarded.
366 ///
367 /// Throws an exception if the number of arguments does not match the axis configuration, or if an argument cannot be
368 /// converted for the axis type at run-time.
369 ///
370 /// \param[in] args the arguments for each axis
371 /// \par See also
372 /// the \ref Fill(const A &... args) "variadic function template overload" accepting arguments directly and the
373 /// \ref Fill(const std::tuple<A...> &args, RWeight weight) "overload for weighted filling"
374 template <typename... A>
375 void Fill(const std::tuple<A...> &args)
376 {
377 fEngine.Fill(args);
378 fStats.Fill(args);
379 }
380
381 /// Fill an entry into the histogram with a weight.
382 ///
383 /// This overload is not available for integral bin content types (see \ref RHistEngine::SupportsWeightedFilling).
384 ///
385 /// \code
386 /// ROOT::Experimental::RHist<float> hist({/* two dimensions */});
387 /// auto args = std::make_tuple(8.5, 10.5);
388 /// hist.Fill(args, ROOT::Experimental::RWeight(0.8));
389 /// \endcode
390 ///
391 /// If one of the arguments is outside the corresponding axis and flow bins are disabled, the entry will be silently
392 /// discarded.
393 ///
394 /// Throws an exception if the number of arguments does not match the axis configuration, or if an argument cannot be
395 /// converted for the axis type at run-time.
396 ///
397 /// \param[in] args the arguments for each axis
398 /// \param[in] weight the weight for this entry
399 /// \par See also
400 /// the \ref Fill(const A &... args) "variadic function template overload" accepting arguments directly and the
401 /// \ref Fill(const std::tuple<A...> &args) "overload for unweighted filling"
402 template <typename... A>
403 void Fill(const std::tuple<A...> &args, RWeight weight)
404 {
405 fEngine.Fill(args, weight);
406 fStats.Fill(args, weight);
407 }
408
409 /// Fill an entry into the histogram.
410 ///
411 /// \code
412 /// ROOT::Experimental::RHist<int> hist({/* two dimensions */});
413 /// hist.Fill(8.5, 10.5);
414 /// \endcode
415 ///
416 /// For weighted filling, pass an RWeight as the last argument:
417 /// \code
418 /// ROOT::Experimental::RHist<float> hist({/* two dimensions */});
419 /// hist.Fill(8.5, 10.5, ROOT::Experimental::RWeight(0.8));
420 /// \endcode
421 /// This is not available for integral bin content types (see \ref RHistEngine::SupportsWeightedFilling).
422 ///
423 /// If one of the arguments is outside the corresponding axis and flow bins are disabled, the entry will be silently
424 /// discarded.
425 ///
426 /// Throws an exception if the number of arguments does not match the axis configuration, or if an argument cannot be
427 /// converted for the axis type at run-time.
428 ///
429 /// \param[in] args the arguments for each axis
430 /// \par See also
431 /// the function overloads accepting `std::tuple` \ref Fill(const std::tuple<A...> &args) "for unweighted filling"
432 /// and \ref Fill(const std::tuple<A...> &args, RWeight) "for weighted filling"
433 template <typename... A>
434 void Fill(const A &...args)
435 {
436 static_assert(sizeof...(A) >= 1, "need at least one argument to Fill");
437 if constexpr (sizeof...(A) >= 1) {
438 fEngine.Fill(args...);
439 fStats.Fill(args...);
440 }
441 }
442
443 /// Scale all histogram bin contents and statistics.
444 ///
445 /// This method is not available for integral bin content types.
446 ///
447 /// \param[in] factor the scale factor
448 void Scale(double factor)
449 {
450 fEngine.Scale(factor);
451 fStats.Scale(factor);
452 }
453
454 /// %ROOT Streamer function to throw when trying to store an object of this class.
455 void Streamer(TBuffer &) { throw std::runtime_error("unable to store RHist"); }
456};
457
458} // namespace Experimental
459} // namespace ROOT
460
461#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.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
A variant of all supported axis types.
A multidimensional range of bin indices.
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 Taint()
Taint 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:65
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:160
RHist(std::uint64_t nNormalBins, std::pair< double, double > interval)
Construct a one-dimensional histogram with a regular axis.
Definition RHist.hxx:122
std::size_t GetNDimensions() const
Definition RHist.hxx:153
RHist Clone() const
Clone this histogram.
Definition RHist.hxx:333
RHist & operator=(RHist &&)=default
Efficiently move a histogram.
RHist(const RAxisVariant &axis1, const Axes &...axes)
Construct a histogram.
Definition RHist.hxx:111
void Scale(double factor)
Scale all histogram bin contents and statistics.
Definition RHist.hxx:448
const BinContentType & GetBinContent(const std::vector< RBinIndex > &indices) const
Get the content of a single bin.
Definition RHist.hxx:206
RHist(std::initializer_list< RAxisVariant > axes)
Construct a histogram.
Definition RHist.hxx:101
void Fill(const std::tuple< A... > &args)
Fill an entry into the histogram.
Definition RHist.hxx:375
RHist & operator=(const RHist &)=delete
The copy assignment operator is deleted.
RHistStats fStats
The global histogram statistics.
Definition RHist.hxx:75
void AddAtomic(const RHist &other)
Add all bin contents and statistics of another histogram using atomic instructions.
Definition RHist.hxx:315
void Fill(const std::tuple< A... > &args, RWeight weight)
Fill an entry into the histogram with a weight.
Definition RHist.hxx:403
RHist< U > Convert() const
Convert this histogram to a different bin content type.
Definition RHist.hxx:349
RHistEngine< BinContentType > fEngine
The histogram engine including the bin contents.
Definition RHist.hxx:73
double ComputeNEffectiveEntries() const
Compute the number of effective entries.
Definition RHist.hxx:158
std::uint64_t GetTotalNBins() const
Definition RHist.hxx:154
RHist(std::vector< RAxisVariant > axes)
Construct a histogram.
Definition RHist.hxx:84
RBinIndexMultiDimRange GetFullMultiDimRange() const
Get the multidimensional range of all bins.
Definition RHist.hxx:239
const RHistStats & GetStats() const
Definition RHist.hxx:150
const RHistEngine< BinContentType > & GetEngine() const
Definition RHist.hxx:149
void Streamer(TBuffer &)
ROOT Streamer function to throw when trying to store an object of this class.
Definition RHist.hxx:455
void Fill(const A &...args)
Fill an entry into the histogram.
Definition RHist.hxx:434
void SetBinContent(const A &...args)
Set the content of a single bin.
Definition RHist.hxx:293
double ComputeStdDev(std::size_t dim=0) const
Compute the standard deviation of unbinned values.
Definition RHist.hxx:162
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:183
const std::vector< RAxisVariant > & GetAxes() const
Definition RHist.hxx:152
void Add(const RHist &other)
Add all bin contents and statistics of another histogram.
Definition RHist.hxx:304
void SetBinContent(const std::array< RBinIndex, N > &indices, const V &value)
Set the content of a single bin.
Definition RHist.hxx:264
RHist(RHistEngine< BinContentType > engine)
Private constructor based off an engine.
Definition RHist.hxx:78
const BinContentType & GetBinContent(const A &...args) const
Get the content of a single bin.
Definition RHist.hxx:231
void Clear()
Clear all bin contents and statistics.
Definition RHist.hxx:322
std::uint64_t GetNEntries() const
Definition RHist.hxx:156
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