Logo ROOT   6.12/07
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/TypeTraits.hxx"
15 #include "ROOT/TDataSource.hxx"
16 #include "ROOT/TDFUtils.hxx"
17 #include "ROOT/TArrayBranch.hxx"
18 #include "ROOT/TSpinMutex.hxx"
19 #include "TTreeReaderArray.h"
20 #include "TTreeReaderValue.h"
21 #include "TError.h"
22 
23 #include <map>
24 #include <numeric> // std::accumulate (PrintReport), std::iota (TSlotStack)
25 #include <string>
26 #include <tuple>
27 #include <cassert>
28 #include <climits>
29 #include <deque> // std::vector substitute in case of vector<bool>
30 #include <functional>
31 
32 namespace ROOT {
33 
34 namespace Internal {
35 namespace TDF {
36 class TActionBase;
37 
38 // This is an helper class to allow to pick a slot without resorting to a map
39 // indexed by thread ids.
40 // WARNING: this class does not work as a regular stack. The size is
41 // fixed at construction time and no blocking is foreseen.
42 class TSlotStack {
43 private:
44  unsigned int &GetCount()
45  {
46  TTHREAD_TLS(unsigned int) count = 0U;
47  return count;
48  }
49  unsigned int &GetIndex()
50  {
51  TTHREAD_TLS(unsigned int) index = UINT_MAX;
52  return index;
53  }
54  unsigned int fCursor;
55  std::vector<unsigned int> fBuf;
57 
58 public:
59  TSlotStack() = delete;
60  TSlotStack(unsigned int size) : fCursor(size), fBuf(size) { std::iota(fBuf.begin(), fBuf.end(), 0U); }
61  void ReturnSlot(unsigned int slotNumber);
62  unsigned int GetSlot();
63 };
64 }
65 }
66 
67 namespace Detail {
68 namespace TDF {
69 using namespace ROOT::TypeTraits;
71 
72 // forward declarations for TLoopManager
73 using ActionBasePtr_t = std::shared_ptr<TDFInternal::TActionBase>;
74 using ActionBaseVec_t = std::vector<ActionBasePtr_t>;
75 class TCustomColumnBase;
76 using TCustomColumnBasePtr_t = std::shared_ptr<TCustomColumnBase>;
77 class TFilterBase;
78 using FilterBasePtr_t = std::shared_ptr<TFilterBase>;
79 using FilterBaseVec_t = std::vector<FilterBasePtr_t>;
80 class TRangeBase;
81 using RangeBasePtr_t = std::shared_ptr<TRangeBase>;
82 using RangeBaseVec_t = std::vector<RangeBasePtr_t>;
83 
84 class TLoopManager : public std::enable_shared_from_this<TLoopManager> {
86  enum class ELoopType { kROOTFiles, kROOTFilesMT, kNoFiles, kNoFilesMT, kDataSource, kDataSourceMT };
87 
88  using Callback_t = std::function<void(unsigned int)>;
89  class TCallback {
92  std::vector<ULong64_t> fCounters;
93 
94  public:
95  TCallback(ULong64_t everyN, Callback_t &&f, unsigned int nSlots)
96  : fFun(std::move(f)), fEveryN(everyN), fCounters(nSlots, 0ull) {}
97 
98  void operator()(unsigned int slot)
99  {
100  auto &c = fCounters[slot];
101  ++c;
102  if (c == fEveryN) {
103  c = 0ull;
104  fFun(slot);
105  }
106  }
107  };
108 
111  std::vector<int> fHasBeenCalled; // std::vector<bool> is thread-unsafe for our purposes (and generally evil)
112 
113  public:
114  TOneTimeCallback(Callback_t &&f, unsigned int nSlots) : fFun(std::move(f)), fHasBeenCalled(nSlots, 0) {}
115 
116  void operator()(unsigned int slot)
117  {
118  if (fHasBeenCalled[slot] == 1)
119  return;
120  fFun(slot);
121  fHasBeenCalled[slot] = 1;
122  }
123  };
124 
127  FilterBaseVec_t fBookedNamedFilters; ///< Contains a subset of fBookedFilters, i.e. only the named filters
128  std::map<std::string, TCustomColumnBasePtr_t> fBookedCustomColumns;
129  ColumnNames_t fCustomColumnNames; ///< Contains names of all custom columns defined in the functional graph.
131  std::vector<std::shared_ptr<bool>> fResProxyReadiness;
132  ::TDirectory *const fDirPtr{nullptr};
133  std::shared_ptr<TTree> fTree{nullptr}; //< Shared pointer to the input TTree/TChain. It does not own the pointee if
134  // the TTree/TChain was passed directly as an argument to TDataFrame's ctor (in
135  // which case we let users retain ownership).
136  const ColumnNames_t fDefaultColumns;
137  const ULong64_t fNEmptyEntries{0};
138  const unsigned int fNSlots{1};
139  bool fMustRunNamedFilters{true};
140  unsigned int fNChildren{0}; ///< Number of nodes of the functional graph hanging from this object
141  unsigned int fNStopsReceived{0}; ///< Number of times that a children node signaled to stop processing entries.
142  const ELoopType fLoopType; ///< The kind of event loop that is going to be run (e.g. on ROOT files, on no files)
143  std::string fToJit; ///< string containing all `BuildAndBook` actions that should be jitted before running
144  const std::unique_ptr<TDataSource> fDataSource; ///< Owning pointer to a data-source object. Null if no data-source
145  ColumnNames_t fDefinedDataSourceColumns; ///< List of data-source columns that have been `Define`d so far
146  std::map<std::string, std::string> fAliasColumnNameMap; ///< ColumnNameAlias-columnName pairs
147  std::vector<TCallback> fCallbacks; ///< Registered callbacks
148  std::vector<TOneTimeCallback> fCallbacksOnce; ///< Registered callbacks to invoke just once before running the loop
149 
150  void RunEmptySourceMT();
151  void RunEmptySource();
152  void RunTreeProcessorMT();
153  void RunTreeReader();
154  void RunDataSourceMT();
155  void RunDataSource();
156  void RunAndCheckFilters(unsigned int slot, Long64_t entry);
157  void InitNodeSlots(TTreeReader *r, unsigned int slot);
158  void InitNodes();
159  void CleanUpNodes();
160  void CleanUpTask(unsigned int slot);
161  void JitActions();
162  void EvalChildrenCounts();
163 
164 public:
165  TLoopManager(TTree *tree, const ColumnNames_t &defaultBranches);
166  TLoopManager(ULong64_t nEmptyEntries);
167  TLoopManager(std::unique_ptr<TDataSource> ds, const ColumnNames_t &defaultBranches);
168  TLoopManager(const TLoopManager &) = delete;
169  TLoopManager &operator=(const TLoopManager &) = delete;
170 
171  void Run();
172  TLoopManager *GetImplPtr();
173  std::shared_ptr<TLoopManager> GetSharedPtr() { return shared_from_this(); }
174  const ColumnNames_t &GetDefaultColumnNames() const;
175  const ColumnNames_t &GetCustomColumnNames() const { return fCustomColumnNames; };
176  TTree *GetTree() const;
177  TCustomColumnBase *GetBookedBranch(const std::string &name) const;
178  const std::map<std::string, TCustomColumnBasePtr_t> &GetBookedColumns() const { return fBookedCustomColumns; }
179  ::TDirectory *GetDirectory() const;
180  ULong64_t GetNEmptyEntries() const { return fNEmptyEntries; }
181  TDataSource *GetDataSource() const { return fDataSource.get(); }
182  void Book(const ActionBasePtr_t &actionPtr);
183  void Book(const FilterBasePtr_t &filterPtr);
184  void Book(const TCustomColumnBasePtr_t &branchPtr);
185  void Book(const std::shared_ptr<bool> &branchPtr);
186  void Book(const RangeBasePtr_t &rangePtr);
187  bool CheckFilters(int, unsigned int);
188  unsigned int GetNSlots() const { return fNSlots; }
189  bool MustRunNamedFilters() const { return fMustRunNamedFilters; }
190  void Report() const;
191  /// End of recursive chain of calls, does nothing
192  void PartialReport() const {}
193  void SetTree(const std::shared_ptr<TTree> &tree) { fTree = tree; }
194  void IncrChildrenCount() { ++fNChildren; }
195  void StopProcessing() { ++fNStopsReceived; }
196  void Jit(const std::string &s) { fToJit.append(s); }
197  const ColumnNames_t &GetDefinedDataSourceColumns() const { return fDefinedDataSourceColumns; }
198  void AddDataSourceColumn(std::string_view name) { fDefinedDataSourceColumns.emplace_back(name); }
199  void AddColumnAlias(const std::string &alias, const std::string &colName) { fAliasColumnNameMap[alias] = colName; }
200  const std::map<std::string, std::string> &GetAliasMap() const { return fAliasColumnNameMap; }
201  void RegisterCallback(ULong64_t everyNEvents, std::function<void(unsigned int)> &&f);
202 };
203 } // end ns TDF
204 } // end ns Detail
205 
206 namespace Internal {
207 namespace TDF {
208 using namespace ROOT::Detail::TDF;
209 
210 /**
211 \class ROOT::Internal::TDF::TColumnValue
212 \ingroup dataframe
213 \brief Helper class that updates and returns TTree branches as well as TDataFrame temporary columns
214 \tparam T The type of the column
215 
216 TDataFrame nodes must access two different types of values during the event loop:
217 values of real branches, for which TTreeReader{Values,Arrays} act as proxies, or
218 temporary columns whose values are generated on the fly. While the type of the
219 value is known at compile time (or just-in-time), it is only at runtime that nodes
220 can check whether a certain value is generated on the fly or not.
221 
222 TColumnValue abstracts this difference by providing the same interface for
223 both cases and handling the reading or generation of new values transparently.
224 Only one of the two data members fReaderProxy or fValuePtr will be non-null
225 for a given TColumnValue, depending on whether the value comes from a real
226 TTree branch or from a temporary column respectively.
227 
228 TDataFrame nodes can store tuples of TColumnValues and retrieve an updated
229 value for the column via the `Get` method.
230 **/
231 template <typename T>
233  // following line is equivalent to pseudo-code: ProxyParam_t == TArrayBranch<U> ? U : T
234  // ReaderValueOrArray_t is a TTreeReaderValue<T> unless T is TArrayBranch<U>
235  using ProxyParam_t = typename std::conditional<std::is_same<ReaderValueOrArray_t<T>, TTreeReaderValue<T>>::value, T,
236  TakeFirstParameter_t<T>>::type;
237 
238  /// TColumnValue has a slightly different behaviour whether the column comes from a TTreeReader, a TDataFrame Define
239  /// or a TDataSource. It stores which it is as an enum.
240  enum class EColumnKind { kTreeValue, kTreeArray, kCustomColumn, kDataSource, kInvalid };
241  // Set to the correct value by MakeProxy or SetTmpColumn
243  /// The slot this value belongs to. Only needed when querying custom column values, it is set in `SetTmpColumn`.
244  unsigned int fSlot = std::numeric_limits<unsigned int>::max();
245 
246  // Each element of the following data members will be in use by a _single task_.
247  // The vectors are used as very small stacks (1-2 elements typically) that fill in case of interleaved task execution
248  // i.e. when more than one task needs readers in this worker thread.
249 
250  /// Owning ptrs to a TTreeReaderValue. Used for non-temporary columns when T != TArrayBranch<U>
251  std::vector<std::unique_ptr<TTreeReaderValue<T>>> fReaderValues;
252  /// Owning ptrs to a TTreeReaderArray. Used for non-temporary columns when T == TArrayBranch<U>.
253  std::vector<std::unique_ptr<TTreeReaderArray<ProxyParam_t>>> fReaderArrays;
254  /// Non-owning ptrs to the value of a custom column.
255  std::vector<T *> fCustomValuePtrs;
256  /// Non-owning ptrs to the value of a data-source column.
257  std::vector<T **> fDSValuePtrs;
258  /// Non-owning ptrs to the node responsible for the custom column. Needed when querying custom values.
259  std::vector<TCustomColumnBase *> fCustomColumns;
260  /// Signal whether we ever checked that the branch we are reading with a TTreeReaderArray stores array elements
261  /// in contiguous memory. Only used when T == TArrayBranch<U>.
262  bool fArrayHasBeenChecked = false;
263 
264 public:
265  TColumnValue() = default;
266 
267  void SetTmpColumn(unsigned int slot, TCustomColumnBase *tmpColumn);
268 
269  void MakeProxy(TTreeReader *r, const std::string &bn)
270  {
271  constexpr bool useReaderValue = std::is_same<ProxyParam_t, T>::value;
272  if (useReaderValue) {
273  fColumnKind = EColumnKind::kTreeValue;
274  fReaderValues.emplace_back(new TTreeReaderValue<T>(*r, bn.c_str()));
275  } else {
276  fColumnKind = EColumnKind::kTreeArray;
277  fReaderArrays.emplace_back(new TTreeReaderArray<ProxyParam_t>(*r, bn.c_str()));
278  }
279  }
280 
281  /// This overload is used to return scalar quantities (i.e. types that are not read into a TArrayBranch)
282  template <typename U = T,
283  typename std::enable_if<std::is_same<typename TColumnValue<U>::ProxyParam_t, U>::value, int>::type = 0>
284  T &Get(Long64_t entry);
285 
286  /// This overload is used to return arrays (i.e. types that are read into a TArrayBranch)
287  template <typename U = T, typename std::enable_if<!std::is_same<ProxyParam_t, U>::value, int>::type = 0>
289  {
290  auto &readerArray = *fReaderArrays.back();
291  // We only use TTreeReaderArrays to read columns that users flagged as type `TArrayBranch`, so we need to check
292  // that the branch stores the array as contiguous memory that we can actually wrap in an `TArrayBranch`.
293  // Currently we need the first entry to have been loaded to perform the check
294  // TODO Move check to `MakeProxy` once Axel implements this kind of check in TTreeReaderArray using TBranchProxy
295  if (!fArrayHasBeenChecked) {
296  if (readerArray.GetSize() > 1) {
297  if (1 != (&readerArray[1] - &readerArray[0])) {
298  std::string exceptionText = "Branch ";
299  exceptionText += readerArray.GetBranchName();
300  exceptionText +=
301  " hangs from a non-split branch. For this reason, it cannot be accessed via a TArrayBranch."
302  " Please read the top level branch instead.";
303  throw std::runtime_error(exceptionText);
304  }
305  fArrayHasBeenChecked = true;
306  }
307  }
308 
309  return TArrayBranch<ProxyParam_t>(readerArray);
310  }
311 
312  void Reset()
313  {
314  switch (fColumnKind) {
315  case EColumnKind::kTreeValue: fReaderValues.pop_back(); break;
316  case EColumnKind::kTreeArray: fReaderArrays.pop_back(); break;
317  case EColumnKind::kCustomColumn:
318  fCustomColumns.pop_back();
319  fCustomValuePtrs.pop_back();
320  break;
321  case EColumnKind::kDataSource:
322  fCustomColumns.pop_back();
323  fDSValuePtrs.pop_back();
324  break;
325  case EColumnKind::kInvalid: throw std::runtime_error("ColumnKind not set for this TColumnValue");
326  }
327  }
328 };
329 
330 template <typename T>
332 };
333 
334 template <typename... BranchTypes>
335 struct TTDFValueTuple<TypeList<BranchTypes...>> {
336  using type = std::tuple<TColumnValue<BranchTypes>...>;
337 };
338 
339 template <typename BranchType>
341 
342 /// Clear the proxies of a tuple of TColumnValues
343 template <typename ValueTuple, int... S>
344 void ResetTDFValueTuple(ValueTuple &values, StaticSeq<S...>)
345 {
346  // hack to expand a parameter pack without c++17 fold expressions.
347  std::initializer_list<int> expander{(std::get<S>(values).Reset(), 0)...};
348  (void)expander; // avoid "unused variable" warnings
349 }
350 
351 class TActionBase {
352 protected:
353  TLoopManager *fImplPtr; ///< A raw pointer to the TLoopManager at the root of this functional
354  /// graph. It is only guaranteed to contain a valid address during an
355  /// event loop.
356  const unsigned int fNSlots; ///< Number of thread slots used by this node.
357 
358 public:
359  TActionBase(TLoopManager *implPtr, const unsigned int nSlots);
360  TActionBase(const TActionBase &) = delete;
361  TActionBase &operator=(const TActionBase &) = delete;
362  virtual ~TActionBase() = default;
363 
364  virtual void Run(unsigned int slot, Long64_t entry) = 0;
365  virtual void InitSlot(TTreeReader *r, unsigned int slot) = 0;
366  virtual void TriggerChildrenCount() = 0;
367  virtual void ClearValueReaders(unsigned int slot) = 0;
368  unsigned int GetNSlots() const { return fNSlots; }
369  /// This method is invoked to update a partial result during the event loop, right before passing the result to a
370  /// user-defined callback registered via TResultProxy::RegisterCallback
371  virtual void *PartialUpdate(unsigned int slot) = 0;
372 };
373 
374 template <typename Helper, typename PrevDataFrame, typename BranchTypes_t = typename Helper::BranchTypes_t>
375 class TAction final : public TActionBase {
376  using TypeInd_t = GenStaticSeq_t<BranchTypes_t::list_size>;
377 
378  Helper fHelper;
379  const ColumnNames_t fBranches;
380  PrevDataFrame &fPrevData;
381  std::vector<TDFValueTuple_t<BranchTypes_t>> fValues;
382 
383 public:
384  TAction(Helper &&h, const ColumnNames_t &bl, PrevDataFrame &pd)
385  : TActionBase(pd.GetImplPtr(), pd.GetNSlots()), fHelper(std::move(h)), fBranches(bl), fPrevData(pd),
386  fValues(fNSlots)
387  {
388  }
389 
390  TAction(const TAction &) = delete;
391  TAction &operator=(const TAction &) = delete;
392  ~TAction() { fHelper.Finalize(); }
393 
394  void InitSlot(TTreeReader *r, unsigned int slot) final
395  {
396  InitTDFValues(slot, fValues[slot], r, fBranches, fImplPtr->GetCustomColumnNames(), fImplPtr->GetBookedColumns(),
397  TypeInd_t());
398  fHelper.InitSlot(r, slot);
399  }
400 
401  void Run(unsigned int slot, Long64_t entry) final
402  {
403  // check if entry passes all filters
404  if (fPrevData.CheckFilters(slot, entry))
405  Exec(slot, entry, TypeInd_t());
406  }
407 
408  template <int... S>
409  void Exec(unsigned int slot, Long64_t entry, TDFInternal::StaticSeq<S...>)
410  {
411  (void)entry; // avoid bogus 'unused parameter' warning in gcc4.9
412  fHelper.Exec(slot, std::get<S>(fValues[slot]).Get(entry)...);
413  }
414 
415  void TriggerChildrenCount() final { fPrevData.IncrChildrenCount(); }
416 
417  virtual void ClearValueReaders(unsigned int slot) final { ResetTDFValueTuple(fValues[slot], TypeInd_t()); }
418 
419  /// This method is invoked to update a partial result during the event loop, right before passing the result to a
420  /// user-defined callback registered via TResultProxy::RegisterCallback
421  /// TODO the PartialUpdateImpl trick can go away once all action helpers will implement PartialUpdate
422  void *PartialUpdate(unsigned int slot) final { return PartialUpdateImpl(slot); }
423 
424 private:
425  // this overload is SFINAE'd out if Helper does not implement `PartialUpdate`
426  // the template parameter is required to defer instantiation of the method to SFINAE time
427  template <typename H = Helper>
428  auto PartialUpdateImpl(unsigned int slot) -> decltype(std::declval<H>().PartialUpdate(slot), (void *)(nullptr))
429  {
430  return &fHelper.PartialUpdate(slot);
431  }
432  // this one is always available but has lower precedence thanks to `...`
433  void *PartialUpdateImpl(...) {
434  throw std::runtime_error("This action does not support callbacks yet!");
435  }
436 };
437 
438 } // end NS TDF
439 } // end NS Internal
440 
441 namespace Detail {
442 namespace TDF {
443 
445 protected:
446  TLoopManager *fImplPtr; ///< A raw pointer to the TLoopManager at the root of this functional graph. It is only
447  /// guaranteed to contain a valid address during an event loop.
448  const std::string fName;
449  unsigned int fNChildren{0}; ///< number of nodes of the functional graph hanging from this object
450  unsigned int fNStopsReceived{0}; ///< number of times that a children node signaled to stop processing entries.
451  const unsigned int fNSlots; ///< number of thread slots used by this node, inherited from parent node.
452  const bool fIsDataSourceColumn; ///< does the custom column refer to a data-source column? (or a user-define column?)
453  std::vector<Long64_t> fLastCheckedEntry;
454 
455 public:
456  TCustomColumnBase(TLoopManager *df, std::string_view name, const unsigned int nSlots, const bool isDSColumn);
457  TCustomColumnBase &operator=(const TCustomColumnBase &) = delete;
458  virtual ~TCustomColumnBase() = default;
459 
460  virtual void InitSlot(TTreeReader *r, unsigned int slot) = 0;
461  virtual void *GetValuePtr(unsigned int slot) = 0;
462  virtual const std::type_info &GetTypeId() const = 0;
463  TLoopManager *GetImplPtr() const;
464  std::string GetName() const;
465  virtual void Update(unsigned int slot, Long64_t entry) = 0;
466  virtual void ClearValueReaders(unsigned int slot) = 0;
467  unsigned int GetNSlots() const { return fNSlots; }
468  bool IsDataSourceColumn() const { return fIsDataSourceColumn; }
469  void InitNode();
470 };
471 
472 namespace TCCHelperTypes {
473 struct TNothing {
474 };
475 struct TSlot {
476 };
478 };
479 }
480 
481 template <typename F, typename UPDATE_HELPER_TYPE = TCCHelperTypes::TNothing>
482 class TCustomColumn final : public TCustomColumnBase {
483  // shortcuts
487  using UHT_t = UPDATE_HELPER_TYPE;
488  // other types
489  using FunParamTypes_t = typename CallableTraits<F>::arg_types;
490  using BranchTypesTmp_t =
491  typename TDFInternal::RemoveFirstParameterIf<std::is_same<TSlot, UHT_t>::value, FunParamTypes_t>::type;
492  using BranchTypes_t = typename TDFInternal::RemoveFirstTwoParametersIf<std::is_same<TSlotAndEntry, UHT_t>::value,
494  using TypeInd_t = TDFInternal::GenStaticSeq_t<BranchTypes_t::list_size>;
495  using ret_type = typename CallableTraits<F>::ret_type;
496  // Avoid instantiating vector<bool> as `operator[]` returns temporaries in that case. Use std::deque instead.
497  using ValuesPerSlot_t =
498  typename std::conditional<std::is_same<ret_type, bool>::value, std::deque<ret_type>, std::vector<ret_type>>::type;
499 
501  const ColumnNames_t fBranches;
503 
504  std::vector<TDFInternal::TDFValueTuple_t<BranchTypes_t>> fValues;
505 
506 public:
507  TCustomColumn(std::string_view name, F &&expression, const ColumnNames_t &bl, TLoopManager *lm,
508  bool isDSColumn = false)
509  : TCustomColumnBase(lm, name, lm->GetNSlots(), isDSColumn), fExpression(std::move(expression)), fBranches(bl),
510  fLastResults(fNSlots), fValues(fNSlots)
511  {
512  }
513 
514  TCustomColumn(const TCustomColumn &) = delete;
515  TCustomColumn &operator=(const TCustomColumn &) = delete;
516 
517  void InitSlot(TTreeReader *r, unsigned int slot) final
518  {
519  TDFInternal::InitTDFValues(slot, fValues[slot], r, fBranches, fImplPtr->GetCustomColumnNames(),
520  fImplPtr->GetBookedColumns(), TypeInd_t());
521  }
522 
523  void *GetValuePtr(unsigned int slot) final { return static_cast<void *>(&fLastResults[slot]); }
524 
525  void Update(unsigned int slot, Long64_t entry) final
526  {
527  if (entry != fLastCheckedEntry[slot]) {
528  // evaluate this filter, cache the result
529  UpdateHelper(slot, entry, TypeInd_t(), BranchTypes_t(), (UPDATE_HELPER_TYPE *)nullptr);
530  fLastCheckedEntry[slot] = entry;
531  }
532  }
533 
534  const std::type_info &GetTypeId() const
535  {
536  return fIsDataSourceColumn ? typeid(typename std::remove_pointer<ret_type>::type) : typeid(ret_type);
537  }
538 
539  template <int... S, typename... BranchTypes>
540  void UpdateHelper(unsigned int slot, Long64_t entry, TDFInternal::StaticSeq<S...>, TypeList<BranchTypes...>,
542  {
543  fLastResults[slot] = fExpression(std::get<S>(fValues[slot]).Get(entry)...);
544  // silence "unused parameter" warnings in gcc
545  (void)slot;
546  (void)entry;
547  }
548 
549  template <int... S, typename... BranchTypes>
550  void UpdateHelper(unsigned int slot, Long64_t entry, TDFInternal::StaticSeq<S...>, TypeList<BranchTypes...>,
552  {
553  fLastResults[slot] = fExpression(slot, std::get<S>(fValues[slot]).Get(entry)...);
554  // silence "unused parameter" warnings in gcc
555  (void)slot;
556  (void)entry;
557  }
558 
559  template <int... S, typename... BranchTypes>
560  void UpdateHelper(unsigned int slot, Long64_t entry, TDFInternal::StaticSeq<S...>, TypeList<BranchTypes...>,
562  {
563  fLastResults[slot] = fExpression(slot, entry, std::get<S>(fValues[slot]).Get(entry)...);
564  // silence "unused parameter" warnings in gcc
565  (void)slot;
566  (void)entry;
567  }
568 
569  void ClearValueReaders(unsigned int slot) final { ResetTDFValueTuple(fValues[slot], TypeInd_t()); }
570 };
571 
572 class TFilterBase {
573 protected:
574  TLoopManager *fImplPtr; ///< A raw pointer to the TLoopManager at the root of this functional graph. It is only
575  /// guaranteed to contain a valid address during an event loop.
576  std::vector<Long64_t> fLastCheckedEntry;
577  std::vector<int> fLastResult = {true}; // std::vector<bool> cannot be used in a MT context safely
578  std::vector<ULong64_t> fAccepted = {0};
579  std::vector<ULong64_t> fRejected = {0};
580  const std::string fName;
581  unsigned int fNChildren{0}; ///< Number of nodes of the functional graph hanging from this object
582  unsigned int fNStopsReceived{0}; ///< Number of times that a children node signaled to stop processing entries.
583  const unsigned int fNSlots; ///< Number of thread slots used by this node, inherited from parent node.
584 
585 public:
586  TFilterBase(TLoopManager *df, std::string_view name, const unsigned int nSlots);
587  TFilterBase &operator=(const TFilterBase &) = delete;
588  virtual ~TFilterBase() = default;
589 
590  virtual void InitSlot(TTreeReader *r, unsigned int slot) = 0;
591  virtual bool CheckFilters(unsigned int slot, Long64_t entry) = 0;
592  virtual void Report() const = 0;
593  virtual void PartialReport() const = 0;
594  TLoopManager *GetImplPtr() const;
595  bool HasName() const;
596  void PrintReport() const;
597  virtual void IncrChildrenCount() = 0;
598  virtual void StopProcessing() = 0;
600  {
601  fNChildren = 0;
602  fNStopsReceived = 0;
603  }
604  virtual void TriggerChildrenCount() = 0;
605  unsigned int GetNSlots() const { return fNSlots; }
607  {
608  assert(!fName.empty()); // this method is to only be called on named filters
609  // fAccepted and fRejected could be different than 0 if this is not the first event-loop run using this filter
610  std::fill(fAccepted.begin(), fAccepted.end(), 0);
611  std::fill(fRejected.begin(), fRejected.end(), 0);
612  }
613  virtual void ClearValueReaders(unsigned int slot) = 0;
614  void InitNode();
615 };
616 
617 template <typename FilterF, typename PrevDataFrame>
618 class TFilter final : public TFilterBase {
619  using BranchTypes_t = typename CallableTraits<FilterF>::arg_types;
620  using TypeInd_t = TDFInternal::GenStaticSeq_t<BranchTypes_t::list_size>;
621 
622  FilterF fFilter;
623  const ColumnNames_t fBranches;
624  PrevDataFrame &fPrevData;
625  std::vector<TDFInternal::TDFValueTuple_t<BranchTypes_t>> fValues;
626 
627 public:
628  TFilter(FilterF &&f, const ColumnNames_t &bl, PrevDataFrame &pd, std::string_view name = "")
629  : TFilterBase(pd.GetImplPtr(), name, pd.GetNSlots()), fFilter(std::move(f)), fBranches(bl), fPrevData(pd),
630  fValues(fNSlots)
631  {
632  }
633 
634  TFilter(const TFilter &) = delete;
635  TFilter &operator=(const TFilter &) = delete;
636 
637  bool CheckFilters(unsigned int slot, Long64_t entry) final
638  {
639  if (entry != fLastCheckedEntry[slot]) {
640  if (!fPrevData.CheckFilters(slot, entry)) {
641  // a filter upstream returned false, cache the result
642  fLastResult[slot] = false;
643  } else {
644  // evaluate this filter, cache the result
645  auto passed = CheckFilterHelper(slot, entry, TypeInd_t());
646  passed ? ++fAccepted[slot] : ++fRejected[slot];
647  fLastResult[slot] = passed;
648  }
649  fLastCheckedEntry[slot] = entry;
650  }
651  return fLastResult[slot];
652  }
653 
654  template <int... S>
655  bool CheckFilterHelper(unsigned int slot, Long64_t entry, TDFInternal::StaticSeq<S...>)
656  {
657  return fFilter(std::get<S>(fValues[slot]).Get(entry)...);
658  // silence "unused parameter" warnings in gcc
659  (void)slot;
660  (void)entry;
661  }
662 
663  void InitSlot(TTreeReader *r, unsigned int slot) final
664  {
665  TDFInternal::InitTDFValues(slot, fValues[slot], r, fBranches, fImplPtr->GetCustomColumnNames(),
666  fImplPtr->GetBookedColumns(), TypeInd_t());
667  }
668 
669  // recursive chain of `Report`s
670  void Report() const final { PartialReport(); }
671 
672  void PartialReport() const final
673  {
674  fPrevData.PartialReport();
675  PrintReport();
676  }
677 
678  void StopProcessing() final
679  {
680  ++fNStopsReceived;
681  if (fNStopsReceived == fNChildren)
682  fPrevData.StopProcessing();
683  }
684 
685  void IncrChildrenCount() final
686  {
687  ++fNChildren;
688  // propagate "children activation" upstream. named filters do the propagation via `TriggerChildrenCount`.
689  if (fNChildren == 1 && fName.empty())
690  fPrevData.IncrChildrenCount();
691  }
692 
693  void TriggerChildrenCount() final
694  {
695  assert(!fName.empty()); // this method is to only be called on named filters
696  fPrevData.IncrChildrenCount();
697  }
698 
699  virtual void ClearValueReaders(unsigned int slot) final { ResetTDFValueTuple(fValues[slot], TypeInd_t()); }
700 };
701 
702 class TRangeBase {
703 protected:
704  TLoopManager *fImplPtr; ///< A raw pointer to the TLoopManager at the root of this functional graph. It is only
705  /// guaranteed to contain a valid address during an event loop.
706  unsigned int fStart;
707  unsigned int fStop;
708  unsigned int fStride;
709  Long64_t fLastCheckedEntry{-1};
710  bool fLastResult{true};
711  ULong64_t fNProcessedEntries{0};
712  unsigned int fNChildren{0}; ///< Number of nodes of the functional graph hanging from this object
713  unsigned int fNStopsReceived{0}; ///< Number of times that a children node signaled to stop processing entries.
714  bool fHasStopped{false}; ///< True if the end of the range has been reached
715  const unsigned int fNSlots; ///< Number of thread slots used by this node, inherited from parent node.
716 
717  void ResetCounters();
718 
719 public:
720  TRangeBase(TLoopManager *implPtr, unsigned int start, unsigned int stop, unsigned int stride,
721  const unsigned int nSlots);
722  TRangeBase &operator=(const TRangeBase &) = delete;
723  virtual ~TRangeBase() = default;
724 
725  TLoopManager *GetImplPtr() const;
726  virtual bool CheckFilters(unsigned int slot, Long64_t entry) = 0;
727  virtual void Report() const = 0;
728  virtual void PartialReport() const = 0;
729  virtual void IncrChildrenCount() = 0;
730  virtual void StopProcessing() = 0;
732  {
733  fNChildren = 0;
734  fNStopsReceived = 0;
735  }
736  unsigned int GetNSlots() const { return fNSlots; }
737  void InitNode() { ResetCounters(); }
738 };
739 
740 template <typename PrevData>
741 class TRange final : public TRangeBase {
742  PrevData &fPrevData;
743 
744 public:
745  TRange(unsigned int start, unsigned int stop, unsigned int stride, PrevData &pd)
746  : TRangeBase(pd.GetImplPtr(), start, stop, stride, pd.GetNSlots()), fPrevData(pd)
747  {
748  }
749 
750  TRange(const TRange &) = delete;
751  TRange &operator=(const TRange &) = delete;
752 
753  /// Ranges act as filters when it comes to selecting entries that downstream nodes should process
754  bool CheckFilters(unsigned int slot, Long64_t entry) final
755  {
756  if (entry != fLastCheckedEntry) {
757  if (fHasStopped)
758  return false;
759  if (!fPrevData.CheckFilters(slot, entry)) {
760  // a filter upstream returned false, cache the result
761  fLastResult = false;
762  } else {
763  // apply range filter logic, cache the result
764  ++fNProcessedEntries;
765  if (fNProcessedEntries <= fStart || (fStop > 0 && fNProcessedEntries > fStop) ||
766  (fStride != 1 && fNProcessedEntries % fStride != 0))
767  fLastResult = false;
768  else
769  fLastResult = true;
770  if (fNProcessedEntries == fStop) {
771  fHasStopped = true;
772  fPrevData.StopProcessing();
773  }
774  }
775  fLastCheckedEntry = entry;
776  }
777  return fLastResult;
778  }
779 
780  // recursive chain of `Report`s
781  // TRange simply forwards these calls to the previous node
782  void Report() const final { fPrevData.PartialReport(); }
783 
784  void PartialReport() const final { fPrevData.PartialReport(); }
785 
786  void StopProcessing() final
787  {
788  ++fNStopsReceived;
789  if (fNStopsReceived == fNChildren && !fHasStopped)
790  fPrevData.StopProcessing();
791  }
792 
793  void IncrChildrenCount() final
794  {
795  ++fNChildren;
796  // propagate "children activation" upstream
797  if (fNChildren == 1)
798  fPrevData.IncrChildrenCount();
799  }
800 };
801 
802 } // namespace TDF
803 } // namespace Detail
804 
805 // method implementations
806 namespace Internal {
807 namespace TDF {
808 
809 template <typename T>
811 {
812  fCustomColumns.emplace_back(customColumn);
813  if (customColumn->GetTypeId() != typeid(T))
814  throw std::runtime_error(
815  std::string("TColumnValue: type specified for column \"" + customColumn->GetName() + "\" is ") +
816  typeid(T).name() + " but temporary column has type " + customColumn->GetTypeId().name());
817 
818  if (customColumn->IsDataSourceColumn()) {
819  fColumnKind = EColumnKind::kDataSource;
820  fDSValuePtrs.emplace_back(static_cast<T **>(customColumn->GetValuePtr(slot)));
821  } else {
822  fColumnKind = EColumnKind::kCustomColumn;
823  fCustomValuePtrs.emplace_back(static_cast<T *>(customColumn->GetValuePtr(slot)));
824  }
825  fSlot = slot;
826 }
827 
828 // This method is executed inside the event-loop, many times per entry
829 // If need be, the if statement can be avoided using thunks
830 // (have both branches inside functions and have a pointer to
831 // the branch to be executed)
832 template <typename T>
833 template <typename U,
834  typename std::enable_if<std::is_same<typename TColumnValue<U>::ProxyParam_t, U>::value, int>::type>
836 {
837  if (fColumnKind == EColumnKind::kTreeValue) {
838  return *(fReaderValues.back()->Get());
839  } else {
840  fCustomColumns.back()->Update(fSlot, entry);
841  return fColumnKind == EColumnKind::kCustomColumn ? *fCustomValuePtrs.back() : **fDSValuePtrs.back();
842  }
843 }
844 
845 } // namespace TDF
846 } // namespace Internal
847 } // namespace ROOT
848 #endif // ROOT_TDFNODES
typename TTDFValueTuple< BranchType >::type TDFValueTuple_t
Definition: TDFNodes.hxx:340
std::string GetName(const std::string &scope_name)
Definition: Cppyy.cxx:145
void StopProcessing() final
Definition: TDFNodes.hxx:678
ColumnNames_t fDefinedDataSourceColumns
List of data-source columns that have been Defined so far.
Definition: TDFNodes.hxx:145
TDataSource * GetDataSource() const
Definition: TDFNodes.hxx:181
std::vector< std::unique_ptr< TTreeReaderValue< T > > > fReaderValues
Owning ptrs to a TTreeReaderValue. Used for non-temporary columns when T != TArrayBranch<U> ...
Definition: TDFNodes.hxx:251
FilterBaseVec_t fBookedFilters
Definition: TDFNodes.hxx:126
typename CallableTraits< FilterF >::arg_types BranchTypes_t
Definition: TDFNodes.hxx:619
void Report() const final
Definition: TDFNodes.hxx:782
bool CheckFilters(unsigned int slot, Long64_t entry) final
Definition: TDFNodes.hxx:637
void operator()(unsigned int slot)
Definition: TDFNodes.hxx:98
const ColumnNames_t fBranches
Definition: TDFNodes.hxx:501
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
basic_string_view< char > string_view
Definition: RStringView.h:35
std::function< void(unsigned int)> Callback_t
Definition: TDFNodes.hxx:88
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
T & Get(Long64_t entry)
This overload is used to return scalar quantities (i.e. types that are not read into a TArrayBranch) ...
Definition: TDFNodes.hxx:835
PrevDataFrame & fPrevData
Definition: TDFNodes.hxx:624
std::vector< TDFValueTuple_t< BranchTypes_t > > fValues
Definition: TDFNodes.hxx:381
std::map< std::string, TCustomColumnBasePtr_t > fBookedCustomColumns
Definition: TDFNodes.hxx:128
void PartialReport() const final
Definition: TDFNodes.hxx:672
void InitSlot(TTreeReader *r, unsigned int slot) final
Definition: TDFNodes.hxx:663
double T(double x)
Definition: ChebyshevPol.h:34
typename std::conditional< std::is_same< ret_type, bool >::value, std::deque< ret_type >, std::vector< ret_type > >::type ValuesPerSlot_t
Definition: TDFNodes.hxx:498
ColumnNames_t fCustomColumnNames
Contains names of all custom columns defined in the functional graph.
Definition: TDFNodes.hxx:129
TH1 * h
Definition: legend2.C:5
fill
Definition: fit1_py.py:6
void PartialReport() const final
Definition: TDFNodes.hxx:784
void * GetValuePtr(unsigned int slot) final
Definition: TDFNodes.hxx:523
const ColumnNames_t fDefaultColumns
Definition: TDFNodes.hxx:136
const std::unique_ptr< TDataSource > fDataSource
Owning pointer to a data-source object. Null if no data-source.
Definition: TDFNodes.hxx:144
std::vector< TDFInternal::TDFValueTuple_t< BranchTypes_t > > fValues
Definition: TDFNodes.hxx:625
void * PartialUpdate(unsigned int slot) final
This method is invoked to update a partial result during the event loop, right before passing the res...
Definition: TDFNodes.hxx:422
void PartialReport() const
End of recursive chain of calls, does nothing.
Definition: TDFNodes.hxx:192
unsigned int GetNSlots() const
Definition: TDFNodes.hxx:736
typename CallableTraits< F >::arg_types FunParamTypes_t
Definition: TDFNodes.hxx:489
void TriggerChildrenCount() final
Definition: TDFNodes.hxx:693
std::vector< unsigned int > fBuf
Definition: TDFNodes.hxx:55
STL namespace.
virtual void ClearValueReaders(unsigned int slot) final
Definition: TDFNodes.hxx:699
const ColumnNames_t fBranches
Definition: TDFNodes.hxx:623
A spin mutex class which respects the STL interface for mutexes.
Definition: TSpinMutex.hxx:40
const std::map< std::string, TCustomColumnBasePtr_t > & GetBookedColumns() const
Definition: TDFNodes.hxx:178
typename TDFInternal::RemoveFirstParameterIf< std::is_same< TSlot, UHT_t >::value, FunParamTypes_t >::type BranchTypesTmp_t
Definition: TDFNodes.hxx:491
TArrayBranch< ProxyParam_t > Get(Long64_t)
This overload is used to return arrays (i.e. types that are read into a TArrayBranch) ...
Definition: TDFNodes.hxx:288
TAction(Helper &&h, const ColumnNames_t &bl, PrevDataFrame &pd)
Definition: TDFNodes.hxx:384
void AddDataSourceColumn(std::string_view name)
Definition: TDFNodes.hxx:198
const std::map< std::string, std::string > & GetAliasMap() const
Definition: TDFNodes.hxx:200
void StopProcessing() final
Definition: TDFNodes.hxx:786
std::vector< ULong64_t > fCounters
Definition: TDFNodes.hxx:92
void MakeProxy(TTreeReader *r, const std::string &bn)
Definition: TDFNodes.hxx:269
void UpdateHelper(unsigned int slot, Long64_t entry, TDFInternal::StaticSeq< S... >, TypeList< BranchTypes... >, TCCHelperTypes::TSlotAndEntry *)
Definition: TDFNodes.hxx:560
const std::type_info & GetTypeId() const
Definition: TDFNodes.hxx:534
std::shared_ptr< TFilterBase > FilterBasePtr_t
Definition: TDFNodes.hxx:78
unsigned int GetNSlots() const
Definition: TDFNodes.hxx:368
void ReturnSlot(unsigned int slotNumber)
Definition: TDFNodes.cxx:99
Helper class that updates and returns TTree branches as well as TDataFrame temporary columns...
Definition: TDFNodes.hxx:232
unsigned int GetNSlots() const
Definition: TDFNodes.hxx:467
ULong64_t GetNEmptyEntries() const
Definition: TDFNodes.hxx:180
typename CallableTraits< F >::ret_type ret_type
Definition: TDFNodes.hxx:495
std::shared_ptr< TLoopManager > GetSharedPtr()
Definition: TDFNodes.hxx:173
void SetTmpColumn(unsigned int slot, TCustomColumnBase *tmpColumn)
Definition: TDFNodes.hxx:810
const ColumnNames_t & GetCustomColumnNames() const
Definition: TDFNodes.hxx:175
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
Definition: RExports.h:146
EColumnKind
TColumnValue has a slightly different behaviour whether the column comes from a TTreeReader, a TDataFrame Define or a TDataSource.
Definition: TDFNodes.hxx:240
void InitSlot(TTreeReader *r, unsigned int slot) final
Definition: TDFNodes.hxx:517
Extracts data from a TTree.
void InitSlot(TTreeReader *r, unsigned int slot) final
Definition: TDFNodes.hxx:394
ActionBaseVec_t fBookedActions
Definition: TDFNodes.hxx:125
PrevDataFrame & fPrevData
Definition: TDFNodes.hxx:380
When using TDataFrame to read data from a ROOT file, users can specify that the type of a branch is T...
typename std::conditional< std::is_same< ReaderValueOrArray_t< T >, TTreeReaderValue< T > >::value, T, TakeFirstParameter_t< T > >::type ProxyParam_t
Definition: TDFNodes.hxx:236
std::vector< FilterBasePtr_t > FilterBaseVec_t
Definition: TDFNodes.hxx:79
std::vector< Long64_t > fLastCheckedEntry
Definition: TDFNodes.hxx:453
RooArgSet S(const RooAbsArg &v1)
TRange(unsigned int start, unsigned int stop, unsigned int stride, PrevData &pd)
Definition: TDFNodes.hxx:745
const ColumnNames_t & GetDefinedDataSourceColumns() const
Definition: TDFNodes.hxx:197
#define F(x, y, z)
std::vector< TCallback > fCallbacks
Registered callbacks.
Definition: TDFNodes.hxx:147
const unsigned int fNSlots
number of thread slots used by this node, inherited from parent node.
Definition: TDFNodes.hxx:451
const bool fIsDataSourceColumn
does the custom column refer to a data-source column? (or a user-define column?)
Definition: TDFNodes.hxx:452
void Report() const final
Definition: TDFNodes.hxx:670
ROOT::R::TRInterface & r
Definition: Object.C:4
TDataSource defines an API that TDataFrame can use to read arbitrary data formats.
Definition: TDataSource.hxx:51
std::vector< T * > fCustomValuePtrs
Non-owning ptrs to the value of a custom column.
Definition: TDFNodes.hxx:255
std::vector< RangeBasePtr_t > RangeBaseVec_t
Definition: TDFNodes.hxx:82
std::vector< T ** > fDSValuePtrs
Non-owning ptrs to the value of a data-source column.
Definition: TDFNodes.hxx:257
std::vector< ActionBasePtr_t > ActionBaseVec_t
Definition: TDFNodes.hxx:74
void TriggerChildrenCount() final
Definition: TDFNodes.hxx:415
unsigned int GetNSlots() const
Definition: TDFNodes.hxx:605
TOneTimeCallback(Callback_t &&f, unsigned int nSlots)
Definition: TDFNodes.hxx:114
void ClearValueReaders(unsigned int slot) final
Definition: TDFNodes.hxx:569
void UpdateHelper(unsigned int slot, Long64_t entry, TDFInternal::StaticSeq< S... >, TypeList< BranchTypes... >, TCCHelperTypes::TSlot *)
Definition: TDFNodes.hxx:550
TCallback(ULong64_t everyN, Callback_t &&f, unsigned int nSlots)
Definition: TDFNodes.hxx:95
void Exec(unsigned int slot, Long64_t entry, TDFInternal::StaticSeq< S... >)
Definition: TDFNodes.hxx:409
TLoopManager * fImplPtr
A raw pointer to the TLoopManager at the root of this functional graph.
Definition: TDFNodes.hxx:574
std::string fToJit
string containing all BuildAndBook actions that should be jitted before running
Definition: TDFNodes.hxx:143
std::vector< TDFInternal::TDFValueTuple_t< BranchTypes_t > > fValues
Definition: TDFNodes.hxx:504
std::map< std::string, std::string > fAliasColumnNameMap
ColumnNameAlias-columnName pairs.
Definition: TDFNodes.hxx:146
void Jit(const std::string &s)
Definition: TDFNodes.hxx:196
void Update(unsigned int slot, Long64_t entry) final
Definition: TDFNodes.hxx:525
void Reset(Detail::TBranchProxy *x)
FilterBaseVec_t fBookedNamedFilters
Contains a subset of fBookedFilters, i.e. only the named filters.
Definition: TDFNodes.hxx:127
std::tuple< TColumnValue< BranchTypes >... > type
Definition: TDFNodes.hxx:336
TFilter(FilterF &&f, const ColumnNames_t &bl, PrevDataFrame &pd, std::string_view name="")
Definition: TDFNodes.hxx:628
TDFInternal::GenStaticSeq_t< BranchTypes_t::list_size > TypeInd_t
Definition: TDFNodes.hxx:494
const ELoopType fLoopType
The kind of event loop that is going to be run (e.g. on ROOT files, on no files)
Definition: TDFNodes.hxx:142
Lightweight storage for a collection of types.
Definition: TypeTraits.hxx:27
TCustomColumn(std::string_view name, F &&expression, const ColumnNames_t &bl, TLoopManager *lm, bool isDSColumn=false)
Definition: TDFNodes.hxx:507
std::vector< std::unique_ptr< TTreeReaderArray< ProxyParam_t > > > fReaderArrays
Owning ptrs to a TTreeReaderArray. Used for non-temporary columns when T == TArrayBranch<U>.
Definition: TDFNodes.hxx:253
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:715
Describe directory structure in memory.
Definition: TDirectory.h:34
int type
Definition: TGX11.cxx:120
unsigned long long ULong64_t
Definition: RtypesCore.h:70
std::vector< Long64_t > fLastCheckedEntry
Definition: TDFNodes.hxx:576
const unsigned int fNSlots
Number of thread slots used by this node.
Definition: TDFNodes.hxx:356
void Run(unsigned int slot, Long64_t entry) final
Definition: TDFNodes.hxx:401
ROOT type_traits extensions.
Definition: TypeTraits.hxx:23
TLoopManager * fImplPtr
A raw pointer to the TLoopManager at the root of this functional graph.
Definition: TDFNodes.hxx:704
typename TDFInternal::RemoveFirstTwoParametersIf< std::is_same< TSlotAndEntry, UHT_t >::value, BranchTypesTmp_t >::type BranchTypes_t
Definition: TDFNodes.hxx:493
static constexpr double s
std::shared_ptr< TDFInternal::TActionBase > ActionBasePtr_t
Definition: TDFNodes.hxx:73
TDFInternal::GenStaticSeq_t< BranchTypes_t::list_size > TypeInd_t
Definition: TDFNodes.hxx:620
Binding & operator=(OUT(*fun)(void))
unsigned int GetNSlots() const
Definition: TDFNodes.hxx:188
TLoopManager * fImplPtr
A raw pointer to the TLoopManager at the root of this functional graph.
Definition: TDFNodes.hxx:446
TSlotStack(unsigned int size)
Definition: TDFNodes.hxx:60
typedef void((*Func_t)())
unsigned int GetNSlots()
Definition: TDFUtils.cxx:222
const ColumnNames_t fBranches
Definition: TDFNodes.hxx:379
void IncrChildrenCount() final
Definition: TDFNodes.hxx:685
void AddColumnAlias(const std::string &alias, const std::string &colName)
Definition: TDFNodes.hxx:199
Definition: tree.py:1
virtual void ClearValueReaders(unsigned int slot) final
Definition: TDFNodes.hxx:417
std::vector< TCustomColumnBase * > fCustomColumns
Non-owning ptrs to the node responsible for the custom column. Needed when querying custom values...
Definition: TDFNodes.hxx:259
bool CheckFilterHelper(unsigned int slot, Long64_t entry, TDFInternal::StaticSeq< S... >)
Definition: TDFNodes.hxx:655
std::shared_ptr< TCustomColumnBase > TCustomColumnBasePtr_t
Definition: TDFNodes.hxx:76
std::vector< std::shared_ptr< bool > > fResProxyReadiness
Definition: TDFNodes.hxx:131
void ResetTDFValueTuple(ValueTuple &values, StaticSeq< S... >)
Clear the proxies of a tuple of TColumnValues.
Definition: TDFNodes.hxx:344
auto PartialUpdateImpl(unsigned int slot) -> decltype(std::declval< H >().PartialUpdate(slot),(void *)(nullptr))
Definition: TDFNodes.hxx:428
void UpdateHelper(unsigned int slot, Long64_t entry, TDFInternal::StaticSeq< S... >, TypeList< BranchTypes... >, TCCHelperTypes::TNothing *)
Definition: TDFNodes.hxx:540
void IncrChildrenCount() final
Definition: TDFNodes.hxx:793
const unsigned int fNSlots
Number of thread slots used by this node, inherited from parent node.
Definition: TDFNodes.hxx:583
TLoopManager * fImplPtr
A raw pointer to the TLoopManager at the root of this functional graph.
Definition: TDFNodes.hxx:353
char name[80]
Definition: TGX11.cxx:109
std::vector< TOneTimeCallback > fCallbacksOnce
Registered callbacks to invoke just once before running the loop.
Definition: TDFNodes.hxx:148
virtual void * GetValuePtr(unsigned int slot)=0
GenStaticSeq_t< BranchTypes_t::list_size > TypeInd_t
Definition: TDFNodes.hxx:376
std::shared_ptr< TRangeBase > RangeBasePtr_t
Definition: TDFNodes.hxx:81
void SetTree(const std::shared_ptr< TTree > &tree)
Definition: TDFNodes.hxx:193
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:754