Logo ROOT   6.10/09
Reference Guide
TDFNodes.hxx
Go to the documentation of this file.
1 // Author: Enrico Guiraud, Danilo Piparo CERN 03/2017
2 
3 /*************************************************************************
4  * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers. *
5  * All rights reserved. *
6  * *
7  * For the licensing terms see $ROOTSYS/LICENSE. *
8  * For the list of contributors see $ROOTSYS/README/CREDITS. *
9  *************************************************************************/
10 
11 #ifndef ROOT_TDFNODES
12 #define ROOT_TDFNODES
13 
14 #include "ROOT/TDFUtils.hxx"
15 #include "ROOT/RArrayView.hxx"
16 #include "ROOT/TSpinMutex.hxx"
17 #include "TTreeReaderArray.h"
18 #include "TTreeReaderValue.h"
19 
20 #include <map>
21 #include <numeric> // std::iota for TSlotStack
22 #include <string>
23 #include <tuple>
24 #include <cassert>
25 
26 namespace ROOT {
27 
28 namespace Internal {
29 namespace TDF {
30 class TActionBase;
31 }
32 }
33 
34 namespace Detail {
35 namespace TDF {
37 
38 // forward declarations for TLoopManager
39 using ActionBasePtr_t = std::shared_ptr<TDFInternal::TActionBase>;
40 using ActionBaseVec_t = std::vector<ActionBasePtr_t>;
41 class TCustomColumnBase;
42 using TmpBranchBasePtr_t = std::shared_ptr<TCustomColumnBase>;
43 class TFilterBase;
44 using FilterBasePtr_t = std::shared_ptr<TFilterBase>;
45 using FilterBaseVec_t = std::vector<FilterBasePtr_t>;
46 class TRangeBase;
47 using RangeBasePtr_t = std::shared_ptr<TRangeBase>;
48 using RangeBaseVec_t = std::vector<RangeBasePtr_t>;
49 
50 class TLoopManager : public std::enable_shared_from_this<TLoopManager> {
51 
55  std::map<std::string, TmpBranchBasePtr_t> fBookedBranches;
57  std::vector<std::shared_ptr<bool>> fResProxyReadiness;
58  ::TDirectory *fDirPtr{nullptr};
59  std::shared_ptr<TTree> fTree{nullptr};
60  const ColumnNames_t fDefaultBranches;
61  const Long64_t fNEmptyEntries{0};
62  const unsigned int fNSlots{0};
63  bool fHasRunAtLeastOnce{false};
64  unsigned int fNChildren{0}; ///< Number of nodes of the functional graph hanging from this object
65  unsigned int fNStopsReceived{0}; ///< Number of times that a children node signaled to stop processing entries.
66 
67  void RunAndCheckFilters(unsigned int slot, Long64_t entry);
68  void InitNodes();
69 
70 public:
71  TLoopManager(TTree *tree, const ColumnNames_t &defaultBranches);
72  TLoopManager(Long64_t nEmptyEntries);
73  TLoopManager(const TLoopManager &) = delete;
75  void Run();
76  void InitAllNodes(TTreeReader *r, unsigned int slot);
77  TLoopManager *GetImplPtr();
78  std::shared_ptr<TLoopManager> GetSharedPtr() { return shared_from_this(); }
79  const ColumnNames_t &GetDefaultBranches() const;
80  const ColumnNames_t GetTmpBranches() const { return {}; };
81  TTree *GetTree() const;
82  TCustomColumnBase *GetBookedBranch(const std::string &name) const;
83  const std::map<std::string, TmpBranchBasePtr_t> &GetBookedBranches() const { return fBookedBranches; }
84  ::TDirectory *GetDirectory() const;
85  Long64_t GetNEmptyEntries() const { return fNEmptyEntries; }
86  void Book(const ActionBasePtr_t &actionPtr);
87  void Book(const FilterBasePtr_t &filterPtr);
88  void Book(const TmpBranchBasePtr_t &branchPtr);
89  void Book(const std::shared_ptr<bool> &branchPtr);
90  void Book(const RangeBasePtr_t &rangePtr);
91  bool CheckFilters(int, unsigned int);
92  unsigned int GetNSlots() const { return fNSlots; }
93  bool HasRunAtLeastOnce() const { return fHasRunAtLeastOnce; }
94  void Report() const;
95  /// End of recursive chain of calls, does nothing
96  void PartialReport() const {}
97  void SetTree(std::shared_ptr<TTree> tree) { fTree = tree; }
98  void IncrChildrenCount() { ++fNChildren; }
99  void StopProcessing() { ++fNStopsReceived; }
100  void CleanUpTask(unsigned int slot);
101 };
102 } // end ns TDF
103 } // end ns Detail
104 
105 namespace Internal {
106 namespace TDF {
107 using namespace ROOT::Detail::TDF;
108 
109 /**
110 \class ROOT::Internal::TDF::TColumnValue
111 \ingroup dataframe
112 \brief Helper class that updates and returns TTree branches as well as TDataFrame temporary columns
113 \tparam T The type of the column
114 
115 TDataFrame nodes must access two different types of values during the event loop:
116 values of real branches, for which TTreeReader{Values,Arrays} act as proxies, or
117 temporary columns whose values are generated on the fly. While the type of the
118 value is known at compile time (or just-in-time), it is only at runtime that nodes
119 can check whether a certain value is generated on the fly or not.
120 
121 TColumnValuePtr abstracts this difference by providing the same interface for
122 both cases and handling the reading or generation of new values transparently.
123 Only one of the two data members fReaderProxy or fValuePtr will be non-null
124 for a given TColumnValue, depending on whether the value comes from a real
125 TTree branch or from a temporary column respectively.
126 
127 TDataFrame nodes can store tuples of TColumnValues and retrieve an updated
128 value for the column via the `Get` method.
129 **/
130 template <typename T>
132  // following line is equivalent to pseudo-code: ProxyParam_t == array_view<U> ? U : T
133  // ReaderValueOrArray_t is a TTreeReaderValue<T> unless T is array_view<U>
134  using ProxyParam_t = typename std::conditional<std::is_same<ReaderValueOrArray_t<T>, TTreeReaderValue<T>>::value, T,
135  ExtractType_t<T>>::type;
136  std::unique_ptr<TTreeReaderValue<T>> fReaderValue{nullptr}; //< Owning ptr to a TTreeReaderValue. Used for
137  /// non-temporary columns and T != std::array_view<U>
138  std::unique_ptr<TTreeReaderArray<ProxyParam_t>> fReaderArray{nullptr}; //< Owning ptr to a TTreeReaderArray. Used for
139  /// non-temporary columsn and
140  /// T == std::array_view<U>.
141  T *fValuePtr{nullptr}; //< Non-owning ptr to the value of a temporary column.
142  TCustomColumnBase *fTmpColumn{nullptr}; //< Non-owning ptr to the node responsible for the temporary column.
143  unsigned int fSlot{0}; //< The slot this value belongs to. Only used for temporary columns, not for real branches.
144 
145 public:
146  TColumnValue() = default;
147 
148  void SetTmpColumn(unsigned int slot, TCustomColumnBase *tmpColumn);
149 
150  void MakeProxy(TTreeReader *r, const std::string &bn)
151  {
152  Reset();
153  bool useReaderValue = std::is_same<ProxyParam_t, T>::value;
154  if (useReaderValue)
155  fReaderValue.reset(new TTreeReaderValue<T>(*r, bn.c_str()));
156  else
157  fReaderArray.reset(new TTreeReaderArray<ProxyParam_t>(*r, bn.c_str()));
158  }
159 
160  template <typename U = T,
161  typename std::enable_if<std::is_same<typename TColumnValue<U>::ProxyParam_t, U>::value, int>::type = 0>
162  T &Get(Long64_t entry);
163 
164  template <typename U = T, typename std::enable_if<!std::is_same<ProxyParam_t, U>::value, int>::type = 0>
165  std::array_view<ProxyParam_t> Get(Long64_t)
166  {
167  auto &readerArray = *fReaderArray;
168  if (readerArray.GetSize() > 1 && 1 != (&readerArray[1] - &readerArray[0])) {
169  std::string exceptionText = "Branch ";
170  exceptionText += fReaderArray->GetBranchName();
171  exceptionText += " hangs from a non-split branch. For this reason, it cannot be accessed via an array_view."
172  " Please read the top level branch instead.";
173  throw std::runtime_error(exceptionText.c_str());
174  }
175 
176  return std::array_view<ProxyParam_t>(fReaderArray->begin(), fReaderArray->end());
177  }
178 
179  void Reset()
180  {
181  fReaderValue = nullptr;
182  fReaderArray = nullptr;
183  fValuePtr = nullptr;
184  fTmpColumn = nullptr;
185  fSlot = 0;
186  }
187 };
188 
189 template <typename T>
191 };
192 
193 template <typename... BranchTypes>
194 struct TTDFValueTuple<TTypeList<BranchTypes...>> {
195  using type = std::tuple<TColumnValue<BranchTypes>...>;
196 };
197 
198 template <typename BranchType>
200 
201 /// Clear the proxies of a tuple of TColumnValues
202 template<typename ValueTuple, int...S>
203 void ResetTDFValueTuple(ValueTuple& values, TStaticSeq<S...>)
204 {
205  // hack to expand a parameter pack without c++17 fold expressions.
206  std::initializer_list<int> expander{(std::get<S>(values).Reset(), 0)...};
207  (void)expander; // avoid "unused variable" warnings
208 }
209 
210 class TActionBase {
211 protected:
212  TLoopManager *fImplPtr; ///< A raw pointer to the TLoopManager at the root of this functional
213  /// graph. It is only guaranteed to contain a valid address during an
214  /// event loop.
215  const ColumnNames_t fTmpBranches;
216  const unsigned int fNSlots; ///< Number of thread slots used by this node.
217 
218 public:
219  TActionBase(TLoopManager *implPtr, const ColumnNames_t &tmpBranches, unsigned int nSlots);
220  virtual ~TActionBase() {}
221  virtual void Run(unsigned int slot, Long64_t entry) = 0;
222  virtual void Init(TTreeReader *r, unsigned int slot) = 0;
223  unsigned int GetNSlots() const { return fNSlots; }
224  virtual void ClearValueReaders(unsigned int slot) = 0;
225 };
226 
227 template <typename Helper, typename PrevDataFrame, typename BranchTypes_t = typename Helper::BranchTypes_t>
228 class TAction final : public TActionBase {
229  using TypeInd_t = typename TGenStaticSeq<BranchTypes_t::fgSize>::Type_t;
230 
231  Helper fHelper;
232  const ColumnNames_t fBranches;
233  PrevDataFrame &fPrevData;
234  std::vector<TDFValueTuple_t<BranchTypes_t>> fValues;
235 
236 public:
237  TAction(Helper &&h, const ColumnNames_t &bl, PrevDataFrame &pd)
238  : TActionBase(pd.GetImplPtr(), pd.GetTmpBranches(), pd.GetNSlots()), fHelper(std::move(h)), fBranches(bl),
239  fPrevData(pd), fValues(fNSlots)
240  {
241  }
242 
243  TAction(const TAction &) = delete;
244 
245  void Init(TTreeReader *r, unsigned int slot) final
246  {
247  InitTDFValues(slot, fValues[slot], r, fBranches, fTmpBranches, fImplPtr->GetBookedBranches(), TypeInd_t());
248  fHelper.Init(r, slot);
249  }
250 
251  void Run(unsigned int slot, Long64_t entry) final
252  {
253  // check if entry passes all filters
254  if (fPrevData.CheckFilters(slot, entry)) Exec(slot, entry, TypeInd_t());
255  }
256 
257  template <int... S>
258  void Exec(unsigned int slot, Long64_t entry, TStaticSeq<S...>)
259  {
260  (void)entry; // avoid bogus 'unused parameter' warning in gcc4.9
261  fHelper.Exec(slot, std::get<S>(fValues[slot]).Get(entry)...);
262  }
263 
264  ~TAction() { fHelper.Finalize(); }
265 
266  void ClearValueReaders(unsigned int slot) final { ResetTDFValueTuple(fValues[slot], TypeInd_t()); }
267 };
268 
269 } // end NS TDF
270 } // end NS Internal
271 
272 namespace Detail {
273 namespace TDF {
274 
276 protected:
277  TLoopManager *fImplPtr; ///< A raw pointer to the TLoopManager at the root of this functional graph. It is only
278  /// guaranteed to contain a valid address during an event loop.
279  ColumnNames_t fTmpBranches;
280  const std::string fName;
281  unsigned int fNChildren{0}; ///< Number of nodes of the functional graph hanging from this object
282  unsigned int fNStopsReceived{0}; ///< Number of times that a children node signaled to stop processing entries.
283  const unsigned int fNSlots; ///< Number of thread slots used by this node, inherited from parent node.
284 
285 public:
286  TCustomColumnBase(TLoopManager *df, const ColumnNames_t &tmpBranches, std::string_view name, unsigned int nSlots);
287  virtual ~TCustomColumnBase() {}
288  virtual void Init(TTreeReader *r, unsigned int slot) = 0;
289  virtual void *GetValuePtr(unsigned int slot) = 0;
290  virtual const std::type_info &GetTypeId() const = 0;
291  virtual bool CheckFilters(unsigned int slot, Long64_t entry) = 0;
292  TLoopManager *GetImplPtr() const;
293  virtual void Report() const = 0;
294  virtual void PartialReport() const = 0;
295  std::string GetName() const;
296  ColumnNames_t GetTmpBranches() const;
297  virtual void Update(unsigned int slot, Long64_t entry) = 0;
298  void IncrChildrenCount() { ++fNChildren; }
299  virtual void StopProcessing() = 0;
300  unsigned int GetNSlots() const { return fNSlots; }
301  virtual void ClearValueReaders(unsigned int slot) = 0;
302 };
303 
304 template <typename F, typename PrevData>
305 class TCustomColumn final : public TCustomColumnBase {
306  using BranchTypes_t = typename TDFInternal::TFunctionTraits<F>::Args_t;
307  using TypeInd_t = typename TDFInternal::TGenStaticSeq<BranchTypes_t::fgSize>::Type_t;
308  using Ret_t = typename TDFInternal::TFunctionTraits<F>::Ret_t;
309 
311  const ColumnNames_t fBranches;
312  std::vector<std::unique_ptr<Ret_t>> fLastResultPtr;
313  PrevData &fPrevData;
314  std::vector<Long64_t> fLastCheckedEntry = {-1};
315 
316  std::vector<TDFInternal::TDFValueTuple_t<BranchTypes_t>> fValues;
317 
318 public:
319  TCustomColumn(std::string_view name, F &&expression, const ColumnNames_t &bl, PrevData &pd)
320  : TCustomColumnBase(pd.GetImplPtr(), pd.GetTmpBranches(), name, pd.GetNSlots()),
321  fExpression(std::move(expression)), fBranches(bl), fLastResultPtr(fNSlots), fPrevData(pd),
322  fLastCheckedEntry(fNSlots, -1), fValues(fNSlots)
323  {
324  std::generate(fLastResultPtr.begin(), fLastResultPtr.end(),
325  []() { return std::unique_ptr<Ret_t>(new Ret_t()); });
326  fTmpBranches.emplace_back(name);
327  }
328 
329  TCustomColumn(const TCustomColumn &) = delete;
330 
331  void Init(TTreeReader *r, unsigned int slot) final
332  {
333  TDFInternal::InitTDFValues(slot, fValues[slot], r, fBranches, fTmpBranches, fImplPtr->GetBookedBranches(),
334  TypeInd_t());
335  }
336 
337  void *GetValuePtr(unsigned int slot) final { return static_cast<void *>(fLastResultPtr[slot].get()); }
338 
339  void Update(unsigned int slot, Long64_t entry) final
340  {
341  if (entry != fLastCheckedEntry[slot]) {
342  // evaluate this filter, cache the result
343  UpdateHelper(slot, entry, TypeInd_t(), BranchTypes_t());
344  fLastCheckedEntry[slot] = entry;
345  }
346  }
347 
348  const std::type_info &GetTypeId() const { return typeid(Ret_t); }
349 
350  bool CheckFilters(unsigned int slot, Long64_t entry) final
351  {
352  // dummy call: it just forwards to the previous object in the chain
353  return fPrevData.CheckFilters(slot, entry);
354  }
355 
356  template <int... S, typename... BranchTypes>
357  void UpdateHelper(unsigned int slot, Long64_t entry, TDFInternal::TStaticSeq<S...>,
358  TDFInternal::TTypeList<BranchTypes...>)
359  {
360  *fLastResultPtr[slot] = fExpression(std::get<S>(fValues[slot]).Get(entry)...);
361  (void)entry; // avoid bogus unused parameter warning in gcc
362  }
363 
364  // recursive chain of `Report`s
365  // TCustomColumn simply forwards the call to the previous node
366  void Report() const final { fPrevData.PartialReport(); }
367 
368  void PartialReport() const final { fPrevData.PartialReport(); }
369 
371  {
372  ++fNStopsReceived;
373  if (fNStopsReceived == fNChildren) fPrevData.StopProcessing();
374  }
375 
376  virtual void ClearValueReaders(unsigned int slot) final { ResetTDFValueTuple(fValues[slot], TypeInd_t()); }
377 };
378 
379 class TFilterBase {
380 protected:
381  TLoopManager *fImplPtr; ///< A raw pointer to the TLoopManager at the root of this functional graph. It is only
382  /// guaranteed to contain a valid address during an event loop.
383  const ColumnNames_t fTmpBranches;
384  std::vector<Long64_t> fLastCheckedEntry = {-1};
385  std::vector<int> fLastResult = {true}; // std::vector<bool> cannot be used in a MT context safely
386  std::vector<ULong64_t> fAccepted = {0};
387  std::vector<ULong64_t> fRejected = {0};
388  const std::string fName;
389  unsigned int fNChildren{0}; ///< Number of nodes of the functional graph hanging from this object
390  unsigned int fNStopsReceived{0}; ///< Number of times that a children node signaled to stop processing entries.
391  const unsigned int fNSlots; ///< Number of thread slots used by this node, inherited from parent node.
392 
393 public:
394  TFilterBase(TLoopManager *df, const ColumnNames_t &tmpBranches, std::string_view name, unsigned int nSlots);
395  virtual ~TFilterBase() {}
396  virtual void Init(TTreeReader *r, unsigned int slot) = 0;
397  virtual bool CheckFilters(unsigned int slot, Long64_t entry) = 0;
398  virtual void Report() const = 0;
399  virtual void PartialReport() const = 0;
400  TLoopManager *GetImplPtr() const;
401  ColumnNames_t GetTmpBranches() const;
402  bool HasName() const;
403  void PrintReport() const;
404  void IncrChildrenCount() { ++fNChildren; }
405  virtual void StopProcessing() = 0;
406  unsigned int GetNSlots() const { return fNSlots; }
407  virtual void ResetReportCount() = 0;
408  virtual void ClearValueReaders(unsigned int slot) = 0;
409 };
410 
411 template <typename FilterF, typename PrevDataFrame>
412 class TFilter final : public TFilterBase {
413  using BranchTypes_t = typename TDFInternal::TFunctionTraits<FilterF>::Args_t;
414  using TypeInd_t = typename TDFInternal::TGenStaticSeq<BranchTypes_t::fgSize>::Type_t;
415 
416  FilterF fFilter;
417  const ColumnNames_t fBranches;
418  PrevDataFrame &fPrevData;
419  std::vector<TDFInternal::TDFValueTuple_t<BranchTypes_t>> fValues;
420 
421 public:
422  TFilter(FilterF &&f, const ColumnNames_t &bl, PrevDataFrame &pd, std::string_view name = "")
423  : TFilterBase(pd.GetImplPtr(), pd.GetTmpBranches(), name, pd.GetNSlots()), fFilter(std::move(f)), fBranches(bl),
424  fPrevData(pd), fValues(fNSlots)
425  {
426  }
427 
428  TFilter(const TFilter &) = delete;
429 
430  bool CheckFilters(unsigned int slot, Long64_t entry) final
431  {
432  if (entry != fLastCheckedEntry[slot]) {
433  if (!fPrevData.CheckFilters(slot, entry)) {
434  // a filter upstream returned false, cache the result
435  fLastResult[slot] = false;
436  } else {
437  // evaluate this filter, cache the result
438  auto passed = CheckFilterHelper(slot, entry, TypeInd_t());
439  passed ? ++fAccepted[slot] : ++fRejected[slot];
440  fLastResult[slot] = passed;
441  }
442  fLastCheckedEntry[slot] = entry;
443  }
444  return fLastResult[slot];
445  }
446 
447  template <int... S>
448  bool CheckFilterHelper(unsigned int slot, Long64_t entry, TDFInternal::TStaticSeq<S...>)
449  {
450  return fFilter(std::get<S>(fValues[slot]).Get(entry)...);
451  }
452 
453  void Init(TTreeReader *r, unsigned int slot) final
454  {
455  TDFInternal::InitTDFValues(slot, fValues[slot], r, fBranches, fTmpBranches, fImplPtr->GetBookedBranches(),
456  TypeInd_t());
457  }
458 
459  // recursive chain of `Report`s
460  void Report() const final { PartialReport(); }
461 
462  void PartialReport() const final
463  {
464  fPrevData.PartialReport();
465  PrintReport();
466  }
467 
469  {
470  ++fNStopsReceived;
471  if (fNStopsReceived == fNChildren) fPrevData.StopProcessing();
472  }
473 
475  {
476  assert(!fName.empty()); // this method is to only be called on named filters
477  // fAccepted and fRejected could be different than 0 if this is not the first event-loop run using this filter
478  std::fill(fAccepted.begin(), fAccepted.end(), 0);
479  std::fill(fRejected.begin(), fRejected.end(), 0);
480  }
481 
482  void ClearValueReaders(unsigned int slot) final { ResetTDFValueTuple(fValues[slot], TypeInd_t()); }
483 };
484 
485 class TRangeBase {
486 protected:
487  TLoopManager *fImplPtr; ///< A raw pointer to the TLoopManager at the root of this functional graph. It is only
488  /// guaranteed to contain a valid address during an event loop.
489  ColumnNames_t fTmpBranches;
490  unsigned int fStart;
491  unsigned int fStop;
492  unsigned int fStride;
493  Long64_t fLastCheckedEntry{-1};
494  bool fLastResult{true};
495  ULong64_t fNProcessedEntries{0};
496  unsigned int fNChildren{0}; ///< Number of nodes of the functional graph hanging from this object
497  unsigned int fNStopsReceived{0}; ///< Number of times that a children node signaled to stop processing entries.
498  bool fHasStopped{false}; ///< True if the end of the range has been reached
499  const unsigned int fNSlots; ///< Number of thread slots used by this node, inherited from parent node.
500 
501 public:
502  TRangeBase(TLoopManager *implPtr, const ColumnNames_t &tmpBranches, unsigned int start, unsigned int stop,
503  unsigned int stride, unsigned int nSlots);
504  virtual ~TRangeBase() {}
505  TLoopManager *GetImplPtr() const;
506  ColumnNames_t GetTmpBranches() const;
507  virtual bool CheckFilters(unsigned int slot, Long64_t entry) = 0;
508  virtual void Report() const = 0;
509  virtual void PartialReport() const = 0;
510  void IncrChildrenCount() { ++fNChildren; }
511  virtual void StopProcessing() = 0;
512  unsigned int GetNSlots() const { return fNSlots; }
513 };
514 
515 template <typename PrevData>
516 class TRange final : public TRangeBase {
517  PrevData &fPrevData;
518 
519 public:
520  TRange(unsigned int start, unsigned int stop, unsigned int stride, PrevData &pd)
521  : TRangeBase(pd.GetImplPtr(), pd.GetTmpBranches(), start, stop, stride, pd.GetNSlots()), fPrevData(pd)
522  {
523  }
524 
525  TRange(const TRange &) = delete;
526 
527  /// Ranges act as filters when it comes to selecting entries that downstream nodes should process
528  bool CheckFilters(unsigned int slot, Long64_t entry) final
529  {
530  if (fHasStopped) {
531  return false;
532  } else if (entry != fLastCheckedEntry) {
533  if (!fPrevData.CheckFilters(slot, entry)) {
534  // a filter upstream returned false, cache the result
535  fLastResult = false;
536  } else {
537  // apply range filter logic, cache the result
538  ++fNProcessedEntries;
539  if (fNProcessedEntries <= fStart || (fStop > 0 && fNProcessedEntries > fStop) ||
540  (fStride != 1 && fNProcessedEntries % fStride != 0))
541  fLastResult = false;
542  else
543  fLastResult = true;
544  if (fNProcessedEntries == fStop) {
545  fHasStopped = true;
546  fPrevData.StopProcessing();
547  }
548  }
549  fLastCheckedEntry = entry;
550  }
551  return fLastResult;
552  }
553 
554  // recursive chain of `Report`s
555  // TRange simply forwards these calls to the previous node
556  void Report() const final { fPrevData.PartialReport(); }
557 
558  void PartialReport() const final { fPrevData.PartialReport(); }
559 
561  {
562  ++fNStopsReceived;
563  if (fNStopsReceived == fNChildren && !fHasStopped) fPrevData.StopProcessing();
564  }
565 };
566 
567 } // namespace TDF
568 } // namespace Detail
569 } // namespace ROOT
570 
571 // method implementations
572 template <typename T>
575 {
576  Reset();
577  fTmpColumn = tmpColumn;
578  if (tmpColumn->GetTypeId() != typeid(T))
579  throw std::runtime_error(std::string("TColumnValue: type specified is ") + typeid(T).name() +
580  " but temporary column has type " + tmpColumn->GetTypeId().name());
581  fValuePtr = static_cast<T *>(tmpColumn->GetValuePtr(slot));
582  fSlot = slot;
583 }
584 
585 // This method is executed inside the event-loop, many times per entry
586 // If need be, the if statement can be avoided using thunks
587 // (have both branches inside functions and have a pointer to
588 // the branch to be executed)
589 template <typename T>
590 template <typename U,
591  typename std::enable_if<std::is_same<typename ROOT::Internal::TDF::TColumnValue<U>::ProxyParam_t, U>::value,
592  int>::type>
594 {
595  if (fReaderValue) {
596  return *(fReaderValue->Get());
597  } else {
598  fTmpColumn->Update(fSlot, entry);
599  return *fValuePtr;
600  }
601 }
602 
603 #endif // ROOT_TDFNODES
typename TTDFValueTuple< BranchType >::type TDFValueTuple_t
Definition: TDFNodes.hxx:199
std::string GetName(const std::string &scope_name)
Definition: Cppyy.cxx:145
FilterBaseVec_t fBookedFilters
Definition: TDFNodes.hxx:53
void Report() const final
Definition: TDFNodes.hxx:556
bool CheckFilters(unsigned int slot, Long64_t entry) final
Definition: TDFNodes.hxx:430
typename std::conditional< std::is_same< ReaderValueOrArray_t< T >, TTreeReaderValue< T > >::value, T, ExtractType_t< T > >::type ProxyParam_t
Definition: TDFNodes.hxx:135
long long Long64_t
Definition: RtypesCore.h:69
TTreeReader is a simple, robust and fast interface to read values from a TTree, TChain or TNtuple...
Definition: TTreeReader.h:43
void Init(TTreeReader *r, unsigned int slot) final
Definition: TDFNodes.hxx:453
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
PrevDataFrame & fPrevData
Definition: TDFNodes.hxx:418
std::array_view< ProxyParam_t > Get(Long64_t)
Definition: TDFNodes.hxx:165
std::vector< TDFValueTuple_t< BranchTypes_t > > fValues
Definition: TDFNodes.hxx:234
void PartialReport() const final
Definition: TDFNodes.hxx:462
void ClearValueReaders(unsigned int slot) final
Definition: TDFNodes.hxx:266
double T(double x)
Definition: ChebyshevPol.h:34
TH1 * h
Definition: legend2.C:5
std::vector< std::unique_ptr< Ret_t > > fLastResultPtr
Definition: TDFNodes.hxx:312
Long64_t GetNEmptyEntries() const
Definition: TDFNodes.hxx:85
fill
Definition: fit1_py.py:6
void PartialReport() const final
Definition: TDFNodes.hxx:558
void Update(unsigned int slot, Long64_t entry) final
Definition: TDFNodes.hxx:339
std::vector< TDFInternal::TDFValueTuple_t< BranchTypes_t > > fValues
Definition: TDFNodes.hxx:419
std::map< std::string, TmpBranchBasePtr_t > fBookedBranches
Definition: TDFNodes.hxx:55
void generate(R &r, TH1D *h)
Definition: piRandom.C:28
void PartialReport() const
End of recursive chain of calls, does nothing.
Definition: TDFNodes.hxx:96
unsigned int GetNSlots() const
Definition: TDFNodes.hxx:512
void Init(TTreeReader *r, unsigned int slot) final
Definition: TDFNodes.hxx:245
STL namespace.
const ColumnNames_t fBranches
Definition: TDFNodes.hxx:417
const std::type_info & GetTypeId() const
Definition: TDFNodes.hxx:348
TAction(Helper &&h, const ColumnNames_t &bl, PrevDataFrame &pd)
Definition: TDFNodes.hxx:237
void PartialReport() const final
Definition: TDFNodes.hxx:368
void ResetTDFValueTuple(ValueTuple &values, TStaticSeq< S... >)
Clear the proxies of a tuple of TColumnValues.
Definition: TDFNodes.hxx:203
const ColumnNames_t fTmpBranches
Definition: TDFNodes.hxx:215
void MakeProxy(TTreeReader *r, const std::string &bn)
Definition: TDFNodes.hxx:150
std::shared_ptr< TFilterBase > FilterBasePtr_t
Definition: TDFNodes.hxx:44
unsigned int GetNSlots() const
Definition: TDFNodes.hxx:223
typename TDFInternal::TFunctionTraits< FilterF >::Args_t BranchTypes_t
Definition: TDFNodes.hxx:413
Helper class that updates and returns TTree branches as well as TDataFrame temporary columns...
Definition: TDFNodes.hxx:131
typename TDFInternal::TFunctionTraits< F >::Ret_t Ret_t
Definition: TDFNodes.hxx:308
bool CheckFilters(unsigned int slot, Long64_t entry) final
Definition: TDFNodes.hxx:350
unsigned int GetNSlots() const
Definition: TDFNodes.hxx:300
void ClearValueReaders(unsigned int slot) final
Definition: TDFNodes.hxx:482
typename TDFInternal::TGenStaticSeq< BranchTypes_t::fgSize >::Type_t TypeInd_t
Definition: TDFNodes.hxx:307
std::shared_ptr< TLoopManager > GetSharedPtr()
Definition: TDFNodes.hxx:78
void SetTmpColumn(unsigned int slot, TCustomColumnBase *tmpColumn)
Definition: TDFNodes.hxx:573
const ColumnNames_t fTmpBranches
Definition: TDFNodes.hxx:383
typename TGenStaticSeq< BranchTypes_t::fgSize >::Type_t TypeInd_t
Definition: TDFNodes.hxx:229
Extracts data from a TTree.
const ColumnNames_t fBranches
Definition: TDFNodes.hxx:311
ActionBaseVec_t fBookedActions
Definition: TDFNodes.hxx:52
PrevDataFrame & fPrevData
Definition: TDFNodes.hxx:233
std::vector< FilterBasePtr_t > FilterBaseVec_t
Definition: TDFNodes.hxx:45
TCustomColumn(std::string_view name, F &&expression, const ColumnNames_t &bl, PrevData &pd)
Definition: TDFNodes.hxx:319
RooArgSet S(const RooAbsArg &v1)
TRange(unsigned int start, unsigned int stop, unsigned int stride, PrevData &pd)
Definition: TDFNodes.hxx:520
#define F(x, y, z)
bool CheckFilterHelper(unsigned int slot, Long64_t entry, TDFInternal::TStaticSeq< S... >)
Definition: TDFNodes.hxx:448
const unsigned int fNSlots
Number of thread slots used by this node, inherited from parent node.
Definition: TDFNodes.hxx:283
void Report() const final
Definition: TDFNodes.hxx:460
TRandom2 r(17)
std::vector< RangeBasePtr_t > RangeBaseVec_t
Definition: TDFNodes.hxx:48
std::vector< ActionBasePtr_t > ActionBaseVec_t
Definition: TDFNodes.hxx:40
unsigned int GetNSlots() const
Definition: TDFNodes.hxx:406
std::shared_ptr< TCustomColumnBase > TmpBranchBasePtr_t
Definition: TDFNodes.hxx:42
TLoopManager * fImplPtr
A raw pointer to the TLoopManager at the root of this functional graph.
Definition: TDFNodes.hxx:381
void Exec(unsigned int slot, Long64_t entry, TStaticSeq< S... >)
Definition: TDFNodes.hxx:258
void SetTree(std::shared_ptr< TTree > tree)
Definition: TDFNodes.hxx:97
std::vector< TDFInternal::TDFValueTuple_t< BranchTypes_t > > fValues
Definition: TDFNodes.hxx:316
std::tuple< TColumnValue< BranchTypes >... > type
Definition: TDFNodes.hxx:195
typename TDFInternal::TFunctionTraits< F >::Args_t BranchTypes_t
Definition: TDFNodes.hxx:306
void Reset(Detail::TBranchProxy *x)
FilterBaseVec_t fBookedNamedFilters
Definition: TDFNodes.hxx:54
virtual void ClearValueReaders(unsigned int slot) final
Definition: TDFNodes.hxx:376
TFilter(FilterF &&f, const ColumnNames_t &bl, PrevDataFrame &pd, std::string_view name="")
Definition: TDFNodes.hxx:422
double f(double x)
virtual const std::type_info & GetTypeId() const =0
const unsigned int fNSlots
Number of thread slots used by this node, inherited from parent node.
Definition: TDFNodes.hxx:499
Describe directory structure in memory.
Definition: TDirectory.h:34
int type
Definition: TGX11.cxx:120
unsigned long long ULong64_t
Definition: RtypesCore.h:70
const unsigned int fNSlots
Number of thread slots used by this node.
Definition: TDFNodes.hxx:216
void Run(unsigned int slot, Long64_t entry) final
Definition: TDFNodes.hxx:251
TLoopManager * fImplPtr
A raw pointer to the TLoopManager at the root of this functional graph.
Definition: TDFNodes.hxx:487
const ColumnNames_t fDefaultBranches
Definition: TDFNodes.hxx:60
void * GetValuePtr(unsigned int slot) final
Definition: TDFNodes.hxx:337
std::shared_ptr< TDFInternal::TActionBase > ActionBasePtr_t
Definition: TDFNodes.hxx:39
unsigned int GetNSlots() const
Definition: TDFNodes.hxx:92
TLoopManager * fImplPtr
A raw pointer to the TLoopManager at the root of this functional graph.
Definition: TDFNodes.hxx:277
const ColumnNames_t GetTmpBranches() const
Definition: TDFNodes.hxx:80
typedef void((*Func_t)())
typename TDFInternal::TGenStaticSeq< BranchTypes_t::fgSize >::Type_t TypeInd_t
Definition: TDFNodes.hxx:414
const std::map< std::string, TmpBranchBasePtr_t > & GetBookedBranches() const
Definition: TDFNodes.hxx:83
unsigned int GetNSlots()
Definition: TDFUtils.cxx:125
const ColumnNames_t fBranches
Definition: TDFNodes.hxx:232
Definition: tree.py:1
A TTree object has a header with a name and a title.
Definition: TTree.h:78
std::vector< std::shared_ptr< bool > > fResProxyReadiness
Definition: TDFNodes.hxx:57
void Init(TTreeReader *r, unsigned int slot) final
Definition: TDFNodes.hxx:331
const unsigned int fNSlots
Number of thread slots used by this node, inherited from parent node.
Definition: TDFNodes.hxx:391
void UpdateHelper(unsigned int slot, Long64_t entry, TDFInternal::TStaticSeq< S... >, TDFInternal::TTypeList< BranchTypes... >)
Definition: TDFNodes.hxx:357
TLoopManager * fImplPtr
A raw pointer to the TLoopManager at the root of this functional graph.
Definition: TDFNodes.hxx:212
virtual void * GetValuePtr(unsigned int slot)=0
std::shared_ptr< TRangeBase > RangeBasePtr_t
Definition: TDFNodes.hxx:47
bool CheckFilters(unsigned int slot, Long64_t entry) final
Ranges act as filters when it comes to selecting entries that downstream nodes should process...
Definition: TDFNodes.hxx:528