19#ifndef ROOT_RDFOPERATIONS
20#define ROOT_RDFOPERATIONS
35#include "RConfigure.h"
69using namespace ROOT::TypeTraits;
70using namespace ROOT::VecOps;
71using namespace ROOT::RDF;
72using namespace ROOT::Detail::RDF;
81using Results = std::conditional_t<std::is_same<T, bool>::value, std::deque<T>, std::vector<T>>;
84class R__CLING_PTRCHECK(off) ForeachSlotHelper :
public RActionImpl<ForeachSlotHelper<F>> {
88 using ColumnTypes_t = RemoveFirstParameter_t<typename CallableTraits<F>::arg_types>;
89 ForeachSlotHelper(
F &&
f) : fCallable(
f) {}
90 ForeachSlotHelper(ForeachSlotHelper &&) =
default;
91 ForeachSlotHelper(
const ForeachSlotHelper &) =
delete;
93 void InitTask(TTreeReader *,
unsigned int) {}
95 template <
typename... Args>
96 void Exec(
unsigned int slot, Args &&... args)
99 static_assert(std::is_same<TypeList<std::decay_t<Args>...>, ColumnTypes_t>
::value,
"");
100 fCallable(slot, std::forward<Args>(args)...);
107 std::string GetActionName() {
return "ForeachSlot"; }
110class R__CLING_PTRCHECK(off) CountHelper :
public RActionImpl<CountHelper> {
111 std::shared_ptr<ULong64_t> fResultCount;
112 Results<ULong64_t> fCounts;
115 using ColumnTypes_t = TypeList<>;
116 CountHelper(
const std::shared_ptr<ULong64_t> &resultCount,
const unsigned int nSlots);
117 CountHelper(CountHelper &&) =
default;
118 CountHelper(
const CountHelper &) =
delete;
119 void InitTask(TTreeReader *,
unsigned int) {}
120 void Exec(
unsigned int slot);
127 return std::make_unique<RMergeableCount>(*fResultCount);
130 ULong64_t &PartialUpdate(
unsigned int slot);
132 std::string GetActionName() {
return "Count"; }
134 CountHelper MakeNew(
void *newResult, std::string_view =
"nominal")
136 auto &
result = *
static_cast<std::shared_ptr<ULong64_t> *
>(newResult);
137 return CountHelper(
result, fCounts.size());
141template <
typename RNode_t>
142class R__CLING_PTRCHECK(off) ReportHelper :
public RActionImpl<ReportHelper<RNode_t>> {
143 std::shared_ptr<RCutFlowReport> fReport;
147 bool fReturnEmptyReport;
150 using ColumnTypes_t = TypeList<>;
151 ReportHelper(
const std::shared_ptr<RCutFlowReport> &report, RNode_t *node,
bool emptyRep)
152 : fReport(report), fNode(node), fReturnEmptyReport(emptyRep){};
153 ReportHelper(ReportHelper &&) =
default;
154 ReportHelper(
const ReportHelper &) =
delete;
155 void InitTask(TTreeReader *,
unsigned int) {}
156 void Exec(
unsigned int ) {}
160 if (!fReturnEmptyReport)
161 fNode->Report(*fReport);
166 auto cutinfo_vec = fReport->fCutInfos;
167 return std::make_unique<RMergeableReport>(*fReport, cutinfo_vec);
170 std::string GetActionName() {
return "Report"; }
172 ReportHelper MakeNew(
void *newResult, std::string_view variation =
"nominal")
174 auto &&
result = *
static_cast<std::shared_ptr<RCutFlowReport> *
>(newResult);
175 return ReportHelper{
result,
176 std::static_pointer_cast<RNode_t>(fNode->GetVariedFilter(std::string(variation))).get(),
188class R__CLING_PTRCHECK(off) BufferedFillHelper :
public RActionImpl<BufferedFillHelper> {
190 static constexpr unsigned int fgTotalBufSize = 2097152;
191 using BufEl_t = double;
192 using Buf_t = std::vector<BufEl_t>;
194 std::vector<Buf_t> fBuffers;
195 std::vector<Buf_t> fWBuffers;
196 std::shared_ptr<Hist_t> fResultHist;
197 unsigned int fNSlots;
198 unsigned int fBufSize;
200 Results<std::unique_ptr<Hist_t>> fPartialHists;
204 void UpdateMinMax(
unsigned int slot,
double v);
207 BufferedFillHelper(
const std::shared_ptr<Hist_t> &
h,
const unsigned int nSlots);
208 BufferedFillHelper(BufferedFillHelper &&) =
default;
209 BufferedFillHelper(
const BufferedFillHelper &) =
delete;
210 void InitTask(TTreeReader *,
unsigned int) {}
211 void Exec(
unsigned int slot,
double v);
212 void Exec(
unsigned int slot,
double v,
double w);
214 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
215 void Exec(
unsigned int slot,
const T &vs)
217 auto &thisBuf = fBuffers[slot];
219 for (
auto v = vs.begin();
v != vs.end(); ++
v) {
220 UpdateMinMax(slot, *
v);
221 thisBuf.emplace_back(*
v);
225 template <typename T, typename W, std::enable_if_t<IsDataContainer<T>::value && IsDataContainer<W>::value,
int> = 0>
226 void Exec(
unsigned int slot,
const T &vs,
const W &ws)
228 auto &thisBuf = fBuffers[slot];
231 UpdateMinMax(slot,
v);
232 thisBuf.emplace_back(
v);
235 auto &thisWBuf = fWBuffers[slot];
237 thisWBuf.emplace_back(
w);
241 template <typename T, typename W, std::enable_if_t<IsDataContainer<T>::value && !IsDataContainer<W>::value,
int> = 0>
242 void Exec(
unsigned int slot,
const T &vs,
const W
w)
244 auto &thisBuf = fBuffers[slot];
246 UpdateMinMax(slot,
v);
247 thisBuf.emplace_back(
v);
250 auto &thisWBuf = fWBuffers[slot];
251 thisWBuf.insert(thisWBuf.end(), vs.size(),
w);
254 template <typename T, typename W, std::enable_if_t<IsDataContainer<W>::value && !IsDataContainer<T>::value,
int> = 0>
255 void Exec(
unsigned int slot,
const T
v,
const W &ws)
257 UpdateMinMax(slot,
v);
258 auto &thisBuf = fBuffers[slot];
259 thisBuf.insert(thisBuf.end(), ws.size(),
v);
261 auto &thisWBuf = fWBuffers[slot];
262 thisWBuf.insert(thisWBuf.end(), ws.begin(), ws.end());
265 Hist_t &PartialUpdate(
unsigned int);
274 return std::make_unique<RMergeableFill<Hist_t>>(*fResultHist);
277 std::string GetActionName()
279 return std::string(fResultHist->IsA()->GetName()) +
"\\n" + std::string(fResultHist->GetName());
282 BufferedFillHelper MakeNew(
void *newResult, std::string_view =
"nominal")
284 auto &
result = *
static_cast<std::shared_ptr<Hist_t> *
>(newResult);
286 result->SetDirectory(
nullptr);
287 return BufferedFillHelper(
result, fNSlots);
293class ScalarConstIterator {
297 using iterator_category = std::forward_iterator_tag;
298 using difference_type = std::ptrdiff_t;
299 using value_type =
T;
301 using reference =
T &;
302 ScalarConstIterator(
const T *obj) : obj_(obj) {}
304 ScalarConstIterator<T> &operator++() {
return *
this; }
309auto MakeBegin(
const T &val)
311 if constexpr (IsDataContainer<T>::value) {
312 return std::begin(val);
314 return ScalarConstIterator<T>(&val);
320std::size_t GetSize(
const T &val)
322 if constexpr (IsDataContainer<T>::value) {
323 return std::size(val);
330template <typename H, typename = decltype(std::declval<H>().Reset())>
344template <
typename HIST = Hist_t>
345class R__CLING_PTRCHECK(off) FillHelper :
public RActionImpl<FillHelper<HIST>> {
346 std::vector<HIST *> fObjects;
349 template <typename H, typename = std::enable_if_t<std::is_base_of<TObject, H>::value,
int>>
350 auto Merge(std::vector<H *> &objs,
int )
351 ->
decltype(objs[0]->Merge((TCollection *)
nullptr),
void())
354 for (
auto it = ++objs.begin(); it != objs.end(); ++it)
360 template <
typename H>
361 auto Merge(std::vector<H *> &objs,
double )
362 ->
decltype(objs[0]->Merge(std::vector<HIST *>{}),
void())
364 objs[0]->Merge({++objs.begin(), objs.end()});
368 template <
typename T>
371 static_assert(
sizeof(
T) < 0,
372 "The type passed to Fill does not provide a Merge(TCollection*) or Merge(const std::vector&) method.");
375 template <std::size_t ColIdx,
typename End_t,
typename... Its>
376 void ExecLoop(
unsigned int slot, End_t end, Its... its)
378 for (
auto *thisSlotH = fObjects[slot]; GetNthElement<ColIdx>(its...) != end; (std::advance(its, 1), ...)) {
379 thisSlotH->Fill(*its...);
384 FillHelper(FillHelper &&) =
default;
385 FillHelper(
const FillHelper &) =
delete;
387 FillHelper(
const std::shared_ptr<HIST> &
h,
const unsigned int nSlots) : fObjects(nSlots, nullptr)
389 fObjects[0] =
h.get();
391 for (
unsigned int i = 1; i < nSlots; ++i) {
392 fObjects[i] =
new HIST(*fObjects[0]);
397 void InitTask(TTreeReader *,
unsigned int) {}
400 template <
typename... ValTypes, std::enable_if_t<!Disjunction<IsDataContainer<ValTypes>...>
::value,
int> = 0>
401 auto Exec(
unsigned int slot,
const ValTypes &...
x) ->
decltype(fObjects[slot]->Fill(
x...),
void())
403 fObjects[slot]->Fill(
x...);
407 template <
typename... Xs, std::enable_if_t<Disjunction<IsDataContainer<Xs>...>
::value,
int> = 0>
408 auto Exec(
unsigned int slot,
const Xs &...xs) ->
decltype(fObjects[slot]->Fill(*MakeBegin(xs)...),
void())
411 constexpr std::array<bool,
sizeof...(Xs)> isContainer{IsDataContainer<Xs>::value...};
414 constexpr std::size_t colidx =
FindIdxTrue(isContainer);
416 static_assert(colidx <
sizeof...(Xs),
"Error: index of collection-type argument not found.");
419 auto const xrefend = std::end(GetNthElement<colidx>(xs...));
422 std::array<std::size_t,
sizeof...(xs)> sizes = {{GetSize(xs)...}};
424 for (std::size_t i = 0; i <
sizeof...(xs); ++i) {
425 if (isContainer[i] && sizes[i] != sizes[colidx]) {
426 throw std::runtime_error(
"Cannot fill histogram with values in containers of different sizes.");
430 ExecLoop<colidx>(slot, xrefend, MakeBegin(xs)...);
433 template <
typename T = HIST>
436 static_assert(
sizeof(
T) < 0,
437 "When filling an object with RDataFrame (e.g. via a Fill action) the number or types of the "
438 "columns passed did not match the signature of the object's `Fill` method.");
445 if (fObjects.size() == 1)
451 for (
auto it = ++fObjects.begin(); it != fObjects.end(); ++it)
455 HIST &PartialUpdate(
unsigned int slot) {
return *fObjects[slot]; }
460 return std::make_unique<RMergeableFill<HIST>>(*fObjects[0]);
464 template <typename T = HIST, std::enable_if_t<std::is_base_of<TObject, T>::value,
int> = 0>
465 std::string GetActionName()
467 return std::string(fObjects[0]->
IsA()->GetName()) +
"\\n" + std::string(fObjects[0]->GetName());
471 template <typename T = HIST, std::enable_if_t<!std::is_base_of<TObject, T>::value,
int> = 0>
472 std::string GetActionName()
474 return "Fill custom object";
477 template <
typename H = HIST>
478 FillHelper MakeNew(
void *newResult, std::string_view =
"nominal")
480 auto &
result = *
static_cast<std::shared_ptr<H> *
>(newResult);
483 return FillHelper(
result, fObjects.size());
488template <
typename BinContentType,
bool WithWeight = false>
489class R__CLING_PTRCHECK(off) RHistFillHelper
490 :
public ROOT::Detail::RDF::RActionImpl<RHistFillHelper<BinContentType, WithWeight>> {
492 using Result_t = ROOT::Experimental::RHist<BinContentType>;
495 std::unique_ptr<ROOT::Experimental::RHistConcurrentFiller<BinContentType>> fFiller;
496 std::vector<std::shared_ptr<ROOT::Experimental::RHistFillContext<BinContentType>>> fContexts;
499 RHistFillHelper(std::shared_ptr<ROOT::Experimental::RHist<BinContentType>>
h,
unsigned int nSlots)
500 : fFiller(new ROOT::Experimental::RHistConcurrentFiller<BinContentType>(
h)), fContexts(nSlots)
502 for (
unsigned int i = 0; i < nSlots; i++) {
503 fContexts[i] = fFiller->CreateFillContext();
506 RHistFillHelper(
const RHistFillHelper &) =
delete;
507 RHistFillHelper(RHistFillHelper &&) =
default;
508 RHistFillHelper &
operator=(
const RHistFillHelper &) =
delete;
509 RHistFillHelper &
operator=(RHistFillHelper &&) =
default;
510 ~RHistFillHelper() =
default;
512 std::shared_ptr<Result_t> GetResultPtr()
const {
return fFiller.GetHist(); }
515 void InitTask(TTreeReader *,
unsigned int) {}
517 template <
typename... ColumnTypes,
const std::size_t...
I>
519 ExecWithWeight(
unsigned int slot,
const std::tuple<const ColumnTypes &...> &columnValues, std::index_sequence<I...>)
522 std::tuple<
const std::tuple_element_t<
I, std::tuple<ColumnTypes...>> &...> args(std::get<I>(columnValues)...);
523 ROOT::Experimental::RWeight weight(std::get<
sizeof...(ColumnTypes) - 1>(columnValues));
524 fContexts[slot]->Fill(args, weight);
527 template <
typename... ColumnTypes>
528 void Exec(
unsigned int slot,
const ColumnTypes &...columnValues)
530 if constexpr (WithWeight) {
531 auto t = std::forward_as_tuple(columnValues...);
532 ExecWithWeight(slot, t, std::make_index_sequence<
sizeof...(ColumnTypes) - 1>());
534 fContexts[slot]->Fill(columnValues...);
540 for (
auto &&context : fContexts) {
545 std::string GetActionName() {
return "Hist"; }
548template <
typename BinContentType,
bool WithWeight = false>
549class R__CLING_PTRCHECK(off) RHistEngineFillHelper
550 :
public ROOT::Detail::RDF::RActionImpl<RHistEngineFillHelper<BinContentType, WithWeight>> {
552 using Result_t = ROOT::Experimental::RHistEngine<BinContentType>;
555 std::shared_ptr<Result_t> fHist;
558 RHistEngineFillHelper(std::shared_ptr<ROOT::Experimental::RHistEngine<BinContentType>>
h) : fHist(
h) {}
559 RHistEngineFillHelper(
const RHistEngineFillHelper &) =
delete;
560 RHistEngineFillHelper(RHistEngineFillHelper &&) =
default;
561 RHistEngineFillHelper &
operator=(
const RHistEngineFillHelper &) =
delete;
562 RHistEngineFillHelper &
operator=(RHistEngineFillHelper &&) =
default;
563 ~RHistEngineFillHelper() =
default;
565 std::shared_ptr<Result_t> GetResultPtr()
const {
return fHist; }
568 void InitTask(TTreeReader *,
unsigned int) {}
570 template <
typename... ColumnTypes,
const std::size_t...
I>
571 void ExecWithWeight(
const std::tuple<const ColumnTypes &...> &columnValues, std::index_sequence<I...>)
574 std::tuple<
const std::tuple_element_t<
I, std::tuple<ColumnTypes...>> &...> args(std::get<I>(columnValues)...);
575 ROOT::Experimental::RWeight weight(std::get<
sizeof...(ColumnTypes) - 1>(columnValues));
576 fHist->FillAtomic(args, weight);
579 template <
typename... ColumnTypes>
580 void Exec(
unsigned int,
const ColumnTypes &...columnValues)
582 if constexpr (WithWeight) {
583 auto t = std::forward_as_tuple(columnValues...);
584 ExecWithWeight(t, std::make_index_sequence<
sizeof...(ColumnTypes) - 1>());
586 fHist->FillAtomic(columnValues...);
592 std::string GetActionName() {
return "Hist"; }
596class R__CLING_PTRCHECK(off) FillTGraphHelper :
public ROOT::Detail::RDF::RActionImpl<FillTGraphHelper> {
598 using Result_t = ::TGraph;
601 std::vector<::TGraph *> fGraphs;
604 FillTGraphHelper(FillTGraphHelper &&) =
default;
605 FillTGraphHelper(
const FillTGraphHelper &) =
delete;
607 FillTGraphHelper(
const std::shared_ptr<::TGraph> &
g,
const unsigned int nSlots) : fGraphs(nSlots, nullptr)
609 fGraphs[0] =
g.get();
611 for (
unsigned int i = 1; i < nSlots; ++i) {
612 fGraphs[i] =
new TGraph(*fGraphs[0]);
617 void InitTask(TTreeReader *,
unsigned int) {}
620 template <
typename X0,
typename X1,
621 std::enable_if_t<IsDataContainer<X0>::value && IsDataContainer<X1>::value,
int> = 0>
622 void Exec(
unsigned int slot,
const X0 &x0s,
const X1 &x1s)
624 if (x0s.size() != x1s.size()) {
625 throw std::runtime_error(
"Cannot fill Graph with values in containers of different sizes.");
627 auto *thisSlotG = fGraphs[slot];
628 auto x0sIt = std::begin(x0s);
629 const auto x0sEnd = std::end(x0s);
630 auto x1sIt = std::begin(x1s);
631 for (; x0sIt != x0sEnd; x0sIt++, x1sIt++) {
632 thisSlotG->SetPoint(thisSlotG->GetN(), *x0sIt, *x1sIt);
637 template <
typename X0,
typename X1,
638 std::enable_if_t<!IsDataContainer<X0>::value && !IsDataContainer<X1>::value,
int> = 0>
639 void Exec(
unsigned int slot, X0 x0, X1
x1)
641 auto thisSlotG = fGraphs[slot];
642 thisSlotG->SetPoint(thisSlotG->GetN(), x0,
x1);
647 template <
typename X0,
typename X1,
typename... ExtraArgsToLowerPriority>
648 void Exec(
unsigned int, X0, X1, ExtraArgsToLowerPriority...)
650 throw std::runtime_error(
"Graph was applied to a mix of scalar values and collections. This is not supported.");
655 const auto nSlots = fGraphs.size();
656 auto resGraph = fGraphs[0];
659 for (
unsigned int slot = 1; slot < nSlots; ++slot) {
660 l.Add(fGraphs[slot]);
668 return std::make_unique<RMergeableFill<Result_t>>(*fGraphs[0]);
671 std::string GetActionName() {
return "Graph"; }
673 Result_t &PartialUpdate(
unsigned int slot) {
return *fGraphs[slot]; }
675 FillTGraphHelper MakeNew(
void *newResult, std::string_view =
"nominal")
677 auto &
result = *
static_cast<std::shared_ptr<TGraph> *
>(newResult);
679 return FillTGraphHelper(
result, fGraphs.size());
683class R__CLING_PTRCHECK(off) FillTGraphAsymmErrorsHelper
684 :
public ROOT::Detail::RDF::RActionImpl<FillTGraphAsymmErrorsHelper> {
686 using Result_t = ::TGraphAsymmErrors;
689 std::vector<::TGraphAsymmErrors *> fGraphAsymmErrors;
692 FillTGraphAsymmErrorsHelper(FillTGraphAsymmErrorsHelper &&) =
default;
693 FillTGraphAsymmErrorsHelper(
const FillTGraphAsymmErrorsHelper &) =
delete;
695 FillTGraphAsymmErrorsHelper(
const std::shared_ptr<::TGraphAsymmErrors> &
g,
const unsigned int nSlots)
696 : fGraphAsymmErrors(nSlots, nullptr)
698 fGraphAsymmErrors[0] =
g.get();
700 for (
unsigned int i = 1; i < nSlots; ++i) {
701 fGraphAsymmErrors[i] =
new TGraphAsymmErrors(*fGraphAsymmErrors[0]);
706 void InitTask(TTreeReader *,
unsigned int) {}
710 typename X,
typename Y,
typename EXL,
typename EXH,
typename EYL,
typename EYH,
711 std::enable_if_t<IsDataContainer<X>::value && IsDataContainer<Y>::value && IsDataContainer<EXL>::value &&
712 IsDataContainer<EXH>::value && IsDataContainer<EYL>::value && IsDataContainer<EYH>::value,
715 Exec(
unsigned int slot,
const X &xs,
const Y &ys,
const EXL &exls,
const EXH &exhs,
const EYL &eyls,
const EYH &eyhs)
717 if ((xs.size() != ys.size()) || (xs.size() != exls.size()) || (xs.size() != exhs.size()) ||
718 (xs.size() != eyls.size()) || (xs.size() != eyhs.size())) {
719 throw std::runtime_error(
"Cannot fill GraphAsymmErrors with values in containers of different sizes.");
721 auto *thisSlotG = fGraphAsymmErrors[slot];
722 auto xsIt = std::begin(xs);
723 auto ysIt = std::begin(ys);
724 auto exlsIt = std::begin(exls);
725 auto exhsIt = std::begin(exhs);
726 auto eylsIt = std::begin(eyls);
727 auto eyhsIt = std::begin(eyhs);
728 while (xsIt != std::end(xs)) {
729 const auto n = thisSlotG->GetN();
730 thisSlotG->SetPoint(
n, *xsIt++, *ysIt++);
731 thisSlotG->SetPointError(
n, *exlsIt++, *exhsIt++, *eylsIt++, *eyhsIt++);
737 typename X,
typename Y,
typename EXL,
typename EXH,
typename EYL,
typename EYH,
738 std::enable_if_t<!IsDataContainer<X>::value && !IsDataContainer<Y>::value && !IsDataContainer<EXL>::value &&
739 !IsDataContainer<EXH>::value && !IsDataContainer<EYL>::value && !IsDataContainer<EYH>::value,
741 void Exec(
unsigned int slot,
X x, Y
y, EXL exl, EXH exh, EYL eyl, EYH eyh)
743 auto thisSlotG = fGraphAsymmErrors[slot];
744 const auto n = thisSlotG->GetN();
745 thisSlotG->SetPoint(
n,
x,
y);
746 thisSlotG->SetPointError(
n, exl, exh, eyl, eyh);
751 template <
typename X,
typename Y,
typename EXL,
typename EXH,
typename EYL,
typename EYH,
752 typename... ExtraArgsToLowerPriority>
753 void Exec(
unsigned int,
X, Y, EXL, EXH, EYL, EYH, ExtraArgsToLowerPriority...)
755 throw std::runtime_error(
756 "GraphAsymmErrors was applied to a mix of scalar values and collections. This is not supported.");
761 const auto nSlots = fGraphAsymmErrors.size();
762 auto resGraphAsymmErrors = fGraphAsymmErrors[0];
765 for (
unsigned int slot = 1; slot < nSlots; ++slot) {
766 l.Add(fGraphAsymmErrors[slot]);
768 resGraphAsymmErrors->Merge(&
l);
774 return std::make_unique<RMergeableFill<Result_t>>(*fGraphAsymmErrors[0]);
777 std::string GetActionName() {
return "GraphAsymmErrors"; }
779 Result_t &PartialUpdate(
unsigned int slot) {
return *fGraphAsymmErrors[slot]; }
781 FillTGraphAsymmErrorsHelper MakeNew(
void *newResult, std::string_view =
"nominal")
783 auto &
result = *
static_cast<std::shared_ptr<TGraphAsymmErrors> *
>(newResult);
785 return FillTGraphAsymmErrorsHelper(
result, fGraphAsymmErrors.size());
790template <
typename HIST>
791class R__CLING_PTRCHECK(off) ThreadSafeFillHelper :
public RActionImpl<ThreadSafeFillHelper<HIST>> {
792 std::vector<std::shared_ptr<HIST>> fObjects;
793 std::vector<std::unique_ptr<std::mutex>> fMutexPtrs;
796 template <
typename T,
typename... Args>
797 auto TryCallFillThreadSafe(T &
object, std::mutex &,
int , Args... args)
803 template <
typename T,
typename... Args>
804 auto TryCallFillThreadSafe(T &
object, std::mutex &mutex,
char , Args... args)
806 std::scoped_lock lock{mutex};
807 object.Fill(args...);
810 template <std::size_t ColIdx,
typename End_t,
typename... Its>
811 void ExecLoop(
unsigned int slot, End_t end, Its... its)
813 const auto localSlot = slot % fObjects.size();
814 for (; GetNthElement<ColIdx>(its...) != end; (std::advance(its, 1), ...)) {
815 TryCallFillThreadSafe(*fObjects[localSlot], *fMutexPtrs[localSlot], 0, *its...);
820 ThreadSafeFillHelper(ThreadSafeFillHelper &&) =
default;
821 ThreadSafeFillHelper(
const ThreadSafeFillHelper &) =
delete;
823 ThreadSafeFillHelper(
const std::shared_ptr<HIST> &
h,
const unsigned int nSlots)
825 fObjects.resize(nSlots);
826 fObjects.front() =
h;
828 std::generate(fObjects.begin() + 1, fObjects.end(), [
h]() {
829 auto hist = std::make_shared<HIST>(*h);
830 UnsetDirectoryIfPossible(hist.get());
833 fMutexPtrs.resize(nSlots);
834 std::generate(fMutexPtrs.begin(), fMutexPtrs.end(), []() { return std::make_unique<std::mutex>(); });
837 void InitTask(TTreeReader *,
unsigned int) {}
840 template <
typename... ValTypes, std::enable_if_t<!Disjunction<IsDataContainer<ValTypes>...>
::value,
int> = 0>
841 void Exec(
unsigned int slot,
const ValTypes &...
x)
843 const auto localSlot = slot % fObjects.size();
844 TryCallFillThreadSafe(*fObjects[localSlot], *fMutexPtrs[localSlot], 0,
x...);
848 template <
typename... Xs, std::enable_if_t<Disjunction<IsDataContainer<Xs>...>
::value,
int> = 0>
849 void Exec(
unsigned int slot,
const Xs &...xs)
852 constexpr std::array<bool,
sizeof...(Xs)> isContainer{IsDataContainer<Xs>::value...};
855 constexpr std::size_t colidx =
FindIdxTrue(isContainer);
857 static_assert(colidx <
sizeof...(Xs),
"Error: index of collection-type argument not found.");
860 auto const xrefend = std::end(GetNthElement<colidx>(xs...));
863 std::array<std::size_t,
sizeof...(xs)> sizes = {{GetSize(xs)...}};
865 for (std::size_t i = 0; i <
sizeof...(xs); ++i) {
866 if (isContainer[i] && sizes[i] != sizes[colidx]) {
867 throw std::runtime_error(
"Cannot fill histogram with values in containers of different sizes.");
871 ExecLoop<colidx>(slot, xrefend, MakeBegin(xs)...);
874 template <
typename T = HIST>
877 static_assert(
sizeof(
T) < 0,
878 "When filling an object with RDataFrame (e.g. via a Fill action) the number or types of the "
879 "columns passed did not match the signature of the object's `FillThreadSafe` method.");
886 if (fObjects.size() > 1) {
888 for (
auto it = fObjects.cbegin() + 1; it != fObjects.end(); ++it) {
891 fObjects[0]->Merge(&list);
901 return std::make_unique<RMergeableFill<HIST>>(*fObjects[0]);
905 template <typename T = HIST, std::enable_if_t<std::is_base_of<TObject, T>::value,
int> = 0>
906 std::string GetActionName()
908 return std::string(fObjects[0]->
IsA()->GetName()) +
"\\n" + std::string(fObjects[0]->GetName());
911 template <
typename H = HIST>
912 ThreadSafeFillHelper MakeNew(
void *newResult, std::string_view =
"nominal")
914 auto &
result = *
static_cast<std::shared_ptr<H> *
>(newResult);
917 return ThreadSafeFillHelper(
result, fObjects.size());
927template <
typename V,
typename COLL>
928void FillColl(V&&
v, COLL&
c) {
933template <
typename COLL>
934void FillColl(
bool v, COLL&
c) {
940template <
typename RealT_t,
typename T,
typename COLL>
941class R__CLING_PTRCHECK(off) TakeHelper :
public RActionImpl<TakeHelper<RealT_t, T, COLL>> {
942 Results<std::shared_ptr<COLL>> fColls;
945 using ColumnTypes_t = TypeList<T>;
946 TakeHelper(
const std::shared_ptr<COLL> &resultColl,
const unsigned int nSlots)
948 fColls.emplace_back(resultColl);
949 for (
unsigned int i = 1; i < nSlots; ++i)
950 fColls.emplace_back(std::make_shared<COLL>());
952 TakeHelper(TakeHelper &&);
953 TakeHelper(
const TakeHelper &) =
delete;
955 void InitTask(TTreeReader *,
unsigned int) {}
957 void Exec(
unsigned int slot, T &
v) { FillColl(
v, *fColls[slot]); }
963 auto rColl = fColls[0];
964 for (
unsigned int i = 1; i < fColls.size(); ++i) {
965 const auto &coll = fColls[i];
966 const auto end = coll->end();
969 for (
auto j = coll->begin(); j != end; j++) {
970 FillColl(*j, *rColl);
975 COLL &PartialUpdate(
unsigned int slot) {
return *fColls[slot].get(); }
977 std::string GetActionName() {
return "Take"; }
979 TakeHelper MakeNew(
void *newResult, std::string_view =
"nominal")
981 auto &
result = *
static_cast<std::shared_ptr<COLL> *
>(newResult);
983 return TakeHelper(
result, fColls.size());
989template <
typename RealT_t,
typename T>
990class R__CLING_PTRCHECK(off) TakeHelper<RealT_t,
T, std::vector<T>>
991 :
public RActionImpl<TakeHelper<RealT_t, T, std::vector<T>>> {
992 Results<std::shared_ptr<std::vector<T>>> fColls;
995 using ColumnTypes_t = TypeList<T>;
996 TakeHelper(
const std::shared_ptr<std::vector<T>> &resultColl,
const unsigned int nSlots)
998 fColls.emplace_back(resultColl);
999 for (
unsigned int i = 1; i < nSlots; ++i) {
1000 auto v = std::make_shared<std::vector<T>>();
1002 fColls.emplace_back(
v);
1005 TakeHelper(TakeHelper &&);
1006 TakeHelper(
const TakeHelper &) =
delete;
1008 void InitTask(TTreeReader *,
unsigned int) {}
1010 void Exec(
unsigned int slot, T &
v) { FillColl(
v, *fColls[slot]); }
1018 for (
auto &coll : fColls)
1019 totSize += coll->size();
1020 auto rColl = fColls[0];
1021 rColl->reserve(totSize);
1022 for (
unsigned int i = 1; i < fColls.size(); ++i) {
1023 auto &coll = fColls[i];
1024 rColl->insert(rColl->end(), coll->begin(), coll->end());
1028 std::vector<T> &PartialUpdate(
unsigned int slot) {
return *fColls[slot]; }
1030 std::string GetActionName() {
return "Take"; }
1032 TakeHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1034 auto &
result = *
static_cast<std::shared_ptr<std::vector<T>
> *>(newResult);
1036 return TakeHelper(
result, fColls.size());
1042template <
typename RealT_t,
typename COLL>
1043class R__CLING_PTRCHECK(off) TakeHelper<RealT_t,
RVec<RealT_t>, COLL>
1044 :
public RActionImpl<TakeHelper<RealT_t, RVec<RealT_t>, COLL>> {
1045 Results<std::shared_ptr<COLL>> fColls;
1048 using ColumnTypes_t = TypeList<RVec<RealT_t>>;
1049 TakeHelper(
const std::shared_ptr<COLL> &resultColl,
const unsigned int nSlots)
1051 fColls.emplace_back(resultColl);
1052 for (
unsigned int i = 1; i < nSlots; ++i)
1053 fColls.emplace_back(std::make_shared<COLL>());
1055 TakeHelper(TakeHelper &&);
1056 TakeHelper(
const TakeHelper &) =
delete;
1058 void InitTask(TTreeReader *,
unsigned int) {}
1060 void Exec(
unsigned int slot, RVec<RealT_t> av) { fColls[slot]->emplace_back(av.
begin(), av.
end()); }
1066 auto rColl = fColls[0];
1067 for (
unsigned int i = 1; i < fColls.size(); ++i) {
1068 auto &coll = fColls[i];
1069 for (
auto &
v : *coll) {
1070 rColl->emplace_back(
v);
1075 std::string GetActionName() {
return "Take"; }
1077 TakeHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1079 auto &
result = *
static_cast<std::shared_ptr<COLL> *
>(newResult);
1081 return TakeHelper(
result, fColls.size());
1087template <
typename RealT_t>
1088class R__CLING_PTRCHECK(off) TakeHelper<RealT_t,
RVec<RealT_t>, std::vector<RealT_t>>
1089 :
public RActionImpl<TakeHelper<RealT_t, RVec<RealT_t>, std::vector<RealT_t>>> {
1091 Results<std::shared_ptr<std::vector<std::vector<RealT_t>>>> fColls;
1094 using ColumnTypes_t = TypeList<RVec<RealT_t>>;
1095 TakeHelper(
const std::shared_ptr<std::vector<std::vector<RealT_t>>> &resultColl,
const unsigned int nSlots)
1097 fColls.emplace_back(resultColl);
1098 for (
unsigned int i = 1; i < nSlots; ++i) {
1099 auto v = std::make_shared<std::vector<RealT_t>>();
1101 fColls.emplace_back(
v);
1104 TakeHelper(TakeHelper &&);
1105 TakeHelper(
const TakeHelper &) =
delete;
1107 void InitTask(TTreeReader *,
unsigned int) {}
1109 void Exec(
unsigned int slot, RVec<RealT_t> av) { fColls[slot]->emplace_back(av.
begin(), av.
end()); }
1117 for (
auto &coll : fColls)
1118 totSize += coll->size();
1119 auto rColl = fColls[0];
1120 rColl->reserve(totSize);
1121 for (
unsigned int i = 1; i < fColls.size(); ++i) {
1122 auto &coll = fColls[i];
1123 rColl->insert(rColl->end(), coll->begin(), coll->end());
1127 std::string GetActionName() {
return "Take"; }
1129 TakeHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1131 auto &
result = *
static_cast<typename decltype(fColls)::value_type *
>(newResult);
1133 return TakeHelper(
result, fColls.size());
1140template <
typename RealT_t,
typename T,
typename COLL>
1141TakeHelper<RealT_t, T, COLL>::TakeHelper(TakeHelper<RealT_t, T, COLL> &&) =
default;
1142template <
typename RealT_t,
typename T>
1143TakeHelper<RealT_t, T, std::vector<T>>::TakeHelper(TakeHelper<RealT_t, T, std::vector<T>> &&) =
default;
1144template <
typename RealT_t,
typename COLL>
1145TakeHelper<RealT_t, RVec<RealT_t>, COLL>::TakeHelper(TakeHelper<RealT_t, RVec<RealT_t>, COLL> &&) =
default;
1146template <
typename RealT_t>
1147TakeHelper<RealT_t, RVec<RealT_t>, std::vector<RealT_t>>::TakeHelper(TakeHelper<RealT_t, RVec<RealT_t>, std::vector<RealT_t>> &&) =
default;
1151extern template class TakeHelper<bool, bool, std::vector<bool>>;
1152extern template class TakeHelper<unsigned int, unsigned int, std::vector<unsigned int>>;
1153extern template class TakeHelper<unsigned long, unsigned long, std::vector<unsigned long>>;
1154extern template class TakeHelper<unsigned long long, unsigned long long, std::vector<unsigned long long>>;
1155extern template class TakeHelper<int, int, std::vector<int>>;
1156extern template class TakeHelper<long, long, std::vector<long>>;
1157extern template class TakeHelper<long long, long long, std::vector<long long>>;
1158extern template class TakeHelper<float, float, std::vector<float>>;
1159extern template class TakeHelper<double, double, std::vector<double>>;
1162template <
typename ResultType>
1163class R__CLING_PTRCHECK(off) MinHelper :
public RActionImpl<MinHelper<ResultType>> {
1164 std::shared_ptr<ResultType> fResultMin;
1165 Results<ResultType> fMins;
1168 MinHelper(MinHelper &&) =
default;
1169 MinHelper(
const std::shared_ptr<ResultType> &minVPtr,
const unsigned int nSlots)
1170 : fResultMin(minVPtr), fMins(nSlots, std::numeric_limits<ResultType>::
max())
1174 void Exec(
unsigned int slot, ResultType
v) { fMins[slot] = std::min(
v, fMins[slot]); }
1176 void InitTask(TTreeReader *,
unsigned int) {}
1178 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
1179 void Exec(
unsigned int slot,
const T &vs)
1182 fMins[slot] = std::min(
static_cast<ResultType
>(
v), fMins[slot]);
1189 *fResultMin = std::numeric_limits<ResultType>::max();
1190 for (
auto &
m : fMins)
1191 *fResultMin = std::min(
m, *fResultMin);
1197 return std::make_unique<RMergeableMin<ResultType>>(*fResultMin);
1200 ResultType &PartialUpdate(
unsigned int slot) {
return fMins[slot]; }
1202 std::string GetActionName() {
return "Min"; }
1204 MinHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1206 auto &
result = *
static_cast<std::shared_ptr<ResultType> *
>(newResult);
1207 return MinHelper(
result, fMins.size());
1211template <
typename ResultType>
1212class R__CLING_PTRCHECK(off) MaxHelper :
public RActionImpl<MaxHelper<ResultType>> {
1213 std::shared_ptr<ResultType> fResultMax;
1214 Results<ResultType> fMaxs;
1217 MaxHelper(MaxHelper &&) =
default;
1218 MaxHelper(
const MaxHelper &) =
delete;
1219 MaxHelper(
const std::shared_ptr<ResultType> &maxVPtr,
const unsigned int nSlots)
1220 : fResultMax(maxVPtr), fMaxs(nSlots, std::numeric_limits<ResultType>::lowest())
1224 void InitTask(TTreeReader *,
unsigned int) {}
1225 void Exec(
unsigned int slot, ResultType
v) { fMaxs[slot] = std::max(
v, fMaxs[slot]); }
1227 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
1228 void Exec(
unsigned int slot,
const T &vs)
1231 fMaxs[slot] = std::max(
static_cast<ResultType
>(
v), fMaxs[slot]);
1238 *fResultMax = std::numeric_limits<ResultType>::lowest();
1239 for (
auto &
m : fMaxs) {
1240 *fResultMax = std::max(
m, *fResultMax);
1247 return std::make_unique<RMergeableMax<ResultType>>(*fResultMax);
1250 ResultType &PartialUpdate(
unsigned int slot) {
return fMaxs[slot]; }
1252 std::string GetActionName() {
return "Max"; }
1254 MaxHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1256 auto &
result = *
static_cast<std::shared_ptr<ResultType> *
>(newResult);
1257 return MaxHelper(
result, fMaxs.size());
1261template <
typename ResultType>
1262class R__CLING_PTRCHECK(off) SumHelper :
public RActionImpl<SumHelper<ResultType>> {
1263 std::shared_ptr<ResultType> fResultSum;
1264 Results<ResultType> fSums;
1265 Results<ResultType> fCompensations;
1270 template <
typename T = ResultType>
1271 auto NeutralElement(
const T &
v,
int ) ->
decltype(
v -
v)
1276 template <
typename T = ResultType,
typename Dummy =
int>
1277 ResultType NeutralElement(
const T &, Dummy)
1279 return ResultType{};
1283 SumHelper(SumHelper &&) =
default;
1284 SumHelper(
const SumHelper &) =
delete;
1285 SumHelper(
const std::shared_ptr<ResultType> &sumVPtr,
const unsigned int nSlots)
1286 : fResultSum(sumVPtr), fSums(nSlots, NeutralElement(*sumVPtr, -1)),
1287 fCompensations(nSlots, NeutralElement(*sumVPtr, -1))
1290 void InitTask(TTreeReader *,
unsigned int) {}
1292 void Exec(
unsigned int slot, ResultType
x)
1295 ResultType
y =
x - fCompensations[slot];
1296 ResultType t = fSums[slot] +
y;
1297 fCompensations[slot] = (t - fSums[slot]) -
y;
1301 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
1302 void Exec(
unsigned int slot,
const T &vs)
1304 for (
auto &&
v : vs) {
1313 ResultType
sum(NeutralElement(ResultType{}, -1));
1314 ResultType compensation(NeutralElement(ResultType{}, -1));
1315 ResultType
y(NeutralElement(ResultType{}, -1));
1316 ResultType t(NeutralElement(ResultType{}, -1));
1317 for (
auto &
m : fSums) {
1319 y =
m - compensation;
1321 compensation = (t -
sum) -
y;
1330 return std::make_unique<RMergeableSum<ResultType>>(*fResultSum);
1333 ResultType &PartialUpdate(
unsigned int slot) {
return fSums[slot]; }
1335 std::string GetActionName() {
return "Sum"; }
1337 SumHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1339 auto &
result = *
static_cast<std::shared_ptr<ResultType> *
>(newResult);
1341 return SumHelper(
result, fSums.size());
1345class R__CLING_PTRCHECK(off) MeanHelper :
public RActionImpl<MeanHelper> {
1346 std::shared_ptr<double> fResultMean;
1347 std::vector<ULong64_t> fCounts;
1348 std::vector<double> fSums;
1349 std::vector<double> fPartialMeans;
1350 std::vector<double> fCompensations;
1353 MeanHelper(
const std::shared_ptr<double> &meanVPtr,
const unsigned int nSlots);
1354 MeanHelper(MeanHelper &&) =
default;
1355 MeanHelper(
const MeanHelper &) =
delete;
1356 void InitTask(TTreeReader *,
unsigned int) {}
1357 void Exec(
unsigned int slot,
double v);
1359 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
1360 void Exec(
unsigned int slot,
const T &vs)
1362 for (
auto &&
v : vs) {
1366 double y =
v - fCompensations[slot];
1367 double t = fSums[slot] +
y;
1368 fCompensations[slot] = (t - fSums[slot]) -
y;
1380 const ULong64_t counts = std::accumulate(fCounts.begin(), fCounts.end(), 0ull);
1381 return std::make_unique<RMergeableMean>(*fResultMean, counts);
1384 double &PartialUpdate(
unsigned int slot);
1386 std::string GetActionName() {
return "Mean"; }
1388 MeanHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1390 auto &
result = *
static_cast<std::shared_ptr<double> *
>(newResult);
1391 return MeanHelper(
result, fSums.size());
1395class R__CLING_PTRCHECK(off) StdDevHelper :
public RActionImpl<StdDevHelper> {
1397 unsigned int fNSlots;
1398 std::shared_ptr<double> fResultStdDev;
1400 std::vector<ULong64_t> fCounts;
1402 std::vector<double> fMeans;
1404 std::vector<double> fDistancesfromMean;
1407 StdDevHelper(
const std::shared_ptr<double> &meanVPtr,
const unsigned int nSlots);
1408 StdDevHelper(StdDevHelper &&) =
default;
1409 StdDevHelper(
const StdDevHelper &) =
delete;
1410 void InitTask(TTreeReader *,
unsigned int) {}
1411 void Exec(
unsigned int slot,
double v);
1413 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
1414 void Exec(
unsigned int slot,
const T &vs)
1416 for (
auto &&
v : vs) {
1428 const ULong64_t counts = std::accumulate(fCounts.begin(), fCounts.end(), 0ull);
1430 std::inner_product(fMeans.begin(), fMeans.end(), fCounts.begin(), 0.) /
static_cast<Double_t>(counts);
1431 return std::make_unique<RMergeableStdDev>(*fResultStdDev, counts, mean);
1434 std::string GetActionName() {
return "StdDev"; }
1436 StdDevHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1438 auto &
result = *
static_cast<std::shared_ptr<double> *
>(newResult);
1439 return StdDevHelper(
result, fCounts.size());
1443template <
typename PrevNodeType>
1444class R__CLING_PTRCHECK(off) DisplayHelper :
public RActionImpl<DisplayHelper<PrevNodeType>> {
1447 std::shared_ptr<Display_t> fDisplayerHelper;
1448 std::shared_ptr<PrevNodeType> fPrevNode;
1449 size_t fEntriesToProcess;
1452 DisplayHelper(
size_t nRows,
const std::shared_ptr<Display_t> &
d,
const std::shared_ptr<PrevNodeType> &prevNode)
1453 : fDisplayerHelper(
d), fPrevNode(prevNode), fEntriesToProcess(nRows)
1456 DisplayHelper(DisplayHelper &&) =
default;
1457 DisplayHelper(
const DisplayHelper &) =
delete;
1458 void InitTask(TTreeReader *,
unsigned int) {}
1460 template <
typename...
Columns>
1461 void Exec(
unsigned int, Columns &... columns)
1463 if (fEntriesToProcess == 0)
1466 fDisplayerHelper->AddRow(columns...);
1467 --fEntriesToProcess;
1469 if (fEntriesToProcess == 0) {
1474 fPrevNode->StopProcessing();
1482 std::string GetActionName() {
return "Display"; }
1485template <
typename Acc,
typename Merge,
typename R,
typename T,
typename U,
1486 bool MustCopyAssign = std::is_same<R, U>::value>
1487class R__CLING_PTRCHECK(off) AggregateHelper
1488 :
public RActionImpl<AggregateHelper<Acc, Merge, R, T, U, MustCopyAssign>> {
1491 std::shared_ptr<U> fResult;
1492 Results<U> fAggregators;
1495 using ColumnTypes_t = TypeList<T>;
1497 AggregateHelper(Acc &&
f, Merge &&
m,
const std::shared_ptr<U> &
result,
const unsigned int nSlots)
1498 : fAggregate(std::move(
f)), fMerge(std::move(
m)), fResult(
result), fAggregators(nSlots, *
result)
1502 AggregateHelper(Acc &
f, Merge &
m,
const std::shared_ptr<U> &
result,
const unsigned int nSlots)
1503 : fAggregate(
f), fMerge(
m), fResult(
result), fAggregators(nSlots, *
result)
1507 AggregateHelper(AggregateHelper &&) =
default;
1508 AggregateHelper(
const AggregateHelper &) =
delete;
1510 void InitTask(TTreeReader *,
unsigned int) {}
1512 template <
bool MustCopyAssign_ = MustCopyAssign, std::enable_if_t<MustCopyAssign_,
int> = 0>
1513 void Exec(
unsigned int slot,
const T &
value)
1515 fAggregators[slot] = fAggregate(fAggregators[slot],
value);
1518 template <
bool MustCopyAssign_ = MustCopyAssign, std::enable_if_t<!MustCopyAssign_,
int> = 0>
1519 void Exec(
unsigned int slot,
const T &
value)
1521 fAggregate(fAggregators[slot],
value);
1526 template <typename MergeRet = typename CallableTraits<Merge>::ret_type,
1527 bool MergeAll = std::is_same<void, MergeRet>::value>
1528 std::enable_if_t<MergeAll, void> Finalize()
1530 fMerge(fAggregators);
1531 *fResult = fAggregators[0];
1534 template <typename MergeRet = typename CallableTraits<Merge>::ret_type,
1535 bool MergeTwoByTwo = std::is_same<U, MergeRet>::value>
1536 std::enable_if_t<MergeTwoByTwo, void> Finalize(...)
1538 for (
const auto &acc : fAggregators)
1539 *fResult = fMerge(*fResult, acc);
1542 U &PartialUpdate(
unsigned int slot) {
return fAggregators[slot]; }
1544 std::string GetActionName() {
return "Aggregate"; }
1546 AggregateHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1548 auto &
result = *
static_cast<std::shared_ptr<U> *
>(newResult);
1549 return AggregateHelper(fAggregate, fMerge,
result, fAggregators.size());
Handle_t Display_t
Display handle.
RInterface & operator=(const RInterface &)=default
Copy-assignment operator for RInterface.
#define R(a, b, c, d, e, f, g, h, i)
TClass * IsA() const override
Basic types used by ROOT and required by TInterpreter.
double Double_t
Double 8 bytes.
unsigned long long ULong64_t
Portable unsigned long integer 8 bytes.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void w
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
TTime operator*(const TTime &t1, const TTime &t2)
iterator begin() noexcept
Collection abstract base class.
void Add(TObject *obj) override
Statistical variable, defined by its mean and variance (RMS).
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
RooCmdArg Columns(Int_t ncol)
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 .
void ResetIfPossible(TStatistic *h)
constexpr std::size_t FindIdxTrue(const T &arr)
void UnsetDirectoryIfPossible(TH1 *h)
void(off) SmallVectorTemplateBase< T
ROOT::VecOps::RVec< T > RVec
auto FillThreadSafe(T &histo, Args... args) -> decltype(histo.FillThreadSafe(args...), void())
Entrypoint for thread-safe filling from RDataFrame.
__device__ AFloat max(AFloat x, AFloat y)
void Initialize(Bool_t useTMVAStyle=kTRUE)
static uint64_t sum(uint64_t i)