Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
ColumnReaderUtils.hxx
Go to the documentation of this file.
1// Author: Enrico Guiraud CERN 09/2020
2
3/*************************************************************************
4 * Copyright (C) 1995-2020, 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_RDF_COLUMNREADERUTILS
12#define ROOT_RDF_COLUMNREADERUTILS
13
14#include "RColumnReaderBase.hxx"
15#include "RColumnRegister.hxx"
16#include "RDefineBase.hxx"
17#include "RDefineReader.hxx"
18#include "RDSColumnReader.hxx"
19#include "RTreeColumnReader.hxx"
20#include "RVariationBase.hxx"
21#include "RVariationReader.hxx"
22
23#include <ROOT/RDataSource.hxx>
24#include <ROOT/TypeTraits.hxx>
25#include <TTreeReader.h>
26
27#include <array>
28#include <cassert>
29#include <map>
30#include <memory>
31#include <string>
32#include <typeinfo> // for typeid
33#include <vector>
34
35namespace ROOT {
36namespace Internal {
37namespace RDF {
38
39using namespace ROOT::TypeTraits;
41
42template <typename T>
43std::unique_ptr<RDFDetail::RColumnReaderBase>
44MakeColumnReader(unsigned int slot, RDefineBase *define,
45 const std::map<std::string, std::vector<void *>> &DSValuePtrsMap, TTreeReader *r,
46 ROOT::RDF::RDataSource *ds, const std::string &colName, RVariationBase *variation,
47 const std::string &variationName)
48{
49 using Ret_t = std::unique_ptr<RDFDetail::RColumnReaderBase>;
50
51 // variations have precedence over everything else: if this is not null, it means we are in the
52 // universe where this variation applies.
53 if (variation != nullptr)
54 return Ret_t{new RVariationReader(slot, colName, variationName, *variation, typeid(T))};
55
56 // defines come second, so that Redefine'd columns have precedence over dataset columns
57 if (define != nullptr) {
58 if (variationName != "nominal" && IsStrInVec(variationName, define->GetVariations()))
59 define = &define->GetVariedDefine(variationName);
60 return Ret_t{new RDefineReader(slot, *define, typeid(T))};
61 }
62
63 const auto DSValuePtrsIt = DSValuePtrsMap.find(colName);
64 if (DSValuePtrsIt != DSValuePtrsMap.end()) {
65 // reading from a RDataSource with the old column reader interface
66 const std::vector<void *> &DSValuePtrs = DSValuePtrsIt->second;
67 return Ret_t(new RDSColumnReader<T>(DSValuePtrs[slot]));
68 }
69
70 if (ds != nullptr) {
71 // reading from a RDataSource with the new column reader interface
72 return ds->GetColumnReaders(slot, colName, typeid(T));
73 }
74
75 assert(r != nullptr && "We could not find a reader for this column, this should never happen at this point.");
76
77 // reading from a TTree
78 return Ret_t{new RTreeColumnReader<T>(*r, colName)};
79}
80
81/// This type aggregates some of the arguments passed to MakeColumnReaders.
82/// We need to pass a single RColumnReadersInfo object rather than each argument separately because with too many
83/// arguments passed, gcc 7.5.0 and cling disagree on the ABI, which leads to the last function argument being read
84/// incorrectly from a compiled MakeColumnReaders symbols when invoked from a jitted symbol.
86 const std::vector<std::string> &fColNames;
88 const bool *fIsDefine;
89 const std::map<std::string, std::vector<void *>> &fDSValuePtrsMap;
91};
92
93/// Create a group of column readers, one per type in the parameter pack.
94/// colInfo.fColNames and colInfo.fIsDefine are expected to have size equal to the parameter pack, and elements ordered
95/// accordingly, i.e. fIsDefine[0] refers to fColNames[0] which is of type "ColTypes[0]".
96///
97/// Pre-condition: colInfo.isDefine must not be null.
98template <typename... ColTypes>
99std::array<std::unique_ptr<RDFDetail::RColumnReaderBase>, sizeof...(ColTypes)>
101 const std::string &variationName = "nominal")
102{
103 // see RColumnReadersInfo for why we pass these arguments like this rather than directly as function arguments
104 const auto &colNames = colInfo.fColNames;
105 const auto &defines = colInfo.fCustomCols.GetColumns();
106 const bool *isDefine = colInfo.fIsDefine;
107 const auto &DSValuePtrsMap = colInfo.fDSValuePtrsMap;
108 auto *ds = colInfo.fDataSource;
109 const auto &colRegister = colInfo.fCustomCols;
110
111 // the i-th element indicates whether variation variationName provides alternative values for the i-th column
112 std::array<bool, sizeof...(ColTypes)> doesVariationApply;
113 if (variationName == "nominal")
114 doesVariationApply.fill(false);
115 else {
116 for (auto i = 0u; i < sizeof...(ColTypes); ++i)
117 doesVariationApply[i] = IsStrInVec(variationName, colRegister.GetVariationsFor(colNames[i]));
118 }
119
120 int i = -1;
121 std::array<std::unique_ptr<RDFDetail::RColumnReaderBase>, sizeof...(ColTypes)> ret{
122 {{(++i, MakeColumnReader<ColTypes>(
123 slot, isDefine[i] ? defines.at(colNames[i]).get() : nullptr, DSValuePtrsMap, r, ds, colNames[i],
124 doesVariationApply[i] ? &colRegister.FindVariation(colNames[i], variationName) : nullptr,
125 variationName))}...}};
126 return ret;
127
128 // avoid bogus "unused variable" warnings
129 (void)ds;
130 (void)slot;
131 (void)r;
132}
133
134// dummy overload for for the case of no columns, to silence compiler warnings
135inline std::array<std::unique_ptr<RDFDetail::RColumnReaderBase>, 0>
136MakeColumnReaders(unsigned int, TTreeReader *, TypeList<>, const RColumnReadersInfo &, const std::string & = "nominal")
137{
138 return {};
139}
140
141} // namespace RDF
142} // namespace Internal
143} // namespace ROOT
144
145#endif // ROOT_RDF_COLUMNREADERS
typedef void(GLAPIENTRYP _GLUfuncptr)(void)
ROOT::R::TRInterface & r
Definition Object.C:4
const std::vector< std::string > & GetVariations() const
virtual RDefineBase & GetVariedDefine(const std::string &variationName)=0
Return a clone of this Define that works with values in the variationName "universe".
A binder for user-defined columns and aliases.
const DefinesMap_t & GetColumns() const
Returns a map of pointers to the defined columns.
Column reader type that deals with values read from RDataSources.
Column reader for defined (aka custom) columns.
RTreeColumnReader specialization for TTree values read via TTreeReaderValues.
This type includes all parts of RVariation that do not depend on the callable signature.
Column reader that reads the value for a specific column, variation and slot.
RDataSource defines an API that RDataFrame can use to read arbitrary data formats.
std::vector< T ** > GetColumnReaders(std::string_view columnName)
Called at most once per column by RDF.
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
Definition TTreeReader.h:44
std::unique_ptr< RDFDetail::RColumnReaderBase > MakeColumnReader(unsigned int slot, RDefineBase *define, const std::map< std::string, std::vector< void * > > &DSValuePtrsMap, TTreeReader *r, ROOT::RDF::RDataSource *ds, const std::string &colName, RVariationBase *variation, const std::string &variationName)
bool IsStrInVec(const std::string &str, const std::vector< std::string > &vec)
Definition RDFUtils.cxx:419
std::array< std::unique_ptr< RDFDetail::RColumnReaderBase >, sizeof...(ColTypes)> MakeColumnReaders(unsigned int slot, TTreeReader *r, TypeList< ColTypes... >, const RColumnReadersInfo &colInfo, const std::string &variationName="nominal")
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...
This type aggregates some of the arguments passed to MakeColumnReaders.
const std::map< std::string, std::vector< void * > > & fDSValuePtrsMap
const std::vector< std::string > & fColNames
Lightweight storage for a collection of types.