11 #ifndef ROOT_TDF_TINTERFACE 12 #define ROOT_TDF_TINTERFACE 31 #include <initializer_list> 36 #include <type_traits> 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 {
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();
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();
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();
245 auto tree = df->GetTree();
246 auto branches = tree ? tree->GetListOfBranches() :
nullptr;
247 auto tmpBranches = fProxiedPtr->GetTmpBranches();
248 auto tmpBookedBranches = df->GetBookedBranches();
249 const std::string expressionInt(expression);
250 const std::string nameInt(name);
263 template <
typename... BranchTypes>
267 using TypeInd_t =
typename TDFInternal::TGenStaticSeq<
sizeof...(BranchTypes)>::Type_t;
268 return SnapshotImpl<BranchTypes...>(treename, filename, bnames, TypeInd_t());
282 auto df = GetDataFrameChecked();
283 auto tree = df->GetTree();
284 std::stringstream snapCall;
287 snapCall <<
"if (gROOTMutex) gROOTMutex->UnLock(); ((" << GetNodeTypeName() <<
"*)" <<
this <<
")->Snapshot<";
289 for (
auto &
b : bnames) {
290 if (!first) snapCall <<
", ";
294 const std::string treeNameInt(treename);
295 const std::string filenameInt(filename);
296 snapCall <<
">(\"" << treeNameInt <<
"\", \"" << filenameInt <<
"\", " 297 <<
"*reinterpret_cast<std::vector<std::string>*>(" 301 auto newTDFPtr =
gInterpreter->Calc(snapCall.str().c_str(), &errorCode);
302 if (TInterpreter::EErrorCode::kNoError != errorCode) {
303 std::string msg =
"Cannot jit Snapshot call. Interpreter error code is " + std::to_string(errorCode) +
".";
304 throw std::runtime_error(msg);
318 std::string_view columnNameRegexp =
"")
320 const auto theRegexSize = columnNameRegexp.size();
321 std::string theRegex(columnNameRegexp);
323 const auto isEmptyRegex = 0 == theRegexSize;
325 if (theRegexSize > 0 && theRegex[0] !=
'^') theRegex =
"^" + theRegex;
326 if (theRegexSize > 0 && theRegex[theRegexSize-1] !=
'$') theRegex = theRegex +
"$";
329 selectedColumns.reserve(32);
331 const auto tmpBranches = fProxiedPtr->GetTmpBranches();
342 auto df = GetDataFrameChecked();
343 auto tree = df->GetTree();
354 return Snapshot(treename, filename, selectedColumns);
367 if (stride == 0 || (stop != 0 && stop < start))
368 throw std::runtime_error(
"Range: stride must be strictly greater than 0 and stop must be greater than start.");
370 throw std::runtime_error(
"Range was called with ImplicitMT enabled. Multi-thread ranges are not supported.");
372 auto df = GetDataFrameChecked();
374 auto RangePtr = std::make_shared<Range_t>(start, stop, stride, *fProxiedPtr);
399 template <
typename F>
402 using Args_t =
typename TDFInternal::TFunctionTraits<decltype(f)>::ArgsNoDecay_t;
403 using Ret_t =
typename TDFInternal::TFunctionTraits<decltype(f)>::Ret_t;
404 ForeachSlot(TDFInternal::AddSlotParameter<Ret_t>(f, Args_t()), bl);
423 template <
typename F>
426 auto df = GetDataFrameChecked();
428 auto nArgs = TDFInternal::TFunctionTraits<F>::Args_t::fgSize;
430 using Op_t = TDFInternal::ForeachSlotHelper<F>;
432 df->Book(std::make_shared<DFA_t>(Op_t(std::move(f)), actualBl, *fProxiedPtr));
433 fProxiedPtr->IncrChildrenCount();
453 template <typename F, typename T = typename TDFInternal::TFunctionTraits<F>::Ret_t>
456 static_assert(std::is_default_constructible<T>::value,
457 "reduce object cannot be default-constructed. Please provide an initialisation value (initValue)");
470 template <typename F, typename T = typename TDFInternal::TFunctionTraits<F>::Ret_t>
473 using Args_t =
typename TDFInternal::TFunctionTraits<F>::Args_t;
474 TDFInternal::CheckReduce(f, Args_t());
475 auto df = GetDataFrameChecked();
476 unsigned int nSlots = df->GetNSlots();
477 auto bl = GetBranchNames<T>({branchName},
"reduce branch values");
478 auto redObjPtr = std::make_shared<T>(initValue);
479 using Op_t = TDFInternal::ReduceHelper<F, T>;
481 df->Book(std::make_shared<DFA_t>(Op_t(std::move(f), redObjPtr, nSlots), bl, *fProxiedPtr));
482 fProxiedPtr->IncrChildrenCount();
493 auto df = GetDataFrameChecked();
494 unsigned int nSlots = df->GetNSlots();
495 auto cSPtr = std::make_shared<unsigned int>(0);
496 using Op_t = TDFInternal::CountHelper;
498 df->Book(std::make_shared<DFA_t>(Op_t(cSPtr, nSlots),
ColumnNames_t({}), *fProxiedPtr));
499 fProxiedPtr->IncrChildrenCount();
511 template <
typename T,
typename COLL = std::vector<T>>
514 auto df = GetDataFrameChecked();
515 unsigned int nSlots = df->GetNSlots();
516 auto bl = GetBranchNames<T>({
branchName},
"get the values of the branch");
517 auto valuesPtr = std::make_shared<COLL>();
518 using Op_t = TDFInternal::TakeHelper<T, COLL>;
520 df->Book(std::make_shared<DFA_t>(Op_t(valuesPtr, nSlots), bl, *fProxiedPtr));
521 fProxiedPtr->IncrChildrenCount();
539 template <
typename V = TDFDetail::TInferType>
542 auto bl = GetBranchNames<V>({vName},
"fill the histogram");
543 auto h = std::make_shared<::TH1F>(std::move(
model));
544 if (h->GetXaxis()->GetXmax() == h->GetXaxis()->GetXmin())
545 TDFInternal::HistoUtils<::TH1F>::SetCanExtendAllAxes(*h);
546 return CreateAction<TDFInternal::ActionTypes::Histo1D, V>(bl,
h);
549 template <
typename V = TDFDetail::TInferType>
552 return Histo1D<V>(
::TH1F{
"",
"", 128u, 0., 0.}, vName);
570 template <
typename V = TDFDetail::TInferType,
typename W = TDFDetail::TInferType>
573 auto bl = GetBranchNames<V, W>({vName, wName},
"fill the histogram");
574 auto h = std::make_shared<::TH1F>(std::move(
model));
575 return CreateAction<TDFInternal::ActionTypes::Histo1D, V, W>(bl,
h);
578 template <
typename V = TDFDetail::TInferType,
typename W = TDFDetail::TInferType>
581 return Histo1D<V, W>(
::TH1F{
"",
"", 128u, 0., 0.}, vName, wName);
584 template <
typename V,
typename W>
587 return Histo1D<V, W>(std::move(
model),
"",
"");
601 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType>
604 auto h = std::make_shared<::TH2F>(std::move(
model));
605 if (!TDFInternal::HistoUtils<::TH2F>::HasAxisLimits(*h)) {
606 throw std::runtime_error(
"2D histograms with no axes limits are not supported yet.");
608 auto bl = GetBranchNames<V1, V2>({v1Name, v2Name},
"fill the histogram");
609 return CreateAction<TDFInternal::ActionTypes::Histo2D, V1, V2>(bl,
h);
625 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType,
626 typename W = TDFDetail::TInferType>
628 std::string_view wName)
630 auto h = std::make_shared<::TH2F>(std::move(
model));
631 if (!TDFInternal::HistoUtils<::TH2F>::HasAxisLimits(*h)) {
632 throw std::runtime_error(
"2D histograms with no axes limits are not supported yet.");
634 auto bl = GetBranchNames<V1, V2, W>({v1Name, v2Name, wName},
"fill the histogram");
635 return CreateAction<TDFInternal::ActionTypes::Histo2D, V1, V2, W>(bl,
h);
638 template <
typename V1,
typename V2,
typename W>
641 return Histo2D<V1, V2, W>(std::move(
model),
"",
"",
"");
657 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType,
658 typename V3 = TDFDetail::TInferType>
660 std::string_view v3Name =
"")
662 auto h = std::make_shared<::TH3F>(std::move(
model));
663 if (!TDFInternal::HistoUtils<::TH3F>::HasAxisLimits(*h)) {
664 throw std::runtime_error(
"3D histograms with no axes limits are not supported yet.");
666 auto bl = GetBranchNames<V1, V2, V3>({v1Name, v2Name, v3Name},
"fill the histogram");
667 return CreateAction<TDFInternal::ActionTypes::Histo3D, V1, V2, V3>(bl,
h);
685 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType,
686 typename V3 = TDFDetail::TInferType,
typename W = TDFDetail::TInferType>
688 std::string_view v3Name, std::string_view wName)
690 auto h = std::make_shared<::TH3F>(std::move(
model));
691 if (!TDFInternal::HistoUtils<::TH3F>::HasAxisLimits(*h)) {
692 throw std::runtime_error(
"3D histograms with no axes limits are not supported yet.");
694 auto bl = GetBranchNames<V1, V2, V3, W>({v1Name, v2Name, v3Name, wName},
"fill the histogram");
695 return CreateAction<TDFInternal::ActionTypes::Histo3D, V1, V2, V3, W>(bl,
h);
698 template <
typename V1,
typename V2,
typename V3,
typename W>
701 return Histo3D<V1, V2, V3, W>(std::move(
model),
"",
"",
"",
"");
715 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType>
717 std::string_view v2Name =
"")
719 auto h = std::make_shared<::TProfile>(std::move(
model));
720 if (!TDFInternal::HistoUtils<::TProfile>::HasAxisLimits(*h)) {
721 throw std::runtime_error(
"Profiles with no axes limits are not supported yet.");
723 auto bl = GetBranchNames<V1, V2>({v1Name, v2Name},
"fill the 1D Profile");
724 return CreateAction<TDFInternal::ActionTypes::Profile1D, V1, V2>(bl,
h);
740 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType,
741 typename W = TDFDetail::TInferType>
743 std::string_view wName)
745 auto h = std::make_shared<::TProfile>(std::move(
model));
746 if (!TDFInternal::HistoUtils<::TProfile>::HasAxisLimits(*h)) {
747 throw std::runtime_error(
"Profile histograms with no axes limits are not supported yet.");
749 auto bl = GetBranchNames<V1, V2, W>({v1Name, v2Name, wName},
"fill the 1D profile");
750 return CreateAction<TDFInternal::ActionTypes::Profile1D, V1, V2, W>(bl,
h);
753 template <
typename V1,
typename V2,
typename W>
756 return Profile1D<V1, V2, W>(std::move(
model),
"",
"",
"");
772 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType,
773 typename V3 = TDFDetail::TInferType>
775 std::string_view v2Name =
"", std::string_view v3Name =
"")
777 auto h = std::make_shared<::TProfile2D>(std::move(
model));
778 if (!TDFInternal::HistoUtils<::TProfile2D>::HasAxisLimits(*h)) {
779 throw std::runtime_error(
"2D profiles with no axes limits are not supported yet.");
781 auto bl = GetBranchNames<V1, V2, V3>({v1Name, v2Name, v3Name},
"fill the 2D profile");
782 return CreateAction<TDFInternal::ActionTypes::Profile2D, V1, V2, V3>(bl,
h);
800 template <
typename V1 = TDFDetail::TInferType,
typename V2 = TDFDetail::TInferType,
801 typename V3 = TDFDetail::TInferType,
typename W = TDFDetail::TInferType>
803 std::string_view v3Name, std::string_view wName)
805 auto h = std::make_shared<::TProfile2D>(std::move(
model));
806 if (!TDFInternal::HistoUtils<::TProfile2D>::HasAxisLimits(*h)) {
807 throw std::runtime_error(
"2D profiles with no axes limits are not supported yet.");
809 auto bl = GetBranchNames<V1, V2, V3, W>({v1Name, v2Name, v3Name, wName},
"fill the histogram");
810 return CreateAction<TDFInternal::ActionTypes::Profile2D, V1, V2, V3, W>(bl,
h);
813 template <
typename V1,
typename V2,
typename V3,
typename W>
816 return Profile2D<V1, V2, V3, W>(std::move(
model),
"",
"",
"",
"");
830 template <
typename FirstBranch,
typename... OtherBranches,
typename T>
833 auto h = std::make_shared<T>(std::move(
model));
834 if (!TDFInternal::HistoUtils<T>::HasAxisLimits(*h)) {
835 throw std::runtime_error(
"The absence of axes limits is not supported yet.");
840 template <
typename T>
843 auto h = std::make_shared<T>(std::move(
model));
844 if (!TDFInternal::HistoUtils<T>::HasAxisLimits(*h)) {
845 throw std::runtime_error(
"The absence of axes limits is not supported yet.");
847 return CreateAction<TDFInternal::ActionTypes::Fill, TDFDetail::TInferType>(bl,
h);
859 template <
typename T = TDFDetail::TInferType>
862 auto bl = GetBranchNames<T>({
branchName},
"calculate the minimum");
863 auto minV = std::make_shared<double>(std::numeric_limits<double>::max());
864 return CreateAction<TDFInternal::ActionTypes::Min, T>(bl, minV);
876 template <
typename T = TDFDetail::TInferType>
879 auto bl = GetBranchNames<T>({
branchName},
"calculate the maximum");
880 auto maxV = std::make_shared<double>(std::numeric_limits<double>::lowest());
881 return CreateAction<TDFInternal::ActionTypes::Max, T>(bl, maxV);
893 template <
typename T = TDFDetail::TInferType>
896 auto bl = GetBranchNames<T>({
branchName},
"calculate the mean");
897 auto meanV = std::make_shared<double>(0);
898 return CreateAction<TDFInternal::ActionTypes::Mean, T>(bl, meanV);
912 auto df = GetDataFrameChecked();
913 if (!df->HasRunAtLeastOnce()) df->Run();
914 fProxiedPtr->Report();
921 template <
typename T1,
typename T2 =
void,
typename T3 =
void,
typename T4 =
void>
924 constexpr
auto isT2Void = std::is_same<T2, void>::value;
925 constexpr
auto isT3Void = std::is_same<T3, void>::value;
926 constexpr
auto isT4Void = std::is_same<T4, void>::value;
928 unsigned int neededBranches = 1 + !isT2Void + !isT3Void + !isT4Void;
930 unsigned int providedBranches = 0;
931 std::for_each(bl.begin(), bl.end(), [&providedBranches](std::string_view s) {
932 if (!s.empty()) providedBranches++;
935 if (neededBranches == providedBranches) {
940 return GetDefaultBranchNames(neededBranches, actionNameForErr);
949 template <
typename... BranchTypes,
typename ActionType,
typename ActionResultType>
950 void BuildAndBook(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &h,
unsigned int nSlots,
953 using Op_t = TDFInternal::FillTOHelper<ActionResultType>;
955 auto df = GetDataFrameChecked();
956 df->Book(std::make_shared<DFA_t>(Op_t(h, nSlots), bl, *fProxiedPtr));
960 template <
typename... BranchTypes>
961 void BuildAndBook(
const ColumnNames_t &bl,
const std::shared_ptr<::TH1F> &h,
unsigned int nSlots,
962 TDFInternal::ActionTypes::Histo1D *)
964 auto df = GetDataFrameChecked();
965 auto hasAxisLimits = TDFInternal::HistoUtils<::TH1F>::HasAxisLimits(*h);
968 using Op_t = TDFInternal::FillTOHelper<::TH1F>;
970 df->Book(std::make_shared<DFA_t>(Op_t(h, nSlots), bl, *fProxiedPtr));
972 using Op_t = TDFInternal::FillHelper;
974 df->Book(std::make_shared<DFA_t>(Op_t(h, nSlots), bl, *fProxiedPtr));
979 template <
typename BranchType>
980 void BuildAndBook(
const ColumnNames_t &bl,
const std::shared_ptr<double> &minV,
unsigned int nSlots,
983 using Op_t = TDFInternal::MinHelper;
985 auto df = GetDataFrameChecked();
986 df->Book(std::make_shared<DFA_t>(Op_t(minV, nSlots), bl, *fProxiedPtr));
990 template <
typename BranchType>
991 void BuildAndBook(
const ColumnNames_t &bl,
const std::shared_ptr<double> &maxV,
unsigned int nSlots,
994 using Op_t = TDFInternal::MaxHelper;
996 auto df = GetDataFrameChecked();
997 df->Book(std::make_shared<DFA_t>(Op_t(maxV, nSlots), bl, *fProxiedPtr));
1001 template <
typename BranchType>
1002 void BuildAndBook(
const ColumnNames_t &bl,
const std::shared_ptr<double> &meanV,
unsigned int nSlots,
1005 using Op_t = TDFInternal::MeanHelper;
1007 auto df = GetDataFrameChecked();
1008 df->Book(std::make_shared<DFA_t>(Op_t(meanV, nSlots), bl, *fProxiedPtr));
1014 template <
typename ActionType,
typename... BranchTypes,
typename ActionResultType,
1015 typename std::enable_if<!TDFInternal::TNeedJitting<BranchTypes...>::value,
int>::type = 0>
1018 auto df = GetDataFrameChecked();
1019 unsigned int nSlots = df->GetNSlots();
1020 BuildAndBook<BranchTypes...>(bl,
r, nSlots, (ActionType *)
nullptr);
1021 fProxiedPtr->IncrChildrenCount();
1026 template <
typename ActionType,
typename... BranchTypes,
typename ActionResultType,
1027 typename std::enable_if<TDFInternal::TNeedJitting<BranchTypes...>::value,
int>::type = 0>
1030 auto df = GetDataFrameChecked();
1031 unsigned int nSlots = df->GetNSlots();
1032 const auto &tmpBranches = df->GetBookedBranches();
1033 auto tree = df->GetTree();
1035 typeid(ActionType), &r,
tree, nSlots, tmpBranches);
1036 fProxiedPtr->IncrChildrenCount();
1044 auto df = fImplWeakPtr.lock();
1046 throw std::runtime_error(
"The main TDataFrame is not reachable: did it go out of scope?");
1053 auto df = GetDataFrameChecked();
1054 const ColumnNames_t &defaultBranches = df->GetDefaultBranches();
1055 const auto dBSize = defaultBranches.size();
1056 if (nExpectedBranches > dBSize) {
1057 std::string msg(
"Trying to deduce the branches from the default list in order to ");
1058 msg += actionNameForErr;
1059 msg +=
". A set of branches of size ";
1060 msg += std::to_string(dBSize);
1061 msg +=
" was found. ";
1062 msg += std::to_string(nExpectedBranches);
1063 msg += 1 != nExpectedBranches ?
" are" :
" is";
1064 msg +=
" needed. Please specify the branches explicitly.";
1065 throw std::runtime_error(msg);
1067 auto bnBegin = defaultBranches.begin();
1081 template <
typename... Args,
int...
S>
1083 const ColumnNames_t &bnames, TDFInternal::TStaticSeq<S...> )
1085 const std::string filenameInt(filename);
1086 const auto templateParamsN =
sizeof...(S);
1087 const auto bNamesN = bnames.size();
1088 if (templateParamsN != bNamesN) {
1089 std::string err_msg =
"The number of template parameters specified for the snapshot is ";
1090 err_msg += std::to_string(templateParamsN);
1091 err_msg +=
" while ";
1092 err_msg += std::to_string(bNamesN);
1093 err_msg +=
" branches have been specified.";
1094 throw std::runtime_error(err_msg.c_str());
1098 auto getDirTreeName = [](std::string_view treePath) {
1099 auto lastSlash = treePath.rfind(
'/');
1100 std::string_view treeDir, treeName;
1101 if (std::string_view::npos != lastSlash) {
1102 treeDir = treePath.substr(0,lastSlash);
1103 treeName = treePath.substr(lastSlash+1,treePath.size());
1105 treeName = treePath;
1108 return std::make_pair(std::string(treeDir), std::string(treeName));
1111 auto df = GetDataFrameChecked();
1113 std::string treenameInt;
1114 std::string dirnameInt;
1115 std::unique_ptr<TFile> ofile(
TFile::Open(filenameInt.c_str(),
"RECREATE"));
1116 std::tie(dirnameInt, treenameInt) = getDirTreeName(treename);
1117 if (!dirnameInt.empty()) {
1118 ofile->mkdir(dirnameInt.c_str());
1119 ofile->cd(dirnameInt.c_str());
1121 TTree t(treenameInt.c_str(), treenameInt.c_str());
1123 bool FirstEvent =
true;
1125 auto fillTree = [&t, &bnames, &FirstEvent](
unsigned int , Args &... args) {
1128 std::initializer_list<int> expander = {(t.Branch(bnames[
S].c_str(), &args), 0)..., 0};
1135 auto initLambda = [&t] (
TTreeReader *
r,
unsigned int ) {
1143 using Op_t = TDFInternal::SnapshotHelper<decltype(initLambda), decltype(fillTree)>;
1145 df->Book(std::make_shared<DFA_t>(Op_t(std::move(initLambda), std::move(
fillTree)), bnames, *fProxiedPtr));
1146 fProxiedPtr->IncrChildrenCount();
1150 unsigned int nSlots = df->GetNSlots();
1152 std::vector<std::shared_ptr<TBufferMergerFile>> files(nSlots);
1153 std::vector<TTree *> trees(nSlots,
nullptr);
1154 std::vector<int> isFirstEvent(nSlots, 1);
1156 auto fillTree = [&](
unsigned int slot, Args &... args) {
1157 if (isFirstEvent[slot]) {
1159 std::initializer_list<int> expander = {(trees[slot]->Branch(bnames[
S].c_str(), &args), 0)..., 0};
1161 isFirstEvent[slot] = 0;
1163 trees[slot]->Fill();
1164 auto entries = trees[slot]->GetEntries();
1165 auto autoflush = trees[slot]->GetAutoFlush();
1166 if ((autoflush > 0) && (entries % autoflush == 0)) files[slot]->Write();
1170 auto initLambda = [&trees, &merger, &files, &treename, &isFirstEvent, &getDirTreeName](
TTreeReader *
r,
1171 unsigned int slot) {
1172 std::string treenameInt;
1173 std::string dirnameInt;
1177 files[slot] = merger.GetFile();
1179 files[slot]->Write();
1181 std::tie(dirnameInt, treenameInt) = getDirTreeName(treename);
1183 if (!dirnameInt.empty()) subdir = files[slot]->mkdir(dirnameInt.c_str());
1185 trees[slot] =
new TTree(treenameInt.c_str(), treenameInt.c_str());
1187 trees[slot]->SetImplicitMT(
false);
1190 auto tree = r->GetTree();
1191 tree->AddClone(trees[slot]);
1193 isFirstEvent[slot] = 1;
1196 using Op_t = TDFInternal::SnapshotHelper<decltype(initLambda), decltype(fillTree)>;
1198 df->Book(std::make_shared<DFA_t>(Op_t(std::move(initLambda), std::move(
fillTree)), bnames, *fProxiedPtr));
1199 fProxiedPtr->IncrChildrenCount();
1201 for (
auto &&
file : files) {
1207 std::string fullTreeNameInt(treename);
1211 auto chain =
new TChain(fullTreeNameInt.c_str());
1212 chain->
Add(filenameInt.c_str());
1213 snapshotTDF.
fProxiedPtr->SetTree(std::shared_ptr<TTree>(static_cast<TTree *>(chain)));
1218 TInterface(
const std::shared_ptr<Proxied> &proxied,
const std::weak_ptr<TLoopManager> &impl)
1219 : fProxiedPtr(proxied), fImplWeakPtr(impl)
1224 template <typename T = Proxied, typename std::enable_if<std::is_same<T, TLoopManager>::value,
int>::type = 0>
1225 TInterface(
const std::shared_ptr<Proxied> &proxied) : fProxiedPtr(proxied), fImplWeakPtr(proxied->GetSharedPtr())
1236 return "ROOT::Experimental::TDF::TInterface<ROOT::Detail::TDF::TFilterBase>";
1242 return "ROOT::Experimental::TDF::TInterface<ROOT::Detail::TDF::TCustomColumnBase>";
1248 return "ROOT::Experimental::TDF::TInterface<ROOT::Detail::TDF::TLoopManager>";
1254 return "ROOT::Experimental::TDF::TInterface<ROOT::Detail::TDF::TRangeBase>";
1261 #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...
Namespace for new ROOT classes and functions.
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.
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.})
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)
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) ...
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)
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)
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...
Print a TSeq at the prompt:
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
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)
Key/value store of objects.
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.
TInterface< TLoopManager > SnapshotImpl(std::string_view treename, std::string_view filename, const ColumnNames_t &bnames, TDFInternal::TStaticSeq< S... >)
Implementation of snapshot.
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)