40#pragma GCC diagnostic push
41#pragma GCC diagnostic ignored "-Woverloaded-virtual"
42#pragma GCC diagnostic ignored "-Wshadow"
46#pragma GCC diagnostic pop
60#include <unordered_map>
61#include <unordered_set>
74struct ParsedExpression {
79 ColumnNames_t fUsedCols;
81 ColumnNames_t fVarNames;
92 const auto msg =
"Failed to tokenize expression:\n" +
expr +
"\n\nMake sure it is valid C++.";
93 throw std::runtime_error(
msg);
96 std::unordered_set<std::string>
usedCols;
101 const auto kSymbol = lexertk::token::e_symbol;
102 for (
auto i = 0
u; i <
nTokens; ++i) {
151 dot.Substitute(out,
"\\.",
"g");
152 return std::string(std::move(out));
163 replacer.Substitute(out, col.data(),
"g");
187 R
"REGEX(#(?!(ifdef|ifndef|if|else|elif|endif|pragma|define|undef|include|line))([a-zA-Z_][a-zA-Z0-9_]*)(?=(?:[^"]*"[^"]*")*[^"]*$))REGEX");
202 for (
auto i = 0
u; i <
varNames.size(); ++i)
203 varNames[i] =
"var" + std::to_string(i);
211 [](
const std::string &
a,
const std::string &
b) { return a.size() > b.size(); });
274 std::stringstream
ss;
276 for (
auto i = 0
u; i < vars.size(); ++i) {
290 ss.seekp(-2,
ss.cur);
343 const auto funcName =
exprIt->second;
352 "_ret_t = typename ROOT::TypeTraits::CallableTraits<decltype(" +
funcBaseName +
366 const auto dt =
gROOT->GetType((funcName +
"_ret_t").c_str());
368 const auto type =
dt->GetFullTypeName();
383 "RDataFrame::Jit: cannot just-in-time compile a \"" +
actionTypeNameBase +
"\" action using helper type \"" +
385 "\". This typically happens in a custom `Fill` or `Book` invocation where the types of the input columns have "
386 "not been specified as template parameters and the ROOT interpreter has no knowledge of this type of action "
387 "helper. Please add template parameters for the types of the input columns to avoid jitting this action (i.e. "
388 "`df.Fill<float>(..., {\"x\"})`, where `float` is the type of `x`) or declare the action helper type to the "
389 "interpreter, e.g. via gInterpreter->Declare.";
407 [&](
const std::string &
name) {
408 if (name[0] ==
'#') {
409 filteredColumns.emplace_back(name);
417 std::string
msg =
"Column name(s) {";
420 msg[
msg.size() - 2] =
'}';
421 msg +=
"will be ignored. Please go through a valid Alias to " +
action +
" an array size column";
422 throw std::runtime_error(
msg);
437 auto isALetter = [](
char c) {
return (
c >=
'A' &&
c <=
'Z') || (
c >=
'a' &&
c <=
'z'); };
443 auto isANumber = [](
char c) {
return c >=
'0' &&
c <=
'9'; };
445 for (
const char c : var)
450 const auto objName =
where ==
"Define" ?
"column" :
"variation";
451 const auto error =
"RDataFrame::" +
where +
": cannot define " +
objName +
" \"" + std::string(var) +
452 "\". Not a valid C++ variable name.";
453 throw std::runtime_error(error);
493 text =
": there is no column available to match.";
497 throw std::runtime_error(
text);
510 "\", already exists in this branch of the computation graph.";
512 error =
"A column with that name has already been Define'd. Use Redefine to force redefinition.";
515 "A column with that name is already present in the input data source. Use Redefine to force redefinition.";
517 if (!error.empty()) {
518 error =
"RDataFrame::" +
where +
": cannot define column \"" + std::string(
definedColView) +
"\". " + error;
519 throw std::runtime_error(error);
531 "\", already exists. Aliases cannot be Redefined or Varied.";
540 error =
"No column with that name was found in the dataset. Use Define to create a new column.";
543 if (!error.empty()) {
544 if (
where ==
"DefaultValueFor")
545 error =
"RDataFrame::" +
where +
": cannot provide default values for column \"" +
548 error =
"RDataFrame::" +
where +
": cannot redefine or vary column \"" + std::string(
definedColView) +
"\". " +
550 throw std::runtime_error(error);
560 if (
where ==
"Redefine") {
561 const std::string error =
"RDataFrame::" +
where +
": cannot redefine column \"" +
definedCol +
562 "\". The column depends on one or more systematic variations and re-defining varied "
563 "columns is not supported.";
564 throw std::runtime_error(error);
565 }
else if (
where ==
"DefaultValueFor") {
566 const std::string error =
"RDataFrame::" +
where +
": cannot provide a default value for column \"" +
568 "\". The column depends on one or more systematic variations and it should not be "
569 "possible to have missing values in varied columns.";
570 throw std::runtime_error(error);
572 const std::string error =
573 "RDataFrame::" +
where +
": this operation cannot work with columns that depend on systematic variations.";
574 throw std::runtime_error(error);
582 std::string
err_msg =
"The number of template parameters specified is ";
586 err_msg +=
" columns have been specified.";
587 throw std::runtime_error(
err_msg);
598 throw std::runtime_error(
600 " required but none were provided and the default list has size " + std::to_string(
defaultNames.
size()));
607 " required but " + std::to_string(names.size()) + (names.size() == 1 ?
" was" :
" were") +
609 for (
const auto &
name : names)
612 throw std::runtime_error(
msg);
634std::vector<std::string> GetFilterNames(
const std::shared_ptr<RLoopManager> &
loopManager)
645 if (std::string_view::npos !=
lastSlash) {
661std::shared_ptr<RDFDetail::RJittedFilter>
662BookFilterJit(std::shared_ptr<RDFDetail::RNodeBase> prevNode, std::string_view
name, std::string_view expression,
665 const auto &
dsColumns =
ds ?
ds->GetColumnNames() : ColumnNames_t{};
673 throw std::runtime_error(
"Filter: the following expression does not evaluate to bool:\n" +
674 std::string(expression));
676 auto *
lm = prevNode->GetLoopManagerUnchecked();
677 const auto jittedFilter = std::make_shared<RDFDetail::RJittedFilter>(
683 <<
"ROOT::Internal::RDF::RColumnRegister &colRegister, "
684 <<
"ROOT::Detail::RDF::RLoopManager &lm, "
685 <<
"void *jittedFilter, "
686 <<
"std::shared_ptr<void> *) {\n";
687 filterInvocation <<
" ROOT::Internal::RDF::JitFilterHelper(" << funcName <<
", "
691 <<
"reinterpret_cast<ROOT::Detail::RDF::RJittedFilter*>(jittedFilter)"
701std::shared_ptr<RJittedDefine>
BookDefineJit(std::string_view
name, std::string_view expression, RLoopManager &
lm,
704 const auto &
dsColumns =
ds ?
ds->GetColumnNames() : ColumnNames_t{};
720 <<
"ROOT::Internal::RDF::RColumnRegister &colRegister, "
721 <<
"ROOT::Detail::RDF::RLoopManager &lm, "
722 <<
"void *jittedDefine, "
723 <<
"std::shared_ptr<void> *) {\n";
724 defineInvocation <<
" ROOT::Internal::RDF::JitDefineHelper<ROOT::Internal::RDF::DefineTypes::RDefineTag>("
729 <<
"reinterpret_cast<ROOT::Detail::RDF::RJittedDefine *>(jittedDefine)"
741 const auto funcName =
DeclareFunction(std::string(expression), {
"rdfslot_",
"rdfsampleinfo_"},
742 {
"unsigned int",
"const ROOT::RDF::RSampleInfo"});
753 <<
"ROOT::Internal::RDF::RColumnRegister &colRegister, "
754 <<
"ROOT::Detail::RDF::RLoopManager &lm, "
755 <<
"void *jittedDefine, "
756 <<
"std::shared_ptr<void> *) {\n";
757 defineInvocation <<
" ROOT::Internal::RDF::JitDefineHelper<ROOT::Internal::RDF::DefineTypes::RDefinePerSampleTag>("
762 <<
"reinterpret_cast<ROOT::Detail::RDF::RJittedDefine *>(jittedDefine)"
770std::shared_ptr<RJittedVariation>
772 const std::vector<std::string> &
variationTags, std::string_view expression, RLoopManager &
lm,
776 const auto &
dsColumns =
ds ?
ds->GetColumnNames() : ColumnNames_t{};
781 const auto funcName =
785 if (
type.rfind(
"ROOT::VecOps::RVec", 0) != 0) {
786 throw std::runtime_error(
787 "Jitted Vary expressions must return an RVec object. The following expression return type is '" +
type +
802 varyInvocation <<
"(const std::vector<std::string> &inputColNames, "
803 <<
"ROOT::Internal::RDF::RColumnRegister &colRegister, "
804 <<
"ROOT::Detail::RDF::RLoopManager &lm, "
805 <<
"void *jittedVariation, "
806 <<
"std::shared_ptr<void> *helperArg) {\n";
808 <<
" auto *variedColNamesAndTags = reinterpret_cast<std::shared_ptr<std::pair<std::vector<std::string>, "
809 "std::vector<std::string>>> *>(helperArg);"
810 <<
" ROOT::Internal::RDF::JitVariationHelper<" << (
isSingleColumn ?
"true" :
"false") <<
">(" << funcName
815 <<
"reinterpret_cast<ROOT::Internal::RDF::RJittedVariation *>(jittedVariation), "
816 <<
"(*variedColNamesAndTags)->first, "
817 <<
"(*variedColNamesAndTags)->second"
819 lm.RegisterJitHelperCall(
822 std::make_shared<std::pair<std::vector<std::string>, std::vector<std::string>>>(
colNames,
variationTags));
835 std::string
exceptionText =
"An error occurred while inferring the action type of the operation.";
851 <<
"ROOT::Internal::RDF::RColumnRegister &colRegister, "
852 <<
"ROOT::Detail::RDF::RLoopManager &lm, "
853 <<
"void *jittedAction, "
854 <<
"std::shared_ptr<void> *helperArg) {\n";
863 <<
"reinterpret_cast<ROOT::Internal::RDF::RJittedAction *>(jittedAction), " <<
nSlots <<
", "
871 for (
const auto &s :
strings) {
878std::shared_ptr<RNodeBase>
UpcastNode(std::shared_ptr<RNodeBase> ptr)
888ColumnNames_t GetValidatedColumnNames(RLoopManager &
lm,
const unsigned int nColumns,
const ColumnNames_t &
columns,
906 const auto &
colsToIgnore =
lm.GetSuppressErrorsForMissingBranches();
911 std::string
errMsg = std::string(
"Unknown column") + (
unknownColumns.size() > 1 ?
"s: " :
": ");
915 throw std::runtime_error(
errMsg);
923 TTree *tree, RDataSource *
ds,
const std::string &context,
929 if (
colType.rfind(
"CLING_UNKNOWN_TYPE", 0) == 0) {
931 "The type of custom column \"" +
c +
"\" (" +
colType.substr(19) +
932 ") is not known to the interpreter, but a just-in-time-compiled " + context +
933 " call requires this column. Make sure to create and load ROOT dictionaries for this column's class.";
934 throw std::runtime_error(
msg);
947 for (
auto &col :
cols) {
949 const auto msg =
"Error: column \"" + col +
950 "\" was passed to Snapshot twice. This is not supported: only one of the columns would be "
951 "readable with RDataFrame.";
952 throw std::logic_error(
msg);
980 "The RNTuple-specific %s option in RSnapshotOptions has been set, but the output format is "
981 "set to TTree, so this option won't have any effect. Use the other options available in "
982 "RSnapshotOptions to "
983 "configure the output TTree. Alternatively, change fOutputFormat to snapshot to RNTuple instead.",
998 "The TTree-specific %s option in RSnapshotOptions has been set, but the output format is set to RNTuple, "
999 "so this option won't have any effect. Use the fNTupleWriteOptions option available in RSnapshotOptions to "
1000 "configure the output RNTuple. Alternatively, change fOutputFormat to snapshot to TTree instead.",
1008std::pair<std::vector<std::string>, std::vector<std::string>>
1014 tree =
treeDS->GetTree();
1022 for (std::size_t i = 0
u; i <
nCols; ++i) {
1032 auto *
leaves =
b->GetListOfLeaves();
1055 [&
uniqueCols](
const std::string &
colName) { return !uniqueCols.insert(colName).second; }),
1064 [](
const std::string &
colName) { return colName.find(
'.') == std::string::npos; });
1068 if (colName.find(
'.') == std::string::npos)
1070 const auto parentFieldName = colName.substr(0, colName.find_first_of(
'.'));
1071 return std::find(parentFields.cbegin(), parentFields.cend(), parentFieldName) !=
1092 lm.GetSuppressErrorsForMissingBranches().find(
colName) ==
lm.GetSuppressErrorsForMissingBranches().
end())
1095 const auto nSlots =
lm.GetNSlots();
1096 std::vector<std::unique_ptr<ROOT::Detail::RDF::RColumnReaderBase>>
colReaders;
1109 const std::vector<const std::type_info *> &
colTypeIDs,
1113 assert(
nCols ==
colTypeIDs.size() &&
"Must provide exactly one column type for each column to create");
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
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.
A binder for user-defined columns, variations and aliases.
RDataSource defines an API that RDataFrame can use to read arbitrary data formats.
const_iterator begin() const
const_iterator end() const
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.
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.
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)
std::string PrettyPrintAddr(const void *const addr)
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)
std::string ColumnName2ColumnTypeName(const std::string &colName, TTree *, RDataSource *, RDefineBase *, bool vector2RVec=true)
Return a string containing the type of the given branch.
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.
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.
std::vector< std::string > ColumnNames_t
char * DemangleTypeIdName(const std::type_info &ti, int &errorCode)
Demangle in a portable way the type id name.
BVH_ALWAYS_INLINE T dot(const Vec< T, N > &a, const Vec< T, N > &b)
A collection of options to steer the creation of the dataset on disk through Snapshot().