19#ifndef ROOT_RDFOPERATIONS
20#define ROOT_RDFOPERATIONS
75 std::vector<TBranch *> fBranches;
76 std::vector<std::string> fNames;
81 auto it = std::find(fNames.begin(), fNames.end(),
name);
82 if (it == fNames.end())
84 return fBranches[std::distance(fNames.begin(), it)];
87 void Insert(
const std::string &
name,
TBranch *address)
89 if (address ==
nullptr) {
90 throw std::logic_error(
"Trying to insert a null branch address.");
92 if (std::find(fBranches.begin(), fBranches.end(), address) != fBranches.end()) {
93 throw std::logic_error(
"Trying to insert a branch address that's already present.");
95 if (std::find(fNames.begin(), fNames.end(),
name) != fNames.end()) {
96 throw std::logic_error(
"Trying to insert a branch name that's already present.");
98 fNames.emplace_back(
name);
99 fBranches.emplace_back(address);
108 void AssertNoNullBranchAddresses()
110 std::vector<TBranch *> branchesWithNullAddress;
111 std::copy_if(fBranches.begin(), fBranches.end(), std::back_inserter(branchesWithNullAddress),
112 [](
TBranch *
b) { return b->GetAddress() == nullptr; });
114 if (branchesWithNullAddress.empty())
118 std::vector<std::string> missingBranchNames;
119 std::transform(branchesWithNullAddress.begin(), branchesWithNullAddress.end(),
120 std::back_inserter(missingBranchNames), [](
TBranch *
b) { return b->GetName(); });
121 std::string msg =
"RDataFrame::Snapshot:";
122 if (missingBranchNames.size() == 1) {
123 msg +=
" branch " + missingBranchNames[0] +
124 " is needed as it provides the size for one or more branches containing dynamically sized arrays, but "
128 for (
const auto &bName : missingBranchNames)
130 msg.resize(msg.size() - 2);
132 " are needed as they provide the size of other branches containing dynamically sized arrays, but they are";
134 msg +=
" not part of the set of branches that are being written out.";
135 throw std::runtime_error(msg);
147class R__CLING_PTRCHECK(off) ForeachSlotHelper :
public RActionImpl<ForeachSlotHelper<F>> {
153 ForeachSlotHelper(ForeachSlotHelper &&) =
default;
154 ForeachSlotHelper(
const ForeachSlotHelper &) =
delete;
158 template <
typename... Args>
159 void Exec(
unsigned int slot, Args &&... args)
162 static_assert(std::is_same<TypeList<std::decay_t<Args>...>, ColumnTypes_t>
::value,
"");
163 fCallable(slot, std::forward<Args>(args)...);
170 std::string GetActionName() {
return "ForeachSlot"; }
173class R__CLING_PTRCHECK(off) CountHelper :
public RActionImpl<CountHelper> {
174 std::shared_ptr<ULong64_t> fResultCount;
175 Results<ULong64_t> fCounts;
179 CountHelper(
const std::shared_ptr<ULong64_t> &resultCount,
const unsigned int nSlots);
180 CountHelper(CountHelper &&) =
default;
181 CountHelper(
const CountHelper &) =
delete;
183 void Exec(
unsigned int slot);
190 return std::make_unique<RMergeableCount>(*fResultCount);
193 ULong64_t &PartialUpdate(
unsigned int slot);
195 std::string GetActionName() {
return "Count"; }
197 CountHelper MakeNew(
void *newResult)
199 auto &
result = *
static_cast<std::shared_ptr<ULong64_t> *
>(newResult);
200 return CountHelper(
result, fCounts.size());
204template <
typename RNode_t>
205class R__CLING_PTRCHECK(off) ReportHelper :
public RActionImpl<ReportHelper<RNode_t>> {
206 std::shared_ptr<RCutFlowReport> fReport;
210 bool fReturnEmptyReport;
214 ReportHelper(
const std::shared_ptr<RCutFlowReport> &report, RNode_t *node,
bool emptyRep)
215 : fReport(report), fNode(node), fReturnEmptyReport(emptyRep){};
216 ReportHelper(ReportHelper &&) =
default;
217 ReportHelper(
const ReportHelper &) =
delete;
219 void Exec(
unsigned int ) {}
223 if (!fReturnEmptyReport)
224 fNode->Report(*fReport);
227 std::string GetActionName() {
return "Report"; }
239class R__CLING_PTRCHECK(off) BufferedFillHelper :
public RActionImpl<BufferedFillHelper> {
241 static constexpr unsigned int fgTotalBufSize = 2097152;
243 using Buf_t = std::vector<BufEl_t>;
245 std::vector<Buf_t> fBuffers;
246 std::vector<Buf_t> fWBuffers;
247 std::shared_ptr<Hist_t> fResultHist;
248 unsigned int fNSlots;
249 unsigned int fBufSize;
251 Results<std::unique_ptr<Hist_t>> fPartialHists;
255 void UpdateMinMax(
unsigned int slot,
double v);
258 BufferedFillHelper(
const std::shared_ptr<Hist_t> &
h,
const unsigned int nSlots);
259 BufferedFillHelper(BufferedFillHelper &&) =
default;
260 BufferedFillHelper(
const BufferedFillHelper &) =
delete;
262 void Exec(
unsigned int slot,
double v);
263 void Exec(
unsigned int slot,
double v,
double w);
266 void Exec(
unsigned int slot,
const T &vs)
268 auto &thisBuf = fBuffers[slot];
270 for (
auto v = vs.begin();
v != vs.end(); ++
v) {
271 UpdateMinMax(slot, *
v);
272 thisBuf.emplace_back(*
v);
277 void Exec(
unsigned int slot,
const T &vs,
const W &ws)
279 auto &thisBuf = fBuffers[slot];
282 UpdateMinMax(slot,
v);
283 thisBuf.emplace_back(
v);
286 auto &thisWBuf = fWBuffers[slot];
288 thisWBuf.emplace_back(
w);
293 void Exec(
unsigned int slot,
const T &vs,
const W
w)
295 auto &thisBuf = fBuffers[slot];
297 UpdateMinMax(slot,
v);
298 thisBuf.emplace_back(
v);
301 auto &thisWBuf = fWBuffers[slot];
302 thisWBuf.insert(thisWBuf.end(), vs.size(),
w);
307 void Exec(
unsigned int,
const T &,
const W &)
309 throw std::runtime_error(
310 "Cannot fill object if the type of the first column is a scalar and the one of the second a container.");
313 Hist_t &PartialUpdate(
unsigned int);
322 return std::make_unique<RMergeableFill<Hist_t>>(*fResultHist);
325 std::string GetActionName()
327 return std::string(fResultHist->IsA()->GetName()) +
"\\n" + std::string(fResultHist->GetName());
330 BufferedFillHelper MakeNew(
void *newResult)
332 auto &
result = *
static_cast<std::shared_ptr<Hist_t> *
>(newResult);
334 result->SetDirectory(
nullptr);
335 return BufferedFillHelper(
result, fNSlots);
345extern template void BufferedFillHelper::Exec(
unsigned int,
const std::vector<double> &,
const std::vector<double> &);
353template <
typename HIST = Hist_t>
355 std::vector<HIST *> fObjects;
357 template <typename H = HIST, typename = decltype(std::declval<H>().Reset())>
358 void ResetIfPossible(
H *
h)
366 void ResetIfPossible(...)
368 throw std::runtime_error(
369 "A systematic variation was requested for a custom Fill action, but the type of the object to be filled does "
370 "not implement a Reset method, so we cannot safely re-initialize variations of the result. Aborting.");
373 void UnsetDirectoryIfPossible(
TH1 *
h) {
374 h->SetDirectory(
nullptr);
377 void UnsetDirectoryIfPossible(...) {}
381 auto Merge(std::vector<H *> &objs,
int )
385 for (
auto it = ++objs.begin(); it != objs.end(); ++it)
391 template <
typename H>
392 auto Merge(std::vector<H *> &objs,
double )
393 ->
decltype(objs[0]->Merge(std::vector<HIST *>{}),
void())
395 objs[0]->Merge({++objs.begin(), objs.end()});
399 template <
typename T>
402 static_assert(
sizeof(
T) < 0,
403 "The type passed to Fill does not provide a Merge(TCollection*) or Merge(const std::vector&) method.");
407 template <
typename T>
408 class ScalarConstIterator {
412 ScalarConstIterator(
const T *obj) : obj_(obj) {}
414 ScalarConstIterator<T> &operator++() {
return *
this; }
423 ScalarConstIterator<T> MakeBegin(
const T &val)
425 return ScalarConstIterator<T>(&val);
430 auto MakeBegin(
const T &val)
432 return std::begin(val);
437 std::size_t GetSize(
const T &)
444 std::size_t GetSize(
const T &val)
446#if __cplusplus >= 201703L
453 template <std::size_t ColIdx,
typename End_t,
typename... Its>
454 void ExecLoop(
unsigned int slot, End_t end, Its... its)
456 auto *thisSlotH = fObjects[slot];
459 auto nop = [](
auto &&...) {};
460 for (; GetNthElement<ColIdx>(its...) != end; nop(++its...)) {
461 thisSlotH->Fill(*its...);
466 FillHelper(FillHelper &&) =
default;
467 FillHelper(
const FillHelper &) =
delete;
469 FillHelper(
const std::shared_ptr<HIST> &
h,
const unsigned int nSlots) : fObjects(nSlots, nullptr)
471 fObjects[0] =
h.get();
473 for (
unsigned int i = 1; i < nSlots; ++i) {
474 fObjects[i] =
new HIST(*fObjects[0]);
475 UnsetDirectoryIfPossible(fObjects[i]);
482 template <
typename... ValTypes, std::enable_if_t<!Disjunction<IsDataContainer<ValTypes>...>
::value,
int> = 0>
483 auto Exec(
unsigned int slot,
const ValTypes &...
x) ->
decltype(fObjects[slot]->Fill(
x...),
void())
485 fObjects[slot]->Fill(
x...);
489 template <
typename... Xs, std::enable_if_t<Disjunction<IsDataContainer<Xs>...>
::value,
int> = 0>
490 auto Exec(
unsigned int slot,
const Xs &...xs) ->
decltype(fObjects[slot]->Fill(*MakeBegin(xs)...),
void())
496 constexpr std::size_t colidx =
FindIdxTrue(isContainer);
498 static_assert(colidx <
sizeof...(Xs),
"Error: index of collection-type argument not found.");
501 auto const xrefend = std::end(GetNthElement<colidx>(xs...));
504 std::array<std::size_t,
sizeof...(xs)> sizes = {{GetSize(xs)...}};
506 for (std::size_t i = 0; i <
sizeof...(xs); ++i) {
507 if (isContainer[i] && sizes[i] != sizes[colidx]) {
508 throw std::runtime_error(
"Cannot fill histogram with values in containers of different sizes.");
512 ExecLoop<colidx>(slot, xrefend, MakeBegin(xs)...);
515 template <
typename T = HIST>
518 static_assert(
sizeof(
T) < 0,
519 "When filling an object with RDataFrame (e.g. via a Fill action) the number or types of the "
520 "columns passed did not match the signature of the object's `Fill` method.");
527 if (fObjects.size() == 1)
533 for (
auto it = ++fObjects.begin(); it != fObjects.end(); ++it)
537 HIST &PartialUpdate(
unsigned int slot) {
return *fObjects[slot]; }
542 return std::make_unique<RMergeableFill<HIST>>(*fObjects[0]);
547 std::string GetActionName()
549 return std::string(fObjects[0]->
IsA()->GetName()) +
"\\n" + std::string(fObjects[0]->GetName());
554 std::string GetActionName()
556 return "Fill custom object";
559 template <
typename H = HIST>
560 FillHelper MakeNew(
void *newResult)
562 auto &
result = *
static_cast<std::shared_ptr<H> *
>(newResult);
563 ResetIfPossible(
result.get());
564 UnsetDirectoryIfPossible(
result.get());
565 return FillHelper(
result, fObjects.size());
574 std::vector<::TGraph *> fGraphs;
577 FillTGraphHelper(FillTGraphHelper &&) =
default;
578 FillTGraphHelper(
const FillTGraphHelper &) =
delete;
580 FillTGraphHelper(
const std::shared_ptr<::TGraph> &
g,
const unsigned int nSlots) : fGraphs(nSlots, nullptr)
582 fGraphs[0] =
g.get();
584 for (
unsigned int i = 1; i < nSlots; ++i) {
585 fGraphs[i] =
new TGraph(*fGraphs[0]);
593 template <
typename X0,
typename X1,
595 void Exec(
unsigned int slot,
const X0 &x0s,
const X1 &x1s)
597 if (x0s.size() != x1s.size()) {
598 throw std::runtime_error(
"Cannot fill Graph with values in containers of different sizes.");
600 auto *thisSlotG = fGraphs[slot];
601 auto x0sIt = std::begin(x0s);
602 const auto x0sEnd = std::end(x0s);
603 auto x1sIt = std::begin(x1s);
604 for (; x0sIt != x0sEnd; x0sIt++, x1sIt++) {
605 thisSlotG->SetPoint(thisSlotG->GetN(), *x0sIt, *x1sIt);
610 template <
typename X0,
typename X1,
612 void Exec(
unsigned int slot, X0 x0, X1
x1)
614 auto thisSlotG = fGraphs[slot];
615 thisSlotG->SetPoint(thisSlotG->GetN(), x0,
x1);
620 template <
typename X0,
typename X1,
typename... ExtraArgsToLowerPriority>
621 void Exec(
unsigned int, X0, X1, ExtraArgsToLowerPriority...)
623 throw std::runtime_error(
"Graph was applied to a mix of scalar values and collections. This is not supported.");
628 const auto nSlots = fGraphs.size();
629 auto resGraph = fGraphs[0];
632 for (
unsigned int slot = 1; slot < nSlots; ++slot) {
633 l.Add(fGraphs[slot]);
641 return std::make_unique<RMergeableFill<Result_t>>(*fGraphs[0]);
644 std::string GetActionName() {
return "Graph"; }
646 Result_t &PartialUpdate(
unsigned int slot) {
return *fGraphs[slot]; }
648 FillTGraphHelper MakeNew(
void *newResult)
650 auto &
result = *
static_cast<std::shared_ptr<TGraph> *
>(newResult);
652 return FillTGraphHelper(
result, fGraphs.size());
656class R__CLING_PTRCHECK(off) FillTGraphAsymmErrorsHelper
662 std::vector<::TGraphAsymmErrors *> fGraphAsymmErrors;
665 FillTGraphAsymmErrorsHelper(FillTGraphAsymmErrorsHelper &&) =
default;
666 FillTGraphAsymmErrorsHelper(
const FillTGraphAsymmErrorsHelper &) =
delete;
668 FillTGraphAsymmErrorsHelper(
const std::shared_ptr<::TGraphAsymmErrors> &
g,
const unsigned int nSlots)
669 : fGraphAsymmErrors(nSlots, nullptr)
671 fGraphAsymmErrors[0] =
g.get();
673 for (
unsigned int i = 1; i < nSlots; ++i) {
683 typename X,
typename Y,
typename EXL,
typename EXH,
typename EYL,
typename EYH,
688 Exec(
unsigned int slot,
const X &xs,
const Y &ys,
const EXL &exls,
const EXH &exhs,
const EYL &eyls,
const EYH &eyhs)
690 if ((xs.size() != ys.size()) || (xs.size() != exls.size()) || (xs.size() != exhs.size()) ||
691 (xs.size() != eyls.size()) || (xs.size() != eyhs.size())) {
692 throw std::runtime_error(
"Cannot fill GraphAsymmErrors with values in containers of different sizes.");
694 auto *thisSlotG = fGraphAsymmErrors[slot];
695 auto xsIt = std::begin(xs);
696 auto ysIt = std::begin(ys);
697 auto exlsIt = std::begin(exls);
698 auto exhsIt = std::begin(exhs);
699 auto eylsIt = std::begin(eyls);
700 auto eyhsIt = std::begin(eyhs);
701 while (xsIt != std::end(xs)) {
702 const auto n = thisSlotG->GetN();
703 thisSlotG->SetPoint(
n, *xsIt++, *ysIt++);
704 thisSlotG->SetPointError(
n, *exlsIt++, *exhsIt++, *eylsIt++, *eyhsIt++);
710 typename X,
typename Y,
typename EXL,
typename EXH,
typename EYL,
typename EYH,
714 void Exec(
unsigned int slot, X
x, Y
y, EXL exl, EXH exh, EYL eyl, EYH eyh)
716 auto thisSlotG = fGraphAsymmErrors[slot];
717 const auto n = thisSlotG->GetN();
718 thisSlotG->SetPoint(
n,
x,
y);
719 thisSlotG->SetPointError(
n, exl, exh, eyl, eyh);
724 template <
typename X,
typename Y,
typename EXL,
typename EXH,
typename EYL,
typename EYH,
725 typename... ExtraArgsToLowerPriority>
726 void Exec(
unsigned int, X, Y, EXL, EXH, EYL, EYH, ExtraArgsToLowerPriority...)
728 throw std::runtime_error(
729 "GraphAsymmErrors was applied to a mix of scalar values and collections. This is not supported.");
734 const auto nSlots = fGraphAsymmErrors.size();
735 auto resGraphAsymmErrors = fGraphAsymmErrors[0];
738 for (
unsigned int slot = 1; slot < nSlots; ++slot) {
739 l.Add(fGraphAsymmErrors[slot]);
741 resGraphAsymmErrors->Merge(&
l);
747 return std::make_unique<RMergeableFill<Result_t>>(*fGraphAsymmErrors[0]);
750 std::string GetActionName() {
return "GraphAsymmErrors"; }
752 Result_t &PartialUpdate(
unsigned int slot) {
return *fGraphAsymmErrors[slot]; }
754 FillTGraphAsymmErrorsHelper MakeNew(
void *newResult)
756 auto &
result = *
static_cast<std::shared_ptr<TGraphAsymmErrors> *
>(newResult);
758 return FillTGraphAsymmErrorsHelper(
result, fGraphAsymmErrors.size());
768template <
typename V,
typename COLL>
769void FillColl(V&&
v, COLL&
c) {
774template <
typename COLL>
775void FillColl(
bool v, COLL&
c) {
781template <
typename RealT_t,
typename T,
typename COLL>
782class R__CLING_PTRCHECK(off) TakeHelper :
public RActionImpl<TakeHelper<RealT_t, T, COLL>> {
783 Results<std::shared_ptr<COLL>> fColls;
787 TakeHelper(
const std::shared_ptr<COLL> &resultColl,
const unsigned int nSlots)
789 fColls.emplace_back(resultColl);
790 for (
unsigned int i = 1; i < nSlots; ++i)
791 fColls.emplace_back(std::make_shared<COLL>());
793 TakeHelper(TakeHelper &&);
794 TakeHelper(
const TakeHelper &) =
delete;
798 void Exec(
unsigned int slot,
T &
v) { FillColl(
v, *fColls[slot]); }
804 auto rColl = fColls[0];
805 for (
unsigned int i = 1; i < fColls.size(); ++i) {
806 const auto &coll = fColls[i];
807 const auto end = coll->end();
810 for (
auto j = coll->begin(); j != end; j++) {
811 FillColl(*j, *rColl);
816 COLL &PartialUpdate(
unsigned int slot) {
return *fColls[slot].get(); }
818 std::string GetActionName() {
return "Take"; }
820 TakeHelper MakeNew(
void *newResult)
822 auto &
result = *
static_cast<std::shared_ptr<COLL> *
>(newResult);
824 return TakeHelper(
result, fColls.size());
830template <
typename RealT_t,
typename T>
831class R__CLING_PTRCHECK(off) TakeHelper<RealT_t,
T, std::vector<T>>
832 :
public RActionImpl<TakeHelper<RealT_t, T, std::vector<T>>> {
833 Results<std::shared_ptr<std::vector<T>>> fColls;
837 TakeHelper(
const std::shared_ptr<std::vector<T>> &resultColl,
const unsigned int nSlots)
839 fColls.emplace_back(resultColl);
840 for (
unsigned int i = 1; i < nSlots; ++i) {
841 auto v = std::make_shared<std::vector<T>>();
843 fColls.emplace_back(
v);
846 TakeHelper(TakeHelper &&);
847 TakeHelper(
const TakeHelper &) =
delete;
851 void Exec(
unsigned int slot,
T &
v) { FillColl(
v, *fColls[slot]); }
859 for (
auto &coll : fColls)
860 totSize += coll->size();
861 auto rColl = fColls[0];
862 rColl->reserve(totSize);
863 for (
unsigned int i = 1; i < fColls.size(); ++i) {
864 auto &coll = fColls[i];
865 rColl->insert(rColl->end(), coll->begin(), coll->end());
869 std::vector<T> &PartialUpdate(
unsigned int slot) {
return *fColls[slot]; }
871 std::string GetActionName() {
return "Take"; }
873 TakeHelper MakeNew(
void *newResult)
875 auto &
result = *
static_cast<std::shared_ptr<std::vector<T>
> *>(newResult);
877 return TakeHelper(
result, fColls.size());
883template <
typename RealT_t,
typename COLL>
884class R__CLING_PTRCHECK(off) TakeHelper<RealT_t,
RVec<RealT_t>, COLL>
885 :
public RActionImpl<TakeHelper<RealT_t, RVec<RealT_t>, COLL>> {
886 Results<std::shared_ptr<COLL>> fColls;
890 TakeHelper(
const std::shared_ptr<COLL> &resultColl,
const unsigned int nSlots)
892 fColls.emplace_back(resultColl);
893 for (
unsigned int i = 1; i < nSlots; ++i)
894 fColls.emplace_back(std::make_shared<COLL>());
896 TakeHelper(TakeHelper &&);
897 TakeHelper(
const TakeHelper &) =
delete;
907 auto rColl = fColls[0];
908 for (
unsigned int i = 1; i < fColls.size(); ++i) {
909 auto &coll = fColls[i];
910 for (
auto &
v : *coll) {
911 rColl->emplace_back(
v);
916 std::string GetActionName() {
return "Take"; }
918 TakeHelper MakeNew(
void *newResult)
920 auto &
result = *
static_cast<std::shared_ptr<COLL> *
>(newResult);
922 return TakeHelper(
result, fColls.size());
928template <
typename RealT_t>
929class R__CLING_PTRCHECK(off) TakeHelper<RealT_t,
RVec<RealT_t>, std::vector<RealT_t>>
930 :
public RActionImpl<TakeHelper<RealT_t, RVec<RealT_t>, std::vector<RealT_t>>> {
932 Results<std::shared_ptr<std::vector<std::vector<RealT_t>>>> fColls;
936 TakeHelper(
const std::shared_ptr<std::vector<std::vector<RealT_t>>> &resultColl,
const unsigned int nSlots)
938 fColls.emplace_back(resultColl);
939 for (
unsigned int i = 1; i < nSlots; ++i) {
940 auto v = std::make_shared<std::vector<RealT_t>>();
942 fColls.emplace_back(
v);
945 TakeHelper(TakeHelper &&);
946 TakeHelper(
const TakeHelper &) =
delete;
958 for (
auto &coll : fColls)
959 totSize += coll->size();
960 auto rColl = fColls[0];
961 rColl->reserve(totSize);
962 for (
unsigned int i = 1; i < fColls.size(); ++i) {
963 auto &coll = fColls[i];
964 rColl->insert(rColl->end(), coll->begin(), coll->end());
968 std::string GetActionName() {
return "Take"; }
970 TakeHelper MakeNew(
void *newResult)
972 auto &
result = *
static_cast<typename decltype(fColls)::value_type *
>(newResult);
974 return TakeHelper(
result, fColls.size());
981template <
typename RealT_t,
typename T,
typename COLL>
982TakeHelper<RealT_t, T, COLL>::TakeHelper(TakeHelper<RealT_t, T, COLL> &&) =
default;
983template <
typename RealT_t,
typename T>
984TakeHelper<RealT_t, T, std::vector<T>>::TakeHelper(TakeHelper<RealT_t,
T, std::vector<T>> &&) =
default;
985template <
typename RealT_t,
typename COLL>
986TakeHelper<RealT_t, RVec<RealT_t>, COLL>::TakeHelper(TakeHelper<RealT_t,
RVec<RealT_t>, COLL> &&) =
default;
987template <
typename RealT_t>
988TakeHelper<RealT_t, RVec<RealT_t>, std::vector<RealT_t>>::TakeHelper(TakeHelper<RealT_t,
RVec<RealT_t>, std::vector<RealT_t>> &&) =
default;
992extern template class TakeHelper<bool, bool, std::vector<bool>>;
993extern template class TakeHelper<unsigned int, unsigned int, std::vector<unsigned int>>;
994extern template class TakeHelper<unsigned long, unsigned long, std::vector<unsigned long>>;
995extern template class TakeHelper<unsigned long long, unsigned long long, std::vector<unsigned long long>>;
996extern template class TakeHelper<int, int, std::vector<int>>;
997extern template class TakeHelper<long, long, std::vector<long>>;
998extern template class TakeHelper<long long, long long, std::vector<long long>>;
999extern template class TakeHelper<float, float, std::vector<float>>;
1000extern template class TakeHelper<double, double, std::vector<double>>;
1003template <
typename ResultType>
1004class R__CLING_PTRCHECK(off) MinHelper :
public RActionImpl<MinHelper<ResultType>> {
1005 std::shared_ptr<ResultType> fResultMin;
1006 Results<ResultType> fMins;
1009 MinHelper(MinHelper &&) =
default;
1010 MinHelper(
const std::shared_ptr<ResultType> &minVPtr,
const unsigned int nSlots)
1011 : fResultMin(minVPtr), fMins(nSlots, std::numeric_limits<ResultType>::max())
1015 void Exec(
unsigned int slot, ResultType
v) { fMins[slot] = std::min(
v, fMins[slot]); }
1020 void Exec(
unsigned int slot,
const T &vs)
1023 fMins[slot] = std::min(
static_cast<ResultType
>(
v), fMins[slot]);
1030 *fResultMin = std::numeric_limits<ResultType>::max();
1031 for (
auto &
m : fMins)
1032 *fResultMin = std::min(
m, *fResultMin);
1038 return std::make_unique<RMergeableMin<ResultType>>(*fResultMin);
1041 ResultType &PartialUpdate(
unsigned int slot) {
return fMins[slot]; }
1043 std::string GetActionName() {
return "Min"; }
1045 MinHelper MakeNew(
void *newResult)
1047 auto &
result = *
static_cast<std::shared_ptr<ResultType> *
>(newResult);
1048 return MinHelper(
result, fMins.size());
1059template <
typename ResultType>
1060class R__CLING_PTRCHECK(off) MaxHelper :
public RActionImpl<MaxHelper<ResultType>> {
1061 std::shared_ptr<ResultType> fResultMax;
1062 Results<ResultType> fMaxs;
1065 MaxHelper(MaxHelper &&) =
default;
1066 MaxHelper(
const MaxHelper &) =
delete;
1067 MaxHelper(
const std::shared_ptr<ResultType> &maxVPtr,
const unsigned int nSlots)
1068 : fResultMax(maxVPtr), fMaxs(nSlots, std::numeric_limits<ResultType>::lowest())
1073 void Exec(
unsigned int slot, ResultType
v) { fMaxs[slot] = std::max(
v, fMaxs[slot]); }
1076 void Exec(
unsigned int slot,
const T &vs)
1079 fMaxs[slot] = std::max(
static_cast<ResultType
>(
v), fMaxs[slot]);
1086 *fResultMax = std::numeric_limits<ResultType>::lowest();
1087 for (
auto &
m : fMaxs) {
1088 *fResultMax = std::max(
m, *fResultMax);
1095 return std::make_unique<RMergeableMax<ResultType>>(*fResultMax);
1098 ResultType &PartialUpdate(
unsigned int slot) {
return fMaxs[slot]; }
1100 std::string GetActionName() {
return "Max"; }
1102 MaxHelper MakeNew(
void *newResult)
1104 auto &
result = *
static_cast<std::shared_ptr<ResultType> *
>(newResult);
1105 return MaxHelper(
result, fMaxs.size());
1116template <
typename ResultType>
1117class R__CLING_PTRCHECK(off) SumHelper :
public RActionImpl<SumHelper<ResultType>> {
1118 std::shared_ptr<ResultType> fResultSum;
1119 Results<ResultType> fSums;
1120 Results<ResultType> fCompensations;
1125 template <
typename T = ResultType>
1126 auto NeutralElement(
const T &
v,
int ) ->
decltype(
v -
v)
1131 template <
typename T = ResultType,
typename Dummy =
int>
1132 ResultType NeutralElement(
const T &, Dummy)
1134 return ResultType{};
1138 SumHelper(SumHelper &&) =
default;
1139 SumHelper(
const SumHelper &) =
delete;
1140 SumHelper(
const std::shared_ptr<ResultType> &sumVPtr,
const unsigned int nSlots)
1141 : fResultSum(sumVPtr), fSums(nSlots, NeutralElement(*sumVPtr, -1)),
1142 fCompensations(nSlots, NeutralElement(*sumVPtr, -1))
1147 void Exec(
unsigned int slot, ResultType
x)
1150 ResultType
y =
x - fCompensations[slot];
1151 ResultType t = fSums[slot] +
y;
1152 fCompensations[slot] = (t - fSums[slot]) -
y;
1157 void Exec(
unsigned int slot,
const T &vs)
1159 for (
auto &&
v : vs) {
1168 ResultType
sum(NeutralElement(ResultType{}, -1));
1169 ResultType compensation(NeutralElement(ResultType{}, -1));
1170 ResultType
y(NeutralElement(ResultType{}, -1));
1171 ResultType t(NeutralElement(ResultType{}, -1));
1172 for (
auto &
m : fSums) {
1174 y =
m - compensation;
1176 compensation = (t -
sum) -
y;
1185 return std::make_unique<RMergeableSum<ResultType>>(*fResultSum);
1188 ResultType &PartialUpdate(
unsigned int slot) {
return fSums[slot]; }
1190 std::string GetActionName() {
return "Sum"; }
1192 SumHelper MakeNew(
void *newResult)
1194 auto &
result = *
static_cast<std::shared_ptr<ResultType> *
>(newResult);
1196 return SumHelper(
result, fSums.size());
1200class R__CLING_PTRCHECK(off) MeanHelper :
public RActionImpl<MeanHelper> {
1201 std::shared_ptr<double> fResultMean;
1202 std::vector<ULong64_t> fCounts;
1203 std::vector<double> fSums;
1204 std::vector<double> fPartialMeans;
1205 std::vector<double> fCompensations;
1208 MeanHelper(
const std::shared_ptr<double> &meanVPtr,
const unsigned int nSlots);
1209 MeanHelper(MeanHelper &&) =
default;
1210 MeanHelper(
const MeanHelper &) =
delete;
1212 void Exec(
unsigned int slot,
double v);
1215 void Exec(
unsigned int slot,
const T &vs)
1217 for (
auto &&
v : vs) {
1221 double y =
v - fCompensations[slot];
1222 double t = fSums[slot] +
y;
1223 fCompensations[slot] = (t - fSums[slot]) -
y;
1235 const ULong64_t counts = std::accumulate(fCounts.begin(), fCounts.end(), 0ull);
1236 return std::make_unique<RMergeableMean>(*fResultMean, counts);
1239 double &PartialUpdate(
unsigned int slot);
1241 std::string GetActionName() {
return "Mean"; }
1243 MeanHelper MakeNew(
void *newResult)
1245 auto &
result = *
static_cast<std::shared_ptr<double> *
>(newResult);
1246 return MeanHelper(
result, fSums.size());
1250extern template void MeanHelper::Exec(
unsigned int,
const std::vector<float> &);
1251extern template void MeanHelper::Exec(
unsigned int,
const std::vector<double> &);
1252extern template void MeanHelper::Exec(
unsigned int,
const std::vector<char> &);
1253extern template void MeanHelper::Exec(
unsigned int,
const std::vector<int> &);
1254extern template void MeanHelper::Exec(
unsigned int,
const std::vector<unsigned int> &);
1258 unsigned int fNSlots;
1259 std::shared_ptr<double> fResultStdDev;
1261 std::vector<ULong64_t> fCounts;
1263 std::vector<double> fMeans;
1265 std::vector<double> fDistancesfromMean;
1268 StdDevHelper(
const std::shared_ptr<double> &meanVPtr,
const unsigned int nSlots);
1269 StdDevHelper(StdDevHelper &&) =
default;
1270 StdDevHelper(
const StdDevHelper &) =
delete;
1272 void Exec(
unsigned int slot,
double v);
1275 void Exec(
unsigned int slot,
const T &vs)
1277 for (
auto &&
v : vs) {
1289 const ULong64_t counts = std::accumulate(fCounts.begin(), fCounts.end(), 0ull);
1292 return std::make_unique<RMergeableStdDev>(*fResultStdDev, counts, mean);
1295 std::string GetActionName() {
return "StdDev"; }
1297 StdDevHelper MakeNew(
void *newResult)
1299 auto &
result = *
static_cast<std::shared_ptr<double> *
>(newResult);
1300 return StdDevHelper(
result, fCounts.size());
1308extern template void StdDevHelper::Exec(
unsigned int,
const std::vector<unsigned int> &);
1310template <
typename PrevNodeType>
1314 std::shared_ptr<Display_t> fDisplayerHelper;
1315 std::shared_ptr<PrevNodeType> fPrevNode;
1316 size_t fEntriesToProcess;
1319 DisplayHelper(
size_t nRows,
const std::shared_ptr<Display_t> &
d,
const std::shared_ptr<PrevNodeType> &prevNode)
1320 : fDisplayerHelper(
d), fPrevNode(prevNode), fEntriesToProcess(nRows)
1323 DisplayHelper(DisplayHelper &&) =
default;
1324 DisplayHelper(
const DisplayHelper &) =
delete;
1327 template <
typename...
Columns>
1330 if (fEntriesToProcess == 0)
1333 fDisplayerHelper->AddRow(columns...);
1334 --fEntriesToProcess;
1336 if (fEntriesToProcess == 0) {
1341 fPrevNode->StopProcessing();
1349 std::string GetActionName() {
return "Display"; }
1352template <
typename T>
1358template <
typename T>
1364template <
typename T>
1365void SetBranchesHelper(
TTree *inputTree,
TTree &outputTree,
const std::string &inName,
const std::string &
name,
1366 TBranch *&branch,
void *&branchAddress,
T *address, RBranchSet &outputBranches,
1369 static TClassRef TBOClRef(
"TBranchObject");
1371 TBranch *inputBranch =
nullptr;
1373 inputBranch = inputTree->
GetBranch(inName.c_str());
1375 inputBranch = inputTree->
FindBranch(inName.c_str());
1378 auto *outputBranch = outputBranches.Get(
name);
1381 if (inputBranch && inputBranch->
IsA() == TBOClRef) {
1382 outputBranch->SetAddress(
reinterpret_cast<T **
>(inputBranch->
GetAddress()));
1384 branchAddress = address;
1385 outputBranch->SetAddress(&branchAddress);
1387 outputBranch->SetAddress(address);
1388 branchAddress = address;
1401 if (inputBranch->
IsA() == TBOClRef) {
1404 outputTree.
Branch(
name.c_str(),
reinterpret_cast<T **
>(inputBranch->
GetAddress()), bufSize, splitLevel);
1406 outputBranch = outputTree.
Branch(
name.c_str(), address, bufSize, splitLevel);
1409 outputBranch = outputTree.
Branch(
name.c_str(), address);
1411 outputBranches.Insert(
name, outputBranch);
1414 branchAddress =
nullptr;
1427template <
typename T>
1428void SetBranchesHelper(
TTree *inputTree,
TTree &outputTree,
const std::string &inName,
const std::string &outName,
1429 TBranch *&branch,
void *&branchAddress,
RVec<T> *ab, RBranchSet &outputBranches,
bool isDefine)
1431 TBranch *inputBranch =
nullptr;
1433 inputBranch = inputTree->
GetBranch(inName.c_str());
1435 inputBranch = inputTree->
FindBranch(inName.c_str());
1437 auto *outputBranch = outputBranches.Get(outName);
1440 bool mustWriteRVec = (inputBranch ==
nullptr || isDefine);
1443 mustWriteRVec =
true;
1445 "Branch \"%s\" contains TClonesArrays but the type specified to Snapshot was RVec<T>. The branch will "
1446 "be written out as a RVec instead of a TClonesArray. Specify that the type of the branch is "
1447 "TClonesArray as a Snapshot template parameter to write out a TClonesArray instead.",
1451 if (!mustWriteRVec) {
1454 mustWriteRVec =
true;
1457 if (mustWriteRVec) {
1464 outputBranch->SetObject(ab);
1466 auto *
b = outputTree.
Branch(outName.c_str(), ab);
1467 outputBranches.Insert(outName,
b);
1473 auto dataPtr = ab->
data();
1477 branchAddress = dataPtr;
1478 outputBranch->SetAddress(&branchAddress);
1480 outputBranch->SetAddress(dataPtr);
1485 const auto bname = leaf->
GetName();
1486 auto *sizeLeaf = leaf->GetLeafCount();
1487 const auto sizeLeafName = sizeLeaf ? std::string(sizeLeaf->GetName()) : std::to_string(leaf->GetLenStatic());
1489 if (sizeLeaf && !outputBranches.Get(sizeLeafName)) {
1494 const auto sizeBufSize = sizeLeaf->GetBranch()->GetBasketSize();
1496 auto *sizeBranch = outputTree.
Branch(sizeLeafName.c_str(), (
void *)
nullptr,
1497 (sizeLeafName +
'/' + sizeTypeStr).c_str(), sizeBufSize);
1498 outputBranches.Insert(sizeLeafName, sizeBranch);
1501 const auto btype = leaf->GetTypeName();
1503 if (rootbtype ==
' ') {
1505 "RDataFrame::Snapshot: could not correctly construct a leaflist for C-style array in column %s. This "
1506 "column will not be written out.",
1509 const auto leaflist = std::string(bname) +
"[" + sizeLeafName +
"]/" + rootbtype;
1510 outputBranch = outputTree.
Branch(outName.c_str(), dataPtr, leaflist.c_str());
1512 outputBranches.Insert(outName, outputBranch);
1513 branch = outputBranch;
1514 branchAddress = ab->
data();
1522template <
typename... ColTypes>
1523class R__CLING_PTRCHECK(off) SnapshotHelper :
public RActionImpl<SnapshotHelper<ColTypes...>> {
1524 std::string fFileName;
1525 std::string fDirName;
1526 std::string fTreeName;
1528 std::unique_ptr<TFile> fOutputFile;
1529 std::unique_ptr<TTree> fOutputTree;
1530 bool fBranchAddressesNeedReset{
true};
1533 TTree *fInputTree =
nullptr;
1535 std::vector<TBranch *> fBranches;
1536 std::vector<void *> fBranchAddresses;
1537 RBranchSet fOutputBranches;
1538 std::vector<bool> fIsDefine;
1541 using ColumnTypes_t =
TypeList<ColTypes...>;
1544 std::vector<bool> &&isDefine)
1545 : fFileName(
filename), fDirName(dirname), fTreeName(treename), fOptions(options), fInputBranchNames(vbnames),
1547 fBranchAddresses(vbnames.
size(), nullptr), fIsDefine(std::move(isDefine))
1552 SnapshotHelper(
const SnapshotHelper &) =
delete;
1553 SnapshotHelper(SnapshotHelper &&) =
default;
1556 if (!fTreeName.empty() && !fOutputFile && fOptions.
fLazy)
1557 Warning(
"Snapshot",
"A lazy Snapshot action was booked but never triggered.");
1563 fInputTree =
r->GetTree();
1564 fBranchAddressesNeedReset =
true;
1567 void Exec(
unsigned int , ColTypes &... values)
1569 using ind_t = std::index_sequence_for<ColTypes...>;
1570 if (!fBranchAddressesNeedReset) {
1571 UpdateCArraysPtrs(values..., ind_t{});
1573 SetBranches(values..., ind_t{});
1574 fBranchAddressesNeedReset =
false;
1576 fOutputTree->Fill();
1579 template <std::size_t...
S>
1580 void UpdateCArraysPtrs(ColTypes &... values, std::index_sequence<S...> )
1588 int expander[] = {(fBranches[
S] && fBranchAddresses[
S] != GetData(values)
1589 ? fBranches[
S]->SetAddress(GetData(values)),
1590 fBranchAddresses[
S] = GetData(values), 0 : 0, 0)...,
1595 template <std::size_t...
S>
1596 void SetBranches(ColTypes &... values, std::index_sequence<S...> )
1599 int expander[] = {(SetBranchesHelper(fInputTree, *fOutputTree, fInputBranchNames[
S], fOutputBranchNames[
S],
1600 fBranches[
S], fBranchAddresses[
S], &values, fOutputBranches, fIsDefine[
S]),
1603 fOutputBranches.AssertNoNullBranchAddresses();
1613 throw std::runtime_error(
"Snapshot: could not create output file " + fFileName);
1616 if (!fDirName.empty()) {
1619 if (checkupdate ==
"update")
1620 outputDir = fOutputFile->
mkdir(fDirName.c_str(),
"",
true);
1622 outputDir = fOutputFile->
mkdir(fDirName.c_str());
1626 std::make_unique<TTree>(fTreeName.c_str(), fTreeName.c_str(), fOptions.
fSplitLevel, outputDir);
1629 fOutputTree->SetAutoFlush(fOptions.
fAutoFlush);
1634 assert(fOutputTree !=
nullptr);
1635 assert(fOutputFile !=
nullptr);
1638 fOutputTree->AutoSave(
"flushbaskets");
1640 fOutputTree.reset();
1641 fOutputFile->Close();
1644 std::string GetActionName() {
return "Snapshot"; }
1648 return [
this](
unsigned int,
const RSampleInfo &)
mutable { fBranchAddressesNeedReset =
true; };
1653template <
typename... ColTypes>
1654class R__CLING_PTRCHECK(off) SnapshotHelperMT :
public RActionImpl<SnapshotHelperMT<ColTypes...>> {
1655 unsigned int fNSlots;
1656 std::unique_ptr<ROOT::TBufferMerger> fMerger;
1657 std::vector<std::shared_ptr<ROOT::TBufferMergerFile>> fOutputFiles;
1658 std::vector<std::unique_ptr<TTree>> fOutputTrees;
1659 std::vector<int> fBranchAddressesNeedReset;
1660 std::string fFileName;
1661 std::string fDirName;
1662 std::string fTreeName;
1666 std::vector<TTree *> fInputTrees;
1668 std::vector<std::vector<TBranch *>> fBranches;
1670 std::vector<std::vector<void *>> fBranchAddresses;
1671 std::vector<RBranchSet> fOutputBranches;
1672 std::vector<bool> fIsDefine;
1675 using ColumnTypes_t =
TypeList<ColTypes...>;
1679 : fNSlots(nSlots), fOutputFiles(fNSlots), fOutputTrees(fNSlots), fBranchAddressesNeedReset(fNSlots, 1),
1680 fFileName(
filename), fDirName(dirname), fTreeName(treename), fOptions(options), fInputBranchNames(vbnames),
1682 fBranches(fNSlots, std::vector<
TBranch *>(vbnames.
size(), nullptr)),
1683 fBranchAddresses(fNSlots, std::vector<
void *>(vbnames.
size(), nullptr)), fOutputBranches(fNSlots),
1684 fIsDefine(std::move(isDefine))
1688 SnapshotHelperMT(
const SnapshotHelperMT &) =
delete;
1689 SnapshotHelperMT(SnapshotHelperMT &&) =
default;
1692 if (!fTreeName.empty() && fOptions.
fLazy &&
1693 std::all_of(fOutputFiles.begin(), fOutputFiles.end(), [](
const auto &
f) { return !f; }) )
1694 Warning(
"Snapshot",
"A lazy Snapshot action was booked but never triggered.");
1700 if (!fOutputFiles[slot]) {
1702 fOutputFiles[slot] = fMerger->GetFile();
1704 TDirectory *treeDirectory = fOutputFiles[slot].get();
1705 if (!fDirName.empty()) {
1707 treeDirectory = fOutputFiles[slot]->
mkdir(fDirName.c_str(),
"",
true);
1711 fOutputTrees[slot] =
1712 std::make_unique<TTree>(fTreeName.c_str(), fTreeName.c_str(), fOptions.
fSplitLevel, treeDirectory);
1715 fOutputTrees[slot]->SetImplicitMT(
false);
1717 fOutputTrees[slot]->SetAutoFlush(fOptions.
fAutoFlush);
1720 fInputTrees[slot] =
r->GetTree();
1722 fBranchAddressesNeedReset[slot] = 1;
1725 void FinalizeTask(
unsigned int slot)
1727 if (fOutputTrees[slot]->GetEntries() > 0)
1728 fOutputFiles[slot]->Write();
1730 fOutputTrees[slot].reset(
nullptr);
1731 fOutputBranches[slot].Clear();
1734 void Exec(
unsigned int slot, ColTypes &... values)
1736 using ind_t = std::index_sequence_for<ColTypes...>;
1737 if (fBranchAddressesNeedReset[slot] == 0) {
1738 UpdateCArraysPtrs(slot, values..., ind_t{});
1740 SetBranches(slot, values..., ind_t{});
1741 fBranchAddressesNeedReset[slot] = 0;
1743 fOutputTrees[slot]->Fill();
1744 auto entries = fOutputTrees[slot]->GetEntries();
1745 auto autoFlush = fOutputTrees[slot]->GetAutoFlush();
1746 if ((autoFlush > 0) && (entries % autoFlush == 0))
1747 fOutputFiles[slot]->Write();
1750 template <std::size_t...
S>
1751 void UpdateCArraysPtrs(
unsigned int slot, ColTypes &... values, std::index_sequence<S...> )
1759 int expander[] = {(fBranches[slot][
S] && fBranchAddresses[slot][
S] != GetData(values)
1760 ? fBranches[slot][
S]->SetAddress(GetData(values)),
1761 fBranchAddresses[slot][
S] = GetData(values), 0 : 0, 0)...,
1766 template <std::size_t...
S>
1767 void SetBranches(
unsigned int slot, ColTypes &... values, std::index_sequence<S...> )
1770 int expander[] = {(SetBranchesHelper(fInputTrees[slot], *fOutputTrees[slot], fInputBranchNames[
S],
1771 fOutputBranchNames[
S], fBranches[slot][
S], fBranchAddresses[slot][
S],
1772 &values, fOutputBranches[slot], fIsDefine[
S]),
1775 fOutputBranches[slot].AssertNoNullBranchAddresses();
1782 auto out_file =
TFile::Open(fFileName.c_str(), fOptions.
fMode.c_str(), fFileName.c_str(), cs);
1784 throw std::runtime_error(
"Snapshot: could not create output file " + fFileName);
1785 fMerger = std::make_unique<ROOT::TBufferMerger>(std::unique_ptr<TFile>(out_file));
1790 assert(std::any_of(fOutputFiles.begin(), fOutputFiles.end(), [](
const auto &ptr) { return ptr != nullptr; }));
1792 auto fileWritten =
false;
1793 for (
auto &
file : fOutputFiles) {
1803 "No input entries (input TTree was empty or no entry passed the Filters). Output TTree is empty.");
1807 fOutputFiles.clear();
1811 std::string GetActionName() {
return "Snapshot"; }
1815 return [
this](
unsigned int slot,
const RSampleInfo &)
mutable { fBranchAddressesNeedReset[slot] = 1; };
1819template <
typename Acc,
typename Merge,
typename R,
typename T,
typename U,
1821class R__CLING_PTRCHECK(off) AggregateHelper
1822 :
public RActionImpl<AggregateHelper<Acc, Merge, R, T, U, MustCopyAssign>> {
1825 std::shared_ptr<U> fResult;
1826 Results<U> fAggregators;
1831 AggregateHelper(Acc &&
f, Merge &&
m,
const std::shared_ptr<U> &
result,
const unsigned int nSlots)
1832 : fAggregate(std::move(
f)), fMerge(std::move(
m)), fResult(
result), fAggregators(nSlots, *
result)
1836 AggregateHelper(Acc &
f, Merge &
m,
const std::shared_ptr<U> &
result,
const unsigned int nSlots)
1837 : fAggregate(
f), fMerge(
m), fResult(
result), fAggregators(nSlots, *
result)
1841 AggregateHelper(AggregateHelper &&) =
default;
1842 AggregateHelper(
const AggregateHelper &) =
delete;
1846 template <
bool MustCopyAssign_ = MustCopyAssign, std::enable_if_t<MustCopyAssign_,
int> = 0>
1849 fAggregators[slot] = fAggregate(fAggregators[slot],
value);
1852 template <
bool MustCopyAssign_ = MustCopyAssign, std::enable_if_t<!MustCopyAssign_,
int> = 0>
1855 fAggregate(fAggregators[slot],
value);
1860 template <typename MergeRet = typename CallableTraits<Merge>::ret_type,
1862 std::enable_if_t<MergeAll, void> Finalize()
1864 fMerge(fAggregators);
1865 *fResult = fAggregators[0];
1868 template <typename MergeRet = typename CallableTraits<Merge>::ret_type,
1870 std::enable_if_t<MergeTwoByTwo, void> Finalize(...)
1872 for (
const auto &acc : fAggregators)
1873 *fResult = fMerge(*fResult, acc);
1876 U &PartialUpdate(
unsigned int slot) {
return fAggregators[slot]; }
1878 std::string GetActionName() {
return "Aggregate"; }
1880 AggregateHelper MakeNew(
void *newResult)
1882 auto &
result = *
static_cast<std::shared_ptr<U> *
>(newResult);
1883 return AggregateHelper(fAggregate, fMerge,
result, fAggregators.size());
Handle_t Display_t
Display handle.
#define R(a, b, c, d, e, f, g, h, i)
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
unsigned long long ULong64_t
#define R__CLING_PTRCHECK(ONOFF)
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t b
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t g
TClass * IsA() const override
TTime operator*(const TTime &t1, const TTime &t2)
Base class for action helpers, see RInterface::Book() for more information.
iterator begin() noexcept
pointer data() noexcept
Return a pointer to the vector's buffer, even if empty().
This class is the textual representation of the content of a columnar dataset.
This type represents a sample identifier, to be used in conjunction with RDataFrame features such as ...
typename RemoveFirstParameter< T >::type RemoveFirstParameter_t
A "std::vector"-like collection of values implementing handy operation to analyse them.
A TTree is a list of TBranches.
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any.
virtual char * GetAddress() const
Int_t GetSplitLevel() const
TClass * IsA() const override
virtual Int_t GetBasketSize() const
TObjArray * GetListOfLeaves()
TClassRef is used to implement a permanent reference to a TClass object.
Collection abstract base class.
TDirectory::TContext keeps track and restore the current directory.
Describe directory structure in memory.
virtual TDirectory * mkdir(const char *name, const char *title="", Bool_t returnExistingDirectory=kFALSE)
Create a sub-directory "a" or a hierarchy of sub-directories "a/b/c/...".
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
TGraph with asymmetric error bars.
A TGraph is an object made of two arrays X and Y with npoints each.
1-D histogram with a double per channel (see TH1 documentation)}
TH1 is the base class of all histogram classes in ROOT.
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
const char * GetName() const override
Returns name of object.
const char * GetTitle() const override
Returns title of object.
TObject * UncheckedAt(Int_t i) const
Statistical variable, defined by its mean and variance (RMS).
void ToLower()
Change string to lower-case.
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
A TTree represents a columnar dataset.
virtual TBranch * FindBranch(const char *name)
Return the branch that correspond to the path 'branchname', which can include the name of the tree or...
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
TBranch * Branch(const char *name, T *obj, Int_t bufsize=32000, Int_t splitlevel=99)
Add a new branch, and infer the data type from the type of obj being passed.
@ kEntriesReshuffled
If set, signals that this TTree is the output of the processing of another TTree, and the entries are...
RooCmdArg Columns(Int_t ncol)
basic_string_view< char > string_view
CPYCPPYY_EXTERN bool Exec(const std::string &cmd)
std::unique_ptr< RMergeableVariations< T > > GetMergeableValue(ROOT::RDF::Experimental::RResultMap< T > &rmap)
Retrieve mergeable values after calling ROOT::RDF::VariationsFor .
std::vector< std::string > ReplaceDotWithUnderscore(const std::vector< std::string > &columnNames)
Replace occurrences of '.
void ValidateSnapshotOutput(const RSnapshotOptions &opts, const std::string &treeName, const std::string &fileName)
char TypeName2ROOTTypeName(const std::string &b)
Convert type name (e.g.
constexpr std::size_t FindIdxTrue(const T &arr)
void(off) SmallVectorTemplateBase< T
double inner_product(const LAVector &, const LAVector &)
std::vector< std::string > ColumnNames_t
std::function< void(unsigned int, const ROOT::RDF::RSampleInfo &)> SampleCallback_t
The type of a data-block callback, registered with a RDataFrame computation graph via e....
ROOT type_traits extensions.
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
int CompressionSettings(RCompressionSetting::EAlgorithm::EValues algorithm, int compressionLevel)
RooArgSet S(Args_t &&... args)
ROOT::ESTLType STLKind(std::string_view type)
Converts STL container name to number.
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container code of cont...
void Initialize(Bool_t useTMVAStyle=kTRUE)
static constexpr bool value
A collection of options to steer the creation of the dataset on file.
int fAutoFlush
AutoFlush value for output tree.
std::string fMode
Mode of creation of output file.
ECAlgo fCompressionAlgorithm
Compression algorithm of output file.
int fSplitLevel
Split level of output tree.
bool fLazy
Do not start the event loop when Snapshot is called.
int fCompressionLevel
Compression level of output file.
Lightweight storage for a collection of types.