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 // For conversion, all other template instantiations must be a friend.
66 template <typename U>
67 friend class RHist;
68
69 friend class RHistFillContext<BinContentType>;
70
71 /// The histogram engine including the bin contents.
73 /// The global histogram statistics.
75
76 /// Private constructor based off an engine.
78
79public:
80 /// Construct a histogram.
81 ///
82 /// \param[in] axes the axis objects, must have size > 0
83 explicit RHist(std::vector<RAxisVariant> axes) : fEngine(std::move(axes)), fStats(fEngine.GetNDimensions())
84 {
85 // The axes parameter was moved, use from the engine.
86 const auto &engineAxes = fEngine.GetAxes();
87 for (std::size_t i = 0; i < engineAxes.size(); i++) {
88 if (engineAxes[i].GetCategoricalAxis() != nullptr) {
90 }
91 }
92 }
93
94 /// Construct a histogram.
95 ///
96 /// Note that there is no perfect forwarding of the axis objects. If that is needed, use the
97 /// \ref RHist(std::vector<RAxisVariant> axes) "overload accepting a std::vector".
98 ///
99 /// \param[in] axes the axis objects, must have size > 0
100 explicit RHist(std::initializer_list<RAxisVariant> axes) : RHist(std::vector(axes)) {}
101
102 /// Construct a histogram.
103 ///
104 /// Note that there is no perfect forwarding of the axis objects. If that is needed, use the
105 /// \ref RHist(std::vector<RAxisVariant> axes) "overload accepting a std::vector".
106 ///
107 /// \param[in] axis1 the first axis object
108 /// \param[in] axes the remaining axis objects
109 template <typename... Axes>
110 explicit RHist(const RAxisVariant &axis1, const Axes &...axes) : RHist(std::vector<RAxisVariant>{axis1, axes...})
111 {
112 }
113
114 /// Construct a one-dimensional histogram with a regular axis.
115 ///
116 /// \param[in] nNormalBins the number of normal bins, must be > 0
117 /// \param[in] interval the axis interval (lower end inclusive, upper end exclusive)
118 /// \par See also
119 /// the \ref RRegularAxis::RRegularAxis(std::uint64_t nNormalBins, std::pair<double, double> interval, bool
120 /// enableFlowBins) "constructor of RRegularAxis"
121 RHist(std::uint64_t nNormalBins, std::pair<double, double> interval)
123 {
124 }
125
126 /// The copy constructor is deleted.
127 ///
128 /// Copying all bin contents can be an expensive operation, depending on the number of bins. If required, users can
129 /// explicitly call Clone().
130 RHist(const RHist &) = delete;
131 /// Efficiently move construct a histogram.
132 ///
133 /// After this operation, the moved-from object is invalid.
134 RHist(RHist &&) = default;
135
136 /// The copy assignment operator is deleted.
137 ///
138 /// Copying all bin contents can be an expensive operation, depending on the number of bins. If required, users can
139 /// explicitly call Clone().
140 RHist &operator=(const RHist &) = delete;
141 /// Efficiently move a histogram.
142 ///
143 /// After this operation, the moved-from object is invalid.
144 RHist &operator=(RHist &&) = default;
145
146 ~RHist() = default;
147
149 const RHistStats &GetStats() const { return fStats; }
150
151 const std::vector<RAxisVariant> &GetAxes() const { return fEngine.GetAxes(); }
152 std::size_t GetNDimensions() const { return fEngine.GetNDimensions(); }
153 std::uint64_t GetTotalNBins() const { return fEngine.GetTotalNBins(); }
154
155 std::uint64_t GetNEntries() const { return fStats.GetNEntries(); }
156 /// \copydoc RHistStats::ComputeNEffectiveEntries()
158 /// \copydoc RHistStats::ComputeMean()
159 double ComputeMean(std::size_t dim = 0) const { return fStats.ComputeMean(dim); }
160 /// \copydoc RHistStats::ComputeStdDev()
161 double ComputeStdDev(std::size_t dim = 0) const { return fStats.ComputeStdDev(dim); }
162
163 /// Get the content of a single bin.
164 ///
165 /// \code
166 /// ROOT::Experimental::RHist<int> hist({/* two dimensions */});
167 /// std::array<ROOT::Experimental::RBinIndex, 2> indices = {3, 5};
168 /// int content = hist.GetBinContent(indices);
169 /// \endcode
170 ///
171 /// \note Compared to TH1 conventions, the first normal bin has index 0 and underflow and overflow bins are special
172 /// values. See also the class documentation of RBinIndex.
173 ///
174 /// Throws an exception if the number of indices does not match the axis configuration or the bin is not found.
175 ///
176 /// \param[in] indices the array of indices for each axis
177 /// \return the bin content
178 /// \par See also
179 /// the \ref GetBinContent(const A &... args) const "variadic function template overload" accepting arguments
180 /// directly
181 template <std::size_t N>
182 const BinContentType &GetBinContent(const std::array<RBinIndex, N> &indices) const
183 {
184 return fEngine.GetBinContent(indices);
185 }
186
187 /// Get the content of a single bin.
188 ///
189 /// \code
190 /// ROOT::Experimental::RHist<int> hist({/* two dimensions */});
191 /// int content = hist.GetBinContent(ROOT::Experimental::RBinIndex(3), ROOT::Experimental::RBinIndex(5));
192 /// // ... or construct the RBinIndex arguments implicitly from integers:
193 /// content = hist.GetBinContent(3, 5);
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 arguments does not match the axis configuration or the bin is not found.
200 ///
201 /// \param[in] args the arguments for each axis
202 /// \return the bin content
203 /// \par See also
204 /// the \ref GetBinContent(const std::array<RBinIndex, N> &indices) const "function overload" accepting
205 /// `std::array`
206 template <typename... A>
207 const BinContentType &GetBinContent(const A &...args) const
208 {
209 return fEngine.GetBinContent(args...);
210 }
211
212 /// Add all bin contents and statistics of another histogram.
213 ///
214 /// Throws an exception if the axes configurations are not identical.
215 ///
216 /// \param[in] other another histogram
217 void Add(const RHist &other)
218 {
219 fEngine.Add(other.fEngine);
220 fStats.Add(other.fStats);
221 }
222
223 /// Add all bin contents and statistics of another histogram using atomic instructions.
224 ///
225 /// Throws an exception if the axes configurations are not identical.
226 ///
227 /// \param[in] other another histogram that must not be modified during the operation
228 void AddAtomic(const RHist &other)
229 {
230 fEngine.AddAtomic(other.fEngine);
231 fStats.AddAtomic(other.fStats);
232 }
233
234 /// Clear all bin contents and statistics.
235 void Clear()
236 {
237 fEngine.Clear();
238 fStats.Clear();
239 }
240
241 /// Clone this histogram.
242 ///
243 /// Copying all bin contents can be an expensive operation, depending on the number of bins.
244 ///
245 /// \return the cloned object
246 RHist Clone() const
247 {
248 RHist h(fEngine.Clone());
249 h.fStats = fStats;
250 return h;
251 }
252
253 /// Convert this histogram to a different bin content type.
254 ///
255 /// There is no bounds checking to make sure that the converted values can be represented. Note that it is not
256 /// possible to convert to RBinWithError since the information about individual weights has been lost since filling.
257 ///
258 /// Converting all bin contents can be an expensive operation, depending on the number of bins.
259 ///
260 /// \return the converted object
261 template <typename U>
263 {
264 RHist<U> h(fEngine.template Convert<U>());
265 h.fStats = fStats;
266 return h;
267 }
268
269 /// Fill an entry into the histogram.
270 ///
271 /// \code
272 /// ROOT::Experimental::RHist<int> hist({/* two dimensions */});
273 /// auto args = std::make_tuple(8.5, 10.5);
274 /// hist.Fill(args);
275 /// \endcode
276 ///
277 /// If one of the arguments is outside the corresponding axis and flow bins are disabled, the entry will be silently
278 /// discarded.
279 ///
280 /// Throws an exception if the number of arguments does not match the axis configuration, or if an argument cannot be
281 /// converted for the axis type at run-time.
282 ///
283 /// \param[in] args the arguments for each axis
284 /// \par See also
285 /// the \ref Fill(const A &... args) "variadic function template overload" accepting arguments directly and the
286 /// \ref Fill(const std::tuple<A...> &args, RWeight weight) "overload for weighted filling"
287 template <typename... A>
288 void Fill(const std::tuple<A...> &args)
289 {
290 fEngine.Fill(args);
291 fStats.Fill(args);
292 }
293
294 /// Fill an entry into the histogram with a weight.
295 ///
296 /// This overload is not available for integral bin content types (see \ref RHistEngine::SupportsWeightedFilling).
297 ///
298 /// \code
299 /// ROOT::Experimental::RHist<float> hist({/* two dimensions */});
300 /// auto args = std::make_tuple(8.5, 10.5);
301 /// hist.Fill(args, ROOT::Experimental::RWeight(0.8));
302 /// \endcode
303 ///
304 /// If one of the arguments is outside the corresponding axis and flow bins are disabled, the entry will be silently
305 /// discarded.
306 ///
307 /// Throws an exception if the number of arguments does not match the axis configuration, or if an argument cannot be
308 /// converted for the axis type at run-time.
309 ///
310 /// \param[in] args the arguments for each axis
311 /// \param[in] weight the weight for this entry
312 /// \par See also
313 /// the \ref Fill(const A &... args) "variadic function template overload" accepting arguments directly and the
314 /// \ref Fill(const std::tuple<A...> &args) "overload for unweighted filling"
315 template <typename... A>
316 void Fill(const std::tuple<A...> &args, RWeight weight)
317 {
318 fEngine.Fill(args, weight);
319 fStats.Fill(args, weight);
320 }
321
322 /// Fill an entry into the histogram.
323 ///
324 /// \code
325 /// ROOT::Experimental::RHist<int> hist({/* two dimensions */});
326 /// hist.Fill(8.5, 10.5);
327 /// \endcode
328 ///
329 /// For weighted filling, pass an RWeight as the last argument:
330 /// \code
331 /// ROOT::Experimental::RHist<float> hist({/* two dimensions */});
332 /// hist.Fill(8.5, 10.5, ROOT::Experimental::RWeight(0.8));
333 /// \endcode
334 /// This is not available for integral bin content types (see \ref RHistEngine::SupportsWeightedFilling).
335 ///
336 /// If one of the arguments is outside the corresponding axis and flow bins are disabled, the entry will be silently
337 /// discarded.
338 ///
339 /// Throws an exception if the number of arguments does not match the axis configuration, or if an argument cannot be
340 /// converted for the axis type at run-time.
341 ///
342 /// \param[in] args the arguments for each axis
343 /// \par See also
344 /// the function overloads accepting `std::tuple` \ref Fill(const std::tuple<A...> &args) "for unweighted filling"
345 /// and \ref Fill(const std::tuple<A...> &args, RWeight) "for weighted filling"
346 template <typename... A>
347 void Fill(const A &...args)
348 {
349 static_assert(sizeof...(A) >= 1, "need at least one argument to Fill");
350 if constexpr (sizeof...(A) >= 1) {
351 fEngine.Fill(args...);
352 fStats.Fill(args...);
353 }
354 }
355
356 /// Scale all histogram bin contents and statistics.
357 ///
358 /// This method is not available for integral bin content types.
359 ///
360 /// \param[in] factor the scale factor
361 void Scale(double factor)
362 {
363 fEngine.Scale(factor);
364 fStats.Scale(factor);
365 }
366
367 /// %ROOT Streamer function to throw when trying to store an object of this class.
368 void Streamer(TBuffer &) { throw std::runtime_error("unable to store RHist"); }
369};
370
371} // namespace Experimental
372} // namespace ROOT
373
374#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:159
RHist(std::uint64_t nNormalBins, std::pair< double, double > interval)
Construct a one-dimensional histogram with a regular axis.
Definition RHist.hxx:121
std::size_t GetNDimensions() const
Definition RHist.hxx:152
RHist Clone() const
Clone this histogram.
Definition RHist.hxx:246
RHist & operator=(RHist &&)=default
Efficiently move a histogram.
RHist(const RAxisVariant &axis1, const Axes &...axes)
Construct a histogram.
Definition RHist.hxx:110
void Scale(double factor)
Scale all histogram bin contents and statistics.
Definition RHist.hxx:361
RHist(std::initializer_list< RAxisVariant > axes)
Construct a histogram.
Definition RHist.hxx:100
void Fill(const std::tuple< A... > &args)
Fill an entry into the histogram.
Definition RHist.hxx:288
RHist & operator=(const RHist &)=delete
The copy assignment operator is deleted.
RHistStats fStats
The global histogram statistics.
Definition RHist.hxx:74
void AddAtomic(const RHist &other)
Add all bin contents and statistics of another histogram using atomic instructions.
Definition RHist.hxx:228
void Fill(const std::tuple< A... > &args, RWeight weight)
Fill an entry into the histogram with a weight.
Definition RHist.hxx:316
RHist< U > Convert() const
Convert this histogram to a different bin content type.
Definition RHist.hxx:262
RHistEngine< BinContentType > fEngine
The histogram engine including the bin contents.
Definition RHist.hxx:72
double ComputeNEffectiveEntries() const
Compute the number of effective entries.
Definition RHist.hxx:157
std::uint64_t GetTotalNBins() const
Definition RHist.hxx:153
RHist(std::vector< RAxisVariant > axes)
Construct a histogram.
Definition RHist.hxx:83
const RHistStats & GetStats() const
Definition RHist.hxx:149
const RHistEngine< BinContentType > & GetEngine() const
Definition RHist.hxx:148
void Streamer(TBuffer &)
ROOT Streamer function to throw when trying to store an object of this class.
Definition RHist.hxx:368
void Fill(const A &...args)
Fill an entry into the histogram.
Definition RHist.hxx:347
double ComputeStdDev(std::size_t dim=0) const
Compute the standard deviation of unbinned values.
Definition RHist.hxx:161
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:182
const std::vector< RAxisVariant > & GetAxes() const
Definition RHist.hxx:151
void Add(const RHist &other)
Add all bin contents and statistics of another histogram.
Definition RHist.hxx:217
RHist(RHistEngine< BinContentType > engine)
Private constructor based off an engine.
Definition RHist.hxx:77
const BinContentType & GetBinContent(const A &...args) const
Get the content of a single bin.
Definition RHist.hxx:207
void Clear()
Clear all bin contents and statistics.
Definition RHist.hxx:235
std::uint64_t GetNEntries() const
Definition RHist.hxx:155
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