15 #include "ROOT/RArrayView.hxx" 50 class TLoopManager :
public std::enable_shared_from_this<TLoopManager> {
59 std::shared_ptr<TTree> fTree{
nullptr};
62 const unsigned int fNSlots{0};
63 bool fHasRunAtLeastOnce{
false};
64 unsigned int fNChildren{0};
65 unsigned int fNStopsReceived{0};
67 void RunAndCheckFilters(
unsigned int slot,
Long64_t entry);
78 std::shared_ptr<TLoopManager>
GetSharedPtr() {
return shared_from_this(); }
79 const ColumnNames_t &GetDefaultBranches()
const;
81 TTree *GetTree()
const;
83 const std::map<std::string, TmpBranchBasePtr_t> &
GetBookedBranches()
const {
return fBookedBranches; }
89 void Book(
const std::shared_ptr<bool> &branchPtr);
91 bool CheckFilters(
int,
unsigned int);
100 void CleanUpTask(
unsigned int slot);
130 template <
typename T>
136 std::unique_ptr<TTreeReaderValue<T>> fReaderValue{
nullptr};
138 std::unique_ptr<TTreeReaderArray<ProxyParam_t>> fReaderArray{
nullptr};
141 T *fValuePtr{
nullptr};
143 unsigned int fSlot{0};
153 bool useReaderValue = std::is_same<ProxyParam_t, T>::value;
160 template <
typename U =
T,
161 typename std::enable_if<std::is_same<typename TColumnValue<U>::ProxyParam_t, U>::value,
int>::type = 0>
164 template <typename U = T, typename std::enable_if<!std::is_same<ProxyParam_t, U>::value,
int>::type = 0>
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());
176 return std::array_view<ProxyParam_t>(fReaderArray->begin(), fReaderArray->end());
181 fReaderValue =
nullptr;
182 fReaderArray =
nullptr;
184 fTmpColumn =
nullptr;
189 template <
typename T>
193 template <
typename... BranchTypes>
195 using type = std::tuple<TColumnValue<BranchTypes>...>;
198 template <
typename BranchType>
202 template<
typename ValueTuple,
int...S>
206 std::initializer_list<int> expander{(std::get<S>(values).
Reset(), 0)...};
221 virtual void Run(
unsigned int slot,
Long64_t entry) = 0;
222 virtual void Init(
TTreeReader *
r,
unsigned int slot) = 0;
224 virtual void ClearValueReaders(
unsigned int slot) = 0;
227 template <
typename Helper,
typename PrevDataFrame,
typename BranchTypes_t =
typename Helper::BranchTypes_t>
229 using TypeInd_t =
typename TGenStaticSeq<BranchTypes_t::fgSize>::Type_t;
234 std::vector<TDFValueTuple_t<BranchTypes_t>>
fValues;
237 TAction(Helper &&
h,
const ColumnNames_t &bl, PrevDataFrame &pd)
239 fPrevData(pd), fValues(fNSlots)
247 InitTDFValues(slot, fValues[slot],
r, fBranches, fTmpBranches, fImplPtr->GetBookedBranches(),
TypeInd_t());
248 fHelper.Init(
r, slot);
254 if (fPrevData.CheckFilters(slot, entry)) Exec(slot, entry,
TypeInd_t());
261 fHelper.Exec(slot, std::get<S>(fValues[slot]).Get(entry)...);
281 unsigned int fNChildren{0};
282 unsigned int fNStopsReceived{0};
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;
293 virtual void Report()
const = 0;
294 virtual void PartialReport()
const = 0;
296 ColumnNames_t GetTmpBranches()
const;
297 virtual void Update(
unsigned int slot,
Long64_t entry) = 0;
299 virtual void StopProcessing() = 0;
301 virtual void ClearValueReaders(
unsigned int slot) = 0;
304 template <
typename F,
typename PrevData>
307 using TypeInd_t =
typename TDFInternal::TGenStaticSeq<BranchTypes_t::fgSize>::Type_t;
308 using Ret_t =
typename TDFInternal::TFunctionTraits<F>::Ret_t;
314 std::vector<Long64_t> fLastCheckedEntry = {-1};
316 std::vector<TDFInternal::TDFValueTuple_t<BranchTypes_t>>
fValues;
321 fExpression(
std::move(expression)), fBranches(bl), fLastResultPtr(fNSlots), fPrevData(pd),
322 fLastCheckedEntry(fNSlots, -1), fValues(fNSlots)
325 []() {
return std::unique_ptr<Ret_t>(
new Ret_t()); });
326 fTmpBranches.emplace_back(name);
333 TDFInternal::InitTDFValues(slot, fValues[slot],
r, fBranches, fTmpBranches, fImplPtr->GetBookedBranches(),
337 void *
GetValuePtr(
unsigned int slot)
final {
return static_cast<void *
>(fLastResultPtr[slot].get()); }
341 if (entry != fLastCheckedEntry[slot]) {
344 fLastCheckedEntry[slot] = entry;
353 return fPrevData.CheckFilters(slot, entry);
356 template <
int...
S,
typename... BranchTypes>
358 TDFInternal::TTypeList<BranchTypes...>)
360 *fLastResultPtr[slot] = fExpression(std::get<S>(fValues[slot]).Get(entry)...);
366 void Report() const final { fPrevData.PartialReport(); }
373 if (fNStopsReceived == fNChildren) fPrevData.StopProcessing();
384 std::vector<Long64_t> fLastCheckedEntry = {-1};
385 std::vector<int> fLastResult = {
true};
386 std::vector<ULong64_t> fAccepted = {0};
387 std::vector<ULong64_t> fRejected = {0};
389 unsigned int fNChildren{0};
390 unsigned int fNStopsReceived{0};
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;
401 ColumnNames_t GetTmpBranches()
const;
402 bool HasName()
const;
403 void PrintReport()
const;
405 virtual void StopProcessing() = 0;
407 virtual void ResetReportCount() = 0;
408 virtual void ClearValueReaders(
unsigned int slot) = 0;
411 template <
typename FilterF,
typename PrevDataFrame>
413 using BranchTypes_t =
typename TDFInternal::TFunctionTraits<FilterF>::Args_t;
414 using TypeInd_t =
typename TDFInternal::TGenStaticSeq<BranchTypes_t::fgSize>::Type_t;
419 std::vector<TDFInternal::TDFValueTuple_t<BranchTypes_t>>
fValues;
422 TFilter(FilterF &&
f,
const ColumnNames_t &bl, PrevDataFrame &pd, std::string_view
name =
"")
424 fPrevData(pd), fValues(fNSlots)
432 if (entry != fLastCheckedEntry[slot]) {
433 if (!fPrevData.CheckFilters(slot, entry)) {
435 fLastResult[slot] =
false;
438 auto passed = CheckFilterHelper(slot, entry,
TypeInd_t());
439 passed ? ++fAccepted[slot] : ++fRejected[slot];
440 fLastResult[slot] = passed;
442 fLastCheckedEntry[slot] = entry;
444 return fLastResult[slot];
450 return fFilter(std::get<S>(fValues[slot]).Get(entry)...);
455 TDFInternal::InitTDFValues(slot, fValues[slot],
r, fBranches, fTmpBranches, fImplPtr->GetBookedBranches(),
460 void Report() const final { PartialReport(); }
464 fPrevData.PartialReport();
471 if (fNStopsReceived == fNChildren) fPrevData.StopProcessing();
476 assert(!fName.empty());
478 std::fill(fAccepted.begin(), fAccepted.end(), 0);
479 std::fill(fRejected.begin(), fRejected.end(), 0);
494 bool fLastResult{
true};
496 unsigned int fNChildren{0};
497 unsigned int fNStopsReceived{0};
498 bool fHasStopped{
false};
502 TRangeBase(
TLoopManager *implPtr,
const ColumnNames_t &tmpBranches,
unsigned int start,
unsigned int stop,
503 unsigned int stride,
unsigned int nSlots);
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;
511 virtual void StopProcessing() = 0;
515 template <
typename PrevData>
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)
532 }
else if (entry != fLastCheckedEntry) {
533 if (!fPrevData.CheckFilters(slot, entry)) {
538 ++fNProcessedEntries;
539 if (fNProcessedEntries <= fStart || (fStop > 0 && fNProcessedEntries > fStop) ||
540 (fStride != 1 && fNProcessedEntries % fStride != 0))
544 if (fNProcessedEntries == fStop) {
546 fPrevData.StopProcessing();
549 fLastCheckedEntry = entry;
556 void Report() const final { fPrevData.PartialReport(); }
563 if (fNStopsReceived == fNChildren && !fHasStopped) fPrevData.StopProcessing();
572 template <
typename T>
577 fTmpColumn = tmpColumn;
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));
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,
596 return *(fReaderValue->Get());
598 fTmpColumn->Update(fSlot, entry);
603 #endif // ROOT_TDFNODES typename TTDFValueTuple< BranchType >::type TDFValueTuple_t
std::string GetName(const std::string &scope_name)
RangeBaseVec_t fBookedRanges
virtual ~TCustomColumnBase()
FilterBaseVec_t fBookedFilters
void Report() const final
bool CheckFilters(unsigned int slot, Long64_t entry) final
typename std::conditional< std::is_same< ReaderValueOrArray_t< T >, TTreeReaderValue< T > >::value, T, ExtractType_t< T > >::type ProxyParam_t
TTreeReader is a simple, robust and fast interface to read values from a TTree, TChain or TNtuple...
void Init(TTreeReader *r, unsigned int slot) final
Namespace for new ROOT classes and functions.
PrevDataFrame & fPrevData
std::array_view< ProxyParam_t > Get(Long64_t)
std::vector< TDFValueTuple_t< BranchTypes_t > > fValues
void PartialReport() const final
void ClearValueReaders(unsigned int slot) final
std::vector< std::unique_ptr< Ret_t > > fLastResultPtr
Long64_t GetNEmptyEntries() const
void PartialReport() const final
void Update(unsigned int slot, Long64_t entry) final
std::vector< TDFInternal::TDFValueTuple_t< BranchTypes_t > > fValues
std::map< std::string, TmpBranchBasePtr_t > fBookedBranches
void generate(R &r, TH1D *h)
void PartialReport() const
End of recursive chain of calls, does nothing.
unsigned int GetNSlots() const
void Init(TTreeReader *r, unsigned int slot) final
const ColumnNames_t fBranches
const std::type_info & GetTypeId() const
TAction(Helper &&h, const ColumnNames_t &bl, PrevDataFrame &pd)
void PartialReport() const final
void ResetTDFValueTuple(ValueTuple &values, TStaticSeq< S... >)
Clear the proxies of a tuple of TColumnValues.
const ColumnNames_t fTmpBranches
void MakeProxy(TTreeReader *r, const std::string &bn)
std::shared_ptr< TFilterBase > FilterBasePtr_t
unsigned int GetNSlots() const
typename TDFInternal::TFunctionTraits< FilterF >::Args_t BranchTypes_t
Helper class that updates and returns TTree branches as well as TDataFrame temporary columns...
typename TDFInternal::TFunctionTraits< F >::Ret_t Ret_t
bool CheckFilters(unsigned int slot, Long64_t entry) final
unsigned int GetNSlots() const
void ClearValueReaders(unsigned int slot) final
typename TDFInternal::TGenStaticSeq< BranchTypes_t::fgSize >::Type_t TypeInd_t
std::shared_ptr< TLoopManager > GetSharedPtr()
void SetTmpColumn(unsigned int slot, TCustomColumnBase *tmpColumn)
const ColumnNames_t fTmpBranches
typename TGenStaticSeq< BranchTypes_t::fgSize >::Type_t TypeInd_t
Extracts data from a TTree.
const ColumnNames_t fBranches
ActionBaseVec_t fBookedActions
PrevDataFrame & fPrevData
std::vector< FilterBasePtr_t > FilterBaseVec_t
TCustomColumn(std::string_view name, F &&expression, const ColumnNames_t &bl, PrevData &pd)
RooArgSet S(const RooAbsArg &v1)
TRange(unsigned int start, unsigned int stop, unsigned int stride, PrevData &pd)
bool CheckFilterHelper(unsigned int slot, Long64_t entry, TDFInternal::TStaticSeq< S... >)
const unsigned int fNSlots
Number of thread slots used by this node, inherited from parent node.
void Report() const final
std::vector< RangeBasePtr_t > RangeBaseVec_t
std::vector< ActionBasePtr_t > ActionBaseVec_t
unsigned int GetNSlots() const
std::shared_ptr< TCustomColumnBase > TmpBranchBasePtr_t
TLoopManager * fImplPtr
A raw pointer to the TLoopManager at the root of this functional graph.
void Exec(unsigned int slot, Long64_t entry, TStaticSeq< S... >)
void SetTree(std::shared_ptr< TTree > tree)
std::vector< TDFInternal::TDFValueTuple_t< BranchTypes_t > > fValues
std::tuple< TColumnValue< BranchTypes >... > type
typename TDFInternal::TFunctionTraits< F >::Args_t BranchTypes_t
void Reset(Detail::TBranchProxy *x)
FilterBaseVec_t fBookedNamedFilters
virtual void ClearValueReaders(unsigned int slot) final
TFilter(FilterF &&f, const ColumnNames_t &bl, PrevDataFrame &pd, std::string_view name="")
bool HasRunAtLeastOnce() const
ColumnNames_t fTmpBranches
virtual const std::type_info & GetTypeId() const =0
const unsigned int fNSlots
Number of thread slots used by this node, inherited from parent node.
Describe directory structure in memory.
unsigned long long ULong64_t
const unsigned int fNSlots
Number of thread slots used by this node.
void Run(unsigned int slot, Long64_t entry) final
ColumnNames_t fTmpBranches
TLoopManager * fImplPtr
A raw pointer to the TLoopManager at the root of this functional graph.
const ColumnNames_t fDefaultBranches
void * GetValuePtr(unsigned int slot) final
std::shared_ptr< TDFInternal::TActionBase > ActionBasePtr_t
unsigned int GetNSlots() const
TLoopManager * fImplPtr
A raw pointer to the TLoopManager at the root of this functional graph.
const ColumnNames_t GetTmpBranches() const
typedef void((*Func_t)())
typename TDFInternal::TGenStaticSeq< BranchTypes_t::fgSize >::Type_t TypeInd_t
const std::map< std::string, TmpBranchBasePtr_t > & GetBookedBranches() const
void Report() const final
const ColumnNames_t fBranches
A TTree object has a header with a name and a title.
std::vector< std::shared_ptr< bool > > fResProxyReadiness
void Init(TTreeReader *r, unsigned int slot) final
const unsigned int fNSlots
Number of thread slots used by this node, inherited from parent node.
void UpdateHelper(unsigned int slot, Long64_t entry, TDFInternal::TStaticSeq< S... >, TDFInternal::TTypeList< BranchTypes... >)
TLoopManager * fImplPtr
A raw pointer to the TLoopManager at the root of this functional graph.
virtual void * GetValuePtr(unsigned int slot)=0
std::shared_ptr< TRangeBase > RangeBasePtr_t
bool CheckFilters(unsigned int slot, Long64_t entry) final
Ranges act as filters when it comes to selecting entries that downstream nodes should process...