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 "RHistUtils.hxx"
11#include "RLinearizedIndex.hxx"
12#include "RRegularAxis.hxx"
13#include "RWeight.hxx"
14
15#include <array>
16#include <cassert>
17#include <cstddef>
18#include <cstdint>
19#include <stdexcept>
20#include <tuple>
21#include <type_traits>
22#include <utility>
23#include <vector>
24
25class TBuffer;
26
27namespace ROOT {
28namespace Experimental {
29
30// forward declarations for friend declaration
31template <typename BinContentType>
32class RHistEngine;
33namespace Internal {
34template <typename T, std::size_t N>
35static void SetBinContent(RHistEngine<T> &hist, const std::array<RBinIndex, N> &indices, const T &value);
36} // namespace Internal
37
38/**
39A histogram data structure to bin data along multiple dimensions.
40
41Every call to \ref Fill(const A &... args) "Fill" bins the data according to the axis configuration and increments the
42bin content:
43\code
44ROOT::Experimental::RHistEngine<int> hist(10, {5, 15});
45hist.Fill(8.5);
46// hist.GetBinContent(ROOT::Experimental::RBinIndex(3)) will return 1
47\endcode
48
49The class is templated on the bin content type. For counting, as in the example above, it may be an integral type such
50as `int` or `long`. Narrower types such as `unsigned char` or `short` are supported, but may overflow due to their
51limited range and must be used with care. For weighted filling, the bin content type must not be an integral type, but
52a floating-point type such as `float` or `double`, or the special type RBinWithError. Note that `float` has a limited
53significand precision of 24 bits.
54
55An object can have arbitrary dimensionality determined at run-time. The axis configuration is passed as a vector of
56RAxisVariant:
57\code
58std::vector<ROOT::Experimental::RAxisVariant> axes;
59axes.push_back(ROOT::Experimental::RRegularAxis(10, 5, 15));
60axes.push_back(ROOT::Experimental::RVariableBinAxis({1, 10, 100, 1000}));
61ROOT::Experimental::RHistEngine<int> hist(axes);
62// hist.GetNDimensions() will return 2
63\endcode
64
65\warning This is part of the %ROOT 7 prototype! It will change without notice. It might trigger earthquakes.
66Feedback is welcome!
67*/
68template <typename BinContentType>
70 template <typename T, std::size_t N>
71 friend void Internal::SetBinContent(RHistEngine<T> &, const std::array<RBinIndex, N> &, const T &);
72
73 /// The axis configuration for this histogram. Relevant methods are forwarded from the public interface.
75 /// The bin contents for this histogram
76 std::vector<BinContentType> fBinContents;
77
78public:
79 /// Construct a histogram engine.
80 ///
81 /// \param[in] axes the axis objects, must have size > 0
82 explicit RHistEngine(std::vector<RAxisVariant> axes) : fAxes(std::move(axes))
83 {
85 }
86
87 /// Construct a histogram engine.
88 ///
89 /// Note that there is no perfect forwarding of the axis objects. If that is needed, use the
90 /// \ref RHistEngine(std::vector<RAxisVariant> axes) "overload accepting a std::vector".
91 ///
92 /// \param[in] axes the axis objects, must have size > 0
93 explicit RHistEngine(std::initializer_list<RAxisVariant> axes) : RHistEngine(std::vector(axes)) {}
94
95 /// Construct a histogram engine.
96 ///
97 /// Note that there is no perfect forwarding of the axis objects. If that is needed, use the
98 /// \ref RHistEngine(std::vector<RAxisVariant> axes) "overload accepting a std::vector".
99 ///
100 /// \param[in] axis1 the first axis object
101 /// \param[in] axes the remaining axis objects
102 template <typename... Axes>
103 explicit RHistEngine(const RAxisVariant &axis1, const Axes &...axes)
104 : RHistEngine(std::vector<RAxisVariant>{axis1, axes...})
105 {
106 }
107
108 /// Construct a one-dimensional histogram engine with a regular axis.
109 ///
110 /// \param[in] nNormalBins the number of normal bins, must be > 0
111 /// \param[in] interval the axis interval (lower end inclusive, upper end exclusive)
112 /// \par See also
113 /// the \ref RRegularAxis::RRegularAxis(std::uint64_t nNormalBins, std::pair<double, double> interval, bool
114 /// enableFlowBins) "constructor of RRegularAxis"
115 RHistEngine(std::uint64_t nNormalBins, std::pair<double, double> interval)
117 {
118 }
119
120 /// The copy constructor is deleted.
121 ///
122 /// Copying all bin contents can be an expensive operation, depending on the number of bins. If required, users can
123 /// explicitly call Clone().
124 RHistEngine(const RHistEngine &) = delete;
125 /// Efficiently move construct a histogram engine.
126 ///
127 /// After this operation, the moved-from object is invalid.
129
130 /// The copy assignment operator is deleted.
131 ///
132 /// Copying all bin contents can be an expensive operation, depending on the number of bins. If required, users can
133 /// explicitly call Clone().
135 /// Efficiently move a histogram engine.
136 ///
137 /// After this operation, the moved-from object is invalid.
139
140 ~RHistEngine() = default;
141
142 const std::vector<RAxisVariant> &GetAxes() const { return fAxes.Get(); }
143 std::size_t GetNDimensions() const { return fAxes.GetNDimensions(); }
144 std::uint64_t GetTotalNBins() const { return fBinContents.size(); }
145
146 /// Get the content of a single bin.
147 ///
148 /// \code
149 /// ROOT::Experimental::RHistEngine<int> hist({/* two dimensions */});
150 /// std::array<ROOT::Experimental::RBinIndex, 2> indices = {3, 5};
151 /// int content = hist.GetBinContent(indices);
152 /// \endcode
153 ///
154 /// \note Compared to TH1 conventions, the first normal bin has index 0 and underflow and overflow bins are special
155 /// values. See also the class documentation of RBinIndex.
156 ///
157 /// Throws an exception if the number of indices does not match the axis configuration or the bin is not found.
158 ///
159 /// \param[in] indices the array of indices for each axis
160 /// \return the bin content
161 /// \par See also
162 /// the \ref GetBinContent(const A &... args) const "variadic function template overload" accepting arguments
163 /// directly
164 template <std::size_t N>
165 const BinContentType &GetBinContent(const std::array<RBinIndex, N> &indices) const
166 {
167 // We could rely on RAxes::ComputeGlobalIndex to check the number of arguments, but its exception message might
168 // be confusing for users.
169 if (N != GetNDimensions()) {
170 throw std::invalid_argument("invalid number of indices passed to GetBinContent");
171 }
173 if (!index.fValid) {
174 throw std::invalid_argument("bin not found in GetBinContent");
175 }
176 assert(index.fIndex < fBinContents.size());
177 return fBinContents[index.fIndex];
178 }
179
180 /// Get the content of a single bin.
181 ///
182 /// \code
183 /// ROOT::Experimental::RHistEngine<int> hist({/* two dimensions */});
184 /// int content = hist.GetBinContent(ROOT::Experimental::RBinIndex(3), ROOT::Experimental::RBinIndex(5));
185 /// // ... or construct the RBinIndex arguments implicitly from integers:
186 /// content = hist.GetBinContent(3, 5);
187 /// \endcode
188 ///
189 /// \note Compared to TH1 conventions, the first normal bin has index 0 and underflow and overflow bins are special
190 /// values. See also the class documentation of RBinIndex.
191 ///
192 /// Throws an exception if the number of arguments does not match the axis configuration or the bin is not found.
193 ///
194 /// \param[in] args the arguments for each axis
195 /// \return the bin content
196 /// \par See also
197 /// the \ref GetBinContent(const std::array<RBinIndex, N> &indices) const "function overload" accepting
198 /// `std::array`
199 template <typename... A>
200 const BinContentType &GetBinContent(const A &...args) const
201 {
202 std::array<RBinIndex, sizeof...(A)> indices{args...};
203 return GetBinContent(indices);
204 }
205
206 /// Add all bin contents of another histogram.
207 ///
208 /// Throws an exception if the axes configurations are not identical.
209 ///
210 /// \param[in] other another histogram
211 void Add(const RHistEngine &other)
212 {
213 if (fAxes != other.fAxes) {
214 throw std::invalid_argument("axes configurations not identical in Add");
215 }
216 for (std::size_t i = 0; i < fBinContents.size(); i++) {
217 fBinContents[i] += other.fBinContents[i];
218 }
219 }
220
221 /// Add all bin contents of another histogram using atomic instructions.
222 ///
223 /// Throws an exception if the axes configurations are not identical.
224 ///
225 /// \param[in] other another histogram that must not be modified during the operation
227 {
228 if (fAxes != other.fAxes) {
229 throw std::invalid_argument("axes configurations not identical in AddAtomic");
230 }
231 for (std::size_t i = 0; i < fBinContents.size(); i++) {
232 Internal::AtomicAdd(&fBinContents[i], other.fBinContents[i]);
233 }
234 }
235
236 /// Clear all bin contents.
237 void Clear()
238 {
239 for (std::size_t i = 0; i < fBinContents.size(); i++) {
240 fBinContents[i] = {};
241 }
242 }
243
244 /// Clone this histogram engine.
245 ///
246 /// Copying all bin contents can be an expensive operation, depending on the number of bins.
247 ///
248 /// \return the cloned object
250 {
252 for (std::size_t i = 0; i < fBinContents.size(); i++) {
253 h.fBinContents[i] = fBinContents[i];
254 }
255 return h;
256 }
257
258 /// Whether this histogram engine type supports weighted filling.
259 static constexpr bool SupportsWeightedFilling = !std::is_integral_v<BinContentType>;
260
261 /// Fill an entry into the histogram.
262 ///
263 /// \code
264 /// ROOT::Experimental::RHistEngine<int> hist({/* two dimensions */});
265 /// auto args = std::make_tuple(8.5, 10.5);
266 /// hist.Fill(args);
267 /// \endcode
268 ///
269 /// If one of the arguments is outside the corresponding axis and flow bins are disabled, the entry will be silently
270 /// discarded.
271 ///
272 /// Throws an exception if the number of arguments does not match the axis configuration, or if an argument cannot be
273 /// converted for the axis type at run-time.
274 ///
275 /// \param[in] args the arguments for each axis
276 /// \par See also
277 /// the \ref Fill(const A &... args) "variadic function template overload" accepting arguments directly and the
278 /// \ref Fill(const std::tuple<A...> &args, RWeight weight) "overload for weighted filling"
279 template <typename... A>
280 void Fill(const std::tuple<A...> &args)
281 {
282 // We could rely on RAxes::ComputeGlobalIndex to check the number of arguments, but its exception message might
283 // be confusing for users.
284 if (sizeof...(A) != GetNDimensions()) {
285 throw std::invalid_argument("invalid number of arguments to Fill");
286 }
288 if (index.fValid) {
289 assert(index.fIndex < fBinContents.size());
290 fBinContents[index.fIndex]++;
291 }
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 SupportsWeightedFilling).
297 ///
298 /// \code
299 /// ROOT::Experimental::RHistEngine<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 static_assert(SupportsWeightedFilling, "weighted filling is not supported for integral bin content types");
319
320 // We could rely on RAxes::ComputeGlobalIndex to check the number of arguments, but its exception message might
321 // be confusing for users.
322 if (sizeof...(A) != GetNDimensions()) {
323 throw std::invalid_argument("invalid number of arguments to Fill");
324 }
326 if (index.fValid) {
327 assert(index.fIndex < fBinContents.size());
328 fBinContents[index.fIndex] += weight.fValue;
329 }
330 }
331
332 /// Fill an entry into the histogram with a user-defined weight.
333 ///
334 /// This overload is only available for user-defined bin content types.
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 /// \param[in] weight the weight for this entry
344 template <typename... A, typename W>
345 void Fill(const std::tuple<A...> &args, const W &weight)
346 {
347 static_assert(std::is_class_v<BinContentType>,
348 "user-defined weight types are only supported for user-defined bin content types");
349
350 // We could rely on RAxes::ComputeGlobalIndex to check the number of arguments, but its exception message might
351 // be confusing for users.
352 if (sizeof...(A) != GetNDimensions()) {
353 throw std::invalid_argument("invalid number of arguments to Fill");
354 }
356 if (index.fValid) {
357 assert(index.fIndex < fBinContents.size());
358 fBinContents[index.fIndex] += weight;
359 }
360 }
361
362 /// Fill an entry into the histogram.
363 ///
364 /// \code
365 /// ROOT::Experimental::RHistEngine<int> hist({/* two dimensions */});
366 /// hist.Fill(8.5, 10.5);
367 /// \endcode
368 ///
369 /// For weighted filling, pass an RWeight as the last argument:
370 /// \code
371 /// ROOT::Experimental::RHistEngine<float> hist({/* two dimensions */});
372 /// hist.Fill(8.5, 10.5, ROOT::Experimental::RWeight(0.8));
373 /// \endcode
374 /// This is not available for integral bin content types (see \ref SupportsWeightedFilling).
375 ///
376 /// If one of the arguments is outside the corresponding axis and flow bins are disabled, the entry will be silently
377 /// discarded.
378 ///
379 /// Throws an exception if the number of arguments does not match the axis configuration, or if an argument cannot be
380 /// converted for the axis type at run-time.
381 ///
382 /// \param[in] args the arguments for each axis
383 /// \par See also
384 /// the function overloads accepting `std::tuple` \ref Fill(const std::tuple<A...> &args) "for unweighted filling"
385 /// and \ref Fill(const std::tuple<A...> &args, RWeight) "for weighted filling"
386 template <typename... A>
387 void Fill(const A &...args)
388 {
389 static_assert(sizeof...(A) >= 1, "need at least one argument to Fill");
390 if constexpr (sizeof...(A) >= 1) {
391 auto t = std::forward_as_tuple(args...);
392 if constexpr (std::is_same_v<typename Internal::LastType<A...>::type, RWeight>) {
393 static_assert(SupportsWeightedFilling, "weighted filling is not supported for integral bin content types");
394 static constexpr std::size_t N = sizeof...(A) - 1;
395 if (N != fAxes.GetNDimensions()) {
396 throw std::invalid_argument("invalid number of arguments to Fill");
397 }
398 RWeight weight = std::get<N>(t);
400 if (index.fValid) {
401 assert(index.fIndex < fBinContents.size());
402 fBinContents[index.fIndex] += weight.fValue;
403 }
404 } else {
405 Fill(t);
406 }
407 }
408 }
409
410 /// Fill an entry into the histogram using atomic instructions.
411 ///
412 /// \param[in] args the arguments for each axis
413 /// \see Fill(const std::tuple<A...> &args)
414 template <typename... A>
415 void FillAtomic(const std::tuple<A...> &args)
416 {
417 // We could rely on RAxes::ComputeGlobalIndex to check the number of arguments, but its exception message might
418 // be confusing for users.
419 if (sizeof...(A) != GetNDimensions()) {
420 throw std::invalid_argument("invalid number of arguments to Fill");
421 }
423 if (index.fValid) {
424 assert(index.fIndex < fBinContents.size());
426 }
427 }
428
429 /// Fill an entry into the histogram with a weight using atomic instructions.
430 ///
431 /// This overload is not available for integral bin content types (see \ref SupportsWeightedFilling).
432 ///
433 /// \param[in] args the arguments for each axis
434 /// \param[in] weight the weight for this entry
435 /// \see Fill(const std::tuple<A...> &args, RWeight weight)
436 template <typename... A>
437 void FillAtomic(const std::tuple<A...> &args, RWeight weight)
438 {
439 static_assert(SupportsWeightedFilling, "weighted filling is not supported for integral bin content types");
440
441 // We could rely on RAxes::ComputeGlobalIndex to check the number of arguments, but its exception message might
442 // be confusing for users.
443 if (sizeof...(A) != GetNDimensions()) {
444 throw std::invalid_argument("invalid number of arguments to Fill");
445 }
447 if (index.fValid) {
448 assert(index.fIndex < fBinContents.size());
450 }
451 }
452
453 /// Fill an entry into the histogram with a user-defined weight using atomic instructions.
454 ///
455 /// This overload is only available for user-defined bin content types.
456 ///
457 /// \param[in] args the arguments for each axis
458 /// \param[in] weight the weight for this entry
459 /// \see Fill(const std::tuple<A...> &args, const W &weight)
460 template <typename... A, typename W>
461 void FillAtomic(const std::tuple<A...> &args, const W &weight)
462 {
463 static_assert(std::is_class_v<BinContentType>,
464 "user-defined weight types are only supported for user-defined bin content types");
465
466 // We could rely on RAxes::ComputeGlobalIndex to check the number of arguments, but its exception message might
467 // be confusing for users.
468 if (sizeof...(A) != GetNDimensions()) {
469 throw std::invalid_argument("invalid number of arguments to Fill");
470 }
472 if (index.fValid) {
473 assert(index.fIndex < fBinContents.size());
474 Internal::AtomicAdd(&fBinContents[index.fIndex], weight);
475 }
476 }
477
478 /// Fill an entry into the histogram using atomic instructions.
479 ///
480 /// \param[in] args the arguments for each axis
481 /// \see Fill(const A &...args)
482 template <typename... A>
483 void FillAtomic(const A &...args)
484 {
485 static_assert(sizeof...(A) >= 1, "need at least one argument to Fill");
486 if constexpr (sizeof...(A) >= 1) {
487 auto t = std::forward_as_tuple(args...);
488 if constexpr (std::is_same_v<typename Internal::LastType<A...>::type, RWeight>) {
489 static_assert(SupportsWeightedFilling, "weighted filling is not supported for integral bin content types");
490 static constexpr std::size_t N = sizeof...(A) - 1;
491 if (N != fAxes.GetNDimensions()) {
492 throw std::invalid_argument("invalid number of arguments to Fill");
493 }
494 RWeight weight = std::get<N>(t);
496 if (index.fValid) {
497 assert(index.fIndex < fBinContents.size());
499 }
500 } else {
501 FillAtomic(t);
502 }
503 }
504 }
505
506 /// Scale all histogram bin contents.
507 ///
508 /// This method is not available for integral bin content types.
509 ///
510 /// \param[in] factor the scale factor
511 void Scale(double factor)
512 {
513 static_assert(!std::is_integral_v<BinContentType>, "scaling is not supported for integral bin content types");
514 for (std::size_t i = 0; i < fBinContents.size(); i++) {
515 fBinContents[i] *= factor;
516 }
517 }
518
519 /// %ROOT Streamer function to throw when trying to store an object of this class.
520 void Streamer(TBuffer &) { throw std::runtime_error("unable to store RHistEngine"); }
521};
522
523namespace Internal {
524/// %Internal function to set the content of a single bin.
525template <typename T, std::size_t N>
526static void SetBinContent(RHistEngine<T> &hist, const std::array<RBinIndex, N> &indices, const T &value)
527{
528 RLinearizedIndex index = hist.fAxes.ComputeGlobalIndex(indices);
529 if (!index.fValid) {
530 throw std::invalid_argument("bin not found in SetBinContent");
531 }
532 assert(index.fIndex < hist.fBinContents.size());
533 hist.fBinContents[index.fIndex] = value;
534}
535} // namespace Internal
536
537} // namespace Experimental
538} // namespace ROOT
539
540#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.
#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
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Bin configurations for all dimensions of a histogram.
Definition RAxes.hxx:41
std::size_t GetNDimensions() const
Definition RAxes.hxx:56
RLinearizedIndex ComputeGlobalIndexImpl(std::size_t index, const std::tuple< A... > &args) const
Definition RAxes.hxx:86
RLinearizedIndex ComputeGlobalIndex(const std::tuple< A... > &args) const
Compute the global index for all axes.
Definition RAxes.hxx:140
std::uint64_t ComputeTotalNBins() const
Compute the total number of bins for all axes.
Definition RAxes.hxx:67
const std::vector< RAxisVariant > & Get() const
Definition RAxes.hxx:57
A bin index with special values for underflow and overflow bins.
Definition RBinIndex.hxx:23
A histogram data structure to bin data along multiple dimensions.
RHistEngine(const RAxisVariant &axis1, const Axes &...axes)
Construct a histogram engine.
void Fill(const A &...args)
Fill an entry into the histogram.
const std::vector< RAxisVariant > & GetAxes() const
RHistEngine Clone() const
Clone this histogram engine.
RHistEngine & operator=(RHistEngine &&)=default
Efficiently move a histogram engine.
void Scale(double factor)
Scale all histogram bin contents.
void Fill(const std::tuple< A... > &args)
Fill an entry into the histogram.
void FillAtomic(const std::tuple< A... > &args)
Fill an entry into the histogram using atomic instructions.
RHistEngine(std::uint64_t nNormalBins, std::pair< double, double > interval)
Construct a one-dimensional histogram engine with a regular axis.
RHistEngine & operator=(const RHistEngine &)=delete
The copy assignment operator is deleted.
RHistEngine(RHistEngine &&)=default
Efficiently move construct a histogram engine.
RHistEngine(const RHistEngine &)=delete
The copy constructor is deleted.
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.
void AddAtomic(const RHistEngine &other)
Add all bin contents of another histogram using atomic instructions.
std::size_t GetNDimensions() const
void Fill(const std::tuple< A... > &args, const W &weight)
Fill an entry into the histogram with a user-defined weight.
void Add(const RHistEngine &other)
Add all bin contents of another histogram.
void FillAtomic(const std::tuple< A... > &args, RWeight weight)
Fill an entry into the histogram with a weight using atomic instructions.
static constexpr bool SupportsWeightedFilling
Whether this histogram engine type supports weighted filling.
void Clear()
Clear all bin contents.
std::uint64_t GetTotalNBins() const
void FillAtomic(const std::tuple< A... > &args, const W &weight)
Fill an entry into the histogram with a user-defined weight using atomic instructions.
RHistEngine(std::vector< RAxisVariant > axes)
Construct a histogram engine.
void FillAtomic(const A &...args)
Fill an entry into the histogram using atomic instructions.
Internal::RAxes fAxes
The axis configuration for this histogram. Relevant methods are forwarded from the public interface.
void Fill(const std::tuple< A... > &args, RWeight weight)
Fill an entry into the histogram with a weight.
RHistEngine(std::initializer_list< RAxisVariant > axes)
Construct a histogram engine.
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
std::enable_if_t< std::is_arithmetic_v< T > > AtomicInc(T *ptr)
static void SetBinContent(RHistEngine< T > &hist, const std::array< RBinIndex, N > &indices, const T &value)
Internal function to set the content of a single bin.
std::enable_if_t< std::is_integral_v< T > > AtomicAdd(T *ptr, T val)
std::variant< RRegularAxis, RVariableBinAxis, RCategoricalAxis > RAxisVariant
Variant of all supported axis types.
Definition RAxes.hxx:30
A linearized index that can be invalid.
A weight for filling histograms.
Definition RWeight.hxx:17