11 #ifndef ROOT_TDF_TINTERFACE
12 #define ROOT_TDF_TINTERFACE
31 #include <initializer_list>
36 #include <type_traits>
42 using namespace ROOT::Experimental::TDF;
43 using namespace ROOT::Detail::TDF;
47 template <
typename TDFNode,
typename ActionType,
typename... BranchTypes,
typename ActionResultType>
49 const std::shared_ptr<ActionResultType> &
r)
51 node->template BuildAndBook<BranchTypes...>(bl,
r, nSlots, (ActionType *)
nullptr);
58 const std::vector<std::string> &tmpBranches,
59 const std::map<std::string, TmpBranchBasePtr_t> &tmpBookedBranches, TTree *
tree);
61 void JitBuildAndBook(
const ColumnNames_t &bl,
const std::string &nodeTypename,
void *thisPtr,
const std::type_info &art,
62 const std::type_info &at,
const void *
r, TTree *
tree,
unsigned int nSlots,
63 const std::map<std::string, TmpBranchBasePtr_t> &tmpBranches);
68 namespace Experimental {
81 namespace Experimental {
83 namespace TDFDetail = ROOT::Detail::TDF;
84 namespace TDFInternal = ROOT::Internal::TDF;
92 template <
typename Proxied>
100 template <
typename T>
102 template <
typename TDFNode,
typename ActionType,
typename... BranchTypes,
typename ActionResultType>
104 const std::shared_ptr<ActionResultType> &);
126 template <typename F, typename std::enable_if<!std::is_convertible<F, std::string>::value,
int>
::type = 0>
129 TDFInternal::CheckFilter(f);
130 auto df = GetDataFrameChecked();
131 const ColumnNames_t &defBl = df->GetDefaultBranches();
132 auto nArgs = TDFInternal::TFunctionTraits<F>::Args_t::fgSize;
135 auto FilterPtr = std::make_shared<DFF_t>(std::move(f), actualBl, *fProxiedPtr,
name);
149 template <typename F, typename std::enable_if<!std::is_convertible<F, std::string>::value,
int>
::type = 0>
154 return Filter(f, {},
name);
164 template <
typename F>
181 auto df = GetDataFrameChecked();
182 auto tree = df->GetTree();
184 auto tmpBranches = fProxiedPtr->GetTmpBranches();
185 auto tmpBookedBranches = df->GetBookedBranches();
186 const std::string expressionInt(expression);
187 const std::string nameInt(
name);
189 tmpBranches, tmpBookedBranches,
tree);
214 template <typename F, typename std::enable_if<!std::is_convertible<F, std::string>::value,
int>
::type = 0>
217 auto df = GetDataFrameChecked();
219 const ColumnNames_t &defBl = df->GetDefaultBranches();
220 auto nArgs = TDFInternal::TFunctionTraits<F>::Args_t::fgSize;
223 const std::string nameInt(name);
224 auto BranchPtr = std::make_shared<DFB_t>(nameInt, std::move(expression), actualBl, *fProxiedPtr);
225 fProxiedPtr->IncrChildrenCount();
242 auto df = GetDataFrameChecked();
243 auto tree = df->GetTree();
245 auto tmpBranches = fProxiedPtr->GetTmpBranches();
246 auto tmpBookedBranches = df->GetBookedBranches();
247 const std::string expressionInt(expression);
248 const std::string nameInt(name);
261 template <
typename... BranchTypes>
265 using TypeInd_t =
typename TDFInternal::TGenStaticSeq<
sizeof...(BranchTypes)>::Type_t;
266 return SnapshotImpl<BranchTypes...>(treename, filename, bnames, TypeInd_t());
280 auto df = GetDataFrameChecked();
281 auto tree = df->GetTree();
282 std::stringstream snapCall;
285 snapCall <<
"if (gROOTMutex) gROOTMutex->UnLock(); ((" << GetNodeTypeName() <<
"*)" <<
this <<
")->Snapshot<";
287 for (
auto &
b : bnames) {
288 if (!first) snapCall <<
", ";
293 const std::string treeNameInt(treename);
294 const std::string filenameInt(filename);
295 snapCall <<
">(\"" << treeNameInt <<
"\", \"" << filenameInt <<
"\", "
296 <<
"*reinterpret_cast<std::vector<std::string>*>(" << &bnames <<
")"
311 std::string_view columnNameRegexp =
"")
313 const auto theRegexSize = columnNameRegexp.size();
314 std::string theRegex(columnNameRegexp);
316 const auto isEmptyRegex = 0 == theRegexSize;
318 if (theRegexSize > 0 && theRegex[0] !=
'^') theRegex =
"^" + theRegex;
319 if (theRegexSize > 0 && theRegex[theRegexSize-1] !=
'$') theRegex = theRegex +
"$";
322 selectedColumns.reserve(32);
324 const auto tmpBranches = fProxiedPtr->GetTmpBranches();
335 auto df = GetDataFrameChecked();
336 auto tree = df->GetTree();
347 return Snapshot(treename, filename, selectedColumns);
360 if (stride == 0 || (stop != 0 && stop < start))
361 throw std::runtime_error(
"Range: stride must be strictly greater than 0 and stop must be greater than start.");
363 throw std::runtime_error(
"Range was called with ImplicitMT enabled. Multi-thread ranges are not supported.");
365 auto df = GetDataFrameChecked();
367 auto RangePtr = std::make_shared<Range_t>(start, stop, stride, *fProxiedPtr);
392 template <
typename F>
395 using Args_t =
typename TDFInternal::TFunctionTraits<decltype(f)>::ArgsNoDecay_t;
396 using Ret_t =
typename TDFInternal::TFunctionTraits<decltype(f)>::Ret_t;
397 ForeachSlot(TDFInternal::AddSlotParameter<Ret_t>(f, Args_t()), bl);
416 template <
typename F>
419 auto df = GetDataFrameChecked();
420 const ColumnNames_t &defBl = df->GetDefaultBranches();
421 auto nArgs = TDFInternal::TFunctionTraits<F>::Args_t::fgSize;
423 using Op_t = TDFInternal::ForeachSlotHelper<F>;
425 df->Book(std::make_shared<DFA_t>(Op_t(std::move(f)), actualBl, *fProxiedPtr));
426 fProxiedPtr->IncrChildrenCount();
446 template <typename F, typename T = typename TDFInternal::TFunctionTraits<F>::Ret_t>
449 static_assert(std::is_default_constructible<T>::value,
450 "reduce object cannot be default-constructed. Please provide an initialisation value (initValue)");
463 template <typename F, typename T = typename TDFInternal::TFunctionTraits<F>::Ret_t>
466 using Args_t =
typename TDFInternal::TFunctionTraits<F>::Args_t;
467 TDFInternal::CheckReduce(f, Args_t());
468 auto df = GetDataFrameChecked();
469 unsigned int nSlots = df->GetNSlots();
470 auto bl = GetBranchNames<T>({branchName},
"reduce branch values");
471 auto redObjPtr = std::make_shared<T>(initValue);
472 using Op_t = TDFInternal::ReduceHelper<F, T>;
474 df->Book(std::make_shared<DFA_t>(Op_t(std::move(f), redObjPtr, nSlots), bl, *fProxiedPtr));
475 fProxiedPtr->IncrChildrenCount();
486 auto df = GetDataFrameChecked();
487 unsigned int nSlots = df->GetNSlots();
488 auto cSPtr = std::make_shared<unsigned int>(0);
489 using Op_t = TDFInternal::CountHelper;
491 df->Book(std::make_shared<DFA_t>(Op_t(cSPtr, nSlots),
ColumnNames_t({}), *fProxiedPtr));
492 fProxiedPtr->IncrChildrenCount();
504 template <
typename T,
typename COLL = std::vector<T>>
507 auto df = GetDataFrameChecked();
508 unsigned int nSlots = df->GetNSlots();
509 auto bl = GetBranchNames<T>({
branchName},
"get the values of the branch");
510 auto valuesPtr = std::make_shared<COLL>();
511 using Op_t = TDFInternal::TakeHelper<T, COLL>;
513 df->Book(std::make_shared<DFA_t>(Op_t(valuesPtr, nSlots), bl, *fProxiedPtr));
514 fProxiedPtr->IncrChildrenCount();
532 template <
typename V = TDFDetail::TInferType>
535 auto bl = GetBranchNames<V>({vName},
"fill the histogram");
536 auto h = std::make_shared<::TH1F>(std::move(
model));
537 if (h->GetXaxis()->GetXmax() == h->GetXaxis()->GetXmin())
538 TDFInternal::HistoUtils<::TH1F>::SetCanExtendAllAxes(*h);
539 return CreateAction<TDFInternal::ActionTypes::Histo1D, V>(bl,
h);
542 template <
typename V = TDFDetail::TInferType>
545 return Histo1D<V>(
::TH1F{
"",
"", 128u, 0., 0.}, vName);
563 template <
typename V = TDFDetail::TInferType,
typename W = TDFDetail::TInferType>
566 auto bl = GetBranchNames<V, W>({vName, wName},
"fill the histogram");
567 auto h = std::make_shared<::TH1F>(std::move(
model));
568 return CreateAction<TDFInternal::ActionTypes::Histo1D, V, W>(bl,
h);
571 template <
typename V = TDFDetail::TInferType,
typename W = TDFDetail::TInferType>
574 return Histo1D<V, W>(
::TH1F{
"",
"", 128u, 0., 0.}, vName, wName);
577 template <
typename V,
typename W>
580 return Histo1D<V, W>(std::move(
model),
"",
"");
594 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType>
597 auto h = std::make_shared<::TH2F>(std::move(
model));
598 if (!TDFInternal::HistoUtils<::TH2F>::HasAxisLimits(*h)) {
599 throw std::runtime_error(
"2D histograms with no axes limits are not supported yet.");
601 auto bl = GetBranchNames<V1, V2>({v1Name, v2Name},
"fill the histogram");
602 return CreateAction<TDFInternal::ActionTypes::Histo2D, V1, V2>(bl,
h);
618 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType,
619 typename W = TDFDetail::TInferType>
621 std::string_view wName)
623 auto h = std::make_shared<::TH2F>(std::move(
model));
624 if (!TDFInternal::HistoUtils<::TH2F>::HasAxisLimits(*h)) {
625 throw std::runtime_error(
"2D histograms with no axes limits are not supported yet.");
627 auto bl = GetBranchNames<V1, V2, W>({v1Name, v2Name, wName},
"fill the histogram");
628 return CreateAction<TDFInternal::ActionTypes::Histo2D, V1, V2, W>(bl,
h);
631 template <
typename V1,
typename V2,
typename W>
634 return Histo2D<V1, V2, W>(std::move(
model),
"",
"",
"");
650 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType,
651 typename V3 = TDFDetail::TInferType>
653 std::string_view v3Name =
"")
655 auto h = std::make_shared<::TH3F>(std::move(
model));
656 if (!TDFInternal::HistoUtils<::TH3F>::HasAxisLimits(*h)) {
657 throw std::runtime_error(
"3D histograms with no axes limits are not supported yet.");
659 auto bl = GetBranchNames<V1, V2, V3>({v1Name, v2Name, v3Name},
"fill the histogram");
660 return CreateAction<TDFInternal::ActionTypes::Histo3D, V1, V2, V3>(bl,
h);
678 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType,
679 typename V3 = TDFDetail::TInferType,
typename W = TDFDetail::TInferType>
681 std::string_view v3Name, std::string_view wName)
683 auto h = std::make_shared<::TH3F>(std::move(
model));
684 if (!TDFInternal::HistoUtils<::TH3F>::HasAxisLimits(*h)) {
685 throw std::runtime_error(
"3D histograms with no axes limits are not supported yet.");
687 auto bl = GetBranchNames<V1, V2, V3, W>({v1Name, v2Name, v3Name, wName},
"fill the histogram");
688 return CreateAction<TDFInternal::ActionTypes::Histo3D, V1, V2, V3, W>(bl,
h);
691 template <
typename V1,
typename V2,
typename V3,
typename W>
694 return Histo3D<V1, V2, V3, W>(std::move(
model),
"",
"",
"",
"");
708 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType>
710 std::string_view v2Name =
"")
712 auto h = std::make_shared<::TProfile>(std::move(
model));
713 if (!TDFInternal::HistoUtils<::TProfile>::HasAxisLimits(*h)) {
714 throw std::runtime_error(
"Profiles with no axes limits are not supported yet.");
716 auto bl = GetBranchNames<V1, V2>({v1Name, v2Name},
"fill the 1D Profile");
717 return CreateAction<TDFInternal::ActionTypes::Profile1D, V1, V2>(bl,
h);
733 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType,
734 typename W = TDFDetail::TInferType>
736 std::string_view wName)
738 auto h = std::make_shared<::TProfile>(std::move(
model));
739 if (!TDFInternal::HistoUtils<::TProfile>::HasAxisLimits(*h)) {
740 throw std::runtime_error(
"Profile histograms with no axes limits are not supported yet.");
742 auto bl = GetBranchNames<V1, V2, W>({v1Name, v2Name, wName},
"fill the 1D profile");
743 return CreateAction<TDFInternal::ActionTypes::Profile1D, V1, V2, W>(bl,
h);
746 template <
typename V1,
typename V2,
typename W>
749 return Profile1D<V1, V2, W>(std::move(
model),
"",
"",
"");
765 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType,
766 typename V3 = TDFDetail::TInferType>
768 std::string_view v2Name =
"", std::string_view v3Name =
"")
770 auto h = std::make_shared<::TProfile2D>(std::move(
model));
771 if (!TDFInternal::HistoUtils<::TProfile2D>::HasAxisLimits(*h)) {
772 throw std::runtime_error(
"2D profiles with no axes limits are not supported yet.");
774 auto bl = GetBranchNames<V1, V2, V3>({v1Name, v2Name, v3Name},
"fill the 2D profile");
775 return CreateAction<TDFInternal::ActionTypes::Profile2D, V1, V2, V3>(bl,
h);
793 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType,
794 typename V3 = TDFDetail::TInferType,
typename W = TDFDetail::TInferType>
796 std::string_view v3Name, std::string_view wName)
798 auto h = std::make_shared<::TProfile2D>(std::move(
model));
799 if (!TDFInternal::HistoUtils<::TProfile2D>::HasAxisLimits(*h)) {
800 throw std::runtime_error(
"2D profiles with no axes limits are not supported yet.");
802 auto bl = GetBranchNames<V1, V2, V3, W>({v1Name, v2Name, v3Name, wName},
"fill the histogram");
803 return CreateAction<TDFInternal::ActionTypes::Profile2D, V1, V2, V3, W>(bl,
h);
806 template <
typename V1,
typename V2,
typename V3,
typename W>
809 return Profile2D<V1, V2, V3, W>(std::move(
model),
"",
"",
"",
"");
823 template <
typename FirstBranch,
typename... OtherBranches,
typename T>
826 auto h = std::make_shared<T>(std::move(
model));
827 if (!TDFInternal::HistoUtils<T>::HasAxisLimits(*h)) {
828 throw std::runtime_error(
"The absence of axes limits is not supported yet.");
833 template <
typename T>
836 auto h = std::make_shared<T>(std::move(
model));
837 if (!TDFInternal::HistoUtils<T>::HasAxisLimits(*h)) {
838 throw std::runtime_error(
"The absence of axes limits is not supported yet.");
840 return CreateAction<TDFInternal::ActionTypes::Fill, TDFDetail::TInferType>(bl,
h);
852 template <
typename T = TDFDetail::TInferType>
855 auto bl = GetBranchNames<T>({
branchName},
"calculate the minimum");
856 auto minV = std::make_shared<double>(std::numeric_limits<double>::max());
857 return CreateAction<TDFInternal::ActionTypes::Min, T>(bl, minV);
869 template <
typename T = TDFDetail::TInferType>
872 auto bl = GetBranchNames<T>({
branchName},
"calculate the maximum");
873 auto maxV = std::make_shared<double>(std::numeric_limits<double>::min());
874 return CreateAction<TDFInternal::ActionTypes::Max, T>(bl, maxV);
886 template <
typename T = TDFDetail::TInferType>
889 auto bl = GetBranchNames<T>({
branchName},
"calculate the mean");
890 auto meanV = std::make_shared<double>(0);
891 return CreateAction<TDFInternal::ActionTypes::Mean, T>(bl, meanV);
905 auto df = GetDataFrameChecked();
906 if (!df->HasRunAtLeastOnce()) df->Run();
907 fProxiedPtr->Report();
914 template <
typename T1,
typename T2 =
void,
typename T3 =
void,
typename T4 =
void>
917 constexpr
auto isT2Void = std::is_same<T2, void>::value;
918 constexpr
auto isT3Void = std::is_same<T3, void>::value;
919 constexpr
auto isT4Void = std::is_same<T4, void>::value;
921 unsigned int neededBranches = 1 + !isT2Void + !isT3Void + !isT4Void;
923 unsigned int providedBranches = 0;
924 std::for_each(bl.begin(), bl.end(), [&providedBranches](std::string_view s) {
925 if (!s.empty()) providedBranches++;
928 if (neededBranches == providedBranches) {
933 return GetDefaultBranchNames(neededBranches, actionNameForErr);
942 template <
typename... BranchTypes,
typename ActionType,
typename ActionResultType>
943 void BuildAndBook(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &h,
unsigned int nSlots,
946 using Op_t = TDFInternal::FillTOHelper<ActionResultType>;
948 auto df = GetDataFrameChecked();
949 df->Book(std::make_shared<DFA_t>(Op_t(h, nSlots), bl, *fProxiedPtr));
953 template <
typename... BranchTypes>
954 void BuildAndBook(
const ColumnNames_t &bl,
const std::shared_ptr<::TH1F> &h,
unsigned int nSlots,
955 TDFInternal::ActionTypes::Histo1D *)
957 auto df = GetDataFrameChecked();
958 auto hasAxisLimits = TDFInternal::HistoUtils<::TH1F>::HasAxisLimits(*h);
961 using Op_t = TDFInternal::FillTOHelper<::TH1F>;
963 df->Book(std::make_shared<DFA_t>(Op_t(h, nSlots), bl, *fProxiedPtr));
965 using Op_t = TDFInternal::FillHelper;
967 df->Book(std::make_shared<DFA_t>(Op_t(h, nSlots), bl, *fProxiedPtr));
972 template <
typename BranchType>
973 void BuildAndBook(
const ColumnNames_t &bl,
const std::shared_ptr<double> &minV,
unsigned int nSlots,
976 using Op_t = TDFInternal::MinHelper;
978 auto df = GetDataFrameChecked();
979 df->Book(std::make_shared<DFA_t>(Op_t(minV, nSlots), bl, *fProxiedPtr));
983 template <
typename BranchType>
984 void BuildAndBook(
const ColumnNames_t &bl,
const std::shared_ptr<double> &maxV,
unsigned int nSlots,
987 using Op_t = TDFInternal::MaxHelper;
989 auto df = GetDataFrameChecked();
990 df->Book(std::make_shared<DFA_t>(Op_t(maxV, nSlots), bl, *fProxiedPtr));
994 template <
typename BranchType>
995 void BuildAndBook(
const ColumnNames_t &bl,
const std::shared_ptr<double> &meanV,
unsigned int nSlots,
998 using Op_t = TDFInternal::MeanHelper;
1000 auto df = GetDataFrameChecked();
1001 df->Book(std::make_shared<DFA_t>(Op_t(meanV, nSlots), bl, *fProxiedPtr));
1007 template <
typename ActionType,
typename... BranchTypes,
typename ActionResultType,
1008 typename std::enable_if<!TDFInternal::TNeedJitting<BranchTypes...>::value,
int>
::type = 0>
1011 auto df = GetDataFrameChecked();
1012 unsigned int nSlots = df->GetNSlots();
1013 BuildAndBook<BranchTypes...>(bl,
r, nSlots, (ActionType *)
nullptr);
1014 fProxiedPtr->IncrChildrenCount();
1019 template <
typename ActionType,
typename... BranchTypes,
typename ActionResultType,
1020 typename std::enable_if<TDFInternal::TNeedJitting<BranchTypes...>::value,
int>
::type = 0>
1023 auto df = GetDataFrameChecked();
1024 unsigned int nSlots = df->GetNSlots();
1025 const auto &tmpBranches = df->GetBookedBranches();
1026 auto tree = df->GetTree();
1028 typeid(ActionType), &r,
tree, nSlots, tmpBranches);
1029 fProxiedPtr->IncrChildrenCount();
1037 auto df = fImplWeakPtr.lock();
1039 throw std::runtime_error(
"The main TDataFrame is not reachable: did it go out of scope?");
1046 auto df = GetDataFrameChecked();
1047 const ColumnNames_t &defaultBranches = df->GetDefaultBranches();
1048 const auto dBSize = defaultBranches.size();
1049 if (nExpectedBranches > dBSize) {
1050 std::string msg(
"Trying to deduce the branches from the default list in order to ");
1051 msg += actionNameForErr;
1052 msg +=
". A set of branches of size ";
1053 msg += std::to_string(dBSize);
1054 msg +=
" was found. ";
1055 msg += std::to_string(nExpectedBranches);
1056 msg += 1 != nExpectedBranches ?
" are" :
" is";
1057 msg +=
" needed. Please specify the branches explicitly.";
1058 throw std::runtime_error(msg);
1060 auto bnBegin = defaultBranches.begin();
1074 template <
typename... Args,
int...
S>
1076 const ColumnNames_t &bnames, TDFInternal::TStaticSeq<S...> )
1078 const std::string treenameInt(treename);
1079 const std::string filenameInt(filename);
1080 const auto templateParamsN =
sizeof...(S);
1081 const auto bNamesN = bnames.size();
1082 if (templateParamsN != bNamesN) {
1083 std::string err_msg =
"The number of template parameters specified for the snapshot is ";
1084 err_msg += std::to_string(templateParamsN);
1085 err_msg +=
" while ";
1086 err_msg += std::to_string(bNamesN);
1087 err_msg +=
" branches have been specified.";
1088 throw std::runtime_error(err_msg.c_str());
1091 auto df = GetDataFrameChecked();
1093 std::unique_ptr<TFile> ofile(
TFile::Open(filenameInt.c_str(),
"RECREATE"));
1094 TTree t(treenameInt.c_str(), treenameInt.c_str());
1096 bool FirstEvent =
true;
1098 auto fillTree = [&t, &bnames, &FirstEvent](
unsigned int , Args &... args) {
1101 std::initializer_list<int> expander = {(t.Branch(bnames[
S].c_str(), &args), 0)..., 0};
1108 auto initLambda = [&t] (
TTreeReader *
r,
unsigned int ) {
1116 using Op_t = TDFInternal::SnapshotHelper<decltype(initLambda), decltype(fillTree)>;
1118 df->Book(std::make_shared<DFA_t>(Op_t(std::move(initLambda), std::move(
fillTree)), bnames, *fProxiedPtr));
1119 fProxiedPtr->IncrChildrenCount();
1123 unsigned int nSlots = df->GetNSlots();
1125 std::vector<std::shared_ptr<TBufferMergerFile>> files(nSlots);
1126 std::vector<TTree *> trees(nSlots);
1127 std::vector<int> isFirstEvent(nSlots, 1);
1129 auto fillTree = [&](
unsigned int slot, Args &... args) {
1130 if (isFirstEvent[slot]) {
1132 std::initializer_list<int> expander = {(trees[slot]->Branch(bnames[
S].c_str(), &args), 0)..., 0};
1134 isFirstEvent[slot] = 0;
1136 trees[slot]->Fill();
1137 auto entries = trees[slot]->GetEntries();
1138 auto autoflush = trees[slot]->GetAutoFlush();
1139 if ((autoflush > 0) && (entries % autoflush == 0)) files[slot]->Write();
1143 auto initLambda = [&trees, &merger, &files, &treenameInt, &isFirstEvent] (
TTreeReader *
r,
unsigned int slot) {
1146 files[slot] = merger.GetFile();
1148 files[slot]->Write();
1150 trees[slot] =
new TTree(treenameInt.c_str(), treenameInt.c_str());
1154 auto tree = r->GetTree();
1155 tree->AddClone(trees[slot]);
1157 isFirstEvent[slot] = 1;
1160 using Op_t = TDFInternal::SnapshotHelper<decltype(initLambda), decltype(fillTree)>;
1162 df->Book(std::make_shared<DFA_t>(Op_t(std::move(initLambda), std::move(
fillTree)), bnames, *fProxiedPtr));
1163 fProxiedPtr->IncrChildrenCount();
1165 for (
auto &&file : files) file->Write();
1172 auto chain =
new TChain(treenameInt.c_str());
1173 chain->
Add(filenameInt.c_str());
1174 snapshotTDF.
fProxiedPtr->SetTree(std::shared_ptr<TTree>(static_cast<TTree *>(chain)));
1179 TInterface(
const std::shared_ptr<Proxied> &proxied,
const std::weak_ptr<TLoopManager> &impl)
1180 : fProxiedPtr(proxied), fImplWeakPtr(impl)
1185 template <typename T = Proxied, typename std::enable_if<std::is_same<T, TLoopManager>::value,
int>
::type = 0>
1186 TInterface(
const std::shared_ptr<Proxied> &proxied) : fProxiedPtr(proxied), fImplWeakPtr(proxied->GetSharedPtr())
1197 return "ROOT::Experimental::TDF::TInterface<ROOT::Detail::TDF::TFilterBase>";
1203 return "ROOT::Experimental::TDF::TInterface<ROOT::Detail::TDF::TCustomColumnBase>";
1209 return "ROOT::Experimental::TDF::TInterface<ROOT::Detail::TDF::TLoopManager>";
1215 return "ROOT::Experimental::TDF::TInterface<ROOT::Detail::TDF::TRangeBase>";
1222 #endif // ROOT_TDF_INTERFACE
TResultProxy<::TProfile2D > Profile2D(::TProfile2D &&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)
TResultProxy<::TH3F > Histo3D(::TH3F &&model, std::string_view v1Name="", std::string_view v2Name="", std::string_view v3Name="")
Fill and return a three-dimensional histogram (lazy action)
TResultProxy<::TProfile2D > Profile2D(::TProfile2D &&model)
TResultProxy<::TH3F > Histo3D(::TH3F &&model)
TResultProxy<::TH3F > Histo3D(::TH3F &&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)
TTreeReader is a simple, robust and fast interface to read values from a TTree, TChain or TNtuple...
TInterface< TLoopManager > Snapshot(std::string_view treename, std::string_view filename, std::string_view columnNameRegexp="")
Create a snapshot of the dataset on disk in the form of a TTree.
TDFDetail::ColumnNames_t ColumnNames_t
std::pair< Double_t, Double_t > Range_t
TInterface< TCustomColumnBase > Define(std::string_view name, std::string_view expression)
Creates a temporary branch.
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...
TInterface< TCustomColumnBase > Define(std::string_view name, F expression, const ColumnNames_t &bl={})
Creates a temporary branch.
TInterface< TLoopManager > Snapshot(std::string_view treename, std::string_view filename, const ColumnNames_t &bnames)
Create a snapshot of the dataset on disk in the form of a TTree.
Regular expression class.
void Foreach(F f, const ColumnNames_t &bl={})
Execute a user-defined function on each entry (instant action)
const ColumnNames_t & PickBranchNames(unsigned int nArgs, const ColumnNames_t &bl, const ColumnNames_t &defBl)
Returns local BranchNames or default BranchNames according to which one should be used...
Short_t Min(Short_t a, Short_t b)
void CallBuildAndBook(TDFNode *node, const ColumnNames_t &bl, unsigned int nSlots, const std::shared_ptr< ActionResultType > &r)
TInterface< TFilterBase > Filter(F f, const std::initializer_list< std::string > &bn)
Append a filter to the call graph.
const ColumnNames_t GetDefaultBranchNames(unsigned int nExpectedBranches, std::string_view actionNameForErr)
TResultProxy<::TH2F > Histo2D(::TH2F &&model)
TResultProxy<::TProfile > Profile1D(::TProfile &&model)
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=1, Int_t netopt=0)
Create / open a file.
TInterface< TFilterBase > Filter(F f, const ColumnNames_t &bn={}, std::string_view name="")
Append a filter to the call graph.
TResultProxy<::TH2F > Histo2D(::TH2F &&model, std::string_view v1Name="", std::string_view v2Name="")
Fill and return a two-dimensional histogram (lazy action)
TInterface< TRangeBase > Range(unsigned int start, unsigned int stop, unsigned int stride=1)
Creates a node that filters entries based on range.
TInterface< TLoopManager > Snapshot(std::string_view treename, std::string_view filename, const ColumnNames_t &bnames)
Create a snapshot of the dataset on disk in the form of a TTree.
TResultProxy<::TH1F > Histo1D(::TH1F &&model=::TH1F{"","", 128u, 0., 0.}, std::string_view vName="")
Fill and return a one-dimensional histogram with the values of a branch (lazy action) ...
TResultProxy<::TProfile > Profile1D(::TProfile &&model, std::string_view v1Name="", std::string_view v2Name="")
Fill and return a one-dimensional profile (lazy action)
TResultProxy<::TProfile2D > Profile2D(::TProfile2D &&model, std::string_view v1Name="", std::string_view v2Name="", std::string_view v3Name="")
Fill and return a two-dimensional profile (lazy action)
TResultProxy<::TH1F > Histo1D(::TH1F &&model, std::string_view vName, std::string_view wName)
Fill and return a one-dimensional histogram with the values of a branch (lazy action) ...
const char * GetNodeTypeName()
TResultProxy< T > Reduce(F f, std::string_view branchName={})
Execute a user-defined reduce operation on the values of a branch.
RooArgSet S(const RooAbsArg &v1)
Smart pointer for the return type of actions.
std::string printValue(const TDatime *val)
Print a TDatime at the prompt.
TResultProxy<::TH2F > Histo2D(::TH2F &&model, std::string_view v1Name, std::string_view v2Name, std::string_view wName)
Fill and return a two-dimensional histogram (lazy action)
TResultProxy<::TH1F > Histo1D(std::string_view vName)
TInterface< TFilterBase > Filter(F f, std::string_view name)
Append a filter to the call graph.
TInterface(const std::shared_ptr< Proxied > &proxied, const std::weak_ptr< TLoopManager > &impl)
Double_t Mean(Long64_t n, const T *a, const Double_t *w=0)
std::shared_ptr< TLoopManager > GetDataFrameChecked()
Get the TLoopManager if reachable. If not, throw.
TBufferMerger is a class to facilitate writing data in parallel from multiple threads, while writing to a single output file.
Histogram class for histograms with DIMENSIONS dimensions, where each bin count is stored by a value ...
std::string ColumnName2ColumnTypeName(const std::string &colName, TTree *tree, TCustomColumnBase *tmpBranch)
Return a string containing the type of the given branch.
void ForeachSlot(F f, const ColumnNames_t &bl={})
Execute a user-defined function requiring a processing slot index on each entry (instant action) ...
TInterface< TRangeBase > Range(unsigned int stop)
Creates a node that filters entries based on range.
TResultProxy< T > Fill(T &&model, const ColumnNames_t &bl)
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)
TResultProxy< ActionResultType > CreateAction(const ColumnNames_t &bl, const std::shared_ptr< ActionResultType > &r)
TInterface< TLoopManager > SnapshotImpl(std::string_view treename, std::string_view filename, const ColumnNames_t &bnames, TDFInternal::TStaticSeq< S...>)
Implementation of snapshot.
TResultProxy< T > MakeResultProxy(const std::shared_ptr< T > &r, const std::shared_ptr< TLoopManager > &df)
TInterface< TFilterBase > Filter(std::string_view expression, std::string_view name="")
Append a filter to the call graph.
TResultProxy< double > Min(std::string_view branchName="")
Return the minimum of processed branch values (lazy action)
void Run(unsigned int slot, Long64_t entry) final
TResultProxy< double > Max(std::string_view branchName="")
Return the maximum of processed branch values (lazy action)
void Report()
Print filtering statistics on screen.
static RooMathCoreReg dummy
TResultProxy<::TH1F > Histo1D(::TH1F &&model=::TH1F{"","", 128u, 0., 0.})
std::shared_ptr< Proxied > fProxiedPtr
Profile2D histograms are used to display the mean value of Z and its RMS for each cell in X...
typedef void((*Func_t)())
TResultProxy< T > Fill(T &&model, const ColumnNames_t &bl)
Fill and return any entity with a Fill method (lazy action)
Bool_t IsImplicitMTEnabled()
Returns true if the implicit multi-threading in ROOT is enabled.
TResultProxy<::TH1F > Histo1D(std::string_view vName, std::string_view wName)
ROOT's TDataFrame offers a high level interface for analyses of data stored in TTrees.
Short_t Max(Short_t a, Short_t b)
A chain is a collection of files containing TTree objects.
void CheckTmpBranch(std::string_view branchName, TTree *treePtr)
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
ColumnNames_t GetBranchNames(const std::vector< std::string_view > &bl, std::string_view actionNameForErr)
Returns the default branches if needed, takes care of the error handling.
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)
TResultProxy< T > Reduce(F f, std::string_view branchName, const T &initValue)
Execute a user-defined reduce operation on the values of a branch.
std::shared_ptr< TCustomColumnBase > TmpBranchBasePtr_t
std::vector< std::string > GetUsedBranchesNames(const std::string, TObjArray *, const std::vector< std::string > &)
TResultProxy< double > Mean(std::string_view branchName="")
Return the mean of processed branch values (lazy action)
std::weak_ptr< TLoopManager > fImplWeakPtr
static void Fill(TTree *tree, int init, int count)
The public interface to the TDataFrame federation of classes.
virtual Int_t Add(TChain *chain)
Add all files referenced by the passed chain to this chain.
TResultProxy<::TProfile > Profile1D(::TProfile &&model, std::string_view v1Name, std::string_view v2Name, std::string_view wName)
Fill and return a one-dimensional profile (lazy action)
TInterface(const std::shared_ptr< Proxied > &proxied)
Only enabled when building a TInterface<TLoopManager>
TResultProxy< COLL > Take(std::string_view branchName="")
Return a collection of values of a branch (lazy action)
TResultProxy< unsigned int > Count()
Return the number of entries processed (lazy action)