Logo ROOT   6.14/05
Reference Guide
df018_customActions.C
Go to the documentation of this file.
1 /// \file
2 /// \ingroup tutorial_dataframe
3 /// \notebook
4 /// This tutorial shows how to implement a custom action.
5 /// As an example, we build a helper for filling THns.
6 ///
7 /// \macro_code
8 ///
9 /// \date April 2018
10 /// \author Enrico Guiraud, Danilo Piparo
11 
12 // This is a custom action which respects a well defined interface. It supports parallelism,
13 // in the sense that it behaves correctly if implicit multi threading is enabled.
14 // We template it on:
15 // - The type of the internal THnT(s)
16 // - The dimension of the internal THnT(s)
17 // Note the plural: in presence of a MT execution, internally more than a single THnT is created.
18 template <typename T, unsigned int NDIM>
19 class THnHelper : public ROOT::Detail::RDF::RActionImpl<THnHelper<T, NDIM>> {
20 public:
21  /// This is a handy, expressive shortcut.
22  using THn_t = THnT<T>;
23  /// This type is a requirement for every helper.
24  using Result_t = THn_t;
25 
26 private:
27  std::vector<std::shared_ptr<THn_t>> fHistos; // one per data processing slot
28 
29 public:
30  /// This constructor takes all the parameters necessary to build the THnTs. In addition, it requires the names of
31  /// the columns which will be used.
32  THnHelper(std::string_view name, std::string_view title, std::array<int, NDIM> nbins, std::array<double, NDIM> xmins,
33  std::array<double, NDIM> xmax)
34  {
35  const auto nSlots = ROOT::IsImplicitMTEnabled() ? ROOT::GetImplicitMTPoolSize() : 1;
36  for (auto i : ROOT::TSeqU(nSlots)) {
37  fHistos.emplace_back(std::make_shared<THn_t>(std::string(name).c_str(), std::string(title).c_str(),
38  NDIM, nbins.data(), xmins.data(), xmax.data()));
39  (void)i;
40  }
41  }
42  THnHelper(THnHelper &&) = default;
43  THnHelper(const THnHelper &) = delete;
44  std::shared_ptr<THn_t> GetResultPtr() const { return fHistos[0]; }
45  void Initialize() {}
46  void InitTask(TTreeReader *, unsigned int) {}
47  /// This is a method executed at every entry
48  template <typename... ColumnTypes>
49  void Exec(unsigned int slot, ColumnTypes... values)
50  {
51  // Since THnT<T>::Fill expects a double*, we build it passing through a std::array.
52  std::array<double, sizeof...(ColumnTypes)> valuesArr{static_cast<double>(values)...};
53  fHistos[slot]->Fill(valuesArr.data());
54  }
55  /// This method is called at the end of the event loop. It is used to merge all the internal THnTs which
56  /// were used in each of the data processing slots.
57  void Finalize()
58  {
59  auto &res = fHistos[0];
60  for (auto slot : ROOT::TSeqU(1, fHistos.size())) {
61  res->Add(fHistos[slot].get());
62  }
63  }
64 };
65 
66 void df018_customActions()
67 {
68  // We enable implicit parallelism
70 
71  // We create an empty RDataFrame which contains 4 columns filled with random numbers.
72  // The type of the numbers held by the columns are: double, double, float, int.
73  ROOT::RDataFrame d(128);
74  auto genD = []() { return gRandom->Uniform(-5, 5); };
75  auto genF = [&genD]() { return (float)genD(); };
76  auto genI = [&genD]() { return (int)genD(); };
77  auto dd = d.Define("x0", genD).Define("x1", genD).Define("x2", genF).Define("x3", genI);
78 
79  // Our Helper type: templated on the internal THnT type, the size, the types of the columns
80  // we'll use to fill.
81  using Helper_t = THnHelper<float, 4>;
82 
83  Helper_t helper{"myThN", // Name
84  "A THn with 4 dimensions", // Title
85  {4, 4, 8, 2}, // NBins
86  {-10., -10, -4., -6.}, // Axes min values
87  {10., 10, 5., 7.}}; // Axes max values
88 
89  // We book the action: it will be treated during the event loop.
90  auto myTHnT = dd.Book<double, double, float, int>(std::move(helper), {"x0", "x1", "x2", "x3"});
91 
92  myTHnT->Print();
93 }
UInt_t GetImplicitMTPoolSize()
Returns the size of the pool used for implicit multi-threading.
Definition: TROOT.cxx:614
TTreeReader is a simple, robust and fast interface to read values from a TTree, TChain or TNtuple...
Definition: TTreeReader.h:43
Templated implementation of the abstract base THn.
Definition: THn.h:228
void EnableImplicitMT(UInt_t numthreads=0)
Enable ROOT&#39;s implicit multi-threading for all objects and methods that provide an internal paralleli...
Definition: TROOT.cxx:576
void Initialize(Bool_t useTMVAStyle=kTRUE)
Definition: tmvaglob.cxx:176
float xmax
Definition: THbookFile.cxx:93
R__EXTERN TRandom * gRandom
Definition: TRandom.h:62
ROOT&#39;s RDataFrame offers a high level interface for analyses of data stored in TTrees, CSV&#39;s and other data formats.
Definition: RDataFrame.hxx:42
#define d(i)
Definition: RSha256.hxx:102
A pseudo container class which is a generator of indices.
Definition: TSeq.hxx:66
basic_string_view< char > string_view
Definition: RStringView.hxx:35
virtual Double_t Uniform(Double_t x1=1)
Returns a uniform deviate on the interval (0, x1).
Definition: TRandom.cxx:627
typedef void((*Func_t)())
Bool_t IsImplicitMTEnabled()
Returns true if the implicit multi-threading in ROOT is enabled.
Definition: TROOT.cxx:607
char name[80]
Definition: TGX11.cxx:109