11 #ifndef ROOT_RDF_TINTERFACE 12 #define ROOT_RDF_TINTERFACE 16 #include <initializer_list> 23 #include <type_traits> 65 namespace TCCHelperTypes {
98 template <
typename Proxied,
typename DataSource =
void>
107 template <
typename T,
typename W>
120 template <
typename NewProxied>
123 static_assert(std::is_base_of<NewProxied, Proxied>::value,
124 "RInterface<T> can only be converted to RInterface<BaseOfT>");
142 template <typename T = Proxied, typename std::enable_if<std::is_same<T, RLoopManager>::value,
int>
::type = 0>
144 : fProxiedPtr(proxied), fImplWeakPtr(proxied), fValidCustomColumns(), fDataSource(proxied->GetDataSource())
168 template <typename F, typename std::enable_if<!std::is_convertible<F, std::string>::value,
int>::type = 0>
172 RDFInternal::CheckFilter(f);
173 auto loopManager = GetLoopManager();
175 constexpr
auto nColumns = ColTypes_t::list_size;
178 RDFInternal::DefineDataSourceColumns(validColumnNames, *loopManager, *fDataSource,
181 auto FilterPtr = std::make_shared<F_t>(std::move(f), validColumnNames, *fProxiedPtr,
name);
182 loopManager->Book(FilterPtr);
183 return RInterface<F_t, DS_t>(FilterPtr, fImplWeakPtr, fValidCustomColumns, fBranchNames, fDataSource);
193 template <typename F, typename std::enable_if<!std::is_convertible<F, std::string>::value,
int>::type = 0>
208 template <
typename F>
226 auto df = GetLoopManager();
227 const auto &aliasMap = df->GetAliasMap();
228 auto *
const tree = df->GetTree();
230 const auto &customColumns = df->GetCustomColumnNames();
234 fValidCustomColumns, fBranchNames, fDataSource);
236 const auto jittedFilter = std::make_shared<RDFDetail::RJittedFilter>(df.get(),
name);
238 branches, customColumns,
tree, fDataSource, df->GetID());
240 df->Book(jittedFilter);
242 fBranchNames, fDataSource);
265 template <typename F, typename std::enable_if<!std::is_convertible<F, std::string>::value,
int>::type = 0>
268 return DefineImpl<F, RDFDetail::TCCHelperTypes::TNothing>(
name, std::move(expression), columns);
293 template <
typename F>
296 return DefineImpl<F, RDFDetail::TCCHelperTypes::TSlot>(
name, std::move(expression), columns);
322 template <
typename F>
325 return DefineImpl<F, RDFDetail::TCCHelperTypes::TSlotAndEntry>(
name, std::move(expression), columns);
341 auto lm = GetLoopManager();
349 fBranchNames, fDataSource);
364 auto loopManager = GetLoopManager();
374 loopManager->AddColumnAlias(std::string(alias), validColumnName);
389 template <
typename... BranchTypes>
394 return SnapshotImpl<BranchTypes...>(treename, filename, columnList, options);
410 auto df = GetLoopManager();
414 if (columnList.empty()) {
415 auto nEntries = *this->Count();
416 auto snapshotRDF = std::make_shared<RInterface<RLoopManager>>(std::make_shared<RLoopManager>(nEntries));
419 auto tree = df->GetTree();
420 const auto nsID = df->GetID();
421 std::stringstream snapCall;
424 fValidCustomColumns, fBranchNames, fDataSource);
429 snapCall <<
"reinterpret_cast<ROOT::RDF::RInterface<" << upcastInterface.
GetNodeTypeName() <<
">*>(" << std::hex
430 << std::showbase << (size_t)&upcastInterface <<
")->Snapshot<";
432 const auto &customCols = df->GetCustomColumnNames();
433 const auto dontConvertVector =
false;
435 for (
auto &
c : validCols) {
436 const auto isCustom = std::find(customCols.begin(), customCols.end(),
c) != customCols.end();
440 if (!columnList.empty())
441 snapCall.seekp(-2, snapCall.cur);
442 snapCall <<
">(\"" << treename <<
"\", \"" << filename <<
"\", " 443 <<
"*reinterpret_cast<std::vector<std::string>*>(" 444 << std::hex << std::showbase << (size_t)&columnList <<
")," 445 <<
"*reinterpret_cast<ROOT::RDF::RSnapshotOptions*>(" << std::hex << std::showbase << (
size_t)&options
449 auto newRDFPtr =
gInterpreter->Calc(snapCall.str().c_str(), &errorCode);
450 if (TInterpreter::EErrorCode::kNoError != errorCode) {
451 std::string msg =
"Cannot jit Snapshot call. Interpreter error code is " + std::to_string(errorCode) +
".";
452 throw std::runtime_error(msg);
471 auto selectedColumns = ConvertRegexToColumns(columnNameRegexp,
"Snapshot");
472 return Snapshot(treename, filename, selectedColumns, options);
487 std::initializer_list<std::string> columnList,
491 return Snapshot(treename, filename, selectedColumns, options);
502 template <
typename... BranchTypes>
506 return CacheImpl<BranchTypes...>(columnList, staticSeq);
520 if (columnList.empty()) {
521 auto nEntries = *this->Count();
526 auto df = GetLoopManager();
527 auto tree = df->GetTree();
528 const auto nsID = df->GetID();
529 std::stringstream snapCall;
539 snapCall <<
"reinterpret_cast<ROOT::RDF::RInterface<" << upcastInterface.
GetNodeTypeName() <<
">*>(" << std::hex
540 << std::showbase << (size_t)&upcastInterface <<
")->Cache<";
542 const auto &customCols = df->GetCustomColumnNames();
543 for (
auto &
c : columnList) {
544 const auto isCustom = std::find(customCols.begin(), customCols.end(),
c) != customCols.end();
547 if (!columnList.empty())
548 snapCall.seekp(-2, snapCall.cur);
549 snapCall <<
">(*reinterpret_cast<std::vector<std::string>*>(" 550 << std::hex << std::showbase << (size_t)&columnList <<
"));";
553 auto newRDFPtr =
gInterpreter->Calc(snapCall.str().c_str(), &errorCode);
554 if (TInterpreter::EErrorCode::kNoError != errorCode) {
555 std::string msg =
"Cannot jit Cache call. Interpreter error code is " + std::to_string(errorCode) +
".";
556 throw std::runtime_error(msg);
569 auto selectedColumns = ConvertRegexToColumns(columnNameRegexp,
"Cache");
570 return Cache(selectedColumns);
586 if (stride == 0 || (end != 0 && end < begin))
587 throw std::runtime_error(
"Range: stride must be strictly greater than 0 and end must be greater than begin.");
589 throw std::runtime_error(
"Range was called with ImplicitMT enabled. Multi-thread ranges are not supported.");
591 auto df = GetLoopManager();
593 auto RangePtr = std::make_shared<Range_t>(begin, end, stride, *fProxiedPtr);
596 fBranchNames, fDataSource);
621 template <
typename F>
626 ForeachSlot(RDFInternal::AddSlotParameter<ret_type>(f, arg_types()), columns);
646 template <
typename F>
649 auto loopManager = GetLoopManager();
651 constexpr
auto nColumns = ColTypes_t::list_size;
654 RDFInternal::DefineDataSourceColumns(validColumnNames, *loopManager, *fDataSource,
656 using Helper_t = RDFInternal::ForeachSlotHelper<F>;
658 loopManager->Book(std::make_shared<Action_t>(Helper_t(std::move(f)), validColumnNames, *fProxiedPtr));
686 template <typename F, typename T = typename TTraits::CallableTraits<F>::ret_type>
690 std::is_default_constructible<T>::value,
691 "reduce object cannot be default-constructed. Please provide an initialisation value (redIdentity)");
692 return Reduce(std::move(f), columnName,
T());
704 template <typename F, typename T = typename TTraits::CallableTraits<F>::ret_type>
707 return Aggregate(f, f, columnName, redIdentity);
718 auto df = GetLoopManager();
719 const auto nSlots = df->GetNSlots();
720 auto cSPtr = std::make_shared<ULong64_t>(0);
721 using Helper_t = RDFInternal::CountHelper;
723 auto action = std::make_shared<Action_t>(Helper_t(cSPtr, nSlots),
ColumnNames_t({}), *fProxiedPtr);
737 template <
typename T,
typename COLL = std::vector<T>>
740 auto loopManager = GetLoopManager();
744 RDFInternal::DefineDataSourceColumns(validColumnNames, *loopManager, *fDataSource,
747 using Helper_t = RDFInternal::TakeHelper<T, T, COLL>;
749 auto valuesPtr = std::make_shared<COLL>();
750 const auto nSlots = loopManager->GetNSlots();
751 auto action = std::make_shared<Action_t>(Helper_t(valuesPtr, nSlots), validColumnNames, *fProxiedPtr);
752 loopManager->Book(action);
769 template <
typename V = RDFDetail::TInferType>
772 const auto userColumns = vName.empty() ? ColumnNames_t() : ColumnNames_t({std::string(vName)});
773 std::shared_ptr<::TH1D>
h(
nullptr);
775 ROOT::Internal::RDF::RIgnoreErrorLevelRAII iel(
kError);
777 h->SetDirectory(
nullptr);
780 if (
h->GetXaxis()->GetXmax() ==
h->GetXaxis()->GetXmin())
781 RDFInternal::HistoUtils<::TH1D>::SetCanExtendAllAxes(*
h);
782 return CreateAction<RDFInternal::ActionTypes::Histo1D, V>(userColumns,
h);
785 template <
typename V = RDFDetail::TInferType>
788 return Histo1D<V>({
"",
"", 128u, 0., 0.}, vName);
800 template <
typename V = RDFDetail::TInferType,
typename W = RDFDetail::TInferType>
803 const std::vector<std::string_view> columnViews = {vName, wName};
807 std::shared_ptr<::TH1D>
h(
nullptr);
809 ROOT::Internal::RDF::RIgnoreErrorLevelRAII iel(
kError);
812 return CreateAction<RDFInternal::ActionTypes::Histo1D, V, W>(userColumns,
h);
824 template <
typename V = RDFDetail::TInferType,
typename W = RDFDetail::TInferType>
827 return Histo1D<V, W>({
"",
"", 128u, 0., 0.}, vName, wName);
838 template <
typename V,
typename W>
841 return Histo1D<V, W>(
model,
"",
"");
859 template <
typename V1 = RDFDetail::TInferType,
typename V2 = RDFDetail::TInferType>
862 std::shared_ptr<::TH2D>
h(
nullptr);
864 ROOT::Internal::RDF::RIgnoreErrorLevelRAII iel(
kError);
867 if (!RDFInternal::HistoUtils<::TH2D>::HasAxisLimits(*h)) {
868 throw std::runtime_error(
"2D histograms with no axes limits are not supported yet.");
870 const std::vector<std::string_view> columnViews = {v1Name, v2Name};
874 return CreateAction<RDFInternal::ActionTypes::Histo2D, V1, V2>(userColumns,
h);
890 template <
typename V1 = RDFDetail::TInferType,
typename V2 = RDFDetail::TInferType,
891 typename W = RDFDetail::TInferType>
895 std::shared_ptr<::TH2D>
h(
nullptr);
897 ROOT::Internal::RDF::RIgnoreErrorLevelRAII iel(
kError);
900 if (!RDFInternal::HistoUtils<::TH2D>::HasAxisLimits(*h)) {
901 throw std::runtime_error(
"2D histograms with no axes limits are not supported yet.");
903 const std::vector<std::string_view> columnViews = {v1Name, v2Name, wName};
907 return CreateAction<RDFInternal::ActionTypes::Histo2D, V1, V2, W>(userColumns,
h);
910 template <
typename V1,
typename V2,
typename W>
913 return Histo2D<V1, V2, W>(
model,
"",
"",
"");
929 template <
typename V1 = RDFDetail::TInferType,
typename V2 = RDFDetail::TInferType,
930 typename V3 = RDFDetail::TInferType>
934 std::shared_ptr<::TH3D>
h(
nullptr);
936 ROOT::Internal::RDF::RIgnoreErrorLevelRAII iel(
kError);
939 if (!RDFInternal::HistoUtils<::TH3D>::HasAxisLimits(*h)) {
940 throw std::runtime_error(
"3D histograms with no axes limits are not supported yet.");
942 const std::vector<std::string_view> columnViews = {v1Name, v2Name, v3Name};
946 return CreateAction<RDFInternal::ActionTypes::Histo3D, V1, V2, V3>(userColumns,
h);
964 template <
typename V1 = RDFDetail::TInferType,
typename V2 = RDFDetail::TInferType,
965 typename V3 = RDFDetail::TInferType,
typename W = RDFDetail::TInferType>
969 std::shared_ptr<::TH3D>
h(
nullptr);
971 ROOT::Internal::RDF::RIgnoreErrorLevelRAII iel(
kError);
974 if (!RDFInternal::HistoUtils<::TH3D>::HasAxisLimits(*h)) {
975 throw std::runtime_error(
"3D histograms with no axes limits are not supported yet.");
977 const std::vector<std::string_view> columnViews = {v1Name, v2Name, v3Name, wName};
981 return CreateAction<RDFInternal::ActionTypes::Histo3D, V1, V2, V3, W>(userColumns,
h);
984 template <
typename V1,
typename V2,
typename V3,
typename W>
987 return Histo3D<V1, V2, V3, W>(
model,
"",
"",
"",
"");
1001 template <
typename V1 = RDFDetail::TInferType,
typename V2 = RDFDetail::TInferType>
1005 std::shared_ptr<::TProfile>
h(
nullptr);
1007 ROOT::Internal::RDF::RIgnoreErrorLevelRAII iel(
kError);
1011 if (!RDFInternal::HistoUtils<::TProfile>::HasAxisLimits(*h)) {
1012 throw std::runtime_error(
"Profiles with no axes limits are not supported yet.");
1014 const std::vector<std::string_view> columnViews = {v1Name, v2Name};
1018 return CreateAction<RDFInternal::ActionTypes::Profile1D, V1, V2>(userColumns,
h);
1034 template <
typename V1 = RDFDetail::TInferType,
typename V2 = RDFDetail::TInferType,
1035 typename W = RDFDetail::TInferType>
1039 std::shared_ptr<::TProfile>
h(
nullptr);
1041 ROOT::Internal::RDF::RIgnoreErrorLevelRAII iel(
kError);
1045 if (!RDFInternal::HistoUtils<::TProfile>::HasAxisLimits(*h)) {
1046 throw std::runtime_error(
"Profile histograms with no axes limits are not supported yet.");
1048 const std::vector<std::string_view> columnViews = {v1Name, v2Name, wName};
1052 return CreateAction<RDFInternal::ActionTypes::Profile1D, V1, V2, W>(userColumns,
h);
1055 template <
typename V1,
typename V2,
typename W>
1058 return Profile1D<V1, V2, W>(
model,
"",
"",
"");
1074 template <
typename V1 = RDFDetail::TInferType,
typename V2 = RDFDetail::TInferType,
1075 typename V3 = RDFDetail::TInferType>
1079 std::shared_ptr<::TProfile2D>
h(
nullptr);
1081 ROOT::Internal::RDF::RIgnoreErrorLevelRAII iel(
kError);
1085 if (!RDFInternal::HistoUtils<::TProfile2D>::HasAxisLimits(*h)) {
1086 throw std::runtime_error(
"2D profiles with no axes limits are not supported yet.");
1088 const std::vector<std::string_view> columnViews = {v1Name, v2Name, v3Name};
1092 return CreateAction<RDFInternal::ActionTypes::Profile2D, V1, V2, V3>(userColumns,
h);
1110 template <
typename V1 = RDFDetail::TInferType,
typename V2 = RDFDetail::TInferType,
1111 typename V3 = RDFDetail::TInferType,
typename W = RDFDetail::TInferType>
1115 std::shared_ptr<::TProfile2D>
h(
nullptr);
1117 ROOT::Internal::RDF::RIgnoreErrorLevelRAII iel(
kError);
1121 if (!RDFInternal::HistoUtils<::TProfile2D>::HasAxisLimits(*h)) {
1122 throw std::runtime_error(
"2D profiles with no axes limits are not supported yet.");
1124 const std::vector<std::string_view> columnViews = {v1Name, v2Name, v3Name, wName};
1128 return CreateAction<RDFInternal::ActionTypes::Profile2D, V1, V2, V3, W>(userColumns,
h);
1131 template <
typename V1,
typename V2,
typename V3,
typename W>
1134 return Profile2D<V1, V2, V3, W>(
model,
"",
"",
"",
"");
1153 template <
typename FirstColumn,
typename... OtherColumns,
typename T>
1156 auto h = std::make_shared<T>(std::move(
model));
1157 if (!RDFInternal::HistoUtils<T>::HasAxisLimits(*
h)) {
1158 throw std::runtime_error(
"The absence of axes limits is not supported yet.");
1160 return CreateAction<RDFInternal::ActionTypes::Fill, FirstColumn, OtherColumns...>(columnList,
h);
1174 template <
typename T>
1177 auto h = std::make_shared<T>(std::move(
model));
1178 if (!RDFInternal::HistoUtils<T>::HasAxisLimits(*
h)) {
1179 throw std::runtime_error(
"The absence of axes limits is not supported yet.");
1181 return CreateAction<RDFInternal::ActionTypes::Fill, RDFDetail::TInferType>(bl,
h, bl.size());
1195 template <
typename T = RDFDetail::TInferType>
1199 using RetType_t = RDFDetail::MinReturnType_t<T>;
1200 auto minV = std::make_shared<RetType_t>(std::numeric_limits<RetType_t>::max());
1201 return CreateAction<RDFInternal::ActionTypes::Min, T>(userColumns, minV);
1215 template <
typename T = RDFDetail::TInferType>
1219 using RetType_t = RDFDetail::MaxReturnType_t<T>;
1220 auto maxV = std::make_shared<RetType_t>(std::numeric_limits<RetType_t>::lowest());
1221 return CreateAction<RDFInternal::ActionTypes::Max, T>(userColumns, maxV);
1234 template <
typename T = RDFDetail::TInferType>
1238 auto meanV = std::make_shared<double>(0);
1239 return CreateAction<RDFInternal::ActionTypes::Mean, T>(userColumns, meanV);
1255 template <
typename T = RDFDetail::TInferType>
1258 const RDFDetail::SumReturnType_t<T> &initValue = RDFDetail::SumReturnType_t<T>{})
1261 auto sumV = std::make_shared<RDFDetail::SumReturnType_t<T>>(initValue);
1262 return CreateAction<RDFInternal::ActionTypes::Sum, T>(userColumns, sumV);
1284 bool returnEmptyReport =
false;
1289 if (std::is_same<Proxied, RLoopManager>::value && fValidCustomColumns.size() > 2)
1290 returnEmptyReport =
true;
1292 auto lm = GetLoopManager();
1293 auto rep = std::make_shared<RCutFlowReport>();
1294 using Helper_t = RDFInternal::ReportHelper<Proxied>;
1297 std::make_shared<Action_t>(Helper_t(rep, fProxiedPtr, returnEmptyReport),
ColumnNames_t({}), *fProxiedPtr);
1313 allColumns.emplace_back(colName);
1316 std::for_each(fValidCustomColumns.begin(), fValidCustomColumns.end(), addIfNotInternal);
1318 auto df = GetLoopManager();
1319 auto tree = df->GetTree();
1322 allColumns.insert(allColumns.end(), branchNames.begin(), branchNames.end());
1327 allColumns.insert(allColumns.end(), dsColNames.begin(), dsColNames.end());
1357 template <typename AccFun, typename MergeFun, typename R = typename TTraits::CallableTraits<AccFun>::ret_type,
1364 RDFInternal::CheckAggregate<R, MergeFun>(ArgTypesNoDecay());
1365 auto loopManager = GetLoopManager();
1367 constexpr
auto nColumns = ArgTypes::list_size;
1370 RDFInternal::DefineDataSourceColumns(validColumnNames, *loopManager, *fDataSource,
1372 auto accObjPtr = std::make_shared<U>(aggIdentity);
1373 using Helper_t = RDFInternal::AggregateHelper<AccFun, MergeFun, R, T, U>;
1375 auto action = std::make_shared<Action_t>(
1376 Helper_t(std::move(aggregator), std::move(merger), accObjPtr, loopManager->GetNSlots()), validColumnNames,
1378 loopManager->Book(action);
1394 template <typename AccFun, typename MergeFun, typename R = typename TTraits::CallableTraits<AccFun>::ret_type,
1401 std::is_default_constructible<U>::value,
1402 "aggregated object cannot be default-constructed. Please provide an initialisation value (aggIdentity)");
1403 return Aggregate(std::move(aggregator), std::move(merger), columnName, U());
1438 template <
typename... ColumnTypes,
typename Helper>
1444 using AH = RDFDetail::RActionImpl<Helper>;
1445 static_assert(std::is_base_of<AH, Helper>::value && std::is_convertible<Helper *, AH *>::value,
1446 "Action helper of type T must publicly inherit from ROOT::Detail::RDF::RActionImpl<T>");
1447 auto lm = GetLoopManager();
1448 using Action_t =
typename RDFInternal::RAction<Helper, Proxied, TTraits::TypeList<ColumnTypes...>>;
1449 auto resPtr =
h.GetResultPtr();
1450 auto action = std::make_shared<Action_t>(Helper(std::forward<Helper>(
h)), columns, *fProxiedPtr);
1458 auto lm = GetLoopManager();
1462 const auto entryColName =
"tdfentry_";
1463 auto entryColGen = [](
unsigned int,
ULong64_t entry) {
return entry; };
1464 DefineImpl<decltype(entryColGen), RDFDetail::TCCHelperTypes::TSlotAndEntry>(entryColName, std::move(entryColGen),
1466 fValidCustomColumns.emplace_back(entryColName);
1469 const auto slotColName =
"tdfslot_";
1470 auto slotColGen = [](
unsigned int slot) {
return slot; };
1471 DefineImpl<decltype(slotColGen), RDFDetail::TCCHelperTypes::TSlot>(slotColName, std::move(slotColGen), {});
1472 fValidCustomColumns.emplace_back(slotColName);
1477 const auto theRegexSize = columnNameRegexp.size();
1478 std::string theRegex(columnNameRegexp);
1480 const auto isEmptyRegex = 0 == theRegexSize;
1482 if (theRegexSize > 0 && theRegex[0] !=
'^')
1483 theRegex =
"^" + theRegex;
1484 if (theRegexSize > 0 && theRegex[theRegexSize - 1] !=
'$')
1485 theRegex = theRegex +
"$";
1488 selectedColumns.reserve(32);
1494 for (
auto &&
branchName : fValidCustomColumns) {
1501 auto df = GetLoopManager();
1502 auto tree = df->GetTree();
1514 for (
auto &dsColName : dsColNames) {
1515 if ((isEmptyRegex || -1 != regexp.
Index(dsColName.c_str(), &
dummy)) &&
1517 selectedColumns.emplace_back(dsColName);
1522 if (selectedColumns.empty()) {
1523 std::string
text(callerName);
1524 if (columnNameRegexp.empty()) {
1525 text =
": there is no column available to match.";
1527 text =
": regex \"" + columnNameRegexp +
"\" did not match any column.";
1529 throw std::runtime_error(text);
1531 return selectedColumns;
1537 inline static std::string GetNodeTypeName();
1540 template <
typename ActionType,
typename... BranchTypes,
typename ActionResultType,
1541 typename std::enable_if<!RDFInternal::TNeedJitting<BranchTypes...>::value,
int>::type = 0>
1544 auto lm = GetLoopManager();
1545 constexpr
auto nColumns =
sizeof...(BranchTypes);
1549 RDFInternal::TypeList<BranchTypes...>());
1550 const auto nSlots = lm->GetNSlots();
1552 RDFInternal::BuildAndBook<BranchTypes...>(selectedCols,
r, nSlots, *lm, *fProxiedPtr, (ActionType *)
nullptr);
1559 template <
typename ActionType,
typename... BranchTypes,
typename ActionResultType,
1560 typename std::enable_if<RDFInternal::TNeedJitting<BranchTypes...>::value,
int>::type = 0>
1564 auto lm = GetLoopManager();
1565 auto realNColumns = (nColumns > -1 ? nColumns :
sizeof...(BranchTypes));
1567 const unsigned int nSlots = lm->GetNSlots();
1568 const auto &customColumns = lm->GetCustomColumnNames();
1569 auto tree = lm->GetTree();
1570 auto rOnHeap = RDFInternal::MakeSharedOnHeap(r);
1573 upcastNode, fImplWeakPtr, fValidCustomColumns, fBranchNames, fDataSource);
1575 auto &resultProxy = resultProxyAndActionPtrPtr.first;
1576 auto actionPtrPtrOnHeap = RDFInternal::MakeSharedOnHeap(resultProxyAndActionPtrPtr.second);
1579 typeid(std::shared_ptr<ActionResultType>),
typeid(ActionType), rOnHeap,
tree,
1580 nSlots, customColumns, fDataSource, actionPtrPtrOnHeap, lm->GetID());
1585 template <typename F, typename CustomColumnType, typename RetType = typename TTraits::CallableTraits<F>::ret_type>
1589 auto loopManager = GetLoopManager();
1594 using ColTypesTmp_t =
typename RDFInternal::RemoveFirstParameterIf<
1595 std::is_same<CustomColumnType, RDFDetail::TCCHelperTypes::TSlot>::value, ArgTypes_t>
::type;
1596 using ColTypes_t =
typename RDFInternal::RemoveFirstTwoParametersIf<
1597 std::is_same<CustomColumnType, RDFDetail::TCCHelperTypes::TSlotAndEntry>::value, ColTypesTmp_t>
::type;
1599 constexpr
auto nColumns = ColTypes_t::list_size;
1602 RDFInternal::DefineDataSourceColumns(validColumnNames, *loopManager, *fDataSource,
1608 std::string retTypeNameFwdDecl;
1609 if (retTypeName.empty()) {
1618 retTypeNameFwdDecl =
"class " + retTypeName +
";/* Did you forget to declare type " + retTypeName +
" in the interpreter?*/";
1620 const auto retTypeDeclaration =
"namespace __tdf" + std::to_string(loopManager->GetID()) +
" { " + retTypeNameFwdDecl +
" using " +
1621 std::string(name) +
"_type = " + retTypeName +
"; }";
1624 loopManager->Book(std::make_shared<NewCol_t>(name, std::move(expression), validColumnNames, loopManager.get()));
1625 loopManager->AddCustomColumnName(name);
1626 RInterface<Proxied> newInterface(fProxiedPtr, fImplWeakPtr, fValidCustomColumns, fBranchNames, fDataSource);
1628 return newInterface;
1634 template <typename F, typename CustomColumnType, typename RetType = typename TTraits::CallableTraits<F>::ret_type>
1635 typename std::enable_if<!std::is_convertible<F, std::string>::value &&
1636 !std::is_default_constructible<RetType>::value,
1641 "Error in `Define`: type returned by expression is not default-constructible");
1655 template <
typename... ColumnTypes>
1661 auto lm = GetLoopManager();
1666 TTraits::TypeList<ColumnTypes...>());
1668 const std::string fullTreename(treename);
1670 const auto lastSlash = treename.rfind(
'/');
1672 if (std::string_view::npos != lastSlash) {
1673 dirname = treename.substr(0, lastSlash);
1674 treename = treename.substr(lastSlash + 1, treename.size());
1678 std::shared_ptr<RDFInternal::RActionBase> actionPtr;
1681 using Helper_t = RDFInternal::SnapshotHelper<ColumnTypes...>;
1683 actionPtr.reset(
new Action_t(Helper_t(filename, dirname, treename, validCols, columnList, options), validCols,
1687 using Helper_t = RDFInternal::SnapshotHelperMT<ColumnTypes...>;
1690 new Action_t(Helper_t(lm->GetNSlots(), filename, dirname, treename, validCols, columnList, options),
1691 validCols, *fProxiedPtr));
1694 lm->Book(actionPtr);
1704 auto rlm_ptr = std::make_shared<RLoopManager>(
nullptr, validCols);
1705 auto snapshotRDF = std::make_shared<RInterface<RLoopManager>>(rlm_ptr);
1707 auto chain = std::make_shared<TChain>(fullTreename.c_str());
1708 chain->Add(std::string(filename).c_str());
1709 snapshotRDF->fProxiedPtr->SetTree(chain);
1711 auto snapshotRDFResPtr =
MakeResultPtr(snapshotRDF, lm, actionPtr.get());
1712 if (!options.
fLazy) {
1716 return snapshotRDFResPtr;
1721 template <
typename... BranchTypes, std::size_t...
S>
1726 constexpr
bool areCopyConstructible =
1727 RDFInternal::TEvalAnd<std::is_copy_constructible<BranchTypes>::value...>::value;
1728 static_assert(areCopyConstructible,
"Columns of a type which is not copy constructible cannot be cached yet.");
1734 auto lm = GetLoopManager();
1735 RDFInternal::DefineDataSourceColumns(columnList, *lm, *fDataSource, s, TTraits::TypeList<BranchTypes...>());
1738 auto colHolders = std::make_tuple(Take<BranchTypes>(columnList[
S])...);
1739 auto ds = std::make_unique<
RLazyDS<BranchTypes...>>(std::make_pair(columnList[S], std::get<S>(colHolders))...);
1744 typeid(
typename std::decay<decltype(std::get<S>(colHolders))>::type::Value_t))...};
1753 auto df = fImplWeakPtr.lock();
1755 throw std::runtime_error(
"The main RDataFrame is not reachable: did it go out of scope?");
1760 RInterface(
const std::shared_ptr<Proxied> &proxied,
const std::weak_ptr<RLoopManager> &impl,
1761 const ColumnNames_t &validColumns,
const std::shared_ptr<const ColumnNames_t> &datasetColumns,
1763 : fProxiedPtr(proxied), fImplWeakPtr(impl), fValidCustomColumns(validColumns),
1764 fDataSource(ds), fBranchNames(datasetColumns)
1774 auto loopManager = GetLoopManager();
1775 auto tree = loopManager->GetTree();
1776 if (
tree && !fBranchNames) {
1781 fValidCustomColumns, fDataSource);
1789 return "ROOT::Detail::RDF::RFilterBase";
1795 return "ROOT::Detail::RDF::RLoopManager";
1801 return "ROOT::Detail::RDF::RRangeBase";
1807 return "ROOT::Detail::RDF::RJittedFilter";
1814 #endif // ROOT_RDF_INTERFACE RInterface< Proxied, DS_t > Define(std::string_view name, std::string_view expression)
Creates a custom column.
typename RemoveFirstParameter< T >::type RemoveFirstParameter_t
std::string JitBuildAndBook(const ColumnNames_t &bl, const std::string &prevNodeTypename, void *prevNode, const std::type_info &art, const std::type_info &at, const void *rOnHeap, TTree *tree, const unsigned int nSlots, const ColumnNames_t &customColumns, RDataSource *ds, const std::shared_ptr< RActionBase *> *const actionPtrPtr, unsigned int namespaceID)
RInterface< RDFDetail::RRange< Proxied >, DS_t > Range(unsigned int begin, unsigned int end, unsigned int stride=1)
Creates a node that filters entries based on range: [begin, end)
RResultPtr< typename Helper::Result_t > Book(Helper &&h, const ColumnNames_t &columns={})
Book execution of a custom action using a user-defined helper object.
void BookDefineJit(std::string_view name, std::string_view expression, RLoopManager &lm, RDataSource *ds)
Smart pointer for the return type of actions.
const std::weak_ptr< RLoopManager > fImplWeakPtr
Weak pointer to the RLoopManager at the root of the graph.
RInterface< Proxied, DS_t > Define(std::string_view name, F expression, const ColumnNames_t &columns={})
Creates a custom column.
ColumnNames_t GetTopLevelBranchNames(TTree &t)
Get all the top-level branches names, including the ones of the friend trees.
void Run(unsigned int slot, Long64_t entry) final
bool AtLeastOneEmptyString(const std::vector< std::string_view > strings)
RResultPtr< ActionResultType > CreateAction(const ColumnNames_t &columns, const std::shared_ptr< ActionResultType > &r, const int nColumns=-1)
RInterface< RLoopManager > Cache(std::string_view columnNameRegexp="")
Save selected columns in memory.
A struct which stores the parameters of a TProfile2D.
RResultPtr< T > Fill(T &&model, const ColumnNames_t &bl)
Return an object of type T on which T::Fill will be called once per event (lazy action) ...
Namespace for new ROOT classes and functions.
virtual const std::vector< std::string > & GetColumnNames() const =0
Returns a reference to the collection of the dataset's column names.
RResultPtr< RDFDetail::SumReturnType_t< T > > Sum(std::string_view columnName="", const RDFDetail::SumReturnType_t< T > &initValue=RDFDetail::SumReturnType_t< T >{})
Return the sum of processed column values (lazy action)
bool IsInternalColumn(std::string_view colName)
A struct which stores the parameters of a TH3D.
std::shared_ptr< RLoopManager > GetLoopManager()
Get the RLoopManager if reachable. If not, throw.
typename TakeFirstParameter< T >::type TakeFirstParameter_t
void Foreach(F f, const ColumnNames_t &columns={})
Execute a user-defined function on each entry (instant action)
RInterface< Proxied, DS_t > Alias(std::string_view alias, std::string_view columnName)
Allow to refer to a column with a different name.
std::pair< Double_t, Double_t > Range_t
ColumnNames_t ConvertRegexToColumns(std::string_view columnNameRegexp, std::string_view callerName)
RInterface< RDFDetail::RFilter< F, Proxied >, DS_t > Filter(F f, const std::initializer_list< std::string > &columns)
Append a filter to the call graph.
RResultPtr< T > Reduce(F f, std::string_view columnName, const T &redIdentity)
Execute a user-defined reduce operation on the values of a column.
Regular expression class.
RDFDetail::ColumnNames_t ColumnNames_t
RResultPtr< RDFDetail::MinReturnType_t< T > > Min(std::string_view columnName="")
Return the minimum of processed column values (lazy action)
RResultPtr<::TH2D > Histo2D(const TH2DModel &model)
static std::string GetNodeTypeName()
Return string containing fully qualified type name of the node pointed by fProxied.
RResultPtr< T > Fill(T &&model, const ColumnNames_t &columnList)
Return an object of type T on which T::Fill will be called once per event (lazy action) ...
RResultPtr< RCutFlowReport > Report()
Gather filtering statistics.
RResultPtr<::TH3D > Histo3D(const TH3DModel &model, std::string_view v1Name="", std::string_view v2Name="", std::string_view v3Name="")
Fill and return a three-dimensional histogram (lazy action)
RResultPtr< RInterface< RLoopManager > > Snapshot(std::string_view treename, std::string_view filename, const ColumnNames_t &columnList, const RSnapshotOptions &options=RSnapshotOptions())
Save selected columns to disk, in a new TTree treename in file filename.
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 GetColumnNames()
Returns the names of the available columns.
RInterface< RLoopManager > CacheImpl(const ColumnNames_t &columnList, std::index_sequence< S... > s)
Implementation of cache.
ColumnNames_t fValidCustomColumns
Names of columns Defined for this branch of the functional graph.
RResultPtr< RInterface< RLoopManager > > SnapshotImpl(std::string_view treename, std::string_view filename, const ColumnNames_t &columnList, const RSnapshotOptions &options)
Implementation of snapshot.
RResultPtr< RInterface< RLoopManager > > Snapshot(std::string_view treename, std::string_view filename, std::string_view columnNameRegexp="", const RSnapshotOptions &options=RSnapshotOptions())
Save selected columns to disk, in a new TTree treename in file filename.
A struct which stores the parameters of a TH2D.
RResultPtr<::TProfile > Profile1D(const TProfile1DModel &model, std::string_view v1Name="", std::string_view v2Name="")
Fill and return a one-dimensional profile (lazy action)
RResultPtr< T > MakeResultPtr(const std::shared_ptr< T > &r, const std::shared_ptr< RLoopManager > &df, ROOT::Internal::RDF::RActionBase *actionPtr)
Create a RResultPtr and set its pointer to the corresponding RAction This overload is invoked by non-...
A collection of options to steer the creation of the dataset on file.
RResultPtr<::TProfile > Profile1D(const TProfile1DModel &model, std::string_view v1Name, std::string_view v2Name, std::string_view wName)
Fill and return a one-dimensional profile (lazy action)
RResultPtr< RInterface< RLoopManager > > Snapshot(std::string_view treename, std::string_view filename, std::initializer_list< std::string > columnList, const RSnapshotOptions &options=RSnapshotOptions())
Save selected columns to disk, in a new TTree treename in file filename.
RResultPtr< RDFDetail::MaxReturnType_t< T > > Max(std::string_view columnName="")
Return the maximum of processed column values (lazy action)
RInterface< Proxied, DS_t > DefineSlotEntry(std::string_view name, F expression, const ColumnNames_t &columns={})
Creates a custom column with a value dependent on the processing slot and the current entry...
RResultPtr<::TProfile2D > Profile2D(const TProfile2DModel &model, std::string_view v1Name, std::string_view v2Name, std::string_view v3Name, std::string_view wName)
Fill and return a two-dimensional profile (lazy action)
RResultPtr<::TProfile2D > Profile2D(const TProfile2DModel &model, std::string_view v1Name="", std::string_view v2Name="", std::string_view v3Name="")
Fill and return a two-dimensional profile (lazy action)
char * DemangleTypeIdName(const std::type_info &ti, int &errorCode)
Demangle in a portable way the type id name.
std::shared_ptr<::TH3D > GetHistogram() const
RVec< T > Filter(const RVec< T > &v, F &&f)
Create a new collection with the elements passing the filter expressed by the predicate.
RResultPtr<::TH1D > Histo1D(const TH1DModel &model={"", "", 128u, 0., 0.})
Fill and return a one-dimensional histogram with the weighted values of a column (lazy action) ...
RResultPtr< T > Reduce(F f, std::string_view columnName="")
Execute a user-defined reduce operation on the values of a column.
RInterface< RLoopManager > Cache(const ColumnNames_t &columnList)
Save selected columns in memory.
RooArgSet S(const RooAbsArg &v1)
RResultPtr<::TH1D > Histo1D(std::string_view vName)
std::string printValue(const TDatime *val)
Print a TDatime at the prompt.
3-D histogram with a double per channel (see TH1 documentation)}
std::shared_ptr< RFilterBase > UpcastNode(const std::shared_ptr< RFilterBase > ptr)
RInterface< RDFDetail::RRange< Proxied >, DS_t > Range(unsigned int end)
Creates a node that filters entries based on range.
RResultPtr<::TH1D > Histo1D(std::string_view vName, std::string_view wName)
Fill and return a one-dimensional histogram with the weighted values of a column (lazy action) ...
std::shared_ptr<::TH2D > GetHistogram() const
const std::shared_ptr< Proxied > fProxiedPtr
Smart pointer to the graph node encapsulated by this RInterface.
The public interface to the RDataFrame federation of classes.
void BookFilterJit(RJittedFilter *jittedFilter, void *prevNode, std::string_view prevNodeTypeName, std::string_view name, std::string_view expression, const std::map< std::string, std::string > &aliasMap, const ColumnNames_t &branches, const ColumnNames_t &customCols, TTree *tree, RDataSource *ds, unsigned int namespaceID)
std::shared_ptr<::TProfile > GetProfile() const
RInterface< RDFDetail::RFilter< F, Proxied >, DS_t > Filter(F f, const ColumnNames_t &columns={}, std::string_view name="")
Append a filter to the call graph.
A RDataSource implementation which is built on top of result proxies.
std::shared_ptr<::TProfile2D > GetProfile() const
RResultPtr< U > Aggregate(AccFun aggregator, MergeFun merger, std::string_view columnName="")
Execute a user-defined accumulation operation on the processed column values in each processing slot...
RResultPtr<::TH3D > Histo3D(const TH3DModel &model)
ColumnNames_t GetValidatedColumnNames(RLoopManager &lm, const unsigned int nColumns, const ColumnNames_t &columns, const ColumnNames_t &datasetColumns, const ColumnNames_t &validCustomColumns, RDataSource *ds)
Given the desired number of columns and the user-provided list of columns:
RResultPtr< RInterface< RLoopManager > > Snapshot(std::string_view treename, std::string_view filename, const ColumnNames_t &columnList, const RSnapshotOptions &options=RSnapshotOptions())
Save selected columns to disk, in a new TTree treename in file filename.
RResultPtr<::TH1D > Histo1D(const TH1DModel &model={"", "", 128u, 0., 0.}, std::string_view vName="")
Fill and return a one-dimensional histogram with the values of a column (lazy action) ...
RResultPtr<::TProfile2D > Profile2D(const TProfile2DModel &model)
std::enable_if<!std::is_convertible< F, std::string >::value &&!std::is_default_constructible< RetType >::value, RInterface< Proxied, DS_t > >::type DefineImpl(std::string_view, F, const ColumnNames_t &)
RResultPtr<::TH1D > Histo1D(const TH1DModel &model, std::string_view vName, std::string_view wName)
Fill and return a one-dimensional histogram with the weighted values of a column (lazy action) ...
A struct which stores the parameters of a TH1D.
ROOT's RDataFrame offers a high level interface for analyses of data stored in TTrees, CSV's and other data formats.
RInterface(const std::shared_ptr< Proxied > &proxied, const std::weak_ptr< RLoopManager > &impl, const ColumnNames_t &validColumns, const std::shared_ptr< const ColumnNames_t > &datasetColumns, RDataSource *ds)
std::string ColumnName2ColumnTypeName(const std::string &colName, unsigned int namespaceID, TTree *tree, RDataSource *ds, bool isCustomColumn, bool vector2tvec)
Return a string containing the type of the given branch.
const std::shared_ptr< Proxied > & GetProxiedPtr() const
RInterface< Proxied, DS_t > DefineSlot(std::string_view name, F expression, const ColumnNames_t &columns={})
Creates a custom column with a value dependent on the processing slot.
RResultPtr<::TH3D > Histo3D(const TH3DModel &model, std::string_view v1Name, std::string_view v2Name, std::string_view v3Name, std::string_view wName)
Fill and return a three-dimensional histogram (lazy action)
Ssiz_t Index(const TString &str, Ssiz_t *len, Ssiz_t start=0) const
Find the first occurrence of the regexp in string and return the position, or -1 if there is no match...
A struct which stores the parameters of a TProfile.
unsigned long long ULong64_t
Print a TSeq at the prompt:
static RooMathCoreReg dummy
basic_string_view< char > string_view
std::enable_if< std::is_default_constructible< RetType >::value, RInterface< Proxied, DS_t > >::type DefineImpl(std::string_view name, F &&expression, const ColumnNames_t &columns)
RResultPtr< ULong64_t > Count()
Return the number of entries processed (lazy action)
ROOT type_traits extensions.
static constexpr double s
RResultPtr<::TH2D > Histo2D(const TH2DModel &model, std::string_view v1Name, std::string_view v2Name, std::string_view wName)
Fill and return a weighted two-dimensional histogram (lazy action)
void CheckCustomColumn(std::string_view definedCol, TTree *treePtr, const ColumnNames_t &customCols, const ColumnNames_t &dataSourceColumns)
make_index_sequence< sizeof...(_Tp)> index_sequence_for
Profile2D histograms are used to display the mean value of Z and its RMS for each cell in X...
Extract types from the signature of a callable object. See CallableTraits.
RResultPtr< U > Aggregate(AccFun aggregator, MergeFun merger, std::string_view columnName, const U &aggIdentity)
Execute a user-defined accumulation operation on the processed column values in each processing slot...
Binding & operator=(OUT(*fun)(void))
ColumnNames_t GetValidatedColumnNames(const unsigned int nColumns, const ColumnNames_t &columns)
Prepare the call to the GetValidatedColumnNames routine, making sure that GetBranchNames, which is expensive in terms of runtime, is called at most once.
RInterface< RDFDetail::RJittedFilter, DS_t > Filter(std::string_view expression, std::string_view name="")
Append a filter to the call graph.
void CheckTypesAndPars(unsigned int nTemplateParams, unsigned int nColumnNames)
Bool_t IsImplicitMTEnabled()
Returns true if the implicit multi-threading in ROOT is enabled.
RResultPtr<::TProfile > Profile1D(const TProfile1DModel &model)
RInterface(const std::shared_ptr< Proxied > &proxied)
Only enabled when building a RInterface<RLoopManager>
RResultPtr<::TH2D > Histo2D(const TH2DModel &model, std::string_view v1Name="", std::string_view v2Name="")
Fill and return a two-dimensional histogram (lazy action)
RResultPtr< ActionResultType > CreateAction(const ColumnNames_t &columns, const std::shared_ptr< ActionResultType > &r)
RResultPtr< COLL > Take(std::string_view column="")
Return a collection of values of a column (lazy action, returns a std::vector by default) ...
RResultPtr< double > Mean(std::string_view columnName="")
Return the mean of processed column values (lazy action)
std::shared_ptr<::TH1D > GetHistogram() const
RDataSource defines an API that RDataFrame can use to read arbitrary data formats.
std::shared_ptr< const ColumnNames_t > fBranchNames
Cache of the chain columns names.
RInterface< RDFDetail::RFilter< F, Proxied >, DS_t > Filter(F f, std::string_view name)
Append a filter to the call graph.
make_integer_sequence< size_t, _Np > make_index_sequence
ColumnNames_t GetBranchNames(TTree &t)
Get all the branches names, including the ones of the friend trees.
RInterface< RLoopManager > Cache(const ColumnNames_t &columnList)
Save selected columns in memory.
void ForeachSlot(F f, const ColumnNames_t &columns={})
Execute a user-defined function requiring a processing slot index on each entry (instant action) ...
2-D histogram with a double per channel (see TH1 documentation)}