Logo ROOT  
Reference Guide
RMergeableValue.hxx
Go to the documentation of this file.
1 /**
2  \file ROOT/RDF/RMergeableValue.hxx
3  \ingroup dataframe
4  \author Vincenzo Eduardo Padulano
5  \author Enrico Guiraud
6  \date 2020-06
7 */
8 
9 /*************************************************************************
10  * Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. *
11  * All rights reserved. *
12  * *
13  * For the licensing terms see $ROOTSYS/LICENSE. *
14  * For the list of contributors see $ROOTSYS/README/CREDITS. *
15  *************************************************************************/
16 
17 #ifndef ROOT_RDF_RMERGEABLEVALUE
18 #define ROOT_RDF_RMERGEABLEVALUE
19 
20 #include <memory>
21 #include <stdexcept>
22 #include <algorithm> // std::min, std::max
23 
24 #include "RtypesCore.h"
25 #include "TList.h" // RMergeableFill::Merge
26 
27 namespace ROOT {
28 namespace Detail {
29 namespace RDF {
30 
31 // Fwd declarations for RMergeableValue
32 template <typename T>
33 class RMergeableValue;
34 
35 template <typename T, typename... Ts>
36 std::unique_ptr<RMergeableValue<T>> MergeValues(std::unique_ptr<RMergeableValue<T>> OutputMergeable,
37  std::unique_ptr<RMergeableValue<Ts>>... InputMergeables);
38 
39 template <typename T, typename... Ts>
40 void MergeValues(RMergeableValue<T> &OutputMergeable, const RMergeableValue<Ts> &... InputMergeables);
41 
42 /**
43 \class ROOT::Detail::RDF::RMergeableValueBase
44 \brief Base class of RMergeableValue.
45 \ingroup dataframe
46 Base class of the mergeable RDataFrame results family of classes. Provides a
47 non-templated custom type to allow passing a `std::unique_ptr` to the mergeable
48 object along the call chain. This class is never used in the public API and has
49 no meaning for the final user.
50 */
52 public:
53  virtual ~RMergeableValueBase() = default;
54  /**
55  Default constructor. Needed to allow serialization of ROOT objects. See
56  [TBufferFile::WriteObjectClass]
57  (classTBufferFile.html#a209078a4cb58373b627390790bf0c9c1)
58  */
59  RMergeableValueBase() = default;
60 };
61 
62 /**
63 \class ROOT::Detail::RDF::RMergeableValue
64 \ingroup dataframe
65 \brief A result of an RDataFrame execution, that knows how to merge with other
66 results of the same type.
67 \tparam T Type of the action result.
68 
69 Results of the execution of an RDataFrame computation graph do not natively
70 know how to merge with other results of the same type. In a distributed
71 environment it is often needed to have a merging mechanism for partial results
72 coming from the execution of an analysis on different chunks of the same dataset
73 that has happened on different executors. In order to achieve this,
74 RMergeableValue stores the result of the RDataFrame action and has a `Merge`
75 method to allow the aggregation of information coming from another similar
76 result into the current.
77 
78 A mergeable value can be retrieved from an RResultPtr through the
79 [GetMergeableValue]
80 (namespaceROOT_1_1Detail_1_1RDF.html#a8b3a9c7b416826acc952d78a56d14ecb) free
81 function and a sequence of mergeables can be merged together with the helper
82 function [MergeValues]
83 (namespaceROOT_1_1Detail_1_1RDF.html#af16fefbe2d120983123ddf8a1e137277).
84 All the classes and functions involved are inside the `ROOT::Detail::RDF`
85 namespace.
86 
87 In a nutshell:
88 ~~~{.cpp}
89 using namespace ROOT::Detail::RDF;
90 ROOT::RDataFrame d("myTree", "file_*.root");
91 auto h1 = d.Histo1D("Branch_A");
92 auto h2 = d.Histo1D("Branch_A");
93 
94 // Retrieve mergeables from the `RResultPtr`s
95 auto mergeableh1 = GetMergeableValue(h1);
96 auto mergeableh2 = GetMergeableValue(h2);
97 
98 // Merge the values and get another mergeable back
99 auto mergedptr = MergeValues(std::move(mergeableh1), std::move(mergeableh2));
100 
101 // Retrieve the merged TH1D object
102 const auto &mergedhisto = mergedptr->GetValue();
103 ~~~
104 
105 Though this snippet can run on a single thread of a single machine, it is
106 straightforward to generalize it to a distributed case, e.g. where `mergeableh1`
107 and `mergeableh2` are created on separate machines and sent to a `reduce`
108 process where the `MergeValues` function is called. The final user would then
109 just be given the final merged result coming from `mergedptr->GetValue`.
110 
111 RMergeableValue is the base class for all the different specializations that may
112 be needed according to the peculiarities of the result types. The following
113 subclasses, their names hinting at the action operation of the result, are
114 currently available:
115 
116 - RMergeableCount
117 - RMergeableFill, responsible for the following actions:
118  - Graph
119  - Histo{1,2,3}D
120  - Profile{1,2}D
121  - Stats
122 - RMergeableMax
123 - RMergeableMean
124 - RMergeableMin
125 - RMergeableStdDev
126 - RMergeableSum
127 */
128 template <typename T>
130  // Friend function declarations
131  template <typename T1, typename... Ts>
132  friend std::unique_ptr<RMergeableValue<T1>> MergeValues(std::unique_ptr<RMergeableValue<T1>> OutputMergeable,
133  std::unique_ptr<RMergeableValue<Ts>>... InputMergeables);
134  template <typename T1, typename... Ts>
135  friend void MergeValues(RMergeableValue<T1> &OutputMergeable, const RMergeableValue<Ts> &... InputMergeables);
136 
137  /////////////////////////////////////////////////////////////////////////////
138  /// \brief Aggregate the information contained in another RMergeableValue
139  /// into this.
140  ///
141  /// Virtual function reimplemented in all the subclasses.
142  ///
143  /// \note All the `Merge` methods in the RMergeableValue family are private.
144  /// To merge multiple RMergeableValue objects please use [MergeValues]
145  /// (namespaceROOT_1_1Detail_1_1RDF.html#af16fefbe2d120983123ddf8a1e137277).
146  virtual void Merge(const RMergeableValue<T> &) = 0;
147 
148 protected:
150 
151 public:
152  /**
153  Constructor taking the action result by const reference. This involves a
154  copy of the result into the data member, but gives full ownership of data
155  to the mergeable.
156  */
157  RMergeableValue(const T &value) : fValue{value} {}
158  /**
159  Default constructor. Needed to allow serialization of ROOT objects. See
160  [TBufferFile::WriteObjectClass]
161  (classTBufferFile.html#a209078a4cb58373b627390790bf0c9c1)
162  */
163  RMergeableValue() = default;
164  /////////////////////////////////////////////////////////////////////////////
165  /// \brief Retrieve the result wrapped by this mergeable.
166  const T &GetValue() const { return fValue; }
167 };
168 
169 /**
170 \class ROOT::Detail::RDF::RMergeableCount
171 \ingroup dataframe
172 \brief Specialization of RMergeableValue for the
173 [Count](classROOT_1_1RDF_1_1RInterface.html#a9678150c9c18cddd7b599690ba854734)
174 action.
175 */
176 class RMergeableCount final : public RMergeableValue<ULong64_t> {
177  /////////////////////////////////////////////////////////////////////////////
178  /// \brief Aggregate the information contained in another RMergeableValue
179  /// into this.
180  /// \param[in] other Another RMergeableValue object.
181  /// \throws std::invalid_argument If the cast of the other object to the same
182  /// type as this one fails.
183  ///
184  /// The other RMergeableValue object is cast to the same type as this object.
185  /// This is needed to make sure that only results of the same type of action
186  /// are merged together. Then the two results are added together to update
187  /// the value held by the current object.
188  ///
189  /// \note All the `Merge` methods in the RMergeableValue family are private.
190  /// To merge multiple RMergeableValue objects please use [MergeValues]
191  /// (namespaceROOT_1_1Detail_1_1RDF.html#af16fefbe2d120983123ddf8a1e137277).
192  void Merge(const RMergeableValue<ULong64_t> &other) final
193  {
194  try {
195  const auto &othercast = dynamic_cast<const RMergeableCount &>(other);
196  this->fValue += othercast.fValue;
197  } catch (const std::bad_cast &) {
198  throw std::invalid_argument("Results from different actions cannot be merged together.");
199  }
200  }
201 
202 public:
203  /////////////////////////////////////////////////////////////////////////////
204  /// \brief Constructor that initializes data members.
205  /// \param[in] value The action result.
207  /**
208  Default constructor. Needed to allow serialization of ROOT objects. See
209  [TBufferFile::WriteObjectClass]
210  (classTBufferFile.html#a209078a4cb58373b627390790bf0c9c1)
211  */
212  RMergeableCount() = default;
214  RMergeableCount(const RMergeableCount &) = delete;
215 };
216 
217 /**
218 \class ROOT::Detail::RDF::RMergeableFill
219 \ingroup dataframe
220 \brief Specialization of RMergeableValue for histograms and statistics.
221 
222 This subclass is responsible for merging results coming from the following
223 actions:
224 - [Graph](classROOT_1_1RDF_1_1RInterface.html#a804b466ebdbddef5c7e3400cc6b89301)
225 - [Histo{1D,2D,3D}]
226  (classROOT_1_1RDF_1_1RInterface.html#a247ca3aeb7ce5b95015b7fae72983055)
227 - [Profile{1D,2D}]
228  (classROOT_1_1RDF_1_1RInterface.html#a8ef7dc16b0e9f7bc9cfbe2d9e5de0cef)
229 - [Stats](classROOT_1_1RDF_1_1RInterface.html#abc68922c464e472f5f856e8981955af6)
230 
231 */
232 template <typename T>
233 class RMergeableFill final : public RMergeableValue<T> {
234  /////////////////////////////////////////////////////////////////////////////
235  /// \brief Aggregate the information contained in another RMergeableValue
236  /// into this.
237  /// \param[in] other Another RMergeableValue object.
238  /// \throws std::invalid_argument If the cast of the other object to the same
239  /// type as this one fails.
240  ///
241  /// The other RMergeableValue object is cast to the same type as this object.
242  /// This is needed to make sure that only results of the same type of action
243  /// are merged together. The function then calls the right `Merge` method
244  /// according to the class of the fValue data member.
245  ///
246  /// \note All the `Merge` methods in the RMergeableValue family are private.
247  /// To merge multiple RMergeableValue objects please use [MergeValues]
248  /// (namespaceROOT_1_1Detail_1_1RDF.html#af16fefbe2d120983123ddf8a1e137277).
249  void Merge(const RMergeableValue<T> &other) final
250  {
251  try {
252  const auto &othercast = dynamic_cast<const RMergeableFill<T> &>(other);
253  TList l; // The `Merge` method accepts a TList
254  l.Add(const_cast<T *>(&(othercast.fValue))); // Ugly but needed because of the signature of TList::Add
255  this->fValue.Merge(&l); // if `T == TH1D` Eventually calls TH1::ExtendAxis that creates new instances of TH1D
256  } catch (const std::bad_cast &) {
257  throw std::invalid_argument("Results from different actions cannot be merged together.");
258  }
259  }
260 
261 public:
262  /////////////////////////////////////////////////////////////////////////////
263  /// \brief Constructor that initializes data members.
264  /// \param[in] value The action result.
265  RMergeableFill(const T &value) : RMergeableValue<T>(value) {}
266  /**
267  Default constructor. Needed to allow serialization of ROOT objects. See
268  [TBufferFile::WriteObjectClass]
269  (classTBufferFile.html#a209078a4cb58373b627390790bf0c9c1)
270  */
271  RMergeableFill() = default;
273  RMergeableFill(const RMergeableFill &) = delete;
274 };
275 
276 template <typename T>
277 class RMergeableMax final : public RMergeableValue<T> {
278 
279  void Merge(const RMergeableValue<T> &other) final
280  {
281  try {
282  const auto &othercast = dynamic_cast<const RMergeableMax<T> &>(other);
283  this->fValue = std::max(this->fValue, othercast.fValue);
284  } catch (const std::bad_cast &) {
285  throw std::invalid_argument("Results from different actions cannot be merged together.");
286  }
287  }
288 
289 public:
290  /////////////////////////////////////////////////////////////////////////////
291  /// \brief Constructor that initializes data members.
292  /// \param[in] value The action result.
293  RMergeableMax(const T &value) : RMergeableValue<T>(value) {}
294  /**
295  Default constructor. Needed to allow serialization of ROOT objects. See
296  [TBufferFile::WriteObjectClass]
297  (classTBufferFile.html#a209078a4cb58373b627390790bf0c9c1)
298  */
299  RMergeableMax() = default;
301  RMergeableMax(const RMergeableMax &) = delete;
302 };
303 
304 /**
305 \class ROOT::Detail::RDF::RMergeableMean
306 \ingroup dataframe
307 \brief Specialization of RMergeableValue for the
308 [Mean](classROOT_1_1RDF_1_1RInterface.html#ade6b020284f2f4fe9d3b09246b5f376a)
309 action.
310 
311 This subclass is responsible for merging results coming from Mean actions. Other
312 than the result itself, the number of entries that were used to compute that
313 mean is also stored in the object.
314 */
315 class RMergeableMean final : public RMergeableValue<Double_t> {
316  ULong64_t fCounts; ///< The number of entries used to compute the mean.
317 
318  /////////////////////////////////////////////////////////////////////////////
319  /// \brief Aggregate the information contained in another RMergeableValue
320  /// into this.
321  /// \param[in] other Another RMergeableValue object.
322  /// \throws std::invalid_argument If the cast of the other object to the same
323  /// type as this one fails.
324  ///
325  /// The other RMergeableValue object is cast to the same type as this object.
326  /// This is needed to make sure that only results of the same type of action
327  /// are merged together. The function then computes the weighted mean of the
328  /// two means held by the mergeables.
329  ///
330  /// \note All the `Merge` methods in the RMergeableValue family are private.
331  /// To merge multiple RMergeableValue objects please use [MergeValues]
332  /// (namespaceROOT_1_1Detail_1_1RDF.html#af16fefbe2d120983123ddf8a1e137277).
333  void Merge(const RMergeableValue<Double_t> &other) final
334  {
335  try {
336  const auto &othercast = dynamic_cast<const RMergeableMean &>(other);
337  const auto &othervalue = othercast.fValue;
338  const auto &othercounts = othercast.fCounts;
339 
340  // Compute numerator and denumerator of the weighted mean
341  const auto num = this->fValue * fCounts + othervalue * othercounts;
342  const auto denum = static_cast<Double_t>(fCounts + othercounts);
343 
344  // Update data members
345  this->fValue = num / denum;
346  fCounts += othercounts;
347  } catch (const std::bad_cast &) {
348  throw std::invalid_argument("Results from different actions cannot be merged together.");
349  }
350  }
351 
352 public:
353  /////////////////////////////////////////////////////////////////////////////
354  /// \brief Constructor that initializes data members.
355  /// \param[in] value The action result.
356  /// \param[in] counts The number of entries used to compute that result.
357  RMergeableMean(Double_t value, ULong64_t counts) : RMergeableValue<Double_t>(value), fCounts{counts} {}
358  /**
359  Default constructor. Needed to allow serialization of ROOT objects. See
360  [TBufferFile::WriteObjectClass]
361  (classTBufferFile.html#a209078a4cb58373b627390790bf0c9c1)
362  */
363  RMergeableMean() = default;
365  RMergeableMean(const RMergeableMean &) = delete;
366 };
367 
368 template <typename T>
369 class RMergeableMin final : public RMergeableValue<T> {
370 
371  void Merge(const RMergeableValue<T> &other) final
372  {
373  try {
374  const auto &othercast = dynamic_cast<const RMergeableMin<T> &>(other);
375  this->fValue = std::min(this->fValue, othercast.fValue);
376  } catch (const std::bad_cast &) {
377  throw std::invalid_argument("Results from different actions cannot be merged together.");
378  }
379  }
380 
381 public:
382  /////////////////////////////////////////////////////////////////////////////
383  /// \brief Constructor that initializes data members.
384  /// \param[in] value The action result.
385  RMergeableMin(const T &value) : RMergeableValue<T>(value) {}
386  /**
387  Default constructor. Needed to allow serialization of ROOT objects. See
388  [TBufferFile::WriteObjectClass]
389  (classTBufferFile.html#a209078a4cb58373b627390790bf0c9c1)
390  */
391  RMergeableMin() = default;
393  RMergeableMin(const RMergeableMin &) = delete;
394 };
395 
396 /**
397 \class ROOT::Detail::RDF::RMergeableStdDev
398 \ingroup dataframe
399 \brief Specialization of RMergeableValue for the
400 [StdDev](classROOT_1_1RDF_1_1RInterface.html#a482c4e4f81fe1e421c016f89cd281572)
401 action.
402 
403 This class also stores information about the number of entries and the average
404 used to compute the standard deviation.
405 */
406 class RMergeableStdDev final : public RMergeableValue<Double_t> {
407  ULong64_t fCounts; ///< Number of entries of the set.
408  Double_t fMean; ///< Average of the set.
409 
410  /////////////////////////////////////////////////////////////////////////////
411  /// \brief Aggregate the information contained in another RMergeableValue
412  /// into this.
413  /// \param[in] other Another RMergeableValue object.
414  /// \throws std::invalid_argument If the cast of the other object to the same
415  /// type as this one fails.
416  ///
417  /// The other RMergeableValue object is cast to the same type as this object.
418  /// This is needed to make sure that only results of the same type of action
419  /// are merged together. The function then computes the aggregated standard
420  /// deviation of the two samples using an algorithm by
421  /// [Chan et al. (1979)]
422  /// (http://i.stanford.edu/pub/cstr/reports/cs/tr/79/773/CS-TR-79-773.pdf)
423  ///
424  /// \note All the `Merge` methods in the RMergeableValue family are private.
425  /// To merge multiple RMergeableValue objects please use [MergeValues]
426  /// (namespaceROOT_1_1Detail_1_1RDF.html#af16fefbe2d120983123ddf8a1e137277).
427  void Merge(const RMergeableValue<Double_t> &other) final
428  {
429  try {
430  const auto &othercast = dynamic_cast<const RMergeableStdDev &>(other);
431  const auto &othercounts = othercast.fCounts;
432  const auto &othermean = othercast.fMean;
433 
434  // Compute the aggregated variance using an algorithm by Chan et al.
435  // See https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Parallel_algorithm
436  const auto thisvariance = std::pow(this->fValue, 2);
437  const auto othervariance = std::pow(othercast.fValue, 2);
438 
439  const auto delta = othermean - fMean;
440 
441  const auto m_a = thisvariance * (fCounts - 1);
442  const auto m_b = othervariance * (othercounts - 1);
443 
444  const auto sumcounts = static_cast<Double_t>(fCounts + othercounts);
445 
446  const auto M2 = m_a + m_b + std::pow(delta, 2) * fCounts * othercounts / sumcounts;
447 
448  const auto meannum = fMean * fCounts + othermean * othercounts;
449 
450  // Update the data members
451  this->fValue = std::sqrt(M2 / (sumcounts - 1));
452  fMean = meannum / sumcounts;
453  fCounts += othercounts;
454  } catch (const std::bad_cast &) {
455  throw std::invalid_argument("Results from different actions cannot be merged together.");
456  }
457  }
458 
459 public:
460  /////////////////////////////////////////////////////////////////////////////
461  /// \brief Constructor that initializes data members.
462  /// \param[in] value The action result.
463  /// \param[in] counts The number of entries of the set.
464  /// \param[in] mean The average of the set.
466  : RMergeableValue<Double_t>(value), fCounts{counts}, fMean{mean}
467  {
468  }
469  /**
470  Default constructor. Needed to allow serialization of ROOT objects. See
471  [TBufferFile::WriteObjectClass]
472  (classTBufferFile.html#a209078a4cb58373b627390790bf0c9c1)
473  */
474  RMergeableStdDev() = default;
477 };
478 
479 template <typename T>
480 class RMergeableSum final : public RMergeableValue<T> {
481 
482  void Merge(const RMergeableValue<T> &other) final
483  {
484  try {
485  const auto &othercast = dynamic_cast<const RMergeableSum<T> &>(other);
486  this->fValue += othercast.fValue;
487  } catch (const std::bad_cast &) {
488  throw std::invalid_argument("Results from different actions cannot be merged together.");
489  }
490  }
491 
492 public:
493  /////////////////////////////////////////////////////////////////////////////
494  /// \brief Constructor that initializes data members.
495  /// \param[in] value The action result.
496  RMergeableSum(const T &value) : RMergeableValue<T>(value) {}
497  /**
498  Default constructor. Needed to allow serialization of ROOT objects. See
499  [TBufferFile::WriteObjectClass]
500  (classTBufferFile.html#a209078a4cb58373b627390790bf0c9c1)
501  */
502  RMergeableSum() = default;
504  RMergeableSum(const RMergeableSum &) = delete;
505 };
506 
507 /// \cond HIDDEN_SYMBOLS
508 // What follows mimics C++17 std::conjunction without using recursive template instantiations.
509 // Used in `MergeValues` to check that all the mergeables hold values of the same type.
510 template <bool...>
511 struct bool_pack {
512 };
513 template <class... Ts>
514 using conjunction = std::is_same<bool_pack<true, Ts::value...>, bool_pack<Ts::value..., true>>;
515 /// \endcond
516 
517 ////////////////////////////////////////////////////////////////////////////////
518 /// \brief Merge multiple RMergeableValue objects into one.
519 /// \param[in] OutputMergeable The mergeable object where all the information
520 /// will be aggregated.
521 /// \param[in] InputMergeables Other mergeables containing the partial results.
522 /// \returns An RMergeableValue holding the aggregated value wrapped in an
523 /// `std::unique_ptr`.
524 ///
525 /// This is the recommended way of merging multiple RMergeableValue objects.
526 /// This overload takes ownership of the mergeables and gives back to the user
527 /// a mergeable with the aggregated information. All the mergeables with the
528 /// partial results get destroyed in the process.
529 ///
530 /// Example usage:
531 /// ~~~{.cpp}
532 /// using namespace ROOT::Detail::RDF;
533 /// // mh1, mh2, mh3 are std::unique_ptr<RMergeableValue<TH1D>>
534 /// auto mergedptr = MergeValues(std::move(mh1), std::move(mh2), std::move(mh3));
535 /// const auto &mergedhisto = mergedptr->GetValue(); // Final merged histogram
536 /// // Do stuff with it
537 /// mergedhisto.Draw();
538 /// ~~~
539 template <typename T, typename... Ts>
540 std::unique_ptr<RMergeableValue<T>> MergeValues(std::unique_ptr<RMergeableValue<T>> OutputMergeable,
541  std::unique_ptr<RMergeableValue<Ts>>... InputMergeables)
542 {
543  // Check all mergeables have the same template type
544  static_assert(conjunction<std::is_same<Ts, T>...>::value, "Values must all be of the same type.");
545 
546  // Using dummy array initialization inspired by https://stackoverflow.com/a/25683817
547  using expander = int[];
548  // Cast to void to suppress unused-value warning in Clang
549  (void)expander{0, (OutputMergeable->Merge(*InputMergeables), 0)...};
550 
551  return OutputMergeable;
552 }
553 
554 ////////////////////////////////////////////////////////////////////////////////
555 /// \brief Merge multiple RMergeableValue objects into one.
556 /// \param[in,out] OutputMergeable The mergeable object where all the
557 /// information will be aggregated.
558 /// \param[in] InputMergeables Other mergeables containing the partial results.
559 ///
560 /// This overload modifies the mergeable objects in-place. The ownership is left
561 /// to the caller. The first argument to the function will get all the
562 /// values contained in the other arguments merged into itself. This is a
563 /// convenience overload introduced for the ROOT Python API.
564 ///
565 /// Example usage:
566 /// ~~~{.cpp}
567 /// // mh1, mh2, mh3 are std::unique_ptr<RMergeableValue<TH1D>>
568 /// ROOT::Detail::RDF::MergeValues(*mh1, *mh2, *mh3);
569 /// const auto &mergedhisto = mh1->GetValue(); // Final merged histogram
570 /// // Do stuff with it
571 /// mergedhisto.Draw();
572 /// ~~~
573 template <typename T, typename... Ts>
574 void MergeValues(RMergeableValue<T> &OutputMergeable, const RMergeableValue<Ts> &... InputMergeables)
575 {
576  // Check all mergeables are of the same type
577  static_assert(conjunction<std::is_same<Ts, T>...>::value, "Values must all be of the same type.");
578 
579  // Using dummy array initialization inspired by https://stackoverflow.com/a/25683817
580  using expander = int[];
581  // Cast to void to suppress unused-value warning in Clang
582  (void)expander{0, (OutputMergeable.Merge(InputMergeables), 0)...};
583 }
584 } // namespace RDF
585 } // namespace Detail
586 } // namespace ROOT
587 
588 #endif // ROOT_RDF_RMERGEABLEVALUE
l
auto * l
Definition: textangle.C:4
ROOT::Detail::RDF::RMergeableStdDev::RMergeableStdDev
RMergeableStdDev()=default
Default constructor.
ROOT::Detail::RDF::RMergeableMin::Merge
void Merge(const RMergeableValue< T > &other) final
Aggregate the information contained in another RMergeableValue into this.
Definition: RMergeableValue.hxx:371
ROOT::Detail::RDF::RMergeableSum::RMergeableSum
RMergeableSum()=default
Default constructor.
ROOT::Detail::RDF::RMergeableStdDev::Merge
void Merge(const RMergeableValue< Double_t > &other) final
Aggregate the information contained in another RMergeableValue into this.
Definition: RMergeableValue.hxx:427
ROOT::Detail::RDF::RMergeableStdDev::fMean
Double_t fMean
Average of the set.
Definition: RMergeableValue.hxx:408
ROOT::Detail::RDF::RMergeableSum::RMergeableSum
RMergeableSum(RMergeableSum &&)=default
ROOT::Detail::RDF::RMergeableMin::RMergeableMin
RMergeableMin(RMergeableMin &&)=default
ROOT::Detail::RDF::RMergeableMean::RMergeableMean
RMergeableMean(RMergeableMean &&)=default
ROOT::Detail::RDF::RMergeableStdDev::fCounts
ULong64_t fCounts
Number of entries of the set.
Definition: RMergeableValue.hxx:407
ROOT::Detail::RDF::RMergeableValue::RMergeableValue
RMergeableValue()=default
Default constructor.
ROOT::Detail::RDF::RMergeableMin::RMergeableMin
RMergeableMin(const RMergeableMin &)=delete
ROOT::Detail::RDF::RMergeableMax::RMergeableMax
RMergeableMax(const T &value)
Constructor that initializes data members.
Definition: RMergeableValue.hxx:293
ROOT::Detail::RDF::RMergeableMax
Definition: RMergeableValue.hxx:277
ROOT::Detail::RDF::RMergeableCount::RMergeableCount
RMergeableCount(const RMergeableCount &)=delete
TList.h
ROOT::Detail::RDF::RMergeableValue::MergeValues
friend void MergeValues(RMergeableValue< T1 > &OutputMergeable, const RMergeableValue< Ts > &... InputMergeables)
ROOT::Detail::RDF::RMergeableStdDev::RMergeableStdDev
RMergeableStdDev(Double_t value, ULong64_t counts, Double_t mean)
Constructor that initializes data members.
Definition: RMergeableValue.hxx:465
ROOT::Detail::RDF::MergeValues
std::unique_ptr< RMergeableValue< T > > MergeValues(std::unique_ptr< RMergeableValue< T >> OutputMergeable, std::unique_ptr< RMergeableValue< Ts >>... InputMergeables)
Merge multiple RMergeableValue objects into one.
Definition: RMergeableValue.hxx:540
ROOT::Detail::RDF::RMergeableMean
Specialization of RMergeableValue for the Mean action.
Definition: RMergeableValue.hxx:315
ROOT::Detail::RDF::RMergeableFill::RMergeableFill
RMergeableFill()=default
Default constructor.
ROOT::Detail::RDF::RMergeableFill::RMergeableFill
RMergeableFill(const T &value)
Constructor that initializes data members.
Definition: RMergeableValue.hxx:265
ROOT::Detail::RDF::RMergeableValue::MergeValues
friend std::unique_ptr< RMergeableValue< T1 > > MergeValues(std::unique_ptr< RMergeableValue< T1 >> OutputMergeable, std::unique_ptr< RMergeableValue< Ts >>... InputMergeables)
ROOT::Detail::RDF::RMergeableValue::RMergeableValue
RMergeableValue(const T &value)
Constructor taking the action result by const reference.
Definition: RMergeableValue.hxx:157
ROOT::Detail::RDF::RMergeableMax::RMergeableMax
RMergeableMax()=default
Default constructor.
ROOT::Detail::RDF::RMergeableMax::RMergeableMax
RMergeableMax(RMergeableMax &&)=default
ROOT::Detail::RDF::RMergeableValue::Merge
virtual void Merge(const RMergeableValue< T > &)=0
Aggregate the information contained in another RMergeableValue into this.
ROOT::Detail::RDF::RMergeableSum
Definition: RMergeableValue.hxx:480
ROOT::Detail::RDF::RMergeableStdDev::RMergeableStdDev
RMergeableStdDev(RMergeableStdDev &&)=default
ROOT::Detail::RDF::RMergeableSum::RMergeableSum
RMergeableSum(const T &value)
Constructor that initializes data members.
Definition: RMergeableValue.hxx:496
ROOT::Detail::RDF::RMergeableCount::RMergeableCount
RMergeableCount()=default
Default constructor.
ROOT::Detail::RDF::RMergeableMin::RMergeableMin
RMergeableMin()=default
Default constructor.
ROOT::Detail::RDF::RMergeableMean::fCounts
ULong64_t fCounts
The number of entries used to compute the mean.
Definition: RMergeableValue.hxx:316
ROOT::Detail::RDF::RMergeableValueBase::~RMergeableValueBase
virtual ~RMergeableValueBase()=default
ROOT::Detail::RDF::RMergeableCount::RMergeableCount
RMergeableCount(RMergeableCount &&)=default
ROOT::Detail::RDF::RMergeableValue
A result of an RDataFrame execution, that knows how to merge with other results of the same type.
Definition: RMergeableValue.hxx:129
ROOT::Detail::RDF::RMergeableValue::GetValue
const T & GetValue() const
Retrieve the result wrapped by this mergeable.
Definition: RMergeableValue.hxx:166
ROOT::Detail::RDF::RMergeableValue::fValue
T fValue
Definition: RMergeableValue.hxx:149
ROOT::Detail::RDF::RMergeableFill::RMergeableFill
RMergeableFill(RMergeableFill &&)=default
ROOT::Detail::RDF::RMergeableStdDev
Specialization of RMergeableValue for the StdDev action.
Definition: RMergeableValue.hxx:406
ROOT::Detail::RDF::RMergeableValueBase::RMergeableValueBase
RMergeableValueBase()=default
Default constructor.
sqrt
double sqrt(double)
ROOT::Detail::RDF::RMergeableMean::RMergeableMean
RMergeableMean()=default
Default constructor.
ROOT::Detail::RDF::RMergeableFill
Specialization of RMergeableValue for histograms and statistics.
Definition: RMergeableValue.hxx:233
ROOT::Detail::RDF::RMergeableMin::RMergeableMin
RMergeableMin(const T &value)
Constructor that initializes data members.
Definition: RMergeableValue.hxx:385
ROOT::Detail::RDF::RMergeableMax::RMergeableMax
RMergeableMax(const RMergeableMax &)=delete
void
typedef void((*Func_t)())
ROOT::Detail::RDF::RMergeableFill::RMergeableFill
RMergeableFill(const RMergeableFill &)=delete
ROOT::Detail::RDF::RMergeableCount
Specialization of RMergeableValue for the Count action.
Definition: RMergeableValue.hxx:176
ROOT::Detail::RDF::RMergeableMean::Merge
void Merge(const RMergeableValue< Double_t > &other) final
Aggregate the information contained in another RMergeableValue into this.
Definition: RMergeableValue.hxx:333
ULong64_t
unsigned long long ULong64_t
Definition: RtypesCore.h:74
ROOT::Detail::RDF::RMergeableMean::RMergeableMean
RMergeableMean(const RMergeableMean &)=delete
ROOT::Detail::RDF::RMergeableMin
Definition: RMergeableValue.hxx:369
ROOT::Detail::RDF::RMergeableSum::RMergeableSum
RMergeableSum(const RMergeableSum &)=delete
Double_t
double Double_t
Definition: RtypesCore.h:59
RtypesCore.h
ROOT::Detail::RDF::RMergeableStdDev::RMergeableStdDev
RMergeableStdDev(const RMergeableStdDev &)=delete
T1
#define T1
Definition: md5.inl:145
ROOT::Detail::RDF::RMergeableCount::RMergeableCount
RMergeableCount(ULong64_t value)
Constructor that initializes data members.
Definition: RMergeableValue.hxx:206
ROOT::Detail::RDF::RMergeableValueBase
Base class of RMergeableValue.
Definition: RMergeableValue.hxx:51
ROOT::Math::Chebyshev::T
double T(double x)
Definition: ChebyshevPol.h:34
ROOT::Detail::RDF::RMergeableMean::RMergeableMean
RMergeableMean(Double_t value, ULong64_t counts)
Constructor that initializes data members.
Definition: RMergeableValue.hxx:357
ROOT::Detail::RDF::RMergeableSum::Merge
void Merge(const RMergeableValue< T > &other) final
Aggregate the information contained in another RMergeableValue into this.
Definition: RMergeableValue.hxx:482
pow
double pow(double, double)
ROOT::Detail::RDF::RMergeableMax::Merge
void Merge(const RMergeableValue< T > &other) final
Aggregate the information contained in another RMergeableValue into this.
Definition: RMergeableValue.hxx:279
ROOT
VSD Structures.
Definition: StringConv.hxx:21
ROOT::Detail::RDF::RMergeableCount::Merge
void Merge(const RMergeableValue< ULong64_t > &other) final
Aggregate the information contained in another RMergeableValue into this.
Definition: RMergeableValue.hxx:192
TList
A doubly linked list.
Definition: TList.h:44
ROOT::Detail::RDF::RMergeableFill::Merge
void Merge(const RMergeableValue< T > &other) final
Aggregate the information contained in another RMergeableValue into this.
Definition: RMergeableValue.hxx:249