Logo ROOT  
Reference Guide
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 "RLoopManager.hxx"
20#include "RTreeColumnReader.hxx"
21#include "RVariationBase.hxx"
22#include "RVariationReader.hxx"
23
24#include <ROOT/RDataSource.hxx>
25#include <ROOT/TypeTraits.hxx>
26#include <TTreeReader.h>
27
28#include <array>
29#include <cassert>
30#include <map>
31#include <memory>
32#include <string>
33#include <typeinfo> // for typeid
34#include <vector>
35
36namespace ROOT {
37namespace Internal {
38namespace RDF {
39
40using namespace ROOT::TypeTraits;
42
43template <typename T>
44std::shared_ptr<RDFDetail::RColumnReaderBase>
45MakeColumnReader(unsigned int slot, RDefineBase *define, RLoopManager &lm, TTreeReader *r, const std::string &colName,
46 RVariationBase *variation, const std::string &variationName)
47{
48 using Ret_t = std::shared_ptr<RDFDetail::RColumnReaderBase>;
49
50 // variations have precedence over everything else: if this is not null, it means we are in the
51 // universe where this variation applies.
52 if (variation != nullptr)
53 return Ret_t{new RVariationReader(slot, colName, variationName, *variation, typeid(T))};
54
55 // defines come second, so that Redefine'd columns have precedence over dataset columns
56 if (define != nullptr) {
57 if (variationName != "nominal" && IsStrInVec(variationName, define->GetVariations()))
58 define = &define->GetVariedDefine(variationName);
59 return Ret_t{new RDefineReader(slot, *define, typeid(T))};
60 }
61
62 // Check if we already inserted a reader for this column in the dataset column readers (RDataSource or Tree/TChain
63 // readers)
64 auto datasetColReader = lm.GetDatasetColumnReader(slot, colName, typeid(T));
65 if (datasetColReader != nullptr)
66 return datasetColReader;
67
68 assert(r != nullptr && "We could not find a reader for this column, this should never happen at this point.");
69
70 // Make a RTreeColumnReader for this column and insert it in RLoopManager's map
71 auto treeColReader = std::make_unique<RTreeColumnReader<T>>(*r, colName);
72 return lm.AddTreeColumnReader(slot, colName, std::move(treeColReader), typeid(T));
73}
74
75/// This type aggregates some of the arguments passed to MakeColumnReaders.
76/// We need to pass a single RColumnReadersInfo object rather than each argument separately because with too many
77/// arguments passed, gcc 7.5.0 and cling disagree on the ABI, which leads to the last function argument being read
78/// incorrectly from a compiled MakeColumnReaders symbols when invoked from a jitted symbol.
80 const std::vector<std::string> &fColNames;
82 const bool *fIsDefine;
84};
85
86/// Create a group of column readers, one per type in the parameter pack.
87template <typename... ColTypes>
88std::array<std::shared_ptr<RDFDetail::RColumnReaderBase>, sizeof...(ColTypes)>
90 const std::string &variationName = "nominal")
91{
92 // see RColumnReadersInfo for why we pass these arguments like this rather than directly as function arguments
93 const auto &colNames = colInfo.fColNames;
94 auto &lm = colInfo.fLoopManager;
95 const auto &colRegister = colInfo.fColRegister;
96
97 // the i-th element indicates whether variation variationName provides alternative values for the i-th column
98 std::array<bool, sizeof...(ColTypes)> doesVariationApply;
99 if (variationName == "nominal")
100 doesVariationApply.fill(false);
101 else {
102 for (auto i = 0u; i < sizeof...(ColTypes); ++i)
103 doesVariationApply[i] = IsStrInVec(variationName, colRegister.GetVariationsFor(colNames[i]));
104 }
105
106 int i = -1;
107 std::array<std::shared_ptr<RDFDetail::RColumnReaderBase>, sizeof...(ColTypes)> ret{
108 {{(++i, MakeColumnReader<ColTypes>(slot, colRegister.GetDefine(colNames[i]), lm, r, colNames[i],
109 doesVariationApply[i] ? &colRegister.FindVariation(colNames[i], variationName)
110 : nullptr,
111 variationName))}...}};
112 return ret;
113}
114
115// Shortcut overload for the case of no columns
116inline std::array<std::shared_ptr<RDFDetail::RColumnReaderBase>, 0>
117MakeColumnReaders(unsigned int, TTreeReader *, TypeList<>, const RColumnReadersInfo &, const std::string & = "nominal")
118{
119 return {};
120}
121
122} // namespace RDF
123} // namespace Internal
124} // namespace ROOT
125
126#endif // ROOT_RDF_COLUMNREADERS
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
const std::vector< std::string > & GetVariations() const
Definition: RDefineBase.hxx:72
virtual RDefineBase & GetVariedDefine(const std::string &variationName)=0
Return a clone of this Define that works with values in the variationName "universe".
The head node of a RDF computation graph.
std::shared_ptr< RColumnReaderBase > AddTreeColumnReader(unsigned int slot, const std::string &col, std::unique_ptr< RColumnReaderBase > &&reader, const std::type_info &ti)
Register a new RTreeColumnReader with this RLoopManager.
std::shared_ptr< RColumnReaderBase > GetDatasetColumnReader(unsigned int slot, const std::string &col, const std::type_info &ti) const
A binder for user-defined columns and aliases.
Column reader for defined (aka custom) columns.
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.
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
Definition: TTreeReader.h:44
std::array< std::shared_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.
bool IsStrInVec(const std::string &str, const std::vector< std::string > &vec)
Definition: RDFUtils.cxx:419
std::shared_ptr< RDFDetail::RColumnReaderBase > MakeColumnReader(unsigned int slot, RDefineBase *define, RLoopManager &lm, TTreeReader *r, const std::string &colName, RVariationBase *variation, const std::string &variationName)
double T(double x)
Definition: ChebyshevPol.h:34
ROOT type_traits extensions.
Definition: TypeTraits.hxx:21
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
This type aggregates some of the arguments passed to MakeColumnReaders.
const std::vector< std::string > & fColNames
Lightweight storage for a collection of types.
Definition: TypeTraits.hxx:25