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