Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RDFUtils.cxx
Go to the documentation of this file.
1// Author: Enrico Guiraud, Danilo Piparo CERN 03/2017
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#include "RConfigure.h" // R__USE_IMT
12#include "ROOT/RDataSource.hxx"
15#include "ROOT/RDF/RSample.hxx"
17#include "ROOT/RDF/Utils.hxx"
18#include "ROOT/RLogger.hxx"
19#include "RtypesCore.h"
20#include "TBranch.h"
21#include "TBranchElement.h"
22#include "TClass.h"
23#include "TClassEdit.h"
24#include "TClassRef.h"
25#include "TError.h" // Info
26#include "TInterpreter.h"
27#include "TLeaf.h"
28#include "TROOT.h" // IsImplicitMTEnabled, GetThreadPoolSize
29#include "TTree.h"
30
31#include <fstream>
32#include <nlohmann/json.hpp> // nlohmann::json::parse
33#include <stdexcept>
34#include <string>
35#include <cstring>
36#include <typeinfo>
37
38using namespace ROOT::Detail::RDF;
39using namespace ROOT::RDF;
40
42{
43 static RLogChannel c("ROOT.RDF");
44 return c;
45}
46
47namespace {
48using TypeInfoRef = std::reference_wrapper<const std::type_info>;
49struct TypeInfoRefHash {
50 std::size_t operator()(TypeInfoRef id) const { return id.get().hash_code(); }
51};
52
53struct TypeInfoRefEqualComp {
54 bool operator()(TypeInfoRef left, TypeInfoRef right) const { return left.get() == right.get(); }
55};
56} // namespace
57
58namespace ROOT {
59namespace Internal {
60namespace RDF {
61
62/// Return the type_info associated to a name. If the association fails, an
63/// exception is thrown.
64/// References and pointers are not supported since those cannot be stored in
65/// columns.
66const std::type_info &TypeName2TypeID(const std::string &name)
67{
68
69 const static std::unordered_map<std::string, TypeInfoRef> typeName2TypeIDMap{
70 {"char", typeid(char)},
71 {"Char_t", typeid(char)},
72 {"unsigned char", typeid(unsigned char)},
73 {"UChar_t", typeid(unsigned char)},
74 {"int", typeid(int)},
75 {"Int_t", typeid(int)},
76 {"unsigned", typeid(unsigned int)},
77 {"unsigned int", typeid(unsigned int)},
78 {"UInt_t", typeid(unsigned int)},
79 {"short", typeid(short)},
80 {"short int", typeid(short)},
81 {"Short_t", typeid(short)},
82 {"unsigned short", typeid(unsigned short)},
83 {"unsigned short int", typeid(unsigned short)},
84 {"UShort_t", typeid(unsigned short)},
85 {"long", typeid(long)},
86 {"long int", typeid(long)},
87 {"Long_t", typeid(long)},
88 {"unsigned long", typeid(unsigned long)},
89 {"unsigned long int", typeid(unsigned long)},
90 {"ULong_t", typeid(unsigned long)},
91 {"double", typeid(double)},
92 {"Double_t", typeid(double)},
93 {"float", typeid(float)},
94 {"Float_t", typeid(float)},
95 {"long long", typeid(long long)},
96 {"long long int", typeid(long long)},
97 {"Long64_t", typeid(long long)},
98 {"unsigned long long", typeid(unsigned long long)},
99 {"unsigned long long int", typeid(unsigned long long)},
100 {"ULong64_t", typeid(unsigned long long)},
101 {"bool", typeid(bool)},
102 {"Bool_t", typeid(bool)}};
103
104 if (auto it = typeName2TypeIDMap.find(name); it != typeName2TypeIDMap.end())
105 return it->second.get();
106
107 if (auto c = TClass::GetClass(name.c_str())) {
108 if (!c->GetTypeInfo()) {
109 throw std::runtime_error("Cannot extract type_info of type " + name + ".");
110 }
111 return *c->GetTypeInfo();
112 }
113
114 throw std::runtime_error("Cannot extract type_info of type " + name + ".");
115}
116
117/// Returns the name of a type starting from its type_info
118/// An empty string is returned in case of failure
119/// References and pointers are not supported since those cannot be stored in
120/// columns.
121/// Note that this function will take a lock and may be a potential source of
122/// contention in multithreaded execution.
123std::string TypeID2TypeName(const std::type_info &id)
124{
125 const static std::unordered_map<TypeInfoRef, std::string, TypeInfoRefHash, TypeInfoRefEqualComp> typeID2TypeNameMap{
126 {typeid(char), "char"}, {typeid(unsigned char), "unsigned char"},
127 {typeid(int), "int"}, {typeid(unsigned int), "unsigned int"},
128 {typeid(short), "short"}, {typeid(unsigned short), "unsigned short"},
129 {typeid(long), "long"}, {typeid(unsigned long), "unsigned long"},
130 {typeid(double), "double"}, {typeid(float), "float"},
131 {typeid(Long64_t), "Long64_t"}, {typeid(ULong64_t), "ULong64_t"},
132 {typeid(bool), "bool"}};
133
134 if (auto it = typeID2TypeNameMap.find(id); it != typeID2TypeNameMap.end())
135 return it->second;
136
137 if (auto c = TClass::GetClass(id)) {
138 return c->GetName();
139 }
140
141 return "";
142}
143
144std::string ComposeRVecTypeName(const std::string &valueType)
145{
146 return "ROOT::VecOps::RVec<" + valueType + ">";
147}
148
149std::string GetLeafTypeName(TLeaf *leaf, const std::string &colName)
150{
151 const char *colTypeCStr = leaf->GetTypeName();
152 std::string colType = colTypeCStr == nullptr ? "" : colTypeCStr;
153 if (colType.empty())
154 throw std::runtime_error("Could not deduce type of leaf " + colName);
155 if (leaf->GetLeafCount() != nullptr && leaf->GetLenStatic() == 1) {
156 // this is a variable-sized array
158 } else if (leaf->GetLeafCount() == nullptr && leaf->GetLenStatic() > 1) {
159 // this is a fixed-sized array (we do not differentiate between variable- and fixed-sized arrays)
161 } else if (leaf->GetLeafCount() != nullptr && leaf->GetLenStatic() > 1) {
162 // we do not know how to deal with this branch
163 throw std::runtime_error("TTree leaf " + colName +
164 " has both a leaf count and a static length. This is not supported.");
165 }
166
167 return colType;
168}
169
170/// Return the typename of object colName stored in t, if any. Return an empty string if colName is not in t.
171/// Supported cases:
172/// - leaves corresponding to single values, variable- and fixed-length arrays, with following syntax:
173/// - "leafname", as long as TTree::GetLeaf resolves it
174/// - "b1.b2...leafname", as long as TTree::GetLeaf("b1.b2....", "leafname") resolves it
175/// - TBranchElements, as long as TTree::GetBranch resolves their names
176std::string GetBranchOrLeafTypeName(TTree &t, const std::string &colName)
177{
178 // look for TLeaf either with GetLeaf(colName) or with GetLeaf(branchName, leafName) (splitting on last dot)
179 auto *leaf = t.GetLeaf(colName.c_str());
180 if (!leaf)
181 leaf = t.FindLeaf(colName.c_str()); // try harder
182 if (!leaf) {
183 // try splitting branchname and leafname
184 const auto dotPos = colName.find_last_of('.');
185 const auto hasDot = dotPos != std::string::npos;
186 if (hasDot) {
187 const auto branchName = colName.substr(0, dotPos);
188 const auto leafName = colName.substr(dotPos + 1);
189 leaf = t.GetLeaf(branchName.c_str(), leafName.c_str());
190 }
191 }
192 if (leaf)
193 return GetLeafTypeName(leaf, std::string(leaf->GetFullName()));
194
195 // we could not find a leaf named colName, so we look for a branch called like this
196 auto branch = t.GetBranch(colName.c_str());
197 if (!branch)
198 branch = t.FindBranch(colName.c_str()); // try harder
199 if (branch) {
200 static const TClassRef tbranchelement("TBranchElement");
201 if (branch->InheritsFrom(tbranchelement)) {
202 auto be = static_cast<TBranchElement *>(branch);
203 if (auto currentClass = be->GetCurrentClass())
204 return currentClass->GetName();
205 else {
206 // Here we have a special case for getting right the type of data members
207 // of classes sorted in TClonesArrays: ROOT-9674
208 auto mother = be->GetMother();
209 if (mother && mother->InheritsFrom(tbranchelement) && mother != be) {
210 auto beMom = static_cast<TBranchElement *>(mother);
211 auto beMomClass = beMom->GetClass();
212 if (beMomClass && 0 == std::strcmp("TClonesArray", beMomClass->GetName()))
213 return be->GetTypeName();
214 }
215 return be->GetClassName();
216 }
217 } else if (branch->IsA() == TBranch::Class() && branch->GetListOfLeaves()->GetEntriesUnsafe() == 1) {
218 // normal branch (not a TBranchElement): if it has only one leaf, we pick the type of the leaf:
219 // RDF and TTreeReader allow referring to branch.leaf as just branch if branch has only one leaf
220 leaf = static_cast<TLeaf *>(branch->GetListOfLeaves()->UncheckedAt(0));
221 return GetLeafTypeName(leaf, std::string(leaf->GetFullName()));
222 }
223 }
224
225 // we could not find a branch or a leaf called colName
226 return std::string();
227}
228
229/// Return a string containing the type of the given branch. Works both with real TTree branches and with temporary
230/// column created by Define. Throws if type name deduction fails.
231/// Note that for fixed- or variable-sized c-style arrays the returned type name will be RVec<T>.
232/// vector2RVec specifies whether typename 'std::vector<T>' should be converted to 'RVec<T>' or returned as is
233std::string ColumnName2ColumnTypeName(const std::string &colName, TTree *tree, RDataSource *ds, RDefineBase *define,
234 bool vector2RVec)
235{
236 std::string colType;
237
238 // must check defines first: we want Redefines to have precedence over everything else
239 if (define) {
240 colType = define->GetTypeName();
241 } else if (ds && ds->HasColumn(colName)) {
243 } else if (tree) {
246 std::vector<std::string> split;
247 int dummy;
248 TClassEdit::GetSplit(colType.c_str(), split, dummy);
249 auto &valueType = split[1];
251 }
252 }
253
254 if (colType.empty())
255 throw std::runtime_error("Column \"" + colName +
256 "\" is not in a dataset and is not a custom column been defined.");
257
258 return colType;
259}
260
261/// Convert type name (e.g. "Float_t") to ROOT type code (e.g. 'F') -- see TBranch documentation.
262/// Return a space ' ' in case no match was found.
263char TypeName2ROOTTypeName(const std::string &b)
264{
265 const static std::unordered_map<std::string, char> typeName2ROOTTypeNameMap{{"char", 'B'},
266 {"Char_t", 'B'},
267 {"unsigned char", 'b'},
268 {"UChar_t", 'b'},
269 {"int", 'I'},
270 {"Int_t", 'I'},
271 {"unsigned", 'i'},
272 {"unsigned int", 'i'},
273 {"UInt_t", 'i'},
274 {"short", 'S'},
275 {"short int", 'S'},
276 {"Short_t", 'S'},
277 {"unsigned short", 's'},
278 {"unsigned short int", 's'},
279 {"UShort_t", 's'},
280 {"long", 'G'},
281 {"long int", 'G'},
282 {"Long_t", 'G'},
283 {"unsigned long", 'g'},
284 {"unsigned long int", 'g'},
285 {"ULong_t", 'g'},
286 {"double", 'D'},
287 {"Double_t", 'D'},
288 {"float", 'F'},
289 {"Float_t", 'F'},
290 {"long long", 'L'},
291 {"long long int", 'L'},
292 {"Long64_t", 'L'},
293 {"unsigned long long", 'l'},
294 {"unsigned long long int", 'l'},
295 {"ULong64_t", 'l'},
296 {"bool", 'O'},
297 {"Bool_t", 'O'}};
298
299 if (auto it = typeName2ROOTTypeNameMap.find(b); it != typeName2ROOTTypeNameMap.end())
300 return it->second;
301
302 return ' ';
303}
304
305unsigned int GetNSlots()
306{
307 unsigned int nSlots = 1;
308#ifdef R__USE_IMT
311#endif // R__USE_IMT
312 return nSlots;
313}
314
315/// Replace occurrences of '.' with '_' in each string passed as argument.
316/// An Info message is printed when this happens. Dots at the end of the string are not replaced.
317/// An exception is thrown in case the resulting set of strings would contain duplicates.
318std::vector<std::string> ReplaceDotWithUnderscore(const std::vector<std::string> &columnNames)
319{
321 for (auto &col : newColNames) {
322 const auto dotPos = col.find('.');
323 if (dotPos != std::string::npos && dotPos != col.size() - 1 && dotPos != 0u) {
324 auto oldName = col;
325 std::replace(col.begin(), col.end(), '.', '_');
326 if (std::find(columnNames.begin(), columnNames.end(), col) != columnNames.end())
327 throw std::runtime_error("Column " + oldName + " would be written as " + col +
328 " but this column already exists. Please use Alias to select a new name for " +
329 oldName);
330 Info("Snapshot", "Column %s will be saved as %s", oldName.c_str(), col.c_str());
331 }
332 }
333
334 return newColNames;
335}
336
337void InterpreterDeclare(const std::string &code)
338{
339 R__LOG_DEBUG(10, RDFLogChannel()) << "Declaring the following code to cling:\n\n" << code << '\n';
340
341 if (!gInterpreter->Declare(code.c_str())) {
342 const auto msg =
343 "\nRDataFrame: An error occurred during just-in-time compilation. The lines above might indicate the cause of "
344 "the crash\n All RDF objects that have not run an event loop yet should be considered in an invalid state.\n";
345 throw std::runtime_error(msg);
346 }
347}
348
349void InterpreterCalc(const std::string &code, const std::string &context)
350{
351 if (code.empty())
352 return;
353
354 R__LOG_DEBUG(10, RDFLogChannel()) << "Jitting and executing the following code:\n\n" << code << '\n';
355
356 TInterpreter::EErrorCode errorCode(TInterpreter::kNoError); // storage for cling errors
357
358 auto callCalc = [&errorCode, &context](const std::string &codeSlice) {
359 gInterpreter->Calc(codeSlice.c_str(), &errorCode);
361 std::string msg = "\nAn error occurred during just-in-time compilation";
362 if (!context.empty())
363 msg += " in " + context;
364 msg +=
365 ". The lines above might indicate the cause of the crash\nAll RDF objects that have not run their event "
366 "loop yet should be considered in an invalid state.\n";
367 throw std::runtime_error(msg);
368 }
369 };
370
371 // Call Calc every 1000 newlines in order to avoid jitting a very large function body, which is slow:
372 // see https://github.com/root-project/root/issues/9312 and https://github.com/root-project/root/issues/7604
373 std::size_t substr_start = 0;
374 std::size_t substr_end = 0;
375 while (substr_end != std::string::npos && substr_start != code.size() - 1) {
376 for (std::size_t i = 0u; i < 1000u && substr_end != std::string::npos; ++i) {
377 substr_end = code.find('\n', substr_end + 1);
378 }
379 const std::string subs = code.substr(substr_start, substr_end - substr_start);
381
382 callCalc(subs);
383 }
384}
385
386bool IsInternalColumn(std::string_view colName)
387{
388 const auto str = colName.data();
389 const auto goodPrefix = colName.size() > 3 && // has at least more characters than {r,t}df
390 ('r' == str[0] || 't' == str[0]) && // starts with r or t
391 0 == strncmp("df", str + 1, 2); // 2nd and 3rd letters are df
392 return goodPrefix && '_' == colName.back(); // also ends with '_'
393}
394
395unsigned int GetColumnWidth(const std::vector<std::string>& names, const unsigned int minColumnSpace)
396{
397 auto columnWidth = 0u;
398 for (const auto& name : names) {
399 const auto length = name.length();
400 if (length > columnWidth)
402 }
404 return columnWidth;
405}
406
407void CheckReaderTypeMatches(const std::type_info &colType, const std::type_info &requestedType,
408 const std::string &colName)
409{
410 // We want to explicitly support the reading of bools as unsigned char, as
411 // this is quite common to circumvent the std::vector<bool> specialization.
412 const bool explicitlySupported = (colType == typeid(bool) && requestedType == typeid(unsigned char)) ? true : false;
413
414 // Here we compare names and not typeinfos since they may come from two different contexts: a compiled
415 // and a jitted one.
416 const auto diffTypes = (0 != std::strcmp(colType.name(), requestedType.name()));
417 auto inheritedType = [&]() {
419 return colTClass && colTClass->InheritsFrom(TClass::GetClass(requestedType));
420 };
421
423 const auto tName = TypeID2TypeName(requestedType);
424 const auto colTypeName = TypeID2TypeName(colType);
425 std::string errMsg = "RDataFrame: type mismatch: column \"" + colName + "\" is being used as ";
426 if (tName.empty()) {
427 errMsg += requestedType.name();
428 errMsg += " (extracted from type info)";
429 } else {
430 errMsg += tName;
431 }
432 errMsg += " but the Define or Vary node advertises it as ";
433 if (colTypeName.empty()) {
434 auto &id = colType;
435 errMsg += id.name();
436 errMsg += " (extracted from type info)";
437 } else {
439 }
440 throw std::runtime_error(errMsg);
441 }
442}
443
444bool IsStrInVec(const std::string &str, const std::vector<std::string> &vec)
445{
446 return std::find(vec.cbegin(), vec.cend(), str) != vec.cend();
447}
448
449auto RStringCache::Insert(const std::string &string) -> decltype(fStrings)::const_iterator
450{
451 {
452 std::shared_lock l{fMutex};
453 if (auto it = fStrings.find(string); it != fStrings.end())
454 return it;
455 }
456
457 // TODO: Would be nicer to use a lock upgrade strategy a-la TVirtualRWMutex
458 // but that is unfortunately not usable outside the already available ROOT mutexes
459 std::unique_lock l{fMutex};
460 if (auto it = fStrings.find(string); it != fStrings.end())
461 return it;
462
463 return fStrings.insert(string).first;
464}
465
467{
468 const nlohmann::ordered_json fullData = nlohmann::ordered_json::parse(std::ifstream(jsonFile));
469 if (!fullData.contains("samples") || fullData["samples"].empty()) {
470 throw std::runtime_error(
471 R"(The input specification does not contain any samples. Please provide the samples in the specification like:
472{
473 "samples": {
474 "sampleA": {
475 "trees": ["tree1", "tree2"],
476 "files": ["file1.root", "file2.root"],
477 "metadata": {"lumi": 1.0, }
478 },
479 "sampleB": {
480 "trees": ["tree3", "tree4"],
481 "files": ["file3.root", "file4.root"],
482 "metadata": {"lumi": 0.5, }
483 },
484 ...
485 },
486})");
487 }
488
490 for (const auto &keyValue : fullData["samples"].items()) {
491 const std::string &sampleName = keyValue.key();
492 const auto &sample = keyValue.value();
493 // TODO: if requested in https://github.com/root-project/root/issues/11624
494 // allow union-like types for trees and files, see: https://github.com/nlohmann/json/discussions/3815
495 if (!sample.contains("trees")) {
496 throw std::runtime_error("A list of tree names must be provided for sample " + sampleName + ".");
497 }
498 std::vector<std::string> trees = sample["trees"];
499 if (!sample.contains("files")) {
500 throw std::runtime_error("A list of files must be provided for sample " + sampleName + ".");
501 }
502 std::vector<std::string> files = sample["files"];
503 if (!sample.contains("metadata")) {
505 } else {
507 for (const auto &metadata : sample["metadata"].items()) {
508 const auto &val = metadata.value();
509 if (val.is_string())
510 m.Add(metadata.key(), val.get<std::string>());
511 else if (val.is_number_integer())
512 m.Add(metadata.key(), val.get<int>());
513 else if (val.is_number_float())
514 m.Add(metadata.key(), val.get<double>());
515 else
516 throw std::logic_error("The metadata keys can only be of type [string|int|double].");
517 }
519 }
520 }
521 if (fullData.contains("friends")) {
522 for (const auto &friends : fullData["friends"].items()) {
523 std::string alias = friends.key();
524 std::vector<std::string> trees = friends.value()["trees"];
525 std::vector<std::string> files = friends.value()["files"];
526 if (files.size() != trees.size() && trees.size() > 1)
527 throw std::runtime_error("Mismatch between trees and files in a friend.");
528 spec.WithGlobalFriends(trees, files, alias);
529 }
530 }
531
532 if (fullData.contains("range")) {
533 std::vector<int> range = fullData["range"];
534
535 if (range.size() == 1)
536 spec.WithGlobalRange({range[0]});
537 else if (range.size() == 2)
538 spec.WithGlobalRange({range[0], range[1]});
539 }
540 return spec;
541};
542
543} // end NS RDF
544} // end NS Internal
545} // end NS ROOT
546
547std::string
552
554{
555 return df.GetTopLevelFieldNames();
556}
557
559{
560 return df.GetColumnNamesNoDuplicates();
561}
562
568
570{
571 return ds.DescribeDataset();
572}
573
576 const std::unordered_map<std::string, ROOT::RDF::Experimental::RSample *> &sampleMap)
577{
578 return ds.CreateSampleInfo(sampleMap);
579}
580
585
590
591std::unique_ptr<ROOT::Detail::RDF::RColumnReaderBase>
593 const std::type_info &tid, TTreeReader *treeReader)
594{
595 return ds.CreateColumnReader(slot, col, tid, treeReader);
596}
597
599{
600 return std::move(spec.fSamples);
601}
#define R__LOG_DEBUG(DEBUGLEVEL,...)
Definition RLogger.hxx:360
#define b(i)
Definition RSha256.hxx:100
#define c(i)
Definition RSha256.hxx:101
long long Long64_t
Definition RtypesCore.h:69
unsigned long long ULong64_t
Definition RtypesCore.h:70
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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 Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
char name[80]
Definition TGX11.cxx:110
#define gInterpreter
TRObject operator()(const T1 &t1) const
std::string GetTypeName() const
The head node of a RDF computation graph.
auto Insert(const std::string &string) -> decltype(fStrings)::const_iterator
Inserts the input string in the cache and returns an iterator to the cached string.
Definition RDFUtils.cxx:449
The dataset specification for RDataFrame.
Class behaving as a heterogenuous dictionary to store the metadata of a dataset.
Definition RMetaData.hxx:57
Class representing a sample which is a grouping of trees and their fileglobs, and,...
Definition RSample.hxx:39
RDataSource defines an API that RDataFrame can use to read arbitrary data formats.
virtual const std::vector< std::string > & GetColumnNamesNoDuplicates() const
virtual std::string GetTypeNameWithOpts(std::string_view colName, bool) const
virtual const std::vector< std::string > & GetTopLevelFieldNames() const
This type represents a sample identifier, to be used in conjunction with RDataFrame features such as ...
A log configuration for a channel, e.g.
Definition RLogger.hxx:98
const_iterator begin() const
const_iterator end() const
A Branch for the case of an object.
static TClass * Class()
TClassRef is used to implement a permanent reference to a TClass object.
Definition TClassRef.h:29
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition TClass.cxx:3074
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition TLeaf.h:57
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
Definition TTreeReader.h:46
A TTree represents a columnar dataset.
Definition TTree.h:84
virtual TBranch * FindBranch(const char *name)
Return the branch that correspond to the path 'branchname', which can include the name of the tree or...
Definition TTree.cxx:4846
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
Definition TTree.cxx:5299
virtual TLeaf * GetLeaf(const char *branchname, const char *leafname)
Return pointer to the 1st Leaf named name in any Branch of this Tree or any branch in the list of fri...
Definition TTree.cxx:6205
virtual TLeaf * FindLeaf(const char *name)
Find leaf..
Definition TTree.cxx:4921
std::ostream & Info()
Definition hadd.cxx:171
ROOT::RLogChannel & RDFLogChannel()
Definition RDFUtils.cxx:41
void RunFinalChecks(const ROOT::RDF::RDataSource &ds, bool nodesLeftNotRun)
Definition RDFUtils.cxx:581
std::vector< std::string > ReplaceDotWithUnderscore(const std::vector< std::string > &columnNames)
Replace occurrences of '.
Definition RDFUtils.cxx:318
const std::type_info & TypeName2TypeID(const std::string &name)
Return the type_info associated to a name.
Definition RDFUtils.cxx:66
ROOT::RDF::Experimental::RDatasetSpec RetrieveSpecFromJson(const std::string &jsonFile)
Function to retrieve RDatasetSpec from JSON file provided.
Definition RDFUtils.cxx:466
unsigned int GetNSlots()
Definition RDFUtils.cxx:305
std::string ComposeRVecTypeName(const std::string &valueType)
Definition RDFUtils.cxx:144
void CallInitializeWithOpts(ROOT::RDF::RDataSource &ds, const std::set< std::string > &suppressErrorsForMissingColumns)
Definition RDFUtils.cxx:563
std::string GetLeafTypeName(TLeaf *leaf, const std::string &colName)
Definition RDFUtils.cxx:149
const std::vector< std::string > & GetTopLevelFieldNames(const ROOT::RDF::RDataSource &ds)
Definition RDFUtils.cxx:553
char TypeName2ROOTTypeName(const std::string &b)
Convert type name (e.g.
Definition RDFUtils.cxx:263
std::string TypeID2TypeName(const std::type_info &id)
Returns the name of a type starting from its type_info An empty string is returned in case of failure...
Definition RDFUtils.cxx:123
bool IsStrInVec(const std::string &str, const std::vector< std::string > &vec)
Definition RDFUtils.cxx:444
unsigned int GetColumnWidth(const std::vector< std::string > &names, const unsigned int minColumnSpace=8u)
Get optimal column width for printing a table given the names and the desired minimal space between c...
Definition RDFUtils.cxx:395
std::string GetBranchOrLeafTypeName(TTree &t, const std::string &colName)
Return the typename of object colName stored in t, if any.
Definition RDFUtils.cxx:176
std::string DescribeDataset(ROOT::RDF::RDataSource &ds)
Definition RDFUtils.cxx:569
ROOT::RDF::RSampleInfo CreateSampleInfo(const ROOT::RDF::RDataSource &ds, const std::unordered_map< std::string, ROOT::RDF::Experimental::RSample * > &sampleMap)
Definition RDFUtils.cxx:574
std::unique_ptr< ROOT::Detail::RDF::RColumnReaderBase > CreateColumnReader(ROOT::RDF::RDataSource &ds, unsigned int slot, std::string_view col, const std::type_info &tid, TTreeReader *treeReader)
Definition RDFUtils.cxx:592
std::string ColumnName2ColumnTypeName(const std::string &colName, TTree *, RDataSource *, RDefineBase *, bool vector2RVec=true)
Return a string containing the type of the given branch.
Definition RDFUtils.cxx:233
void InterpreterCalc(const std::string &code, const std::string &context="")
Jit code in the interpreter with TInterpreter::Calc, throw in case of errors.
Definition RDFUtils.cxx:349
void CheckReaderTypeMatches(const std::type_info &colType, const std::type_info &requestedType, const std::string &colName)
Definition RDFUtils.cxx:407
bool IsInternalColumn(std::string_view colName)
Whether custom column with name colName is an "internal" column such as rdfentry_ or rdfslot_.
Definition RDFUtils.cxx:386
std::vector< ROOT::RDF::Experimental::RSample > MoveOutSamples(ROOT::RDF::Experimental::RDatasetSpec &spec)
Definition RDFUtils.cxx:598
void ProcessMT(ROOT::RDF::RDataSource &ds, ROOT::Detail::RDF::RLoopManager &lm)
Definition RDFUtils.cxx:586
std::string GetTypeNameWithOpts(const ROOT::RDF::RDataSource &ds, std::string_view colName, bool vector2RVec)
Definition RDFUtils.cxx:548
void InterpreterDeclare(const std::string &code)
Declare code in the interpreter via the TInterpreter::Declare method, throw in case of errors.
Definition RDFUtils.cxx:337
const std::vector< std::string > & GetColumnNamesNoDuplicates(const ROOT::RDF::RDataSource &ds)
Definition RDFUtils.cxx:558
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Bool_t IsImplicitMTEnabled()
Returns true if the implicit multi-threading in ROOT is enabled.
Definition TROOT.cxx:595
UInt_t GetThreadPoolSize()
Returns the size of ROOT's thread pool.
Definition TROOT.cxx:602
@ kSTLvector
Definition ESTLType.h:30
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container code of cont...
int GetSplit(const char *type, std::vector< std::string > &output, int &nestedLoc, EModType mode=TClassEdit::kNone)
Stores in output (after emptying it) the split type.
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4