Logo ROOT   6.10/06
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  }
362 
363  // recursive chain of `Report`s
364  // TCustomColumn simply forwards the call to the previous node
365  void Report() const final { fPrevData.PartialReport(); }
366 
367  void PartialReport() const final { fPrevData.PartialReport(); }
368 
370  {
371  ++fNStopsReceived;
372  if (fNStopsReceived == fNChildren) fPrevData.StopProcessing();
373  }
374 
375  virtual void ClearValueReaders(unsigned int slot) final { ResetTDFValueTuple(fValues[slot], TypeInd_t()); }
376 };
377 
378 class TFilterBase {
379 protected:
380  TLoopManager *fImplPtr; ///< A raw pointer to the TLoopManager at the root of this functional graph. It is only
381  /// guaranteed to contain a valid address during an event loop.
382  const ColumnNames_t fTmpBranches;
383  std::vector<Long64_t> fLastCheckedEntry = {-1};
384  std::vector<int> fLastResult = {true}; // std::vector<bool> cannot be used in a MT context safely
385  std::vector<ULong64_t> fAccepted = {0};
386  std::vector<ULong64_t> fRejected = {0};
387  const std::string fName;
388  unsigned int fNChildren{0}; ///< Number of nodes of the functional graph hanging from this object
389  unsigned int fNStopsReceived{0}; ///< Number of times that a children node signaled to stop processing entries.
390  const unsigned int fNSlots; ///< Number of thread slots used by this node, inherited from parent node.
391 
392 public:
393  TFilterBase(TLoopManager *df, const ColumnNames_t &tmpBranches, std::string_view name, unsigned int nSlots);
394  virtual ~TFilterBase() {}
395  virtual void Init(TTreeReader *r, unsigned int slot) = 0;
396  virtual bool CheckFilters(unsigned int slot, Long64_t entry) = 0;
397  virtual void Report() const = 0;
398  virtual void PartialReport() const = 0;
399  TLoopManager *GetImplPtr() const;
400  ColumnNames_t GetTmpBranches() const;
401  bool HasName() const;
402  void PrintReport() const;
403  void IncrChildrenCount() { ++fNChildren; }
404  virtual void StopProcessing() = 0;
405  unsigned int GetNSlots() const { return fNSlots; }
406  virtual void ResetReportCount() = 0;
407  virtual void ClearValueReaders(unsigned int slot) = 0;
408 };
409 
410 template <typename FilterF, typename PrevDataFrame>
411 class TFilter final : public TFilterBase {
412  using BranchTypes_t = typename TDFInternal::TFunctionTraits<FilterF>::Args_t;
413  using TypeInd_t = typename TDFInternal::TGenStaticSeq<BranchTypes_t::fgSize>::Type_t;
414 
415  FilterF fFilter;
416  const ColumnNames_t fBranches;
417  PrevDataFrame &fPrevData;
418  std::vector<TDFInternal::TDFValueTuple_t<BranchTypes_t>> fValues;
419 
420 public:
421  TFilter(FilterF &&f, const ColumnNames_t &bl, PrevDataFrame &pd, std::string_view name = "")
422  : TFilterBase(pd.GetImplPtr(), pd.GetTmpBranches(), name, pd.GetNSlots()), fFilter(std::move(f)), fBranches(bl),
423  fPrevData(pd), fValues(fNSlots)
424  {
425  }
426 
427  TFilter(const TFilter &) = delete;
428 
429  bool CheckFilters(unsigned int slot, Long64_t entry) final
430  {
431  if (entry != fLastCheckedEntry[slot]) {
432  if (!fPrevData.CheckFilters(slot, entry)) {
433  // a filter upstream returned false, cache the result
434  fLastResult[slot] = false;
435  } else {
436  // evaluate this filter, cache the result
437  auto passed = CheckFilterHelper(slot, entry, TypeInd_t());
438  passed ? ++fAccepted[slot] : ++fRejected[slot];
439  fLastResult[slot] = passed;
440  }
441  fLastCheckedEntry[slot] = entry;
442  }
443  return fLastResult[slot];
444  }
445 
446  template <int... S>
447  bool CheckFilterHelper(unsigned int slot, Long64_t entry, TDFInternal::TStaticSeq<S...>)
448  {
449  return fFilter(std::get<S>(fValues[slot]).Get(entry)...);
450  }
451 
452  void Init(TTreeReader *r, unsigned int slot) final
453  {
454  TDFInternal::InitTDFValues(slot, fValues[slot], r, fBranches, fTmpBranches, fImplPtr->GetBookedBranches(),
455  TypeInd_t());
456  }
457 
458  // recursive chain of `Report`s
459  void Report() const final { PartialReport(); }
460 
461  void PartialReport() const final
462  {
463  fPrevData.PartialReport();
464  PrintReport();
465  }
466 
468  {
469  ++fNStopsReceived;
470  if (fNStopsReceived == fNChildren) fPrevData.StopProcessing();
471  }
472 
474  {
475  assert(!fName.empty()); // this method is to only be called on named filters
476  // fAccepted and fRejected could be different than 0 if this is not the first event-loop run using this filter
477  std::fill(fAccepted.begin(), fAccepted.end(), 0);
478  std::fill(fRejected.begin(), fRejected.end(), 0);
479  }
480 
481  void ClearValueReaders(unsigned int slot) final { ResetTDFValueTuple(fValues[slot], TypeInd_t()); }
482 };
483 
484 class TRangeBase {
485 protected:
486  TLoopManager *fImplPtr; ///< A raw pointer to the TLoopManager at the root of this functional graph. It is only
487  /// guaranteed to contain a valid address during an event loop.
488  ColumnNames_t fTmpBranches;
489  unsigned int fStart;
490  unsigned int fStop;
491  unsigned int fStride;
492  Long64_t fLastCheckedEntry{-1};
493  bool fLastResult{true};
494  ULong64_t fNProcessedEntries{0};
495  unsigned int fNChildren{0}; ///< Number of nodes of the functional graph hanging from this object
496  unsigned int fNStopsReceived{0}; ///< Number of times that a children node signaled to stop processing entries.
497  bool fHasStopped{false}; ///< True if the end of the range has been reached
498  const unsigned int fNSlots; ///< Number of thread slots used by this node, inherited from parent node.
499 
500 public:
501  TRangeBase(TLoopManager *implPtr, const ColumnNames_t &tmpBranches, unsigned int start, unsigned int stop,
502  unsigned int stride, unsigned int nSlots);
503  virtual ~TRangeBase() {}
504  TLoopManager *GetImplPtr() const;
505  ColumnNames_t GetTmpBranches() const;
506  virtual bool CheckFilters(unsigned int slot, Long64_t entry) = 0;
507  virtual void Report() const = 0;
508  virtual void PartialReport() const = 0;
509  void IncrChildrenCount() { ++fNChildren; }
510  virtual void StopProcessing() = 0;
511  unsigned int GetNSlots() const { return fNSlots; }
512 };
513 
514 template <typename PrevData>
515 class TRange final : public TRangeBase {
516  PrevData &fPrevData;
517 
518 public:
519  TRange(unsigned int start, unsigned int stop, unsigned int stride, PrevData &pd)
520  : TRangeBase(pd.GetImplPtr(), pd.GetTmpBranches(), start, stop, stride, pd.GetNSlots()), fPrevData(pd)
521  {
522  }
523 
524  TRange(const TRange &) = delete;
525 
526  /// Ranges act as filters when it comes to selecting entries that downstream nodes should process
527  bool CheckFilters(unsigned int slot, Long64_t entry) final
528  {
529  if (fHasStopped) {
530  return false;
531  } else if (entry != fLastCheckedEntry) {
532  if (!fPrevData.CheckFilters(slot, entry)) {
533  // a filter upstream returned false, cache the result
534  fLastResult = false;
535  } else {
536  // apply range filter logic, cache the result
537  ++fNProcessedEntries;
538  if (fNProcessedEntries <= fStart || (fStop > 0 && fNProcessedEntries > fStop) ||
539  (fStride != 1 && fNProcessedEntries % fStride != 0))
540  fLastResult = false;
541  else
542  fLastResult = true;
543  if (fNProcessedEntries == fStop) {
544  fHasStopped = true;
545  fPrevData.StopProcessing();
546  }
547  }
548  fLastCheckedEntry = entry;
549  }
550  return fLastResult;
551  }
552 
553  // recursive chain of `Report`s
554  // TRange simply forwards these calls to the previous node
555  void Report() const final { fPrevData.PartialReport(); }
556 
557  void PartialReport() const final { fPrevData.PartialReport(); }
558 
560  {
561  ++fNStopsReceived;
562  if (fNStopsReceived == fNChildren && !fHasStopped) fPrevData.StopProcessing();
563  }
564 };
565 
566 } // namespace TDF
567 } // namespace Detail
568 } // namespace ROOT
569 
570 // method implementations
571 template <typename T>
574 {
575  Reset();
576  fTmpColumn = tmpColumn;
577  if (tmpColumn->GetTypeId() != typeid(T))
578  throw std::runtime_error(std::string("TColumnValue: type specified is ") + typeid(T).name() +
579  " but temporary column has type " + tmpColumn->GetTypeId().name());
580  fValuePtr = static_cast<T *>(tmpColumn->GetValuePtr(slot));
581  fSlot = slot;
582 }
583 
584 // This method is executed inside the event-loop, many times per entry
585 // If need be, the if statement can be avoided using thunks
586 // (have both branches inside functions and have a pointer to
587 // the branch to be executed)
588 template <typename T>
589 template <typename U,
590  typename std::enable_if<std::is_same<typename ROOT::Internal::TDF::TColumnValue<U>::ProxyParam_t, U>::value,
591  int>::type>
593 {
594  if (fReaderValue) {
595  return *(fReaderValue->Get());
596  } else {
597  fTmpColumn->Update(fSlot, entry);
598  return *fValuePtr;
599  }
600 }
601 
602 #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:555
bool CheckFilters(unsigned int slot, Long64_t entry) final
Definition: TDFNodes.hxx:429
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:42
void Init(TTreeReader *r, unsigned int slot) final
Definition: TDFNodes.hxx:452
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
PrevDataFrame & fPrevData
Definition: TDFNodes.hxx:417
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:461
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:557
void Update(unsigned int slot, Long64_t entry) final
Definition: TDFNodes.hxx:339
std::vector< TDFInternal::TDFValueTuple_t< BranchTypes_t > > fValues
Definition: TDFNodes.hxx:418
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:511
void Init(TTreeReader *r, unsigned int slot) final
Definition: TDFNodes.hxx:245
STL namespace.
const ColumnNames_t fBranches
Definition: TDFNodes.hxx:416
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:367
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:412
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:481
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:572
const ColumnNames_t fTmpBranches
Definition: TDFNodes.hxx:382
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:519
#define F(x, y, z)
bool CheckFilterHelper(unsigned int slot, Long64_t entry, TDFInternal::TStaticSeq< S... >)
Definition: TDFNodes.hxx:447
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:459
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:405
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:380
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:375
TFilter(FilterF &&f, const ColumnNames_t &bl, PrevDataFrame &pd, std::string_view name="")
Definition: TDFNodes.hxx:421
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:498
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:486
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:413
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:390
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
char name[80]
Definition: TGX11.cxx:109
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:527