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"
18 #include "ROOT/RDF/RFilterBase.hxx"
21 #include "ROOT/TypeTraits.hxx"
22 #include "RtypesCore.h"
23 
24 #include <algorithm>
25 #include <memory>
26 #include <string>
27 #include <vector>
28 
29 namespace ROOT {
30 
31 namespace Internal {
32 namespace RDF {
33 using namespace ROOT::Detail::RDF;
34 
35 // fwd decl for RFilter
36 namespace GraphDrawing {
37 std::shared_ptr<GraphNode> CreateFilterNode(const RFilterBase *filterPtr);
38 
39 std::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 
47 namespace Detail {
48 namespace RDF {
49 using namespace ROOT::TypeTraits;
51 
52 template <typename FilterF, typename PrevDataFrame>
53 class RFilter final : public RFilterBase {
54  using ColumnTypes_t = typename CallableTraits<FilterF>::arg_types;
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 
66 public:
67  RFilter(FilterF f, const ColumnNames_t &columns, std::shared_ptr<PrevDataFrame> pd,
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]) {
87  if (!fPrevData.CheckFilters(slot, entry)) {
88  // a filter upstream returned false, cache the result
89  fLastResult[slot] = false;
90  } else {
91  // evaluate this filter, cache the result
92  auto passed = CheckFilterHelper(slot, entry, ColumnTypes_t{}, TypeInd_t{});
93  passed ? ++fAccepted[slot] : ++fRejected[slot];
94  fLastResult[slot] = passed;
95  }
96  fLastCheckedEntry[slot] = entry;
97  }
98  return fLastResult[slot];
99  }
100 
101  template <typename... ColTypes, std::size_t... S>
102  bool CheckFilterHelper(unsigned int slot, Long64_t entry, TypeList<ColTypes...>, std::index_sequence<S...>)
103  {
104  // silence "unused parameter" warnings in gcc
105  (void)slot;
106  (void)entry;
107  return fFilter(fValues[slot][S]->template Get<ColTypes>(entry)...);
108  }
109 
110  void InitSlot(TTreeReader *r, unsigned int slot) final
111  {
112  for (auto &bookedBranch : fDefines.GetColumns())
113  bookedBranch.second->InitSlot(r, slot);
114  RDFInternal::RColumnReadersInfo info{fColumnNames, fDefines, fIsDefine.data(), fLoopManager->GetDSValuePtrs(),
115  fLoopManager->GetDataSource()};
116  fValues[slot] = RDFInternal::MakeColumnReaders(slot, r, ColumnTypes_t{}, info);
117  }
118 
119  // recursive chain of `Report`s
120  void Report(ROOT::RDF::RCutFlowReport &rep) const final { PartialReport(rep); }
121 
123  {
124  fPrevData.PartialReport(rep);
125  FillReport(rep);
126  }
127 
128  void StopProcessing() final
129  {
130  ++fNStopsReceived;
131  if (fNStopsReceived == fNChildren)
132  fPrevData.StopProcessing();
133  }
134 
135  void IncrChildrenCount() final
136  {
137  ++fNChildren;
138  // propagate "children activation" upstream. named filters do the propagation via `TriggerChildrenCount`.
139  if (fNChildren == 1 && fName.empty())
140  fPrevData.IncrChildrenCount();
141  }
142 
143  void TriggerChildrenCount() final
144  {
145  R__ASSERT(!fName.empty()); // this method is to only be called on named filters
146  fPrevData.IncrChildrenCount();
147  }
148 
149  void AddFilterName(std::vector<std::string> &filters)
150  {
151  fPrevData.AddFilterName(filters);
152  auto name = (HasName() ? fName : "Unnamed Filter");
153  filters.push_back(name);
154  }
155 
156  /// Clean-up operations to be performed at the end of a task.
157  virtual void FinaliseSlot(unsigned int slot) final
158  {
159  for (auto &column : fDefines.GetColumns())
160  column.second->FinaliseSlot(slot);
161 
162  for (auto &v : fValues[slot])
163  v.reset();
164  }
165 
166  std::shared_ptr<RDFGraphDrawing::GraphNode> GetGraph()
167  {
168  // Recursively call for the previous node.
169  auto prevNode = fPrevData.GetGraph();
170  auto prevColumns = prevNode->GetDefinedColumns();
171 
172  auto thisNode = RDFGraphDrawing::CreateFilterNode(this);
173 
174  /* If the returned node is not new, there is no need to perform any other operation.
175  * This is a likely scenario when building the entire graph in which branches share
176  * some nodes. */
177  if (!thisNode->GetIsNew()) {
178  return thisNode;
179  }
180 
181  auto upmostNode = AddDefinesToGraph(thisNode, fDefines, prevColumns);
182 
183  // Keep track of the columns defined up to this point.
184  thisNode->AddDefinedColumns(fDefines.GetNames());
185 
186  upmostNode->SetPrevNode(prevNode);
187  return thisNode;
188  }
189 };
190 
191 } // ns RDF
192 } // ns Detail
193 } // ns ROOT
194 
195 #endif // ROOT_RFILTER
ROOT::Detail::RDF::RFilterBase
Definition: RFilterBase.hxx:36
filters
const char * filters[]
Definition: TGFileBrowser.cxx:61
ROOT::TypeTraits
ROOT type_traits extensions.
Definition: TypeTraits.hxx:21
ROOT::Detail::RDF::RFilter::GetGraph
std::shared_ptr< RDFGraphDrawing::GraphNode > GetGraph()
Definition: RFilter.hxx:166
f
#define f(i)
Definition: RSha256.hxx:104
ROOT::Detail::RDF::RFilter::operator=
RFilter & operator=(const RFilter &)=delete
ROOT::Detail::RDF::RFilter::fPrevDataPtr
const std::shared_ptr< PrevDataFrame > fPrevDataPtr
Definition: RFilter.hxx:59
r
ROOT::R::TRInterface & r
Definition: Object.C:4
ROOT::Detail::RDF::RFilter::TriggerChildrenCount
void TriggerChildrenCount() final
Definition: RFilter.hxx:143
Long64_t
long long Long64_t
Definition: RtypesCore.h:73
string_view
basic_string_view< char > string_view
Definition: libcpp_string_view.h:785
ColumnReaderUtils.hxx
ROOT::TypeTraits::TypeList
Lightweight storage for a collection of types.
Definition: TypeTraits.hxx:25
RFilterBase.hxx
Utils.hxx
ROOT::Detail::RDF::RFilter::fPrevData
PrevDataFrame & fPrevData
Definition: RFilter.hxx:60
ROOT::Internal::RDF::RBookedDefines
Encapsulates the columns defined by the user.
Definition: RBookedDefines.hxx:39
RooFitShortHand::S
RooArgSet S(const RooAbsArg &v1)
Definition: RooGlobalFunc.cxx:354
ROOT::Detail::RDF::RFilter::fIsDefine
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
RCutFlowReport.hxx
v
@ v
Definition: rootcling_impl.cxx:3635
ROOT::Detail::RDF
Definition: GraphUtils.hxx:28
ROOT::Detail::RDF::ColumnNames_t
std::vector< std::string > ColumnNames_t
Definition: RLoopManager.hxx:53
ROOT::Detail::RDF::RFilter::StopProcessing
void StopProcessing() final
Definition: RFilter.hxx:128
ROOT::Detail::RDF::RFilter::AddFilterName
void AddFilterName(std::vector< std::string > &filters)
Definition: RFilter.hxx:149
RIntegerSequence.hxx
ROOT::Detail::RDF::RFilter::RFilter
RFilter(const RFilter &)=delete
ROOT::Internal::RDF::RColumnReadersInfo
This type aggregates some of the arguments passed to InitColumnReaders.
Definition: ColumnReaderUtils.hxx:80
ROOT::Detail::RDF::RFilter::CheckFilterHelper
bool CheckFilterHelper(unsigned int slot, Long64_t entry, TypeList< ColTypes... >, std::index_sequence< S... >)
Definition: RFilter.hxx:102
ROOT::Internal::RDF::MakeColumnReaders
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.
Definition: ColumnReaderUtils.hxx:93
ROOT::Detail::RDF::RFilter::fValues
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
ROOT::Internal::RDF::GraphDrawing
Definition: GraphNode.hxx:24
ROOT::Detail::RDF::RFilter::TypeInd_t
std::make_index_sequence< ColumnTypes_t::list_size > TypeInd_t
Definition: RFilter.hxx:55
ROOT::Detail::RDF::RFilter::PartialReport
void PartialReport(ROOT::RDF::RCutFlowReport &rep) const final
Definition: RFilter.hxx:122
ROOT::Internal::RDF::GraphDrawing::CreateFilterNode
std::shared_ptr< GraphNode > CreateFilterNode(const ROOT::Detail::RDF::RFilterBase *filterPtr)
Definition: RDFGraphUtils.cxx:108
TTreeReader
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
Definition: TTreeReader.h:44
ROOT::Internal::RDF::GraphDrawing::AddDefinesToGraph
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.
Definition: RDFGraphUtils.cxx:143
TypeTraits.hxx
ROOT::Detail::RDF::RFilter::CheckFilters
bool CheckFilters(unsigned int slot, Long64_t entry) final
Definition: RFilter.hxx:84
void
typedef void((*Func_t)())
ROOT::Detail::RDF::RFilter::RFilter
RFilter(FilterF f, const ColumnNames_t &columns, std::shared_ptr< PrevDataFrame > pd, const RDFInternal::RBookedDefines &defines, std::string_view name="")
Definition: RFilter.hxx:67
ROOT::Detail::RDF::RFilter::ColumnTypes_t
typename CallableTraits< FilterF >::arg_types ColumnTypes_t
Definition: RFilter.hxx:54
ROOT::Internal::RDF::GetNSlots
unsigned int GetNSlots()
Definition: RDFUtils.cxx:268
RtypesCore.h
R__ASSERT
#define R__ASSERT(e)
Definition: TError.h:120
ROOT::Detail::RDF::RFilter::Report
void Report(ROOT::RDF::RCutFlowReport &rep) const final
Definition: RFilter.hxx:120
ROOT::Detail::RDF::RFilter
Definition: RFilter.hxx:53
ROOT::RDF::RCutFlowReport
Definition: RCutFlowReport.hxx:47
name
char name[80]
Definition: TGX11.cxx:110
ROOT::Detail::RDF::RFilter::IncrChildrenCount
void IncrChildrenCount() final
Definition: RFilter.hxx:135
ROOT::Detail::RDF::RFilter::fColumnNames
const ColumnNames_t fColumnNames
Definition: RFilter.hxx:58
RColumnReaderBase.hxx
ROOT::Detail::RDF::RFilter::fFilter
FilterF fFilter
Definition: RFilter.hxx:57
RLoopManager.hxx
ROOT::Detail::RDF::RFilter::~RFilter
~RFilter()
Definition: RFilter.hxx:82
ROOT::Detail::RDF::RFilter::FinaliseSlot
virtual void FinaliseSlot(unsigned int slot) final
Clean-up operations to be performed at the end of a task.
Definition: RFilter.hxx:157
ROOT
VSD Structures.
Definition: StringConv.hxx:21
ROOT::Detail::RDF::RFilter::InitSlot
void InitSlot(TTreeReader *r, unsigned int slot) final
Definition: RFilter.hxx:110