11#include "RConfigure.h"
44using TypeInfoRef = std::reference_wrapper<const std::type_info>;
45struct TypeInfoRefHash {
46 std::size_t
operator()(TypeInfoRef
id)
const {
return id.get().hash_code(); }
49struct TypeInfoRefEqualComp {
50 bool operator()(TypeInfoRef left, TypeInfoRef right)
const {
return left.get() == right.get(); }
65 const static std::unordered_map<std::string, TypeInfoRef> typeName2TypeIDMap{
66 {
"char",
typeid(char)},
67 {
"Char_t",
typeid(char)},
68 {
"unsigned char",
typeid(
unsigned char)},
69 {
"UChar_t",
typeid(
unsigned char)},
71 {
"Int_t",
typeid(
int)},
72 {
"unsigned",
typeid(
unsigned int)},
73 {
"unsigned int",
typeid(
unsigned int)},
74 {
"UInt_t",
typeid(
unsigned int)},
75 {
"short",
typeid(short)},
76 {
"short int",
typeid(short)},
77 {
"Short_t",
typeid(short)},
78 {
"unsigned short",
typeid(
unsigned short)},
79 {
"unsigned short int",
typeid(
unsigned short)},
80 {
"UShort_t",
typeid(
unsigned short)},
81 {
"long",
typeid(long)},
82 {
"long int",
typeid(long)},
83 {
"Long_t",
typeid(long)},
84 {
"unsigned long",
typeid(
unsigned long)},
85 {
"unsigned long int",
typeid(
unsigned long)},
86 {
"ULong_t",
typeid(
unsigned long)},
87 {
"double",
typeid(
double)},
88 {
"Double_t",
typeid(
double)},
89 {
"float",
typeid(float)},
90 {
"Float_t",
typeid(float)},
91 {
"long long",
typeid(
long long)},
92 {
"long long int",
typeid(
long long)},
93 {
"Long64_t",
typeid(
long long)},
94 {
"unsigned long long",
typeid(
unsigned long long)},
95 {
"unsigned long long int",
typeid(
unsigned long long)},
96 {
"ULong64_t",
typeid(
unsigned long long)},
97 {
"bool",
typeid(
bool)},
98 {
"Bool_t",
typeid(
bool)}};
100 if (
auto it = typeName2TypeIDMap.find(
name); it != typeName2TypeIDMap.end())
101 return it->second.get();
104 if (!
c->GetTypeInfo()) {
105 throw std::runtime_error(
"Cannot extract type_info of type " +
name +
".");
107 return *
c->GetTypeInfo();
110 throw std::runtime_error(
"Cannot extract type_info of type " +
name +
".");
121 const static std::unordered_map<TypeInfoRef, std::string, TypeInfoRefHash, TypeInfoRefEqualComp> typeID2TypeNameMap{
122 {
typeid(char),
"char"}, {
typeid(
unsigned char),
"unsigned char"},
123 {
typeid(
int),
"int"}, {
typeid(
unsigned int),
"unsigned int"},
124 {
typeid(short),
"short"}, {
typeid(
unsigned short),
"unsigned short"},
125 {
typeid(long),
"long"}, {
typeid(
unsigned long),
"unsigned long"},
126 {
typeid(
double),
"double"}, {
typeid(float),
"float"},
128 {
typeid(
bool),
"bool"}};
130 if (
auto it = typeID2TypeNameMap.find(
id); it != typeID2TypeNameMap.end())
142 return "ROOT::VecOps::RVec<" + valueType +
">";
148 std::string colType = colTypeCStr ==
nullptr ?
"" : colTypeCStr;
150 throw std::runtime_error(
"Could not deduce type of leaf " + colName);
159 throw std::runtime_error(
"TTree leaf " + colName +
160 " has both a leaf count and a static length. This is not supported.");
175 auto *leaf = t.
GetLeaf(colName.c_str());
180 const auto dotPos = colName.find_last_of(
'.');
181 const auto hasDot = dotPos != std::string::npos;
183 const auto branchName = colName.substr(0, dotPos);
184 const auto leafName = colName.substr(dotPos + 1);
185 leaf = t.
GetLeaf(branchName.c_str(), leafName.c_str());
192 auto branch = t.
GetBranch(colName.c_str());
196 static const TClassRef tbranchelement(
"TBranchElement");
197 if (branch->InheritsFrom(tbranchelement)) {
199 if (
auto currentClass = be->GetCurrentClass())
200 return currentClass->
GetName();
204 auto mother = be->GetMother();
205 if (mother && mother->InheritsFrom(tbranchelement) && mother != be) {
207 auto beMomClass = beMom->
GetClass();
208 if (beMomClass && 0 == std::strcmp(
"TClonesArray", beMomClass->GetName()))
209 return be->GetTypeName();
211 return be->GetClassName();
213 }
else if (branch->IsA() ==
TBranch::Class() && branch->GetListOfLeaves()->GetEntriesUnsafe() == 1) {
216 leaf =
static_cast<TLeaf *
>(branch->GetListOfLeaves()->UncheckedAt(0));
222 return std::string();
237 }
else if (ds && ds->
HasColumn(colName)) {
242 std::vector<std::string> split;
245 auto &valueType = split[1];
251 throw std::runtime_error(
"Column \"" + colName +
252 "\" is not in a dataset and is not a custom column been defined.");
261 const static std::unordered_map<std::string, char> typeName2ROOTTypeNameMap{{
"char",
'B'},
263 {
"unsigned char",
'b'},
268 {
"unsigned int",
'i'},
273 {
"unsigned short",
's'},
274 {
"unsigned short int",
's'},
279 {
"unsigned long",
'g'},
280 {
"unsigned long int",
'g'},
287 {
"long long int",
'L'},
289 {
"unsigned long long",
'l'},
290 {
"unsigned long long int",
'l'},
295 if (
auto it = typeName2ROOTTypeNameMap.find(
b); it != typeName2ROOTTypeNameMap.end())
303 unsigned int nSlots = 1;
316 auto newColNames = columnNames;
317 for (
auto &col : newColNames) {
318 const auto dotPos = col.find(
'.');
319 if (dotPos != std::string::npos && dotPos != col.size() - 1 && dotPos != 0u) {
321 std::replace(col.begin(), col.end(),
'.',
'_');
322 if (std::find(columnNames.begin(), columnNames.end(), col) != columnNames.end())
323 throw std::runtime_error(
"Column " + oldName +
" would be written as " + col +
324 " but this column already exists. Please use Alias to select a new name for " +
326 Info(
"Snapshot",
"Column %s will be saved as %s", oldName.c_str(), col.c_str());
339 "\nRDataFrame: An error occurred during just-in-time compilation. The lines above might indicate the cause of "
340 "the crash\n All RDF objects that have not run an event loop yet should be considered in an invalid state.\n";
341 throw std::runtime_error(msg);
351 auto callCalc = [&errorCode, &context](
const std::string &codeSlice) {
354 std::string msg =
"\nAn error occurred during just-in-time compilation";
355 if (!context.empty())
356 msg +=
" in " + context;
358 ". The lines above might indicate the cause of the crash\nAll RDF objects that have not run their event "
359 "loop yet should be considered in an invalid state.\n";
360 throw std::runtime_error(msg);
366 std::size_t substr_start = 0;
367 std::size_t substr_end = 0;
368 while (substr_end != std::string::npos && substr_start != code.size() - 1) {
369 for (std::size_t i = 0u; i < 1000u && substr_end != std::string::npos; ++i) {
370 substr_end = code.find(
'\n', substr_end + 1);
372 const std::string subs = code.substr(substr_start, substr_end - substr_start);
373 substr_start = substr_end;
383 const auto str = colName.data();
384 const auto goodPrefix = colName.size() > 3 &&
385 (
'r' == str[0] ||
't' == str[0]) &&
386 0 == strncmp(
"df", str + 1, 2);
387 return goodPrefix &&
'_' == colName.back();
390unsigned int GetColumnWidth(
const std::vector<std::string>& names,
const unsigned int minColumnSpace)
392 auto columnWidth = 0u;
393 for (
const auto&
name : names) {
398 columnWidth = (columnWidth / minColumnSpace + 1) * minColumnSpace;
403 const std::string &colName)
407 const bool explicitlySupported = (colType ==
typeid(
bool) && requestedType ==
typeid(
unsigned char)) ?
true :
false;
411 const auto diffTypes = (0 != std::strcmp(colType.name(), requestedType.name()));
412 auto inheritedType = [&]() {
414 return colTClass && colTClass->InheritsFrom(
TClass::GetClass(requestedType));
417 if (!explicitlySupported && diffTypes && !inheritedType()) {
420 std::string errMsg =
"RDataFrame: type mismatch: column \"" + colName +
"\" is being used as ";
422 errMsg += requestedType.name();
423 errMsg +=
" (extracted from type info)";
427 errMsg +=
" but the Define or Vary node advertises it as ";
428 if (colTypeName.empty()) {
431 errMsg +=
" (extracted from type info)";
433 errMsg += colTypeName;
435 throw std::runtime_error(errMsg);
441 return std::find(
vec.cbegin(),
vec.cend(), str) !=
vec.cend();
447 std::shared_lock
l{fMutex};
448 if (
auto it = fStrings.find(
string); it != fStrings.end())
454 std::unique_lock
l{fMutex};
455 if (
auto it = fStrings.find(
string); it != fStrings.end())
458 return fStrings.insert(
string).first;
#define R__LOG_DEBUG(DEBUGLEVEL,...)
unsigned long long ULong64_t
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
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
TRObject operator()(const T1 &t1) const
std::string GetTypeName() const
A log configuration for a channel, e.g.
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.
RDataSource defines an API that RDataFrame can use to read arbitrary data formats.
virtual bool HasColumn(std::string_view colName) const =0
Checks if the dataset has a certain column.
virtual std::string GetTypeName(std::string_view colName) const =0
Type of a column as a string, e.g.
A Branch for the case of an object.
virtual TClass * GetClass() const
TClassRef is used to implement a permanent reference to a TClass object.
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.
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
virtual const char * GetTypeName() const
virtual TLeaf * GetLeafCount() const
If this leaf stores a variable-sized array or a multi-dimensional array whose last dimension has vari...
virtual Int_t GetLenStatic() const
Return the fixed length of this leaf.
const char * GetName() const override
Returns name of object.
A TTree represents a columnar dataset.
virtual TBranch * FindBranch(const char *name)
Return the branch that correspond to the path 'branchname', which can include the name of the tree or...
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
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...
virtual TLeaf * FindLeaf(const char *name)
Find leaf..
ROOT::Experimental::RLogChannel & RDFLogChannel()
std::vector< std::string > ReplaceDotWithUnderscore(const std::vector< std::string > &columnNames)
Replace occurrences of '.
const std::type_info & TypeName2TypeID(const std::string &name)
Return the type_info associated to a name.
std::string ComposeRVecTypeName(const std::string &valueType)
std::string ColumnName2ColumnTypeName(const std::string &colName, TTree *, RDataSource *, RDefineBase *, bool vector2rvec=true)
Return a string containing the type of the given branch.
std::string GetLeafTypeName(TLeaf *leaf, const std::string &colName)
char TypeName2ROOTTypeName(const std::string &b)
Convert type name (e.g.
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...
bool IsStrInVec(const std::string &str, const std::vector< std::string > &vec)
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...
std::string GetBranchOrLeafTypeName(TTree &t, const std::string &colName)
Return the typename of object colName stored in t, if any.
Long64_t InterpreterCalc(const std::string &code, const std::string &context="")
Jit code in the interpreter with TInterpreter::Calc, throw in case of errors.
void CheckReaderTypeMatches(const std::type_info &colType, const std::type_info &requestedType, const std::string &colName)
bool IsInternalColumn(std::string_view colName)
Whether custom column with name colName is an "internal" column such as rdfentry_ or rdfslot_.
void InterpreterDeclare(const std::string &code)
Declare code in the interpreter via the TInterpreter::Declare method, throw in case of errors.
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.
UInt_t GetThreadPoolSize()
Returns the size of ROOT's thread pool.
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.