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