Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RFilter.hxx
Go to the documentation of this file.
1// Author: Enrico Guiraud, Danilo Piparo CERN 09/2018
2
3/*************************************************************************
4 * Copyright (C) 1995-2018, 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_RFILTER
12#define ROOT_RFILTER
13
17#include "ROOT/RDF/Utils.hxx"
21#include "ROOT/TypeTraits.hxx"
22#include "RtypesCore.h"
23
24#include <algorithm>
25#include <memory>
26#include <string>
27#include <vector>
28
29namespace ROOT {
30
31namespace Internal {
32namespace RDF {
33using namespace ROOT::Detail::RDF;
34
35// fwd decl for RFilter
36namespace GraphDrawing {
37std::shared_ptr<GraphNode> CreateFilterNode(const RFilterBase *filterPtr);
38
39std::shared_ptr<GraphNode> AddDefinesToGraph(std::shared_ptr<GraphNode> node,
40 const RDFInternal::RBookedDefines &defines,
41 const std::vector<std::string> &prevNodeDefines);
42} // ns GraphDrawing
43
44} // ns RDF
45} // ns Internal
46
47namespace Detail {
48namespace RDF {
49using namespace ROOT::TypeTraits;
51
52template <typename FilterF, typename PrevDataFrame>
53class R__CLING_PTRCHECK(off) RFilter final : public RFilterBase {
55 using TypeInd_t = std::make_index_sequence<ColumnTypes_t::list_size>;
56
57 FilterF fFilter;
59 const std::shared_ptr<PrevDataFrame> fPrevDataPtr;
60 PrevDataFrame &fPrevData;
61 /// Column readers per slot and per input column
62 std::vector<std::array<std::unique_ptr<RColumnReaderBase>, ColumnTypes_t::list_size>> fValues;
63 /// The nth flag signals whether the nth input column is a custom column or not.
64 std::array<bool, ColumnTypes_t::list_size> fIsDefine;
65
66public:
67 RFilter(FilterF f, const ColumnNames_t &columns, std::shared_ptr<PrevDataFrame> pd,
68 const RDFInternal::RBookedDefines &defines, std::string_view name = "")
69 : RFilterBase(pd->GetLoopManagerUnchecked(), name, pd->GetLoopManagerUnchecked()->GetNSlots(), defines),
70 fFilter(std::move(f)), fColumnNames(columns), fPrevDataPtr(std::move(pd)), fPrevData(*fPrevDataPtr),
71 fValues(fNSlots), fIsDefine()
72 {
73 const auto nColumns = fColumnNames.size();
74 for (auto i = 0u; i < nColumns; ++i)
75 fIsDefine[i] = fDefines.HasName(fColumnNames[i]);
76 }
77
78 RFilter(const RFilter &) = delete;
79 RFilter &operator=(const RFilter &) = delete;
80 // must call Deregister here, before fPrevDataFrame is destroyed,
81 // otherwise if fPrevDataFrame is fLoopManager we get a use after delete
82 ~RFilter() { fLoopManager->Deregister(this); }
83
84 bool CheckFilters(unsigned int slot, Long64_t entry) final
85 {
86 if (entry != fLastCheckedEntry[slot * RDFInternal::CacheLineStep<Long64_t>()]) {
87 if (!fPrevData.CheckFilters(slot, entry)) {
88 // a filter upstream returned false, cache the result
89 fLastResult[slot * RDFInternal::CacheLineStep<int>()] = false;
90 } else {
91 // evaluate this filter, cache the result
92 auto passed = CheckFilterHelper(slot, entry, ColumnTypes_t{}, TypeInd_t{});
93 passed ? ++fAccepted[slot * RDFInternal::CacheLineStep<ULong64_t>()]
94 : ++fRejected[slot * RDFInternal::CacheLineStep<ULong64_t>()];
95 fLastResult[slot * RDFInternal::CacheLineStep<int>()] = passed;
96 }
97 fLastCheckedEntry[slot * RDFInternal::CacheLineStep<Long64_t>()] = entry;
98 }
99 return fLastResult[slot * RDFInternal::CacheLineStep<int>()];
100 }
101
102 template <typename... ColTypes, std::size_t... S>
103 bool CheckFilterHelper(unsigned int slot, Long64_t entry, TypeList<ColTypes...>, std::index_sequence<S...>)
104 {
105 // silence "unused parameter" warnings in gcc
106 (void)slot;
107 (void)entry;
108 return fFilter(fValues[slot][S]->template Get<ColTypes>(entry)...);
109 }
110
111 void InitSlot(TTreeReader *r, unsigned int slot) final
112 {
113 for (auto &bookedBranch : fDefines.GetColumns())
114 bookedBranch.second->InitSlot(r, slot);
115 RDFInternal::RColumnReadersInfo info{fColumnNames, fDefines, fIsDefine.data(), fLoopManager->GetDSValuePtrs(),
116 fLoopManager->GetDataSource()};
117 fValues[slot] = RDFInternal::MakeColumnReaders(slot, r, ColumnTypes_t{}, info);
118 }
119
120 // recursive chain of `Report`s
121 void Report(ROOT::RDF::RCutFlowReport &rep) const final { PartialReport(rep); }
122
124 {
125 fPrevData.PartialReport(rep);
126 FillReport(rep);
127 }
128
129 void StopProcessing() final
130 {
131 ++fNStopsReceived;
132 if (fNStopsReceived == fNChildren)
133 fPrevData.StopProcessing();
134 }
135
136 void IncrChildrenCount() final
137 {
138 ++fNChildren;
139 // propagate "children activation" upstream. named filters do the propagation via `TriggerChildrenCount`.
140 if (fNChildren == 1 && fName.empty())
141 fPrevData.IncrChildrenCount();
142 }
143
145 {
146 R__ASSERT(!fName.empty()); // this method is to only be called on named filters
147 fPrevData.IncrChildrenCount();
148 }
149
150 void AddFilterName(std::vector<std::string> &filters)
151 {
152 fPrevData.AddFilterName(filters);
153 auto name = (HasName() ? fName : "Unnamed Filter");
154 filters.push_back(name);
155 }
156
157 /// Clean-up operations to be performed at the end of a task.
158 virtual void FinaliseSlot(unsigned int slot) final
159 {
160 for (auto &column : fDefines.GetColumns())
161 column.second->FinaliseSlot(slot);
162
163 for (auto &v : fValues[slot])
164 v.reset();
165 }
166
167 std::shared_ptr<RDFGraphDrawing::GraphNode> GetGraph()
168 {
169 // Recursively call for the previous node.
170 auto prevNode = fPrevData.GetGraph();
171 auto prevColumns = prevNode->GetDefinedColumns();
172
173 auto thisNode = RDFGraphDrawing::CreateFilterNode(this);
174
175 /* If the returned node is not new, there is no need to perform any other operation.
176 * This is a likely scenario when building the entire graph in which branches share
177 * some nodes. */
178 if (!thisNode->GetIsNew()) {
179 return thisNode;
180 }
181
182 auto upmostNode = AddDefinesToGraph(thisNode, fDefines, prevColumns);
183
184 // Keep track of the columns defined up to this point.
185 thisNode->AddDefinedColumns(fDefines.GetNames());
186
187 upmostNode->SetPrevNode(prevNode);
188 return thisNode;
189 }
190};
191
192} // ns RDF
193} // ns Detail
194} // ns ROOT
195
196#endif // ROOT_RFILTER
ROOT::R::TRInterface & r
Definition Object.C:4
#define f(i)
Definition RSha256.hxx:104
long long Long64_t
Definition RtypesCore.h:73
#define R__ASSERT(e)
Definition TError.h:120
const char * filters[]
char name[80]
Definition TGX11.cxx:110
typedef void((*Func_t)())
void StopProcessing() final
Definition RFilter.hxx:129
std::vector< std::array< std::unique_ptr< RColumnReaderBase >, ColumnTypes_t::list_size > > fValues
Column readers per slot and per input column.
Definition RFilter.hxx:62
void PartialReport(ROOT::RDF::RCutFlowReport &rep) const final
Definition RFilter.hxx:123
void Report(ROOT::RDF::RCutFlowReport &rep) const final
Definition RFilter.hxx:121
bool CheckFilterHelper(unsigned int slot, Long64_t entry, TypeList< ColTypes... >, std::index_sequence< S... >)
Definition RFilter.hxx:103
const std::shared_ptr< PrevDataFrame > fPrevDataPtr
Definition RFilter.hxx:59
void AddFilterName(std::vector< std::string > &filters)
Definition RFilter.hxx:150
virtual void FinaliseSlot(unsigned int slot) final
Clean-up operations to be performed at the end of a task.
Definition RFilter.hxx:158
void IncrChildrenCount() final
Definition RFilter.hxx:136
void InitSlot(TTreeReader *r, unsigned int slot) final
Definition RFilter.hxx:111
RFilter & operator=(const RFilter &)=delete
RFilter(FilterF f, const ColumnNames_t &columns, std::shared_ptr< PrevDataFrame > pd, const RDFInternal::RBookedDefines &defines, std::string_view name="")
Definition RFilter.hxx:67
void TriggerChildrenCount() final
Definition RFilter.hxx:144
typename CallableTraits< FilterF >::arg_types ColumnTypes_t
Definition RFilter.hxx:54
const ColumnNames_t fColumnNames
Definition RFilter.hxx:58
std::array< bool, ColumnTypes_t::list_size > fIsDefine
The nth flag signals whether the nth input column is a custom column or not.
Definition RFilter.hxx:64
bool CheckFilters(unsigned int slot, Long64_t entry) final
Definition RFilter.hxx:84
RFilter(const RFilter &)=delete
std::make_index_sequence< ColumnTypes_t::list_size > TypeInd_t
Definition RFilter.hxx:55
PrevDataFrame & fPrevData
Definition RFilter.hxx:60
std::shared_ptr< RDFGraphDrawing::GraphNode > GetGraph()
Definition RFilter.hxx:167
Encapsulates the columns defined by the user.
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
Definition TTreeReader.h:44
std::vector< std::string > ColumnNames_t
std::shared_ptr< GraphNode > AddDefinesToGraph(std::shared_ptr< GraphNode > node, const RDFInternal::RBookedDefines &defines, const std::vector< std::string > &prevNodeDefines)
Add the Defines that have been added between this node and the previous to the graph.
std::shared_ptr< GraphNode > CreateFilterNode(const ROOT::Detail::RDF::RFilterBase *filterPtr)
std::array< std::unique_ptr< RDFDetail::RColumnReaderBase >, sizeof...(ColTypes)> MakeColumnReaders(unsigned int slot, TTreeReader *r, TypeList< ColTypes... >, const RColumnReadersInfo &colInfo)
Create a group of column readers, one per type in the parameter pack.
ROOT type_traits extensions.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Extract types from the signature of a callable object. See CallableTraits.
This type aggregates some of the arguments passed to InitColumnReaders.
Lightweight storage for a collection of types.