30#pragma GCC diagnostic push
31#pragma GCC diagnostic ignored "-Woverloaded-virtual"
32#pragma GCC diagnostic ignored "-Wshadow"
36#pragma GCC diagnostic pop
40#include <unordered_set>
67struct ParsedExpression {
84 lexertk::generator tokens;
85 const auto tokensOk = tokens.process(expr);
87 const auto msg =
"Failed to tokenize expression:\n" + expr +
"\n\nMake sure it is valid C++.";
88 throw std::runtime_error(msg);
92 const auto nTokens = tokens.size();
93 const auto kSymbol = lexertk::token::e_symbol;
94 for (
auto i = 0u; i < nTokens; ++i) {
95 const auto &tok = tokens[i];
97 if (tok.type != kSymbol || tok.value ==
"&" || tok.value ==
"|") {
105 auto dotChainKeepsGoing = [&](
unsigned int _i) {
106 return _i + 2 <= nTokens && tokens[_i + 1].value ==
"." && tokens[_i + 2].type == kSymbol;
108 while (dotChainKeepsGoing(i)) {
109 potentialColNames.emplace_back(potentialColNames.back() +
"." + tokens[i + 2].value);
116 auto isRDFColumn = [&](
const std::string &columnOrAlias) {
117 const auto &col = customColumns.
ResolveAlias(columnOrAlias);
122 const auto longestRDFColMatch = std::find_if(potentialColNames.crbegin(), potentialColNames.crend(), isRDFColumn);
124 if (longestRDFColMatch != potentialColNames.crend() && !
IsStrInVec(*longestRDFColMatch, usedCols)) {
126 usedCols.emplace_back(*longestRDFColMatch);
138 TString preProcessedExpr(expr);
141 "(^|\\W)#(?!(ifdef|ifndef|if|else|elif|endif|pragma|define|undef|include|line))([a-zA-Z_][a-zA-Z0-9_]*)");
142 colSizeReplacer.Substitute(preProcessedExpr,
"$1R_rdf_sizeof_$3",
"g");
144 const auto usedColsAndAliases =
145 FindUsedColumns(std::string(preProcessedExpr), treeBranchNames, customColumns, dataSourceColNames);
147 auto escapeDots = [](
const std::string &
s) {
150 dot.Substitute(ss,
"\\.",
"g");
151 return std::string(std::move(ss));
158 TString exprWithVars(preProcessedExpr);
159 for (
const auto &colOrAlias : usedColsAndAliases) {
160 const auto col = customColumns.
ResolveAlias(colOrAlias);
163 usedCols.emplace_back(col);
164 varIdx = varNames.size();
165 varNames.emplace_back(
"var" + std::to_string(varIdx));
169 varIdx = std::distance(usedCols.begin(), std::find(usedCols.begin(), usedCols.end(), col));
171 TPRegexp replacer(
"\\b" + escapeDots(colOrAlias) +
"\\b");
172 replacer.Substitute(exprWithVars, varNames[varIdx],
"g");
175 return ParsedExpression{std::string(std::move(exprWithVars)), std::move(usedCols), std::move(varNames)};
185static std::unordered_map<std::string, std::string> &GetJittedExprs() {
186 static std::unordered_map<std::string, std::string> jittedExpressions;
187 return jittedExpressions;
193 assert(vars.size() == varTypes.size());
196 const bool hasReturnStmt = re.MatchB(expr);
198 static const std::vector<std::string> fundamentalTypes = {
231 std::stringstream ss;
233 for (
auto i = 0u; i < vars.size(); ++i) {
234 std::string fullType;
235 const auto &
type = varTypes[i];
236 if (std::find(fundamentalTypes.begin(), fundamentalTypes.end(),
type) != fundamentalTypes.end()) {
238 fullType =
"const " +
type +
" ";
242 fullType =
type +
"& ";
244 ss << fullType << vars[i] <<
", ";
247 ss.seekp(-2, ss.cur);
253 ss << expr <<
"\n;}";
264 const auto lambdaExpr = BuildLambdaString(expr, vars, varTypes);
265 auto &exprMap = GetJittedExprs();
266 const auto exprIt = exprMap.find(lambdaExpr);
267 if (exprIt != exprMap.end()) {
269 const auto lambdaName = exprIt->second;
274 const auto lambdaBaseName =
"lambda" + std::to_string(exprMap.size());
275 const auto lambdaFullName =
"R_rdf::" + lambdaBaseName;
277 const auto toDeclare =
"namespace R_rdf {\nauto " + lambdaBaseName +
" = " + lambdaExpr +
";\nusing " +
278 lambdaBaseName +
"_ret_t = typename ROOT::TypeTraits::CallableTraits<decltype(" +
279 lambdaBaseName +
")>::ret_type;\n}";
283 exprMap.insert({lambdaExpr, lambdaFullName});
285 return lambdaFullName;
290static std::string RetTypeOfLambda(
const std::string &lambdaName)
292 const auto dt =
gROOT->GetType((lambdaName +
"_ret_t").c_str());
294 const auto type = dt->GetFullTypeName();
298static void GetTopLevelBranchNamesImpl(
TTree &t, std::set<std::string> &bNamesReg,
ColumnNames_t &bNames,
299 std::set<TTree *> &analysedTrees,
const std::string friendName =
"")
301 if (!analysedTrees.insert(&t).second) {
307 for (
auto branchObj : *branches) {
308 const auto name = branchObj->GetName();
309 if (bNamesReg.insert(
name).second) {
310 bNames.emplace_back(
name);
311 }
else if (!friendName.empty()) {
315 const auto longName = friendName +
"." +
name;
316 if (bNamesReg.insert(longName).second)
317 bNames.emplace_back(longName);
327 for (
auto friendTreeObj : *friendTrees) {
328 auto friendElement =
static_cast<TFriendElement *
>(friendTreeObj);
329 auto friendTree = friendElement->
GetTree();
330 const std::string frName(friendElement->GetName());
331 GetTopLevelBranchNamesImpl(*friendTree, bNamesReg, bNames, analysedTrees, frName);
336ThrowJitBuildActionHelperTypeError(
const std::string &actionTypeNameBase,
const std::type_info &helperArgType)
340 std::string actionHelperTypeName =
cname;
343 actionHelperTypeName = helperArgType.name();
345 std::string exceptionText =
346 "RDataFrame::Jit: cannot just-in-time compile a \"" + actionTypeNameBase +
"\" action using helper type \"" +
347 actionHelperTypeName +
348 "\". This typically happens in a custom `Fill` or `Book` invocation where the types of the input columns have "
349 "not been specified as template parameters and the ROOT interpreter has no knowledge of this type of action "
350 "helper. Please add template parameters for the types of the input columns to avoid jitting this action (i.e. "
351 "`df.Fill<float>(..., {\"x\"})`, where `float` is the type of `x`) or declare the action helper type to the "
352 "interpreter, e.g. via gInterpreter->Declare.";
354 throw std::runtime_error(exceptionText);
369 std::copy_if(columnNames.begin(), columnNames.end(), std::back_inserter(columnListWithoutSizeColumns),
370 [&](
const std::string &
name) {
371 if (name[0] ==
'#') {
372 filteredColumns.emplace_back(name);
379 if (!filteredColumns.empty()) {
380 std::string msg =
"Column name(s) {";
381 for (
auto &
c : filteredColumns)
383 msg[msg.size() - 2] =
'}';
384 msg +=
"will be ignored. Please go through a valid Alias to " + action +
" an array size column";
385 throw std::runtime_error(msg);
388 return columnListWithoutSizeColumns;
391std::string
ResolveAlias(
const std::string &col,
const std::map<std::string, std::string> &aliasMap)
393 const auto it = aliasMap.find(col);
394 if (it != aliasMap.end())
398 if (col.size() > 1 && col[0] ==
'#')
399 return "R_rdf_sizeof_" + col.substr(1);
410 const char firstChar = var[0];
413 auto isALetter = [](
char c) {
return (
c >=
'A' &&
c <=
'Z') || (
c >=
'a' &&
c <=
'z'); };
414 const bool isValidFirstChar = firstChar ==
'_' || isALetter(firstChar);
415 if (!isValidFirstChar)
419 auto isANumber = [](
char c) {
return c >=
'0' &&
c <=
'9'; };
420 auto isValidTok = [&isALetter, &isANumber](
char c) {
return c ==
'_' || isALetter(
c) || isANumber(
c); };
421 for (
const char c : var)
427 "RDataFrame::" + where +
": cannot define column \"" + std::string(var) +
"\". Not a valid C++ variable name.";
428 throw std::runtime_error(error);
436 std::set<std::string> bNamesSet;
438 std::set<TTree *> analysedTrees;
439 GetTopLevelBranchNamesImpl(t, bNamesSet, bNames, analysedTrees);
447 std::string tname(tn);
455 const auto theRegexSize = columnNameRegexp.size();
456 std::string theRegex(columnNameRegexp);
458 const auto isEmptyRegex = 0 == theRegexSize;
460 if (theRegexSize > 0 && theRegex[0] !=
'^')
461 theRegex =
"^" + theRegex;
462 if (theRegexSize > 0 && theRegex[theRegexSize - 1] !=
'$')
463 theRegex = theRegex +
"$";
470 for (
auto &&colName : colNames) {
472 selectedColumns.emplace_back(colName);
476 if (selectedColumns.empty()) {
477 std::string
text(callerName);
478 if (columnNameRegexp.empty()) {
479 text =
": there is no column available to match.";
481 text =
": regex \"" + std::string(columnNameRegexp) +
"\" did not match any column.";
483 throw std::runtime_error(
text);
485 return selectedColumns;
492 const std::string definedCol(definedColView);
495 if (customCols.
IsAlias(definedCol))
496 error =
"An alias with that name, pointing to column \"" + customCols.
ResolveAlias(definedCol) +
497 "\", already exists in this branch of the computation graph.";
498 else if (customCols.
HasName(definedCol))
499 error =
"A column with that name has already been Define'd. Use Redefine to force redefinition.";
503 else if (std::find(treeColumns.begin(), treeColumns.end(), definedCol) != treeColumns.end())
505 "A branch with that name is already present in the input TTree/TChain. Use Redefine to force redefinition.";
506 else if (std::find(dataSourceColumns.begin(), dataSourceColumns.end(), definedCol) != dataSourceColumns.end())
508 "A column with that name is already present in the input data source. Use Redefine to force redefinition.";
510 if (!error.empty()) {
511 error =
"RDataFrame::" + where +
": cannot define column \"" + definedCol +
"\". " + error;
512 throw std::runtime_error(error);
520 const std::string definedCol(definedColView);
523 if (customCols.
IsAlias(definedCol)) {
524 error =
"An alias with that name, pointing to column \"" + customCols.
ResolveAlias(definedCol) +
525 "\", already exists. Aliases cannot be Redefined or Varied.";
529 const bool isAlreadyDefined = customCols.
HasName(definedCol);
533 const bool isABranch = std::find(treeColumns.begin(), treeColumns.end(), definedCol) != treeColumns.end();
534 const bool isADSColumn =
535 std::find(dataSourceColumns.begin(), dataSourceColumns.end(), definedCol) != dataSourceColumns.end();
537 if (!isAlreadyDefined && !isABranch && !isADSColumn)
538 error =
"No column with that name was found in the dataset. Use Define to create a new column.";
541 if (!error.empty()) {
542 error =
"RDataFrame::" + where +
": cannot redefine or vary column \"" + definedCol +
"\". " + error;
543 throw std::runtime_error(error);
550 const std::string definedCol(definedColView);
552 if (!variationDeps.empty()) {
553 const std::string error =
554 "RDataFrame::" + where +
": cannot redefine column \"" + definedCol +
555 "\". The column depends on one or more systematic variations and re-defining varied columns is not supported.";
556 throw std::runtime_error(error);
562 if (nTemplateParams != nColumnNames) {
563 std::string err_msg =
"The number of template parameters specified is ";
564 err_msg += std::to_string(nTemplateParams);
565 err_msg +=
" while ";
566 err_msg += std::to_string(nColumnNames);
567 err_msg +=
" columns have been specified.";
568 throw std::runtime_error(err_msg);
578 if (defaultNames.size() < nRequiredNames)
579 throw std::runtime_error(
580 std::to_string(nRequiredNames) +
" column name" + (nRequiredNames == 1 ?
" is" :
"s are") +
581 " required but none were provided and the default list has size " + std::to_string(defaultNames.size()));
583 return ColumnNames_t(defaultNames.begin(), defaultNames.begin() + nRequiredNames);
586 if (names.size() != nRequiredNames) {
587 auto msg = std::to_string(nRequiredNames) +
" column name" + (nRequiredNames == 1 ?
" is" :
"s are") +
588 " required but " + std::to_string(names.size()) + (names.size() == 1 ?
" was" :
" were") +
590 for (
const auto &
name : names)
591 msg +=
" \"" +
name +
"\",";
593 throw std::runtime_error(msg);
603 for (
auto &column : requiredCols) {
604 const auto isBranch = std::find(datasetColumns.begin(), datasetColumns.end(), column) != datasetColumns.end();
607 if (definedCols.
HasName(column))
609 const auto isDataSourceColumn =
610 std::find(dataSourceColumns.begin(), dataSourceColumns.end(), column) != dataSourceColumns.end();
611 if (isDataSourceColumn)
613 unknownColumns.emplace_back(column);
615 return unknownColumns;
618std::vector<std::string>
GetFilterNames(
const std::shared_ptr<RLoopManager> &loopManager)
620 return loopManager->GetFiltersNames();
628 const auto lastSlash = fullTreeName.rfind(
'/');
629 if (std::string_view::npos != lastSlash) {
630 dirName = treeName.substr(0, lastSlash);
631 treeName = treeName.substr(lastSlash + 1, treeName.size());
633 return {std::string(treeName), std::string(dirName)};
640 s << std::hex << std::showbase << reinterpret_cast<size_t>(addr);
645std::shared_ptr<RDFDetail::RJittedFilter>
649 const auto &dsColumns = ds ? ds->GetColumnNames() :
ColumnNames_t{};
651 const auto parsedExpr = ParseRDFExpression(expression, branches, customCols, dsColumns);
652 const auto exprVarTypes =
654 const auto lambdaName = DeclareLambda(parsedExpr.fExpr, parsedExpr.fVarNames, exprVarTypes);
655 const auto type = RetTypeOfLambda(lambdaName);
657 std::runtime_error(
"Filter: the following expression does not evaluate to bool:\n" + std::string(expression));
664 const auto jittedFilter = std::make_shared<RDFDetail::RJittedFilter>(
665 (*prevNodeOnHeap)->GetLoopManagerUnchecked(),
name,
670 std::stringstream filterInvocation;
671 filterInvocation <<
"ROOT::Internal::RDF::JitFilterHelper(" << lambdaName <<
", new const char*["
672 << parsedExpr.fUsedCols.size() <<
"]{";
673 for (
const auto &col : parsedExpr.fUsedCols)
674 filterInvocation <<
"\"" << col <<
"\", ";
675 if (!parsedExpr.fUsedCols.empty())
676 filterInvocation.seekp(-2, filterInvocation.cur);
681 filterInvocation <<
"}, " << parsedExpr.fUsedCols.size() <<
", \"" <<
name <<
"\", "
682 <<
"reinterpret_cast<std::weak_ptr<ROOT::Detail::RDF::RJittedFilter>*>("
684 <<
"reinterpret_cast<std::shared_ptr<ROOT::Detail::RDF::RNodeBase>*>(" << prevNodeAddr <<
"),"
685 <<
"reinterpret_cast<ROOT::Internal::RDF::RColumnRegister*>(" << definesOnHeapAddr <<
")"
688 auto lm = jittedFilter->GetLoopManagerUnchecked();
689 lm->ToJitExec(filterInvocation.str());
698 std::shared_ptr<RNodeBase> *upcastNodeOnHeap)
701 const auto &dsColumns = ds ? ds->GetColumnNames() :
ColumnNames_t{};
703 const auto parsedExpr = ParseRDFExpression(expression, branches, customCols, dsColumns);
704 const auto exprVarTypes =
706 const auto lambdaName = DeclareLambda(parsedExpr.fExpr, parsedExpr.fVarNames, exprVarTypes);
707 const auto type = RetTypeOfLambda(lambdaName);
711 auto jittedDefine = std::make_shared<RDFDetail::RJittedDefine>(
name,
type, lm, customCols, parsedExpr.fUsedCols);
713 std::stringstream defineInvocation;
714 defineInvocation <<
"ROOT::Internal::RDF::JitDefineHelper<ROOT::Internal::RDF::DefineTypes::RDefineTag>("
715 << lambdaName <<
", new const char*[" << parsedExpr.fUsedCols.size() <<
"]{";
716 for (
const auto &col : parsedExpr.fUsedCols) {
717 defineInvocation <<
"\"" << col <<
"\", ";
719 if (!parsedExpr.fUsedCols.empty())
720 defineInvocation.seekp(-2, defineInvocation.cur);
725 defineInvocation <<
"}, " << parsedExpr.fUsedCols.size() <<
", \"" <<
name
726 <<
"\", reinterpret_cast<ROOT::Detail::RDF::RLoopManager*>(" <<
PrettyPrintAddr(&lm)
727 <<
"), reinterpret_cast<std::weak_ptr<ROOT::Detail::RDF::RJittedDefine>*>("
729 <<
"), reinterpret_cast<ROOT::Internal::RDF::RColumnRegister*>(" << definesAddr
730 <<
"), reinterpret_cast<std::shared_ptr<ROOT::Detail::RDF::RNodeBase>*>("
740 std::shared_ptr<RNodeBase> *upcastNodeOnHeap)
742 const auto lambdaName = DeclareLambda(std::string(expression), {
"rdfslot_",
"rdfsampleinfo_"},
743 {
"unsigned int",
"const ROOT::RDF::RSampleInfo"});
744 const auto retType = RetTypeOfLambda(lambdaName);
748 auto jittedDefine = std::make_shared<RDFDetail::RJittedDefine>(
name, retType, lm, customCols,
ColumnNames_t{});
750 std::stringstream defineInvocation;
751 defineInvocation <<
"ROOT::Internal::RDF::JitDefineHelper<ROOT::Internal::RDF::DefineTypes::RDefinePerSampleTag>("
752 << lambdaName <<
", nullptr, 0, ";
757 defineInvocation <<
"\"" <<
name <<
"\", reinterpret_cast<ROOT::Detail::RDF::RLoopManager*>(" <<
PrettyPrintAddr(&lm)
758 <<
"), reinterpret_cast<std::weak_ptr<ROOT::Detail::RDF::RJittedDefine>*>("
760 <<
"), reinterpret_cast<ROOT::Internal::RDF::RColumnRegister*>(" << definesAddr
761 <<
"), reinterpret_cast<std::shared_ptr<ROOT::Detail::RDF::RNodeBase>*>("
769std::shared_ptr<RJittedVariation>
773 std::shared_ptr<RNodeBase> *upcastNodeOnHeap)
776 const auto &dsColumns = ds ? ds->GetColumnNames() :
ColumnNames_t{};
778 const auto parsedExpr = ParseRDFExpression(expression, branches, colRegister, dsColumns);
779 const auto exprVarTypes =
781 const auto lambdaName = DeclareLambda(parsedExpr.fExpr, parsedExpr.fVarNames, exprVarTypes);
782 const auto type = RetTypeOfLambda(lambdaName);
784 if (
type.rfind(
"ROOT::VecOps::RVec", 0) != 0)
785 throw std::runtime_error(
786 "Jitted Vary expressions must return an RVec object. The following expression returns a " +
type +
787 " instead:\n" + parsedExpr.fExpr);
791 auto jittedVariation = std::make_shared<RJittedVariation>(colNames, variationName, variationTags,
type, colRegister,
792 lm, parsedExpr.fUsedCols);
800 std::stringstream varyInvocation;
801 varyInvocation <<
"ROOT::Internal::RDF::JitVariationHelper(" << lambdaName <<
", new const char*["
802 << parsedExpr.fUsedCols.size() <<
"]{";
803 for (
const auto &col : parsedExpr.fUsedCols) {
804 varyInvocation <<
"\"" << col <<
"\", ";
806 if (!parsedExpr.fUsedCols.empty())
807 varyInvocation.seekp(-2, varyInvocation.cur);
808 varyInvocation <<
"}, " << parsedExpr.fUsedCols.size();
809 varyInvocation <<
", new const char*[" << colNames.size() <<
"]{";
810 for (
const auto &col : colNames) {
811 varyInvocation <<
"\"" << col <<
"\", ";
813 varyInvocation.seekp(-2, varyInvocation.cur);
814 varyInvocation <<
"}, " << colNames.size() <<
", new const char*[" << variationTags.size() <<
"]{";
815 for (
const auto &tag : variationTags) {
816 varyInvocation <<
"\"" << tag <<
"\", ";
818 varyInvocation.seekp(-2, varyInvocation.cur);
819 varyInvocation <<
"}, " << variationTags.size() <<
", \"" << variationName
820 <<
"\", reinterpret_cast<ROOT::Detail::RDF::RLoopManager*>(" <<
PrettyPrintAddr(&lm)
821 <<
"), reinterpret_cast<std::weak_ptr<ROOT::Internal::RDF::RJittedVariation>*>("
823 <<
"), reinterpret_cast<ROOT::Internal::RDF::RColumnRegister*>(" << colRegisterAddr
824 <<
"), reinterpret_cast<std::shared_ptr<ROOT::Detail::RDF::RNodeBase>*>("
828 return jittedVariation;
834 const std::type_info &helperArgType,
const std::type_info &at,
void *helperArgOnHeap,
836 std::weak_ptr<RJittedAction> *jittedActionOnHeap)
840 if (!actionTypeClass) {
841 std::string exceptionText =
"An error occurred while inferring the action type of the operation.";
842 throw std::runtime_error(exceptionText);
844 const std::string actionTypeName = actionTypeClass->GetName();
845 const std::string actionTypeNameBase = actionTypeName.substr(actionTypeName.rfind(
':') + 1);
849 if (helperArgTypeName.empty()) {
850 ThrowJitBuildActionHelperTypeError(actionTypeNameBase, helperArgType);
858 std::stringstream createAction_str;
859 createAction_str <<
"ROOT::Internal::RDF::CallBuildAction<" << actionTypeName;
860 const auto columnTypeNames =
862 for (
auto &colType : columnTypeNames)
863 createAction_str <<
", " << colType;
866 createAction_str <<
">(reinterpret_cast<std::shared_ptr<ROOT::Detail::RDF::RNodeBase>*>("
867 <<
PrettyPrintAddr(prevNode) <<
"), new const char*[" << cols.size() <<
"]{";
868 for (
auto i = 0u; i < cols.size(); ++i) {
870 createAction_str <<
", ";
871 createAction_str <<
'"' << cols[i] <<
'"';
873 createAction_str <<
"}, " << cols.size() <<
", " << nSlots <<
", reinterpret_cast<shared_ptr<" << helperArgTypeName
875 <<
"), reinterpret_cast<std::weak_ptr<ROOT::Internal::RDF::RJittedAction>*>("
877 <<
"), reinterpret_cast<ROOT::Internal::RDF::RColumnRegister*>(" << definesAddr <<
"));";
878 return createAction_str.str();
883 for (
const auto &
s : strings) {
890std::shared_ptr<RNodeBase>
UpcastNode(std::shared_ptr<RNodeBase> ptr)
905 for (
auto &col : selectedColumns) {
913 if (!unknownColumns.empty()) {
914 std::stringstream unknowns;
915 std::string delim = unknownColumns.size() > 1 ?
"s: " :
": ";
916 for (
auto &unknownColumn : unknownColumns) {
917 unknowns << delim << unknownColumn;
920 throw std::runtime_error(
"Unknown column" + unknowns.str());
923 return selectedColumns;
930 auto toCheckedArgType = [&](
const std::string &
c) {
933 if (colType.rfind(
"CLING_UNKNOWN_TYPE", 0) == 0) {
935 "The type of custom column \"" +
c +
"\" (" + colType.substr(19) +
936 ") is not known to the interpreter, but a just-in-time-compiled " + context +
937 " call requires this column. Make sure to create and load ROOT dictionaries for this column's class.";
938 throw std::runtime_error(msg);
942 std::vector<std::string> colTypes;
943 colTypes.reserve(colNames.size());
944 std::transform(colNames.begin(), colNames.end(), std::back_inserter(colTypes), toCheckedArgType);
953 const auto nColumns = requestedCols.size();
954 std::vector<bool> mustBeDefined(nColumns,
false);
955 for (
auto i = 0u; i < nColumns; ++i)
956 mustBeDefined[i] = std::find(definedCols.begin(), definedCols.end(), requestedCols[i]) == definedCols.end();
957 return mustBeDefined;
962 std::unordered_set<std::string> uniqueCols;
963 for (
auto &col : cols) {
964 if (!uniqueCols.insert(col).second) {
965 const auto msg =
"Error: column \"" + col +
966 "\" was passed to Snapshot twice. This is not supported: only one of the columns would be "
967 "readable with RDataFrame.";
968 throw std::logic_error(msg);
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 cname
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 Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint const char text
R__EXTERN TVirtualMutex * gROOTMutex
#define R__LOCKGUARD(mutex)
The head node of a RDF computation graph.
const ColumnNames_t & GetBranchNames()
Return all valid TTree::Branch names (caching results for subsequent calls).
void ToJitExec(const std::string &) const
void Run()
Start the event loop with a different mechanism depending on IMT/no IMT, data source/no data source.
const ColumnNames_t & GetDefaultColumnNames() const
Return the list of default columns – empty if none was provided when constructing the RDataFrame.
A binder for user-defined columns and aliases.
bool IsAlias(const std::string &name) const
Return true if the given column name is an existing alias.
const DefinesMap_t & GetColumns() const
Returns a map of pointers to the defined columns.
bool HasName(std::string_view name) const
Check if the provided name is tracked in the names list.
std::string ResolveAlias(std::string_view alias) const
Return the actual column name that the alias resolves to.
std::vector< std::string > GetVariationDeps(const std::string &column) const
Get the names of all variations that directly or indirectly affect a given column.
RDataSource defines an API that RDataFrame can use to read arbitrary data formats.
The public interface to the RDataFrame federation of classes.
RLoopManager * fLoopManager
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 TFriendElement TF describes a TTree object TF in a file.
virtual TTree * GetTree()
Return pointer to friend TTree.
Bool_t MatchB(const TString &s, const TString &mods="", Int_t start=0, Int_t nMaxMatch=10)
A TTree represents a columnar dataset.
virtual TObjArray * GetListOfBranches()
virtual TList * GetListOfFriends() const
basic_string_view< char > string_view
const ColumnNames_t SelectColumns(unsigned int nRequiredNames, const ColumnNames_t &names, const ColumnNames_t &defaultNames)
Choose between local column names or default column names, throw in case of errors.
ParsedTreePath ParseTreePath(std::string_view fullTreeName)
std::shared_ptr< RJittedVariation > BookVariationJit(const std::vector< std::string > &colNames, std::string_view variationName, const std::vector< std::string > &variationTags, std::string_view expression, RLoopManager &lm, RDataSource *ds, const RColumnRegister &colRegister, const ColumnNames_t &branches, std::shared_ptr< RNodeBase > *upcastNodeOnHeap)
Book the jitting of a Vary call.
void CheckValidCppVarName(std::string_view var, const std::string &where)
std::string ColumnName2ColumnTypeName(const std::string &colName, TTree *, RDataSource *, RDefineBase *, bool vector2rvec=true)
Return a string containing the type of the given branch.
std::shared_ptr< RNodeBase > UpcastNode(std::shared_ptr< RNodeBase > ptr)
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...
ColumnNames_t GetValidatedColumnNames(RLoopManager &lm, const unsigned int nColumns, const ColumnNames_t &columns, const RColumnRegister &customColumns, RDataSource *ds)
Given the desired number of columns and the user-provided list of columns:
bool IsStrInVec(const std::string &str, const std::vector< std::string > &vec)
std::string ResolveAlias(const std::string &col, const std::map< std::string, std::string > &aliasMap)
std::vector< std::string > GetFilterNames(const std::shared_ptr< RLoopManager > &loopManager)
std::string PrettyPrintAddr(const void *const addr)
std::string JitBuildAction(const ColumnNames_t &cols, std::shared_ptr< RDFDetail::RNodeBase > *prevNode, const std::type_info &helperArgType, const std::type_info &at, void *helperArgOnHeap, TTree *tree, const unsigned int nSlots, const RColumnRegister &customCols, RDataSource *ds, std::weak_ptr< RJittedAction > *jittedActionOnHeap)
ColumnNames_t GetTopLevelBranchNames(TTree &t)
Get all the top-level branches names, including the ones of the friend trees.
void CheckTypesAndPars(unsigned int nTemplateParams, unsigned int nColumnNames)
std::string DemangleTypeIdName(const std::type_info &typeInfo)
bool AtLeastOneEmptyString(const std::vector< std::string_view > strings)
std::vector< T > Union(const std::vector< T > &v1, const std::vector< T > &v2)
Return a vector with all elements of v1 and v2 and duplicates removed.
void CheckForDefinition(const std::string &where, std::string_view definedColView, const RColumnRegister &customCols, const ColumnNames_t &treeColumns, const ColumnNames_t &dataSourceColumns)
Throw if column definedColView is not already there.
bool IsInternalColumn(std::string_view colName)
Whether custom column with name colName is an "internal" column such as rdfentry_ or rdfslot_.
ColumnNames_t FilterArraySizeColNames(const ColumnNames_t &columnNames, const std::string &action)
Take a list of column names, return that list with entries starting by '#' filtered out.
void InterpreterDeclare(const std::string &code)
Declare code in the interpreter via the TInterpreter::Declare method, throw in case of errors.
std::shared_ptr< RJittedDefine > BookDefinePerSampleJit(std::string_view name, std::string_view expression, RLoopManager &lm, const RColumnRegister &customCols, std::shared_ptr< RNodeBase > *upcastNodeOnHeap)
Book the jitting of a DefinePerSample call.
void CheckForRedefinition(const std::string &where, std::string_view definedColView, const RColumnRegister &customCols, const ColumnNames_t &treeColumns, const ColumnNames_t &dataSourceColumns)
Throw if column definedColView is already there.
void CheckForDuplicateSnapshotColumns(const ColumnNames_t &cols)
ColumnNames_t ConvertRegexToColumns(const ColumnNames_t &colNames, std::string_view columnNameRegexp, std::string_view callerName)
std::vector< bool > FindUndefinedDSColumns(const ColumnNames_t &requestedCols, const ColumnNames_t &definedCols)
Return a bitset each element of which indicates whether the corresponding element in selectedColumns ...
std::shared_ptr< RJittedDefine > BookDefineJit(std::string_view name, std::string_view expression, RLoopManager &lm, RDataSource *ds, const RColumnRegister &customCols, const ColumnNames_t &branches, std::shared_ptr< RNodeBase > *upcastNodeOnHeap)
Book the jitting of a Define call.
std::vector< std::string > GetValidatedArgTypes(const ColumnNames_t &colNames, const RColumnRegister &colRegister, TTree *tree, RDataSource *ds, const std::string &context, bool vector2rvec)
void CheckForNoVariations(const std::string &where, std::string_view definedColView, const RColumnRegister &customCols)
Throw if the column has systematic variations attached.
ColumnNames_t FindUnknownColumns(const ColumnNames_t &requiredCols, const ColumnNames_t &datasetColumns, const RColumnRegister &definedCols, const ColumnNames_t &dataSourceColumns)
void TriggerRun(ROOT::RDF::RNode &node)
Trigger the execution of an RDataFrame computation graph.
std::shared_ptr< RDFDetail::RJittedFilter > BookFilterJit(std::shared_ptr< RDFDetail::RNodeBase > *prevNodeOnHeap, std::string_view name, std::string_view expression, const ColumnNames_t &branches, const RColumnRegister &customCols, TTree *tree, RDataSource *ds)
Book the jitting of a Filter call.
std::vector< std::string > ColumnNames_t
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
char * DemangleTypeIdName(const std::type_info &ti, int &errorCode)
Demangle in a portable way the type id name.
static constexpr double s