11#ifndef ROOT_RDF_TINTERFACE
12#define ROOT_RDF_TINTERFACE
38#include <initializer_list>
69template <
typename Proxied,
typename DataSource>
72using RNode = RInterface<::ROOT::Detail::RDF::RNodeBase, void>;
86template <
typename Proxied,
typename DataSource =
void>
100 const std::string &fullTreeName,
101 const std::string &fileName,
104 std::unique_ptr<RDFInternal::RActionBase> actionPtr);
106 template <
typename T,
typename W>
133 template <typename T = Proxied, typename std::enable_if<std::is_same<T, RLoopManager>::value,
int>
::type = 0>
193 template <typename F, typename std::enable_if<!std::is_convertible<F, std::string>::value,
int>
::type = 0>
197 RDFInternal::CheckFilter(
f);
198 using ColTypes_t =
typename TTraits::CallableTraits<F>::arg_types;
199 constexpr auto nColumns = ColTypes_t::list_size;
201 const auto newColumns =
206 auto filterPtr = std::make_shared<F_t>(std::move(
f), validColumnNames,
fProxiedPtr, newColumns,
name);
219 template <typename F, typename std::enable_if<!std::is_convertible<F, std::string>::value,
int>
::type = 0>
235 template <
typename F>
256 using BaseNodeType_t =
typename std::remove_pointer<
decltype(upcastNodeOnHeap)>::type::element_type;
258 const auto jittedFilter = std::make_shared<RDFDetail::RJittedFilter>(
fLoopManager,
name);
298 template <typename F, typename std::enable_if<!std::is_convertible<F, std::string>::value,
int>
::type = 0>
301 return DefineImpl<F, RDFDetail::CustomColExtraArgs::None>(
name, std::move(expression), columns);
327 template <
typename F>
330 return DefineImpl<F, RDFDetail::CustomColExtraArgs::Slot>(
name, std::move(expression), columns);
357 template <
typename F>
360 return DefineImpl<F, RDFDetail::CustomColExtraArgs::SlotAndEntry>(
name, std::move(expression), columns);
382 auto jittedCustomColumn =
468 template <
typename... ColumnTypes>
473 return SnapshotImpl<ColumnTypes...>(treename, filename, columnList, options);
494 if (columnList.empty()) {
495 auto nEntries = *this->
Count();
496 auto snapshotRDF = std::make_shared<RInterface<RLoopManager>>(std::make_shared<RLoopManager>(nEntries));
501 std::stringstream snapCall;
509 snapCall <<
"*reinterpret_cast<ROOT::RDF::RResultPtr<ROOT::RDF::RInterface<ROOT::Detail::RDF::RLoopManager>>*>("
511 <<
") = reinterpret_cast<ROOT::RDF::RInterface<ROOT::Detail::RDF::RNodeBase>*>("
515 const auto dontConvertVector =
false;
519 for (
auto &
c : validColumnNames) {
520 const auto isCustom = std::find(customCols.begin(), customCols.end(),
c) != customCols.end();
526 if (!columnList.empty())
527 snapCall.seekp(-2, snapCall.cur);
528 snapCall <<
">(\"" << treename <<
"\", \"" << filename <<
"\", "
529 <<
"*reinterpret_cast<std::vector<std::string>*>("
535 if (TInterpreter::EErrorCode::kNoError != errorCode) {
536 std::string msg =
"Cannot jit Snapshot call. Interpreter error code is " + std::to_string(errorCode) +
".";
537 throw std::runtime_error(msg);
560 return Snapshot(treename, filename, selectedColumns, options);
578 std::initializer_list<std::string> columnList,
582 return Snapshot(treename, filename, selectedColumns, options);
598 template <
typename... ColumnTypes>
602 return CacheImpl<ColumnTypes...>(columnList, staticSeq);
615 if (columnList.empty()) {
616 auto nEntries = *this->
Count();
623 std::stringstream cacheCall;
630 cacheCall <<
"*reinterpret_cast<ROOT::RDF::RInterface<ROOT::Detail::RDF::RLoopManager>*>("
632 <<
") = reinterpret_cast<ROOT::RDF::RInterface<ROOT::Detail::RDF::RNodeBase>*>("
636 for (
auto &
c : columnList) {
637 const auto isCustom = std::find(customCols.begin(), customCols.end(),
c) != customCols.end();
643 if (!columnList.empty())
644 cacheCall.seekp(-2, cacheCall.cur);
645 cacheCall <<
">(*reinterpret_cast<std::vector<std::string>*>("
649 gInterpreter->Calc(cacheCall.str().c_str(), &errorCode);
650 if (TInterpreter::EErrorCode::kNoError != errorCode) {
651 std::string msg =
"Cannot jit Cache call. Interpreter error code is " + std::to_string(errorCode) +
".";
652 throw std::runtime_error(msg);
667 return Cache(selectedColumns);
679 return Cache(selectedColumns);
696 if (stride == 0 || (end != 0 && end < begin))
697 throw std::runtime_error(
"Range: stride must be strictly greater than 0 and end must be greater than begin.");
701 auto rangePtr = std::make_shared<Range_t>(begin, end, stride,
fProxiedPtr);
729 template <
typename F>
732 using arg_types =
typename TTraits::CallableTraits<
decltype(
f)>::arg_types_nodecay;
733 using ret_type =
typename TTraits::CallableTraits<
decltype(
f)>::ret_type;
734 ForeachSlot(RDFInternal::AddSlotParameter<ret_type>(
f, arg_types()), columns);
754 template <
typename F>
757 using ColTypes_t = TypeTraits::RemoveFirstParameter_t<typename TTraits::CallableTraits<F>::arg_types>;
758 constexpr auto nColumns = ColTypes_t::list_size;
764 using Helper_t = RDFInternal::ForeachSlotHelper<F>;
767 auto action = std::make_unique<Action_t>(Helper_t(std::move(
f)), validColumnNames,
fProxiedPtr, newColumns);
798 template <typename F, typename T = typename TTraits::CallableTraits<F>::ret_type>
802 std::is_default_constructible<T>::value,
803 "reduce object cannot be default-constructed. Please provide an initialisation value (redIdentity)");
804 return Reduce(std::move(
f), columnName,
T());
817 template <typename F, typename T = typename TTraits::CallableTraits<F>::ret_type>
833 auto cSPtr = std::make_shared<ULong64_t>(0);
834 using Helper_t = RDFInternal::CountHelper;
861 template <
typename T,
typename COLL = std::vector<T>>
870 using Helper_t = RDFInternal::TakeHelper<T, T, COLL>;
872 auto valuesPtr = std::make_shared<COLL>();
875 auto action = std::make_unique<Action_t>(Helper_t(valuesPtr, nSlots), validColumnNames,
fProxiedPtr, newColumns);
894 template <
typename V = RDFDetail::RInferredType>
898 std::shared_ptr<::TH1D>
h(
nullptr);
900 ROOT::Internal::RDF::RIgnoreErrorLevelRAII iel(
kError);
902 h->SetDirectory(
nullptr);
905 if (
h->GetXaxis()->GetXmax() ==
h->GetXaxis()->GetXmin())
906 RDFInternal::HistoUtils<::TH1D>::SetCanExtendAllAxes(*
h);
907 return CreateAction<RDFInternal::ActionTags::Histo1D, V>(userColumns,
h);
919 template <
typename V = RDFDetail::RInferredType>
922 const auto h_name = std::string(vName);
923 const auto h_title = h_name +
";" + h_name +
";";
924 return Histo1D<V>({h_name.c_str(), h_title.c_str(), 128u, 0., 0.}, vName);
937 template <
typename V = RDFDetail::RInferredType,
typename W = RDFDetail::RInferredType>
940 const std::vector<std::string_view> columnViews = {vName, wName};
944 std::shared_ptr<::TH1D>
h(
nullptr);
946 ROOT::Internal::RDF::RIgnoreErrorLevelRAII iel(
kError);
949 return CreateAction<RDFInternal::ActionTags::Histo1D, V, W>(userColumns,
h);
963 template <
typename V = RDFDetail::RInferredType,
typename W = RDFDetail::RInferredType>
967 const auto h_name = std::string(vName) +
"*" + std::string(wName);
968 const auto h_title = h_name +
";" + h_name +
";";
969 return Histo1D<V, W>({h_name.c_str(), h_title.c_str(), 128u, 0., 0.}, vName, wName);
981 template <
typename V,
typename W>
984 return Histo1D<V, W>(
model,
"",
"");
1003 template <
typename V1 = RDFDetail::RInferredType,
typename V2 = RDFDetail::RInferredType>
1006 std::shared_ptr<::TH2D>
h(
nullptr);
1008 ROOT::Internal::RDF::RIgnoreErrorLevelRAII iel(
kError);
1009 h =
model.GetHistogram();
1011 if (!RDFInternal::HistoUtils<::TH2D>::HasAxisLimits(*
h)) {
1012 throw std::runtime_error(
"2D histograms with no axes limits are not supported yet.");
1014 const std::vector<std::string_view> columnViews = {v1Name, v2Name};
1018 return CreateAction<RDFInternal::ActionTags::Histo2D, V1, V2>(userColumns,
h);
1035 template <
typename V1 = RDFDetail::RInferredType,
typename V2 = RDFDetail::RInferredType,
1036 typename W = RDFDetail::RInferredType>
1040 std::shared_ptr<::TH2D>
h(
nullptr);
1042 ROOT::Internal::RDF::RIgnoreErrorLevelRAII iel(
kError);
1043 h =
model.GetHistogram();
1045 if (!RDFInternal::HistoUtils<::TH2D>::HasAxisLimits(*
h)) {
1046 throw std::runtime_error(
"2D histograms with no axes limits are not supported yet.");
1048 const std::vector<std::string_view> columnViews = {v1Name, v2Name, wName};
1052 return CreateAction<RDFInternal::ActionTags::Histo2D, V1, V2, W>(userColumns,
h);
1055 template <
typename V1,
typename V2,
typename W>
1058 return Histo2D<V1, V2, W>(
model,
"",
"",
"");
1075 template <
typename V1 = RDFDetail::RInferredType,
typename V2 = RDFDetail::RInferredType,
1076 typename V3 = RDFDetail::RInferredType>
1080 std::shared_ptr<::TH3D>
h(
nullptr);
1082 ROOT::Internal::RDF::RIgnoreErrorLevelRAII iel(
kError);
1083 h =
model.GetHistogram();
1085 if (!RDFInternal::HistoUtils<::TH3D>::HasAxisLimits(*
h)) {
1086 throw std::runtime_error(
"3D histograms with no axes limits are not supported yet.");
1088 const std::vector<std::string_view> columnViews = {v1Name, v2Name, v3Name};
1092 return CreateAction<RDFInternal::ActionTags::Histo3D, V1, V2, V3>(userColumns,
h);
1111 template <
typename V1 = RDFDetail::RInferredType,
typename V2 = RDFDetail::RInferredType,
1112 typename V3 = RDFDetail::RInferredType,
typename W = RDFDetail::RInferredType>
1116 std::shared_ptr<::TH3D>
h(
nullptr);
1118 ROOT::Internal::RDF::RIgnoreErrorLevelRAII iel(
kError);
1119 h =
model.GetHistogram();
1121 if (!RDFInternal::HistoUtils<::TH3D>::HasAxisLimits(*
h)) {
1122 throw std::runtime_error(
"3D histograms with no axes limits are not supported yet.");
1124 const std::vector<std::string_view> columnViews = {v1Name, v2Name, v3Name, wName};
1128 return CreateAction<RDFInternal::ActionTags::Histo3D, V1, V2, V3, W>(userColumns,
h);
1131 template <
typename V1,
typename V2,
typename V3,
typename W>
1134 return Histo3D<V1, V2, V3, W>(
model,
"",
"",
"",
"");
1153 template <
typename V1 = RDFDetail::RInferredType,
typename V2 = RDFDetail::RInferredType>
1156 auto graph = std::make_shared<::TGraph>();
1157 const std::vector<std::string_view> columnViews = {v1Name, v2Name};
1163 if (!(userColumns[0].empty() && userColumns[1].empty())) {
1164 const auto v2Name_str = std::string(v2Name);
1165 const auto g_name = std::string(v1Name) +
"*" + v2Name_str;
1166 graph->SetNameTitle(g_name.c_str(), g_name.c_str());
1167 graph->GetXaxis()->SetTitle(g_name.c_str());
1168 graph->GetYaxis()->SetTitle(v2Name_str.c_str());
1171 return CreateAction<RDFInternal::ActionTags::Graph, V1, V2>(userColumns,
graph);
1186 template <
typename V1 = RDFDetail::RInferredType,
typename V2 = RDFDetail::RInferredType>
1190 std::shared_ptr<::TProfile>
h(
nullptr);
1192 ROOT::Internal::RDF::RIgnoreErrorLevelRAII iel(
kError);
1196 if (!RDFInternal::HistoUtils<::TProfile>::HasAxisLimits(*
h)) {
1197 throw std::runtime_error(
"Profiles with no axes limits are not supported yet.");
1199 const std::vector<std::string_view> columnViews = {v1Name, v2Name};
1203 return CreateAction<RDFInternal::ActionTags::Profile1D, V1, V2>(userColumns,
h);
1220 template <
typename V1 = RDFDetail::RInferredType,
typename V2 = RDFDetail::RInferredType,
1221 typename W = RDFDetail::RInferredType>
1225 std::shared_ptr<::TProfile>
h(
nullptr);
1227 ROOT::Internal::RDF::RIgnoreErrorLevelRAII iel(
kError);
1231 if (!RDFInternal::HistoUtils<::TProfile>::HasAxisLimits(*
h)) {
1232 throw std::runtime_error(
"Profile histograms with no axes limits are not supported yet.");
1234 const std::vector<std::string_view> columnViews = {v1Name, v2Name, wName};
1238 return CreateAction<RDFInternal::ActionTags::Profile1D, V1, V2, W>(userColumns,
h);
1241 template <
typename V1,
typename V2,
typename W>
1244 return Profile1D<V1, V2, W>(
model,
"",
"",
"");
1261 template <
typename V1 = RDFDetail::RInferredType,
typename V2 = RDFDetail::RInferredType,
1262 typename V3 = RDFDetail::RInferredType>
1266 std::shared_ptr<::TProfile2D>
h(
nullptr);
1268 ROOT::Internal::RDF::RIgnoreErrorLevelRAII iel(
kError);
1272 if (!RDFInternal::HistoUtils<::TProfile2D>::HasAxisLimits(*
h)) {
1273 throw std::runtime_error(
"2D profiles with no axes limits are not supported yet.");
1275 const std::vector<std::string_view> columnViews = {v1Name, v2Name, v3Name};
1279 return CreateAction<RDFInternal::ActionTags::Profile2D, V1, V2, V3>(userColumns,
h);
1298 template <
typename V1 = RDFDetail::RInferredType,
typename V2 = RDFDetail::RInferredType,
1299 typename V3 = RDFDetail::RInferredType,
typename W = RDFDetail::RInferredType>
1303 std::shared_ptr<::TProfile2D>
h(
nullptr);
1305 ROOT::Internal::RDF::RIgnoreErrorLevelRAII iel(
kError);
1309 if (!RDFInternal::HistoUtils<::TProfile2D>::HasAxisLimits(*
h)) {
1310 throw std::runtime_error(
"2D profiles with no axes limits are not supported yet.");
1312 const std::vector<std::string_view> columnViews = {v1Name, v2Name, v3Name, wName};
1316 return CreateAction<RDFInternal::ActionTags::Profile2D, V1, V2, V3, W>(userColumns,
h);
1319 template <
typename V1,
typename V2,
typename V3,
typename W>
1322 return Profile2D<V1, V2, V3, W>(
model,
"",
"",
"",
"");
1342 template <
typename FirstColumn,
typename... OtherColumns,
typename T>
1345 auto h = std::make_shared<T>(std::forward<T>(
model));
1346 if (!RDFInternal::HistoUtils<T>::HasAxisLimits(*
h)) {
1347 throw std::runtime_error(
"The absence of axes limits is not supported yet.");
1349 return CreateAction<RDFInternal::ActionTags::Fill, FirstColumn, OtherColumns...>(columnList,
h);
1364 template <
typename T>
1367 auto h = std::make_shared<T>(std::forward<T>(
model));
1368 if (!RDFInternal::HistoUtils<T>::HasAxisLimits(*
h)) {
1369 throw std::runtime_error(
"The absence of axes limits is not supported yet.");
1371 return CreateAction<RDFInternal::ActionTags::Fill, RDFDetail::RInferredType>(bl,
h, bl.size());
1386 template <
typename T = RDFDetail::RInferredType>
1390 using RetType_t = RDFDetail::MinReturnType_t<T>;
1391 auto minV = std::make_shared<RetType_t>(std::numeric_limits<RetType_t>::max());
1392 return CreateAction<RDFInternal::ActionTags::Min, T>(userColumns, minV);
1407 template <
typename T = RDFDetail::RInferredType>
1411 using RetType_t = RDFDetail::MaxReturnType_t<T>;
1412 auto maxV = std::make_shared<RetType_t>(std::numeric_limits<RetType_t>::lowest());
1413 return CreateAction<RDFInternal::ActionTags::Max, T>(userColumns, maxV);
1427 template <
typename T = RDFDetail::RInferredType>
1431 auto meanV = std::make_shared<double>(0);
1432 return CreateAction<RDFInternal::ActionTags::Mean, T>(userColumns, meanV);
1446 template <
typename T = RDFDetail::RInferredType>
1450 auto stdDeviationV = std::make_shared<double>(0);
1451 return CreateAction<RDFInternal::ActionTags::StdDev, T>(userColumns, stdDeviationV);
1468 template <
typename T = RDFDetail::RInferredType>
1471 const RDFDetail::SumReturnType_t<T> &initValue = RDFDetail::SumReturnType_t<T>{})
1474 auto sumV = std::make_shared<RDFDetail::SumReturnType_t<T>>(initValue);
1475 return CreateAction<RDFInternal::ActionTags::Sum, T>(userColumns, sumV);
1498 bool returnEmptyReport =
false;
1505 returnEmptyReport =
true;
1507 auto rep = std::make_shared<RCutFlowReport>();
1508 using Helper_t = RDFInternal::ReportHelper<Proxied>;
1529 allColumns.emplace_back(colName);
1534 std::for_each(columnNames.begin(), columnNames.end(), addIfNotInternal);
1539 allColumns.insert(allColumns.end(), branchNames.begin(), branchNames.end());
1544 allColumns.insert(allColumns.end(), dsColNames.begin(), dsColNames.end());
1558 const bool convertVector2RVec =
true;
1559 const auto isCustom = std::find(customCols.begin(), customCols.end(), column) != customCols.end();
1563 convertVector2RVec);
1567 const auto call =
"ROOT::Internal::RDF::TypeID2TypeName(typeid(__tdf" + std::to_string(
fLoopManager->
GetID()) +
1568 "::" + std::string(column) + colID +
"_type))";
1570 return *
reinterpret_cast<std::string *
>(callRes);
1596 for (
auto column : columns) {
1598 definedColumns.emplace_back(column.first);
1601 return definedColumns;
1629 template <typename AccFun, typename MergeFun, typename R = typename TTraits::CallableTraits<AccFun>::ret_type,
1630 typename ArgTypes =
typename TTraits::CallableTraits<AccFun>::arg_types,
1631 typename ArgTypesNoDecay =
typename TTraits::CallableTraits<AccFun>::arg_types_nodecay,
1632 typename U = TTraits::TakeFirstParameter_t<ArgTypes>,
1633 typename T = TTraits::TakeFirstParameter_t<TTraits::RemoveFirstParameter_t<ArgTypes>>>
1636 RDFInternal::CheckAggregate<R, MergeFun>(ArgTypesNoDecay());
1638 constexpr auto nColumns = ArgTypes::list_size;
1644 auto accObjPtr = std::make_shared<U>(aggIdentity);
1645 using Helper_t = RDFInternal::AggregateHelper<AccFun, MergeFun, R, T, U>;
1647 auto action = std::make_unique<Action_t>(
1648 Helper_t(std::move(aggregator), std::move(merger), accObjPtr,
fLoopManager->
GetNSlots()), validColumnNames,
1667 template <typename AccFun, typename MergeFun, typename R = typename TTraits::CallableTraits<AccFun>::ret_type,
1668 typename ArgTypes =
typename TTraits::CallableTraits<AccFun>::arg_types,
1669 typename U = TTraits::TakeFirstParameter_t<ArgTypes>,
1670 typename T = TTraits::TakeFirstParameter_t<TTraits::RemoveFirstParameter_t<ArgTypes>>>
1674 std::is_default_constructible<U>::value,
1675 "aggregated object cannot be default-constructed. Please provide an initialisation value (aggIdentity)");
1676 return Aggregate(std::move(aggregator), std::move(merger), columnName, U());
1712 template <
typename... ColumnTypes,
typename Helper>
1715 constexpr auto nColumns =
sizeof...(ColumnTypes);
1721 using AH = RDFDetail::RActionImpl<Helper>;
1722 static_assert(std::is_base_of<AH, Helper>::value && std::is_convertible<Helper *, AH *>::value,
1723 "Action helper of type T must publicly inherit from ROOT::Detail::RDF::RActionImpl<T>");
1726 auto resPtr = helper.GetResultPtr();
1731 auto action = std::make_unique<Action_t>(Helper(std::forward<Helper>(helper)), validColumnNames,
fProxiedPtr,
1747 template <
typename... ColumnTypes>
1752 auto displayer = std::make_shared<RDFInternal::RDisplay>(columnList,
GetColumnTypeNamesList(columnList), nRows);
1753 return CreateAction<RDFInternal::ActionTags::Display, ColumnTypes...>(columnList, displayer);
1767 auto displayer = std::make_shared<RDFInternal::RDisplay>(columnList,
GetColumnTypeNamesList(columnList), nRows);
1768 return CreateAction<RDFInternal::ActionTags::Display, RDFDetail::RInferredType>(columnList, displayer,
1784 return Display(selectedColumns, nRows);
1797 return Display(selectedColumns, nRows);
1806 const auto entryColName =
"rdfentry_";
1807 auto entryColGen = [](
unsigned int,
ULong64_t entry) {
return entry; };
1808 using NewColEntry_t =
1811 auto entryColumn = std::make_shared<NewColEntry_t>(
fLoopManager, entryColName, std::move(entryColGen),
1813 newCols.
AddName(entryColName);
1814 newCols.
AddColumn(entryColumn, entryColName);
1819 auto retTypeDeclaration =
"namespace __tdf" + std::to_string(
fLoopManager->
GetID()) +
" { using " + entryColName +
1820 std::to_string(entryColumn->
GetID()) +
"_type = ULong64_t; }";
1824 const auto slotColName =
"rdfslot_";
1825 auto slotColGen = [](
unsigned int slot) {
return slot; };
1828 auto slotColumn = std::make_shared<NewColSlot_t>(
fLoopManager, slotColName, std::move(slotColGen),
1832 newCols.
AddColumn(slotColumn, slotColName);
1839 retTypeDeclaration =
"namespace __tdf" + std::to_string(
fLoopManager->
GetID()) +
" { using " + slotColName +
1840 std::to_string(slotColumn->
GetID()) +
"_type = unsigned int; }";
1851 std::vector<std::string> types;
1853 for (
auto column : columnList) {
1862 std::string error(callerName);
1863 error +=
" was called with ImplicitMT enabled, but multi-thread is not supported.";
1864 throw std::runtime_error(error);
1869 template <
typename ActionTag,
typename... BranchTypes,
typename ActionResultType,
1870 typename std::enable_if<!RDFInternal::TNeedJitting<BranchTypes...>::value,
int>
::type = 0>
1873 constexpr auto nColumns =
sizeof...(BranchTypes);
1883 RDFInternal::BuildAction<BranchTypes...>(validColumnNames,
r, nSlots,
fProxiedPtr, ActionTag{}, newColumns);
1891 template <
typename ActionTag,
typename... BranchTypes,
typename ActionResultType,
1892 typename std::enable_if<RDFInternal::TNeedJitting<BranchTypes...>::value,
int>
::type = 0>
1896 auto realNColumns = (nColumns > -1 ? nColumns :
sizeof...(BranchTypes));
1902 auto rOnHeap = RDFInternal::MakeSharedOnHeap(
r);
1905 using BaseNodeType_t =
typename std::remove_pointer<
decltype(upcastNodeOnHeap)>::type::element_type;
1908 auto jittedActionOnHeap =
1909 RDFInternal::MakeSharedOnHeap(std::make_shared<RDFInternal::RJittedAction>(*
fLoopManager));
1912 validColumnNames, upcastNodeOnHeap,
typeid(std::shared_ptr<ActionResultType>),
typeid(ActionTag), rOnHeap,
1919 template <typename F, typename CustomColumnType, typename RetType = typename TTraits::CallableTraits<F>::ret_type>
1927 using ArgTypes_t =
typename TTraits::CallableTraits<F>::arg_types;
1928 using ColTypesTmp_t =
typename RDFInternal::RemoveFirstParameterIf<
1929 std::is_same<CustomColumnType, RDFDetail::CustomColExtraArgs::Slot>::value, ArgTypes_t>
::type;
1930 using ColTypes_t =
typename RDFInternal::RemoveFirstTwoParametersIf<
1931 std::is_same<CustomColumnType, RDFDetail::CustomColExtraArgs::SlotAndEntry>::value, ColTypesTmp_t>
::type;
1933 constexpr auto nColumns = ColTypes_t::list_size;
1941 auto newColumn = std::make_shared<NewCol_t>(
fLoopManager,
name, std::forward<F>(expression), validColumnNames,
1946 if (retTypeName.empty()) {
1951 retTypeName =
"void /* The type of column \"" + std::string(
name) +
"\" (" + demangledType +
1952 ") is not known to the interpreter. */";
1954 const auto retTypeDeclaration =
"namespace __tdf" + std::to_string(
fLoopManager->
GetID()) +
1955 " { " + +
" using " + std::string(
name) + std::to_string(newColumn->GetID()) +
1956 "_type = " + retTypeName +
"; }";
1965 return newInterface;
1971 template <typename F, typename CustomColumnType, typename RetType = typename TTraits::CallableTraits<F>::ret_type,
1972 bool IsFStringConv = std::is_convertible<F, std::string>::value,
1973 bool IsRetTypeDefConstr = std::is_default_constructible<RetType>::value>
1974 typename std::enable_if<!IsFStringConv && !IsRetTypeDefConstr, RInterface<Proxied, DS_t>>
::type
1977 static_assert(std::is_default_constructible<typename TTraits::CallableTraits<F>::ret_type>::value,
1978 "Error in `Define`: type returned by expression is not default-constructible");
1992 template <
typename... ColumnTypes>
2003 const std::string fullTreename(treename);
2005 const auto lastSlash = treename.rfind(
'/');
2007 if (std::string_view::npos != lastSlash) {
2008 dirname = treename.substr(0, lastSlash);
2009 treename = treename.substr(lastSlash + 1, treename.size());
2013 std::unique_ptr<RDFInternal::RActionBase> actionPtr;
2018 actionPtr.reset(
new Action_t(Helper_t(filename, dirname, treename, validCols, columnList, options), validCols,
2024 actionPtr.reset(
new Action_t(
2025 Helper_t(
fLoopManager->
GetNSlots(), filename, dirname, treename, validCols, columnList, options), validCols,
2036 template <
typename... BranchTypes, std::size_t...
S>
2040 constexpr bool areCopyConstructible =
2041 RDFInternal::TEvalAnd<std::is_copy_constructible<BranchTypes>::value...>::value;
2042 static_assert(areCopyConstructible,
"Columns of a type which is not copy constructible cannot be cached yet.");
2048 auto colHolders = std::make_tuple(Take<BranchTypes>(columnList[
S])...);
2077 template <
typename... ColumnTypes, std::size_t...
S>
unsigned long long ULong64_t
typedef void((*Func_t)())
unsigned int GetID() const
Return the unique identifier of this RCustomColumnBase.
The head node of a RDF computation graph.
const std::map< std::string, std::string > & GetAliasMap() const
void ToJit(const std::string &s)
const ColumnNames_t & GetBranchNames()
Return all valid TTree::Branch names (caching results for subsequent calls).
void RegisterCustomColumn(RCustomColumnBase *column)
void Run()
Start the event loop with a different mechanism depending on IMT/no IMT, data source/no data source.
unsigned int GetID() const
void AddColumnAlias(const std::string &alias, const std::string &colName)
RDataSource * GetDataSource() const
unsigned int GetNSlots() const
void Book(RDFInternal::RActionBase *actionPtr)
Helper class that provides the operation graph nodes.
An action node in a RDF computation graph.
Encapsulates the columns defined by the user.
ColumnNames_t GetNames() const
Returns the list of the names of the defined columns.
void AddColumn(const std::shared_ptr< RDFDetail::RCustomColumnBase > &column, const std::string_view &name)
Internally it recreates the map with the new column, and swaps with the old one.
void AddName(const std::string_view &name)
Internally it recreates the map with the new column name, and swaps with the old one.
RCustomColumnBasePtrMap_t GetColumns() const
Returns the list of the pointers to the defined columns.
RDataSource defines an API that RDataFrame can use to read arbitrary data formats.
virtual const std::vector< std::string > & GetColumnNames() const =0
Returns a reference to the collection of the dataset's column names.
The public interface to the RDataFrame federation of classes.
RInterface(const RInterface &)=default
Copy-ctor for RInterface.
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)
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<::TH2D > Histo2D(const TH2DModel &model)
RResultPtr<::TProfile > Profile1D(const TProfile1DModel &model, std::string_view v1Name="", std::string_view v2Name="")
Fill and return a one-dimensional profile (lazy action)
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.
RLoopManager * GetLoopManager() const
RResultPtr<::TGraph > Graph(std::string_view v1Name="", std::string_view v2Name="")
Fill and return a graph (lazy action)
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< double > StdDev(std::string_view columnName="")
Return the unbiased standard deviation of processed column values (lazy action)
RInterface(const std::shared_ptr< Proxied > &proxied)
Only enabled when building a RInterface<RLoopManager>
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)
RResultPtr< ActionResultType > CreateAction(const ColumnNames_t &columns, const std::shared_ptr< ActionResultType > &r, const int nColumns=-1)
void ForeachSlot(F f, const ColumnNames_t &columns={})
Execute a user-defined function requiring a processing slot index on each entry (instant action)
RInterface< RLoopManager > Cache(const ColumnNames_t &columnList)
Save selected columns in memory.
RResultPtr< RDisplay > Display(std::initializer_list< std::string > columnList, const int &nRows=5)
Provides a representation of the columns in the dataset.
RInterface< Proxied, DS_t > Define(std::string_view name, F expression, const ColumnNames_t &columns={})
Creates a custom column.
RDataSource * fDataSource
Non-owning pointer to a data-source object. Null if no data-source. RLoopManager has ownership of the...
RResultPtr<::TH2D > Histo2D(const TH2DModel &model, std::string_view v1Name="", std::string_view v2Name="")
Fill and return a two-dimensional histogram (lazy action)
ColumnNames_t GetValidatedColumnNames(const unsigned int nColumns, const ColumnNames_t &columns)
Prepare the call to the GetValidatedColumnNames routine, making sure that GetBranchNames,...
RResultPtr<::TProfile > Profile1D(const TProfile1DModel &model)
RDFInternal::RBookedCustomColumns fCustomColumns
Contains the custom columns defined up to this node.
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< double > Mean(std::string_view columnName="")
Return the mean of processed column values (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.
std::enable_if<!IsFStringConv &&!IsRetTypeDefConstr, RInterface< Proxied, DS_t > >::type DefineImpl(std::string_view, F, const ColumnNames_t &)
RInterface< Proxied, DS_t > Alias(std::string_view alias, std::string_view columnName)
Allow to refer to a column with a different name.
RInterface< RLoopManager > Cache(const ColumnNames_t &columnList)
Save selected columns in memory.
RInterface< RLoopManager > Cache(std::string_view columnNameRegexp="")
Save selected columns in memory.
RResultPtr< RDisplay > Display(std::string_view columnNameRegexp="", const int &nRows=5)
Provides a representation of the columns in the dataset.
RLoopManager * fLoopManager
friend class RDFInternal::GraphDrawing::GraphCreatorHelper
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)
RInterface & operator=(const RInterface &)=default
Copy-assignment operator for RInterface.
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)
RResultPtr< ULong64_t > Count()
Return the number of entries processed (lazy action)
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)
RInterface< Proxied, DS_t > Define(std::string_view name, std::string_view expression)
Creates a custom column.
std::shared_ptr< Proxied > fProxiedPtr
Smart pointer to the graph node encapsulated by this RInterface.
RResultPtr<::TH1D > Histo1D(std::string_view vName)
Fill and return a one-dimensional histogram with the values of a column (lazy action)
RDFInternal::RBookedCustomColumns CheckAndFillDSColumns(ColumnNames_t validCols, std::index_sequence< S... >, TTraits::TypeList< ColumnTypes... >)
ColumnNames_t GetColumnNames()
Returns the names of the available columns.
RResultPtr< RInterface< RLoopManager > > SnapshotImpl(std::string_view treename, std::string_view filename, const ColumnNames_t &columnList, const RSnapshotOptions &options)
Implementation of snapshot.
RResultPtr< RDisplay > Display(const ColumnNames_t &columnList, const int &nRows=5)
Provides a representation of the columns in the dataset.
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)
RInterface< RDFDetail::RRange< Proxied >, DS_t > Range(unsigned int end)
Creates a node that filters entries based on range.
RResultPtr< COLL > Take(std::string_view column="")
Return a collection of values of a column (lazy action, returns a std::vector by default)
RInterface< RLoopManager > Cache(std::initializer_list< std::string > columnList)
Save selected columns in memory.
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)
RResultPtr< typename Helper::Result_t > Book(Helper &&helper, const ColumnNames_t &columns={})
Book execution of a custom action using a user-defined helper object.
RResultPtr< RDisplay > Display(const ColumnNames_t &columnList, const int &nRows=5)
Provides a representation of the columns in the dataset.
const std::shared_ptr< Proxied > & GetProxiedPtr() const
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< ActionResultType > CreateAction(const ColumnNames_t &columns, const std::shared_ptr< ActionResultType > &r)
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< RCutFlowReport > Report()
Gather filtering statistics.
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< 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< 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.
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< RDFDetail::MinReturnType_t< T > > Min(std::string_view columnName="")
Return the minimum of processed column values (lazy action)
RResultPtr< T > Reduce(F f, std::string_view columnName="")
Execute a user-defined reduce operation on the values of a column.
void Foreach(F f, const ColumnNames_t &columns={})
Execute a user-defined function on each entry (instant action)
RInterface< RDFDetail::RJittedFilter, DS_t > Filter(std::string_view expression, std::string_view name="")
Append a filter to the call graph.
RResultPtr<::TProfile2D > Profile2D(const TProfile2DModel &model)
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)
std::string GetColumnType(std::string_view column)
Return the type of a given column as a string.
ColumnNames_t GetDefinedColumnNames()
Returns the names of the defined columns.
RInterface< RDFDetail::RFilter< F, Proxied >, DS_t > Filter(F f, const ColumnNames_t &columns={}, std::string_view name="")
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.
RInterface(RInterface &&)=default
Move-ctor for RInterface.
RResultPtr< T > Reduce(F f, std::string_view columnName, const T &redIdentity)
Execute a user-defined reduce operation on the values of a column.
void CheckIMTDisabled(std::string_view callerName)
RInterface(const std::shared_ptr< Proxied > &proxied, RLoopManager &lm, RDFInternal::RBookedCustomColumns columns, RDataSource *ds)
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)
RInterface< RLoopManager > CacheImpl(const ColumnNames_t &columnList, std::index_sequence< S... > s)
Implementation of cache.
RDFDetail::ColumnNames_t ColumnNames_t
RInterface< RDFDetail::RFilter< F, Proxied >, DS_t > Filter(F f, std::string_view name)
Append a filter to the call graph.
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)
std::vector< std::string > GetColumnTypeNamesList(const ColumnNames_t &columnList)
std::vector< std::string > GetFilterNames()
Returns the names of the filters created.
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<::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<::TH3D > Histo3D(const TH3DModel &model)
RResultPtr< RDFDetail::MaxReturnType_t< T > > Max(std::string_view columnName="")
Return the maximum of processed column values (lazy action)
A RDataSource implementation which is built on top of result proxies.
Smart pointer for the return type of actions.
ROOT's RDataFrame offers a high level interface for analyses of data stored in TTrees,...
A Graph is a graphics object made of two arrays X and Y with npoints each.
RResultPtr< T > MakeResultPtr(const std::shared_ptr< T > &r, RLoopManager &df, std::shared_ptr< ROOT::Internal::RDF::RActionBase > actionPtr)
Create a RResultPtr and set its pointer to the corresponding RAction This overload is invoked by non-...
ColumnNames_t GetBranchNames(TTree &t, bool allowDuplicates=true)
Get all the branches names, including the ones of the friend trees.
ColumnNames_t ConvertRegexToColumns(const ROOT::RDF::RNode &node, std::string_view columnNameRegexp, std::string_view callerName)
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...
std::vector< std::string > GetFilterNames(const std::shared_ptr< RLoopManager > &loopManager)
std::string PrettyPrintAddr(const void *const addr)
void CheckTypesAndPars(unsigned int nTemplateParams, unsigned int nColumnNames)
bool AtLeastOneEmptyString(const std::vector< std::string_view > strings)
std::string JitBuildAction(const ColumnNames_t &bl, void *prevNode, const std::type_info &art, const std::type_info &at, void *rOnHeap, TTree *tree, const unsigned int nSlots, const RDFInternal::RBookedCustomColumns &customCols, RDataSource *ds, std::shared_ptr< RJittedAction > *jittedActionOnHeap, unsigned int namespaceID)
HeadNode_t CreateSnaphotRDF(const ColumnNames_t &validCols, const std::string &fullTreeName, const std::string &fileName, bool isLazy, RLoopManager &loopManager, std::unique_ptr< RDFInternal::RActionBase > actionPtr)
bool IsInternalColumn(std::string_view colName)
ColumnNames_t GetValidatedColumnNames(RLoopManager &lm, const unsigned int nColumns, const ColumnNames_t &columns, const ColumnNames_t &validCustomColumns, RDataSource *ds)
Given the desired number of columns and the user-provided list of columns:
std::string ColumnName2ColumnTypeName(const std::string &colName, unsigned int namespaceID, TTree *tree, RDataSource *ds, bool isCustomColumn, bool vector2tvec, unsigned int customColID)
Return a string containing the type of the given branch.
void BookDefineJit(std::string_view name, std::string_view expression, RLoopManager &lm, RDataSource *ds, const std::shared_ptr< RJittedCustomColumn > &jittedCustomColumn, const RDFInternal::RBookedCustomColumns &customCols, const ColumnNames_t &branches)
void BookFilterJit(RJittedFilter *jittedFilter, void *prevNodeOnHeap, std::string_view name, std::string_view expression, const std::map< std::string, std::string > &aliasMap, const ColumnNames_t &branches, const RDFInternal::RBookedCustomColumns &customCols, TTree *tree, RDataSource *ds, unsigned int namespaceID)
void CheckCustomColumn(std::string_view definedCol, TTree *treePtr, const ColumnNames_t &customCols, const std::map< std::string, std::string > &aliasMap, const ColumnNames_t &dataSourceColumns)
RInterface<::ROOT::Detail::RDF::RNodeBase, void > RNode
ROOT type_traits extensions.
Namespace for new ROOT classes and functions.
Bool_t IsImplicitMTEnabled()
Returns true if the implicit multi-threading in ROOT is enabled.
ROOT::Detail::RDF::ColumnNames_t ColumnNames_t
std::pair< Double_t, Double_t > Range_t
RooArgSet S(const RooAbsArg &v1)
char * DemangleTypeIdName(const std::type_info &ti, int &errorCode)
Demangle in a portable way the type id name.
static constexpr double s
Print a TSeq at the prompt:
std::string printValue(const TDatime *val)
Print a TDatime at the prompt.
std::unique_ptr< T > make_unique(Args &&... args)
make_index_sequence< sizeof...(_Tp)> index_sequence_for
basic_string_view< char > string_view
make_integer_sequence< size_t, _Np > make_index_sequence
A collection of options to steer the creation of the dataset on file.
bool fLazy
Delay the snapshot of the dataset.
A struct which stores the parameters of a TH1D.
A struct which stores the parameters of a TH2D.
A struct which stores the parameters of a TH3D.
A struct which stores the parameters of a TProfile.
A struct which stores the parameters of a TProfile2D.
Lightweight storage for a collection of types.