23 namespace Experimental {
37 const std::vector<std::string> &tmpBranches)
41 std::string paddedExpr =
" " + expression +
" ";
42 int paddedExprLen = paddedExpr.size();
43 static const std::string regexBit(
"[^a-zA-Z0-9_]");
44 std::vector<std::string> usedBranches;
45 for (
auto brName : tmpBranches) {
46 std::string bNameRegexContent = regexBit + brName + regexBit;
47 TRegexp bNameRegex(bNameRegexContent.c_str());
48 if (-1 != bNameRegex.Index(paddedExpr.c_str(), &paddedExprLen)) {
49 usedBranches.emplace_back(brName.c_str());
52 if (!branches)
return usedBranches;
53 for (
auto bro : *branches) {
54 auto brName = bro->GetName();
55 std::string bNameRegexContent = regexBit + brName + regexBit;
56 TRegexp bNameRegex(bNameRegexContent.c_str());
57 if (-1 != bNameRegex.Index(paddedExpr.c_str(), &paddedExprLen)) {
58 usedBranches.emplace_back(brName);
68 const std::vector<std::string> &tmpBranches,
69 const std::map<std::string, TmpBranchBasePtr_t> &tmpBookedBranches, TTree *
tree)
72 auto exprNeedsVariables = !usedBranches.empty();
77 std::vector<std::string> usedBranchesTypes;
79 static unsigned int iNs = 0U;
80 ss <<
"__tdf_" << iNs++;
81 const auto nsName = ss.str();
84 if (exprNeedsVariables) {
86 ss <<
"namespace " << nsName;
88 for (
auto brName : usedBranches) {
90 auto tmpBrIt = tmpBookedBranches.find(brName);
91 auto tmpBr = tmpBrIt == tmpBookedBranches.end() ? nullptr : tmpBrIt->second.get();
93 ss << brTypeName <<
" " << brName <<
";\n";
94 usedBranchesTypes.emplace_back(brTypeName);
97 auto variableDeclarations = ss.str();
101 gInterpreter->ProcessLine(variableDeclarations.c_str(), &interpErrCode);
102 if (TInterpreter::EErrorCode::kNoError != interpErrCode) {
103 std::string msg =
"Cannot declare these variables: ";
104 msg += variableDeclarations;
105 msg +=
"\nInterpreter error code is " + std::to_string(interpErrCode) +
".";
106 throw std::runtime_error(msg);
112 ss <<
"namespace " << nsName <<
"{ auto res = " << expression <<
";}\n";
115 std::string msg =
"Cannot interpret this expression: ";
118 throw std::runtime_error(msg);
124 for (
unsigned int i = 0; i < usedBranchesTypes.size(); ++i) {
126 ss << usedBranchesTypes[i] <<
"& " << usedBranches[i] <<
", ";
128 if (!usedBranchesTypes.empty()) ss.seekp(-2, ss.cur);
129 ss <<
"){ return " << expression <<
";}";
130 auto filterLambda = ss.str();
134 ss <<
"((" << nodeTypeName <<
"*)" << thisPtr <<
")->" << methodName <<
"(";
135 if (methodName ==
"Define") {
136 ss <<
"\"" << name <<
"\", ";
138 ss << filterLambda <<
", {";
139 for (
auto brName : usedBranches) {
140 ss <<
"\"" << brName <<
"\", ";
142 if (exprNeedsVariables) ss.seekp(-2, ss.cur);
145 if (methodName ==
"Filter") {
146 ss <<
", \"" << name <<
"\"";
152 auto retVal =
gInterpreter->Calc(ss.str().c_str(), &interpErrCode);
153 if (TInterpreter::EErrorCode::kNoError != interpErrCode || !retVal) {
154 std::string msg =
"Cannot interpret the invocation to " + methodName +
": ";
156 if (TInterpreter::EErrorCode::kNoError != interpErrCode) {
157 msg +=
"\nInterpreter error code is " + std::to_string(interpErrCode) +
".";
159 throw std::runtime_error(msg);
166 void JitBuildAndBook(
const ColumnNames_t &bl,
const std::string &nodeTypename,
void *thisPtr,
const std::type_info &art,
167 const std::type_info &at,
const void *
r, TTree *
tree,
unsigned int nSlots,
168 const std::map<std::string, TmpBranchBasePtr_t> &tmpBranches)
170 gInterpreter->Declare(
"#include \"ROOT/TDataFrame.hxx\"");
171 auto nBranches = bl.size();
174 std::vector<TCustomColumnBase *> tmpBranchPtrs(nBranches,
nullptr);
175 for (
auto i = 0u; i < nBranches; ++i) {
176 auto tmpBranchIt = tmpBranches.find(bl[i]);
177 if (tmpBranchIt != tmpBranches.end()) tmpBranchPtrs[i] = tmpBranchIt->second.get();
181 std::vector<std::string> branchTypeNames(nBranches);
182 for (
auto i = 0u; i < nBranches; ++i) {
184 if (branchTypeName.empty()) {
185 std::string exceptionText =
"The type of column ";
186 exceptionText += bl[i];
187 exceptionText +=
" could not be guessed. Please specify one.";
188 throw std::runtime_error(exceptionText.c_str());
190 branchTypeNames[i] = branchTypeName;
195 if (!actionResultTypeClass) {
196 std::string exceptionText =
"An error occurred while inferring the result type of an operation.";
197 throw std::runtime_error(exceptionText.c_str());
199 const auto actionResultTypeName = actionResultTypeClass->GetName();
203 if (!actionTypeClass) {
204 std::string exceptionText =
"An error occurred while inferring the action type of the operation.";
205 throw std::runtime_error(exceptionText.c_str());
207 const auto actionTypeName = actionTypeClass->GetName();
213 std::stringstream createAction_str;
214 createAction_str <<
"ROOT::Internal::TDF::CallBuildAndBook<" << nodeTypename <<
", " << actionTypeName;
215 for (
auto &branchTypeName : branchTypeNames) createAction_str <<
", " << branchTypeName;
216 createAction_str <<
">(" 217 <<
"reinterpret_cast<" << nodeTypename <<
"*>(" << thisPtr <<
"), " 218 <<
"*reinterpret_cast<ROOT::Detail::TDF::ColumnNames_t*>(" << &bl <<
"), " << nSlots
219 <<
", *reinterpret_cast<" << actionResultTypeName <<
"*>(" << r <<
"));";
220 auto error = TInterpreter::EErrorCode::kNoError;
221 gInterpreter->Calc(createAction_str.str().c_str(), &error);
223 std::string exceptionText =
"An error occurred while jitting this action:\n";
224 exceptionText += createAction_str.str();
225 throw std::runtime_error(exceptionText.c_str());
Namespace for new ROOT classes and functions.
Regular expression class.
std::string ColumnName2ColumnTypeName(const std::string &colName, TTree *tree, TCustomColumnBase *tmpBranch)
Return a string containing the type of the given branch.
Long_t JitTransformation(void *thisPtr, const std::string &methodName, const std::string &nodeTypeName, const std::string &name, const std::string &expression, TObjArray *branches, const std::vector< std::string > &tmpBranches, const std::map< std::string, TmpBranchBasePtr_t > &tmpBookedBranches, TTree *tree)
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.
void JitBuildAndBook(const ColumnNames_t &bl, const std::string &nodeTypename, void *thisPtr, const std::type_info &art, const std::type_info &at, const void *r, TTree *tree, unsigned int nSlots, const std::map< std::string, TmpBranchBasePtr_t > &tmpBranches)
std::vector< std::string > GetUsedBranchesNames(const std::string, TObjArray *, const std::vector< std::string > &)
The public interface to the TDataFrame federation of classes.