18#ifndef ROOT_RDFOPERATIONS
19#define ROOT_RDFOPERATIONS
37#include "RConfigure.h"
88using Results = std::conditional_t<std::is_same<T, bool>::value, std::deque<T>, std::vector<T>>;
91class R__CLING_PTRCHECK(off) ForeachSlotHelper :
public RActionImpl<ForeachSlotHelper<F>> {
97 ForeachSlotHelper(ForeachSlotHelper &&) =
default;
98 ForeachSlotHelper(
const ForeachSlotHelper &) =
delete;
102 template <
typename... Args>
103 void Exec(
unsigned int slot, Args &&... args)
106 static_assert(std::is_same<TypeList<std::decay_t<Args>...>, ColumnTypes_t>
::value,
"");
107 fCallable(slot, std::forward<Args>(args)...);
114 std::string GetActionName() {
return "ForeachSlot"; }
117class R__CLING_PTRCHECK(off) CountHelper :
public RActionImpl<CountHelper> {
118 std::shared_ptr<ULong64_t> fResultCount;
119 Results<ULong64_t> fCounts;
123 CountHelper(
const std::shared_ptr<ULong64_t> &resultCount,
const unsigned int nSlots);
124 CountHelper(CountHelper &&) =
default;
125 CountHelper(
const CountHelper &) =
delete;
127 void Exec(
unsigned int slot);
134 return std::make_unique<RMergeableCount>(*fResultCount);
137 ULong64_t &PartialUpdate(
unsigned int slot);
139 std::string GetActionName() {
return "Count"; }
141 CountHelper MakeNew(
void *newResult, std::string_view =
"nominal")
143 auto &
result = *
static_cast<std::shared_ptr<ULong64_t> *
>(newResult);
144 return CountHelper(
result, fCounts.size());
148template <
typename RNode_t>
149class R__CLING_PTRCHECK(off) ReportHelper :
public RActionImpl<ReportHelper<RNode_t>> {
150 std::shared_ptr<RCutFlowReport> fReport;
154 bool fReturnEmptyReport;
158 ReportHelper(
const std::shared_ptr<RCutFlowReport> &report, RNode_t *node,
bool emptyRep)
159 : fReport(report), fNode(node), fReturnEmptyReport(emptyRep){};
160 ReportHelper(ReportHelper &&) =
default;
161 ReportHelper(
const ReportHelper &) =
delete;
163 void Exec(
unsigned int ) {}
167 if (!fReturnEmptyReport)
168 fNode->Report(*fReport);
173 auto cutinfo_vec = fReport->fCutInfos;
174 return std::make_unique<RMergeableReport>(*fReport, cutinfo_vec);
177 std::string GetActionName() {
return "Report"; }
179 ReportHelper MakeNew(
void *newResult, std::string_view variation =
"nominal")
181 auto &&
result = *
static_cast<std::shared_ptr<RCutFlowReport> *
>(newResult);
182 return ReportHelper{
result,
183 std::static_pointer_cast<RNode_t>(fNode->GetVariedFilter(std::string(variation))).get(),
195class R__CLING_PTRCHECK(off) BufferedFillHelper :
public RActionImpl<BufferedFillHelper> {
197 static constexpr unsigned int fgTotalBufSize = 2097152;
199 using Buf_t = std::vector<BufEl_t>;
201 std::vector<Buf_t> fBuffers;
202 std::vector<Buf_t> fWBuffers;
203 std::shared_ptr<Hist_t> fResultHist;
204 unsigned int fNSlots;
205 unsigned int fBufSize;
207 Results<std::unique_ptr<Hist_t>> fPartialHists;
211 void UpdateMinMax(
unsigned int slot,
double v);
214 BufferedFillHelper(
const std::shared_ptr<Hist_t> &
h,
const unsigned int nSlots);
215 BufferedFillHelper(BufferedFillHelper &&) =
default;
216 BufferedFillHelper(
const BufferedFillHelper &) =
delete;
218 void Exec(
unsigned int slot,
double v);
219 void Exec(
unsigned int slot,
double v,
double w);
221 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
222 void Exec(
unsigned int slot,
const T &vs)
224 auto &thisBuf = fBuffers[slot];
226 for (
auto v = vs.begin();
v != vs.end(); ++
v) {
227 UpdateMinMax(slot, *
v);
228 thisBuf.emplace_back(*
v);
232 template <typename T, typename W, std::enable_if_t<IsDataContainer<T>::value && IsDataContainer<W>::value,
int> = 0>
233 void Exec(
unsigned int slot,
const T &vs,
const W &ws)
235 auto &thisBuf = fBuffers[slot];
238 UpdateMinMax(slot,
v);
239 thisBuf.emplace_back(
v);
242 auto &thisWBuf = fWBuffers[slot];
244 thisWBuf.emplace_back(
w);
248 template <typename T, typename W, std::enable_if_t<IsDataContainer<T>::value && !IsDataContainer<W>::value,
int> = 0>
249 void Exec(
unsigned int slot,
const T &vs,
const W
w)
251 auto &thisBuf = fBuffers[slot];
253 UpdateMinMax(slot,
v);
254 thisBuf.emplace_back(
v);
257 auto &thisWBuf = fWBuffers[slot];
258 thisWBuf.insert(thisWBuf.end(), vs.size(),
w);
261 template <typename T, typename W, std::enable_if_t<IsDataContainer<W>::value && !IsDataContainer<T>::value,
int> = 0>
262 void Exec(
unsigned int slot,
const T
v,
const W &ws)
264 UpdateMinMax(slot,
v);
265 auto &thisBuf = fBuffers[slot];
266 thisBuf.insert(thisBuf.end(), ws.size(),
v);
268 auto &thisWBuf = fWBuffers[slot];
269 thisWBuf.insert(thisWBuf.end(), ws.begin(), ws.end());
272 Hist_t &PartialUpdate(
unsigned int);
281 return std::make_unique<RMergeableFill<Hist_t>>(*fResultHist);
284 std::string GetActionName()
286 return std::string(fResultHist->IsA()->GetName()) +
"\\n" + std::string(fResultHist->GetName());
289 BufferedFillHelper MakeNew(
void *newResult, std::string_view =
"nominal")
291 auto &
result = *
static_cast<std::shared_ptr<Hist_t> *
>(newResult);
293 result->SetDirectory(
nullptr);
294 return BufferedFillHelper(
result, fNSlots);
300class ScalarConstIterator {
304 using iterator_category = std::forward_iterator_tag;
305 using difference_type = std::ptrdiff_t;
306 using value_type = T;
308 using reference = T &;
309 ScalarConstIterator(
const T *obj) : obj_(obj) {}
310 const T &
operator*()
const {
return *obj_; }
311 ScalarConstIterator<T> &operator++() {
return *
this; }
316auto MakeBegin(
const T &val)
318 if constexpr (IsDataContainer<T>::value) {
319 return std::begin(val);
321 return ScalarConstIterator<T>(&val);
327std::size_t GetSize(
const T &val)
329 if constexpr (IsDataContainer<T>::value) {
330 return std::size(val);
337template <
typename Helper>
338class R__CLING_PTRCHECK(off) ExecLoopTrait {
340 template <
typename... Iterators>
341 void ExecLoop(
unsigned int slot, std::size_t elements, Iterators... its)
343 for (std::size_t i = 0; i < elements; i++) {
345 (std::advance(its, 1), ...);
350 template <
typename... ColumnTypes>
351 void Exec(
unsigned int slot,
const ColumnTypes &...columnValues)
353 if constexpr (std::disjunction_v<IsDataContainer<ColumnTypes>...>) {
354 constexpr std::array<
bool,
sizeof...(ColumnTypes)> isContainer{IsDataContainer<ColumnTypes>::value...};
355 constexpr std::size_t firstContainerIdx =
FindIdxTrue(isContainer);
356 std::array<std::size_t,
sizeof...(columnValues)> sizes = {{GetSize(columnValues)...}};
357 std::size_t elements = 0;
358 for (std::size_t i = 0; i < isContainer.size(); i++) {
359 if (isContainer[i]) {
360 if (i == firstContainerIdx) {
362 }
else if (elements != sizes[i]) {
363 throw std::runtime_error(
"Cannot fill values in containers of different sizes.");
367 ExecLoop(slot, elements, MakeBegin(columnValues)...);
369 static_cast<Helper *
>(
this)->ExecSingle(slot, columnValues...);
375template <typename H, typename = decltype(std::declval<H>().Reset())>
389template <
typename HIST = Hist_t>
390class R__CLING_PTRCHECK(off) FillHelper :
public RActionImpl<FillHelper<HIST>> {
391 std::vector<HIST *> fObjects;
394 template <typename H, typename = std::enable_if_t<std::is_base_of<TObject, H>::value,
int>>
395 auto Merge(std::vector<H *> &objs,
int )
396 ->
decltype(objs[0]->Merge((
TCollection *)
nullptr), void())
399 for (
auto it = ++objs.begin(); it != objs.end(); ++it)
405 template <
typename H>
406 auto Merge(std::vector<H *> &objs,
double )
407 ->
decltype(objs[0]->Merge(std::vector<HIST *>{}),
void())
409 objs[0]->Merge({++objs.begin(), objs.end()});
413 template <
typename T>
416 static_assert(
sizeof(T) < 0,
417 "The type passed to Fill does not provide a Merge(TCollection*) or Merge(const std::vector&) method.");
420 template <std::size_t ColIdx,
typename End_t,
typename... Its>
421 void ExecLoop(
unsigned int slot, End_t end, Its... its)
423 for (
auto *thisSlotH = fObjects[slot]; GetNthElement<ColIdx>(its...) != end; (std::advance(its, 1), ...)) {
424 thisSlotH->Fill(*its...);
429 FillHelper(FillHelper &&) =
default;
430 FillHelper(
const FillHelper &) =
delete;
432 FillHelper(
const std::shared_ptr<HIST> &
h,
const unsigned int nSlots) : fObjects(nSlots, nullptr)
434 fObjects[0] =
h.get();
436 for (
unsigned int i = 1; i < nSlots; ++i) {
437 fObjects[i] =
new HIST(*fObjects[0]);
445 template <
typename... ValTypes, std::enable_if_t<!std::disjunction<IsDataContainer<ValTypes>...>
::value,
int> = 0>
446 auto Exec(
unsigned int slot,
const ValTypes &...
x) ->
decltype(fObjects[slot]->Fill(
x...), void())
448 fObjects[slot]->Fill(
x...);
452 template <
typename... Xs, std::enable_if_t<std::disjunction<IsDataContainer<Xs>...>
::value,
int> = 0>
453 auto Exec(
unsigned int slot,
const Xs &...xs) ->
decltype(fObjects[slot]->Fill(*MakeBegin(xs)...), void())
456 constexpr std::array<
bool,
sizeof...(Xs)> isContainer{IsDataContainer<Xs>::value...};
459 constexpr std::size_t colidx =
FindIdxTrue(isContainer);
461 static_assert(colidx <
sizeof...(Xs),
"Error: index of collection-type argument not found.");
464 auto const xrefend = std::end(GetNthElement<colidx>(xs...));
467 std::array<std::size_t,
sizeof...(xs)> sizes = {{GetSize(xs)...}};
469 for (std::size_t i = 0; i <
sizeof...(xs); ++i) {
470 if (isContainer[i] && sizes[i] != sizes[colidx]) {
471 throw std::runtime_error(
"Cannot fill histogram with values in containers of different sizes.");
475 ExecLoop<colidx>(slot, xrefend, MakeBegin(xs)...);
478 template <
typename T = HIST>
481 static_assert(
sizeof(T) < 0,
482 "When filling an object with RDataFrame (e.g. via a Fill action) the number or types of the "
483 "columns passed did not match the signature of the object's `Fill` method.");
490 if (fObjects.size() == 1)
496 for (
auto it = ++fObjects.begin(); it != fObjects.end(); ++it)
500 HIST &PartialUpdate(
unsigned int slot) {
return *fObjects[slot]; }
505 return std::make_unique<RMergeableFill<HIST>>(*fObjects[0]);
509 template <typename T = HIST, std::enable_if_t<std::is_base_of<TObject, T>::value,
int> = 0>
510 std::string GetActionName()
512 return std::string(fObjects[0]->IsA()->
GetName()) +
"\\n" + std::string(fObjects[0]->
GetName());
516 template <typename T = HIST, std::enable_if_t<!std::is_base_of<TObject, T>::value,
int> = 0>
517 std::string GetActionName()
519 return "Fill custom object";
522 template <
typename H = HIST>
523 FillHelper MakeNew(
void *newResult, std::string_view =
"nominal")
525 auto &
result = *
static_cast<std::shared_ptr<H> *
>(newResult);
528 return FillHelper(
result, fObjects.size());
533template <
typename BinContentType,
bool WithWeight = false>
534class R__CLING_PTRCHECK(off) RHistFillHelper :
public RActionImpl<RHistFillHelper<BinContentType, WithWeight>>,
535 public ExecLoopTrait<RHistFillHelper<BinContentType, WithWeight>> {
540 std::unique_ptr<ROOT::Experimental::RHistConcurrentFiller<BinContentType>> fFiller;
541 std::vector<std::shared_ptr<ROOT::Experimental::RHistFillContext<BinContentType>>> fContexts;
545 : fFiller(new
ROOT::Experimental::RHistConcurrentFiller<BinContentType>(
h)), fContexts(nSlots)
547 for (
unsigned int i = 0; i < nSlots; i++) {
548 fContexts[i] = fFiller->CreateFillContext();
551 RHistFillHelper(
const RHistFillHelper &) =
delete;
552 RHistFillHelper(RHistFillHelper &&) =
default;
553 RHistFillHelper &operator=(
const RHistFillHelper &) =
delete;
554 RHistFillHelper &operator=(RHistFillHelper &&) =
default;
555 ~RHistFillHelper() =
default;
560 template <
typename... ColumnTypes,
const std::size_t... I>
562 ExecWithWeight(
unsigned int slot,
const std::tuple<const ColumnTypes &...> &columnValues, std::index_sequence<I...>)
565 std::tuple<
const std::tuple_element_t<I, std::tuple<ColumnTypes...>> &...> args(std::get<I>(columnValues)...);
567 fContexts[slot]->Fill(args, weight);
570 template <
typename... ColumnTypes>
571 void ExecSingle(
unsigned int slot,
const ColumnTypes &...columnValues)
573 if constexpr (WithWeight) {
574 auto t = std::forward_as_tuple(columnValues...);
575 ExecWithWeight(slot, t, std::make_index_sequence<
sizeof...(ColumnTypes) - 1>());
577 fContexts[slot]->Fill(columnValues...);
583 for (
auto &&context : fContexts) {
588 RHistFillHelper MakeNew(
void *newResult, std::string_view =
"nominal")
590 auto &
result = *
static_cast<std::shared_ptr<Result_t> *
>(newResult);
592 return RHistFillHelper(
result, fContexts.size());
595 std::string GetActionName() {
return "Hist"; }
598template <
typename BinContentType,
bool WithWeight = false>
599class R__CLING_PTRCHECK(off) RHistEngineFillHelper
600 :
public RActionImpl<RHistEngineFillHelper<BinContentType, WithWeight>>,
601 public ExecLoopTrait<RHistEngineFillHelper<BinContentType, WithWeight>> {
606 std::shared_ptr<Result_t> fHist;
610 RHistEngineFillHelper(
const RHistEngineFillHelper &) =
delete;
611 RHistEngineFillHelper(RHistEngineFillHelper &&) =
default;
612 RHistEngineFillHelper &operator=(
const RHistEngineFillHelper &) =
delete;
613 RHistEngineFillHelper &operator=(RHistEngineFillHelper &&) =
default;
614 ~RHistEngineFillHelper() =
default;
619 template <
typename... ColumnTypes,
const std::size_t... I>
620 void ExecWithWeight(
const std::tuple<const ColumnTypes &...> &columnValues, std::index_sequence<I...>)
623 std::tuple<
const std::tuple_element_t<I, std::tuple<ColumnTypes...>> &...> args(std::get<I>(columnValues)...);
625 fHist->FillAtomic(args, weight);
628 template <
typename... ColumnTypes>
629 void ExecSingle(
unsigned int,
const ColumnTypes &...columnValues)
631 if constexpr (WithWeight) {
632 auto t = std::forward_as_tuple(columnValues...);
633 ExecWithWeight(t, std::make_index_sequence<
sizeof...(ColumnTypes) - 1>());
635 fHist->FillAtomic(columnValues...);
641 RHistEngineFillHelper MakeNew(
void *newResult, std::string_view =
"nominal")
643 auto &
result = *
static_cast<std::shared_ptr<Result_t> *
>(newResult);
645 return RHistEngineFillHelper(
result);
648 std::string GetActionName() {
return "Hist"; }
651template <
bool WithWeight = false>
652class R__CLING_PTRCHECK(off) RProfileFillHelper :
public RActionImpl<RProfileFillHelper<WithWeight>>,
653 public ExecLoopTrait<RProfileFillHelper<WithWeight>> {
658 std::unique_ptr<ROOT::Experimental::RProfileConcurrentFiller> fFiller;
659 std::vector<std::shared_ptr<ROOT::Experimental::RProfileFillContext>> fContexts;
662 RProfileFillHelper(std::shared_ptr<ROOT::Experimental::RProfile>
p,
unsigned int nSlots)
663 : fFiller(new
ROOT::Experimental::RProfileConcurrentFiller(
p)), fContexts(nSlots)
665 for (
unsigned int i = 0; i < nSlots; i++) {
666 fContexts[i] = fFiller->CreateFillContext();
669 RProfileFillHelper(
const RProfileFillHelper &) =
delete;
670 RProfileFillHelper(RProfileFillHelper &&) =
default;
671 RProfileFillHelper &operator=(
const RProfileFillHelper &) =
delete;
672 RProfileFillHelper &operator=(RProfileFillHelper &&) =
default;
673 ~RProfileFillHelper() =
default;
678 template <
typename... ColumnTypes,
const std::size_t... I>
679 void ExecWithValueAndWeight(
unsigned int slot,
const std::tuple<const ColumnTypes &...> &columnValues,
680 std::index_sequence<I...>)
684 std::tuple<
const std::tuple_element_t<I, std::tuple<ColumnTypes...>> &...> args(std::get<I>(columnValues)...);
685 const auto &
value = std::get<
sizeof...(ColumnTypes) - 2>(columnValues);
687 fContexts[slot]->Fill(args,
value, weight);
690 template <
typename... ColumnTypes,
const std::size_t... I>
692 ExecWithValue(
unsigned int slot,
const std::tuple<const ColumnTypes &...> &columnValues, std::index_sequence<I...>)
695 std::tuple<
const std::tuple_element_t<I, std::tuple<ColumnTypes...>> &...> args(std::get<I>(columnValues)...);
696 const auto &
value = std::get<
sizeof...(ColumnTypes) - 1>(columnValues);
697 fContexts[slot]->Fill(args,
value);
700 template <
typename... ColumnTypes>
701 void ExecSingle(
unsigned int slot,
const ColumnTypes &...columnValues)
703 auto t = std::forward_as_tuple(columnValues...);
704 if constexpr (WithWeight) {
705 ExecWithValueAndWeight(slot, t, std::make_index_sequence<
sizeof...(ColumnTypes) - 2>());
707 ExecWithValue(slot, t, std::make_index_sequence<
sizeof...(ColumnTypes) - 1>());
713 for (
auto &&context : fContexts) {
718 RProfileFillHelper MakeNew(
void *newResult, std::string_view =
"nominal")
720 auto &
result = *
static_cast<std::shared_ptr<Result_t> *
>(newResult);
722 return RProfileFillHelper(
result, fContexts.size());
725 std::string GetActionName() {
return "Profile"; }
734 std::vector<::TGraph *> fGraphs;
737 FillTGraphHelper(FillTGraphHelper &&) =
default;
738 FillTGraphHelper(
const FillTGraphHelper &) =
delete;
740 FillTGraphHelper(
const std::shared_ptr<::TGraph> &
g,
const unsigned int nSlots) : fGraphs(nSlots, nullptr)
742 fGraphs[0] =
g.get();
744 for (
unsigned int i = 1; i < nSlots; ++i) {
745 fGraphs[i] =
new TGraph(*fGraphs[0]);
753 template <
typename X0,
typename X1,
754 std::enable_if_t<IsDataContainer<X0>::value && IsDataContainer<X1>::value,
int> = 0>
755 void Exec(
unsigned int slot,
const X0 &x0s,
const X1 &x1s)
757 if (x0s.size() != x1s.size()) {
758 throw std::runtime_error(
"Cannot fill Graph with values in containers of different sizes.");
760 auto *thisSlotG = fGraphs[slot];
761 auto x0sIt = std::begin(x0s);
762 const auto x0sEnd = std::end(x0s);
763 auto x1sIt = std::begin(x1s);
764 for (; x0sIt != x0sEnd; x0sIt++, x1sIt++) {
765 thisSlotG->SetPoint(thisSlotG->GetN(), *x0sIt, *x1sIt);
770 template <
typename X0,
typename X1,
771 std::enable_if_t<!IsDataContainer<X0>::value && !IsDataContainer<X1>::value,
int> = 0>
772 void Exec(
unsigned int slot, X0 x0, X1
x1)
774 auto thisSlotG = fGraphs[slot];
775 thisSlotG->SetPoint(thisSlotG->GetN(), x0,
x1);
780 template <
typename X0,
typename X1,
typename... ExtraArgsToLowerPriority>
781 void Exec(
unsigned int, X0, X1, ExtraArgsToLowerPriority...)
783 throw std::runtime_error(
"Graph was applied to a mix of scalar values and collections. This is not supported.");
788 const auto nSlots = fGraphs.size();
789 auto resGraph = fGraphs[0];
792 for (
unsigned int slot = 1; slot < nSlots; ++slot) {
793 l.Add(fGraphs[slot]);
801 return std::make_unique<RMergeableFill<Result_t>>(*fGraphs[0]);
804 std::string GetActionName() {
return "Graph"; }
806 Result_t &PartialUpdate(
unsigned int slot) {
return *fGraphs[slot]; }
808 FillTGraphHelper MakeNew(
void *newResult, std::string_view =
"nominal")
810 auto &
result = *
static_cast<std::shared_ptr<TGraph> *
>(newResult);
812 return FillTGraphHelper(
result, fGraphs.size());
816class R__CLING_PTRCHECK(off) FillTGraphAsymmErrorsHelper
822 std::vector<::TGraphAsymmErrors *> fGraphAsymmErrors;
825 FillTGraphAsymmErrorsHelper(FillTGraphAsymmErrorsHelper &&) =
default;
826 FillTGraphAsymmErrorsHelper(
const FillTGraphAsymmErrorsHelper &) =
delete;
828 FillTGraphAsymmErrorsHelper(
const std::shared_ptr<::TGraphAsymmErrors> &
g,
const unsigned int nSlots)
829 : fGraphAsymmErrors(nSlots, nullptr)
831 fGraphAsymmErrors[0] =
g.get();
833 for (
unsigned int i = 1; i < nSlots; ++i) {
843 typename X,
typename Y,
typename EXL,
typename EXH,
typename EYL,
typename EYH,
844 std::enable_if_t<IsDataContainer<X>::value && IsDataContainer<Y>::value && IsDataContainer<EXL>::value &&
845 IsDataContainer<EXH>::value && IsDataContainer<EYL>::value && IsDataContainer<EYH>::value,
848 Exec(
unsigned int slot,
const X &xs,
const Y &ys,
const EXL &exls,
const EXH &exhs,
const EYL &eyls,
const EYH &eyhs)
850 if ((xs.size() != ys.size()) || (xs.size() != exls.size()) || (xs.size() != exhs.size()) ||
851 (xs.size() != eyls.size()) || (xs.size() != eyhs.size())) {
852 throw std::runtime_error(
"Cannot fill GraphAsymmErrors with values in containers of different sizes.");
854 auto *thisSlotG = fGraphAsymmErrors[slot];
855 auto xsIt = std::begin(xs);
856 auto ysIt = std::begin(ys);
857 auto exlsIt = std::begin(exls);
858 auto exhsIt = std::begin(exhs);
859 auto eylsIt = std::begin(eyls);
860 auto eyhsIt = std::begin(eyhs);
861 while (xsIt != std::end(xs)) {
862 const auto n = thisSlotG->GetN();
863 thisSlotG->SetPoint(
n, *xsIt++, *ysIt++);
864 thisSlotG->SetPointError(
n, *exlsIt++, *exhsIt++, *eylsIt++, *eyhsIt++);
870 typename X,
typename Y,
typename EXL,
typename EXH,
typename EYL,
typename EYH,
871 std::enable_if_t<!IsDataContainer<X>::value && !IsDataContainer<Y>::value && !IsDataContainer<EXL>::value &&
872 !IsDataContainer<EXH>::value && !IsDataContainer<EYL>::value && !IsDataContainer<EYH>::value,
874 void Exec(
unsigned int slot,
X x, Y
y, EXL exl, EXH exh, EYL eyl, EYH eyh)
876 auto thisSlotG = fGraphAsymmErrors[slot];
877 const auto n = thisSlotG->GetN();
878 thisSlotG->SetPoint(
n,
x,
y);
879 thisSlotG->SetPointError(
n, exl, exh, eyl, eyh);
884 template <
typename X,
typename Y,
typename EXL,
typename EXH,
typename EYL,
typename EYH,
885 typename... ExtraArgsToLowerPriority>
886 void Exec(
unsigned int,
X, Y, EXL, EXH, EYL, EYH, ExtraArgsToLowerPriority...)
888 throw std::runtime_error(
889 "GraphAsymmErrors was applied to a mix of scalar values and collections. This is not supported.");
894 const auto nSlots = fGraphAsymmErrors.size();
895 auto resGraphAsymmErrors = fGraphAsymmErrors[0];
898 for (
unsigned int slot = 1; slot < nSlots; ++slot) {
899 l.Add(fGraphAsymmErrors[slot]);
901 resGraphAsymmErrors->Merge(&
l);
907 return std::make_unique<RMergeableFill<Result_t>>(*fGraphAsymmErrors[0]);
910 std::string GetActionName() {
return "GraphAsymmErrors"; }
912 Result_t &PartialUpdate(
unsigned int slot) {
return *fGraphAsymmErrors[slot]; }
914 FillTGraphAsymmErrorsHelper MakeNew(
void *newResult, std::string_view =
"nominal")
916 auto &
result = *
static_cast<std::shared_ptr<TGraphAsymmErrors> *
>(newResult);
918 return FillTGraphAsymmErrorsHelper(
result, fGraphAsymmErrors.size());
923template <
typename HIST>
924class R__CLING_PTRCHECK(off) ThreadSafeFillHelper :
public RActionImpl<ThreadSafeFillHelper<HIST>> {
925 std::vector<std::shared_ptr<HIST>> fObjects;
926 std::vector<std::unique_ptr<std::mutex>> fMutexPtrs;
929 template <
typename T,
typename... Args>
930 auto TryCallFillThreadSafe(T &
object, std::mutex &,
int , Args... args)
936 template <
typename T,
typename... Args>
937 auto TryCallFillThreadSafe(T &
object, std::mutex &mutex,
char , Args... args)
939 std::scoped_lock lock{mutex};
940 object.Fill(args...);
943 template <std::size_t ColIdx,
typename End_t,
typename... Its>
944 void ExecLoop(
unsigned int slot, End_t end, Its... its)
946 const auto localSlot = slot % fObjects.size();
947 for (; GetNthElement<ColIdx>(its...) != end; (std::advance(its, 1), ...)) {
948 TryCallFillThreadSafe(*fObjects[localSlot], *fMutexPtrs[localSlot], 0, *its...);
953 ThreadSafeFillHelper(ThreadSafeFillHelper &&) =
default;
954 ThreadSafeFillHelper(
const ThreadSafeFillHelper &) =
delete;
956 ThreadSafeFillHelper(
const std::shared_ptr<HIST> &
h,
const unsigned int nSlots)
958 fObjects.resize(nSlots);
959 fObjects.front() =
h;
961 std::generate(fObjects.begin() + 1, fObjects.end(), [
h]() {
962 auto hist = std::make_shared<HIST>(*h);
963 UnsetDirectoryIfPossible(hist.get());
966 fMutexPtrs.resize(nSlots);
967 std::generate(fMutexPtrs.begin(), fMutexPtrs.end(), []() { return std::make_unique<std::mutex>(); });
973 template <
typename... ValTypes, std::enable_if_t<!std::disjunction<IsDataContainer<ValTypes>...>
::value,
int> = 0>
974 void Exec(
unsigned int slot,
const ValTypes &...
x)
976 const auto localSlot = slot % fObjects.size();
977 TryCallFillThreadSafe(*fObjects[localSlot], *fMutexPtrs[localSlot], 0,
x...);
981 template <
typename... Xs, std::enable_if_t<std::disjunction<IsDataContainer<Xs>...>
::value,
int> = 0>
982 void Exec(
unsigned int slot,
const Xs &...xs)
985 constexpr std::array<
bool,
sizeof...(Xs)> isContainer{IsDataContainer<Xs>::value...};
988 constexpr std::size_t colidx =
FindIdxTrue(isContainer);
990 static_assert(colidx <
sizeof...(Xs),
"Error: index of collection-type argument not found.");
993 auto const xrefend = std::end(GetNthElement<colidx>(xs...));
996 std::array<std::size_t,
sizeof...(xs)> sizes = {{GetSize(xs)...}};
998 for (std::size_t i = 0; i <
sizeof...(xs); ++i) {
999 if (isContainer[i] && sizes[i] != sizes[colidx]) {
1000 throw std::runtime_error(
"Cannot fill histogram with values in containers of different sizes.");
1004 ExecLoop<colidx>(slot, xrefend, MakeBegin(xs)...);
1007 template <
typename T = HIST>
1010 static_assert(
sizeof(T) < 0,
1011 "When filling an object with RDataFrame (e.g. via a Fill action) the number or types of the "
1012 "columns passed did not match the signature of the object's `FillThreadSafe` method.");
1019 if (fObjects.size() > 1) {
1021 for (
auto it = fObjects.cbegin() + 1; it != fObjects.end(); ++it) {
1022 list.
Add(it->get());
1024 fObjects[0]->Merge(&list);
1034 return std::make_unique<RMergeableFill<HIST>>(*fObjects[0]);
1038 template <typename T = HIST, std::enable_if_t<std::is_base_of<TObject, T>::value,
int> = 0>
1039 std::string GetActionName()
1041 return std::string(fObjects[0]->IsA()->
GetName()) +
"\\n" + std::string(fObjects[0]->
GetName());
1044 template <
typename H = HIST>
1045 ThreadSafeFillHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1047 auto &
result = *
static_cast<std::shared_ptr<H> *
>(newResult);
1050 return ThreadSafeFillHelper(
result, fObjects.size());
1060template <
typename V,
typename COLL>
1061void FillColl(V&&
v, COLL&
c) {
1066template <
typename COLL>
1067void FillColl(
bool v, COLL&
c) {
1073template <
typename RealT_t,
typename T,
typename COLL>
1074class R__CLING_PTRCHECK(off) TakeHelper :
public RActionImpl<TakeHelper<RealT_t, T, COLL>> {
1075 Results<std::shared_ptr<COLL>> fColls;
1079 TakeHelper(
const std::shared_ptr<COLL> &resultColl,
const unsigned int nSlots)
1081 fColls.emplace_back(resultColl);
1082 for (
unsigned int i = 1; i < nSlots; ++i)
1083 fColls.emplace_back(std::make_shared<COLL>());
1085 TakeHelper(TakeHelper &&);
1086 TakeHelper(
const TakeHelper &) =
delete;
1090 void Exec(
unsigned int slot, T &
v) { FillColl(
v, *fColls[slot]); }
1096 auto rColl = fColls[0];
1097 for (
unsigned int i = 1; i < fColls.size(); ++i) {
1098 const auto &coll = fColls[i];
1099 const auto end = coll->end();
1102 for (
auto j = coll->begin(); j != end; j++) {
1103 FillColl(*j, *rColl);
1108 COLL &PartialUpdate(
unsigned int slot) {
return *fColls[slot].get(); }
1110 std::string GetActionName() {
return "Take"; }
1112 TakeHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1114 auto &
result = *
static_cast<std::shared_ptr<COLL> *
>(newResult);
1116 return TakeHelper(
result, fColls.size());
1122template <
typename RealT_t,
typename T>
1123class R__CLING_PTRCHECK(off) TakeHelper<RealT_t, T, std::vector<T>>
1124 :
public RActionImpl<TakeHelper<RealT_t, T, std::vector<T>>> {
1125 Results<std::shared_ptr<std::vector<T>>> fColls;
1129 TakeHelper(
const std::shared_ptr<std::vector<T>> &resultColl,
const unsigned int nSlots)
1131 fColls.emplace_back(resultColl);
1132 for (
unsigned int i = 1; i < nSlots; ++i) {
1133 auto v = std::make_shared<std::vector<T>>();
1135 fColls.emplace_back(
v);
1138 TakeHelper(TakeHelper &&);
1139 TakeHelper(
const TakeHelper &) =
delete;
1143 void Exec(
unsigned int slot, T &
v) { FillColl(
v, *fColls[slot]); }
1151 for (
auto &coll : fColls)
1152 totSize += coll->
size();
1153 auto rColl = fColls[0];
1154 rColl->reserve(totSize);
1155 for (
unsigned int i = 1; i < fColls.size(); ++i) {
1156 auto &coll = fColls[i];
1157 rColl->insert(rColl->end(), coll->begin(), coll->end());
1161 std::vector<T> &PartialUpdate(
unsigned int slot) {
return *fColls[slot]; }
1163 std::string GetActionName() {
return "Take"; }
1165 TakeHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1167 auto &
result = *
static_cast<std::shared_ptr<std::vector<T>
> *>(newResult);
1169 return TakeHelper(
result, fColls.size());
1175template <
typename RealT_t,
typename COLL>
1176class R__CLING_PTRCHECK(off) TakeHelper<RealT_t,
RVec<RealT_t>, COLL>
1177 :
public RActionImpl<TakeHelper<RealT_t, RVec<RealT_t>, COLL>> {
1178 Results<std::shared_ptr<COLL>> fColls;
1182 TakeHelper(
const std::shared_ptr<COLL> &resultColl,
const unsigned int nSlots)
1184 fColls.emplace_back(resultColl);
1185 for (
unsigned int i = 1; i < nSlots; ++i)
1186 fColls.emplace_back(std::make_shared<COLL>());
1188 TakeHelper(TakeHelper &&);
1189 TakeHelper(
const TakeHelper &) =
delete;
1199 auto rColl = fColls[0];
1200 for (
unsigned int i = 1; i < fColls.size(); ++i) {
1201 auto &coll = fColls[i];
1202 for (
auto &
v : *coll) {
1203 rColl->emplace_back(
v);
1208 std::string GetActionName() {
return "Take"; }
1210 TakeHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1212 auto &
result = *
static_cast<std::shared_ptr<COLL> *
>(newResult);
1214 return TakeHelper(
result, fColls.size());
1220template <
typename RealT_t>
1221class R__CLING_PTRCHECK(off) TakeHelper<RealT_t,
RVec<RealT_t>, std::vector<RealT_t>>
1222 :
public RActionImpl<TakeHelper<RealT_t, RVec<RealT_t>, std::vector<RealT_t>>> {
1224 Results<std::shared_ptr<std::vector<std::vector<RealT_t>>>> fColls;
1228 TakeHelper(
const std::shared_ptr<std::vector<std::vector<RealT_t>>> &resultColl,
const unsigned int nSlots)
1230 fColls.emplace_back(resultColl);
1231 for (
unsigned int i = 1; i < nSlots; ++i) {
1232 auto v = std::make_shared<std::vector<RealT_t>>();
1234 fColls.emplace_back(
v);
1237 TakeHelper(TakeHelper &&);
1238 TakeHelper(
const TakeHelper &) =
delete;
1250 for (
auto &coll : fColls)
1251 totSize += coll->
size();
1252 auto rColl = fColls[0];
1253 rColl->reserve(totSize);
1254 for (
unsigned int i = 1; i < fColls.size(); ++i) {
1255 auto &coll = fColls[i];
1256 rColl->insert(rColl->end(), coll->begin(), coll->end());
1260 std::string GetActionName() {
return "Take"; }
1262 TakeHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1264 auto &
result = *
static_cast<typename decltype(fColls)::value_type *
>(newResult);
1266 return TakeHelper(
result, fColls.size());
1273template <
typename RealT_t,
typename T,
typename COLL>
1274TakeHelper<RealT_t, T, COLL>::TakeHelper(TakeHelper<RealT_t, T, COLL> &&) =
default;
1275template <
typename RealT_t,
typename T>
1276TakeHelper<RealT_t, T, std::vector<T>>::TakeHelper(TakeHelper<RealT_t, T, std::vector<T>> &&) =
default;
1277template <
typename RealT_t,
typename COLL>
1278TakeHelper<RealT_t, RVec<RealT_t>, COLL>::TakeHelper(TakeHelper<RealT_t,
RVec<RealT_t>, COLL> &&) =
default;
1279template <
typename RealT_t>
1280TakeHelper<RealT_t, RVec<RealT_t>, std::vector<RealT_t>>::TakeHelper(TakeHelper<RealT_t,
RVec<RealT_t>, std::vector<RealT_t>> &&) =
default;
1284extern template class TakeHelper<bool, bool, std::vector<bool>>;
1285extern template class TakeHelper<unsigned int, unsigned int, std::vector<unsigned int>>;
1286extern template class TakeHelper<unsigned long, unsigned long, std::vector<unsigned long>>;
1287extern template class TakeHelper<unsigned long long, unsigned long long, std::vector<unsigned long long>>;
1288extern template class TakeHelper<int, int, std::vector<int>>;
1289extern template class TakeHelper<long, long, std::vector<long>>;
1290extern template class TakeHelper<long long, long long, std::vector<long long>>;
1291extern template class TakeHelper<float, float, std::vector<float>>;
1292extern template class TakeHelper<double, double, std::vector<double>>;
1295template <
typename ResultType>
1296class R__CLING_PTRCHECK(off) MinHelper :
public RActionImpl<MinHelper<ResultType>> {
1297 std::shared_ptr<ResultType> fResultMin;
1298 Results<ResultType> fMins;
1301 MinHelper(MinHelper &&) =
default;
1302 MinHelper(
const std::shared_ptr<ResultType> &minVPtr,
const unsigned int nSlots)
1303 : fResultMin(minVPtr), fMins(nSlots, std::numeric_limits<ResultType>::max())
1307 void Exec(
unsigned int slot, ResultType
v) { fMins[slot] = std::min(
v, fMins[slot]); }
1311 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
1312 void Exec(
unsigned int slot,
const T &vs)
1315 fMins[slot] = std::min(static_cast<ResultType>(
v), fMins[slot]);
1322 *fResultMin = std::numeric_limits<ResultType>::max();
1323 for (
auto &
m : fMins)
1324 *fResultMin = std::min(
m, *fResultMin);
1330 return std::make_unique<RMergeableMin<ResultType>>(*fResultMin);
1333 ResultType &PartialUpdate(
unsigned int slot) {
return fMins[slot]; }
1335 std::string GetActionName() {
return "Min"; }
1337 MinHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1339 auto &
result = *
static_cast<std::shared_ptr<ResultType> *
>(newResult);
1340 return MinHelper(
result, fMins.size());
1344template <
typename ResultType>
1345class R__CLING_PTRCHECK(off) MaxHelper :
public RActionImpl<MaxHelper<ResultType>> {
1346 std::shared_ptr<ResultType> fResultMax;
1347 Results<ResultType> fMaxs;
1350 MaxHelper(MaxHelper &&) =
default;
1351 MaxHelper(
const MaxHelper &) =
delete;
1352 MaxHelper(
const std::shared_ptr<ResultType> &maxVPtr,
const unsigned int nSlots)
1353 : fResultMax(maxVPtr), fMaxs(nSlots, std::numeric_limits<ResultType>::lowest())
1358 void Exec(
unsigned int slot, ResultType
v) { fMaxs[slot] = std::max(
v, fMaxs[slot]); }
1360 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
1361 void Exec(
unsigned int slot,
const T &vs)
1364 fMaxs[slot] = std::max(static_cast<ResultType>(
v), fMaxs[slot]);
1371 *fResultMax = std::numeric_limits<ResultType>::lowest();
1372 for (
auto &
m : fMaxs) {
1373 *fResultMax = std::max(
m, *fResultMax);
1380 return std::make_unique<RMergeableMax<ResultType>>(*fResultMax);
1383 ResultType &PartialUpdate(
unsigned int slot) {
return fMaxs[slot]; }
1385 std::string GetActionName() {
return "Max"; }
1387 MaxHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1389 auto &
result = *
static_cast<std::shared_ptr<ResultType> *
>(newResult);
1390 return MaxHelper(
result, fMaxs.size());
1394template <
typename ResultType>
1395class R__CLING_PTRCHECK(off) SumHelper :
public RActionImpl<SumHelper<ResultType>> {
1396 std::shared_ptr<ResultType> fResultSum;
1397 Results<ResultType> fSums;
1398 Results<ResultType> fCompensations;
1403 template <
typename T = ResultType>
1404 auto NeutralElement(
const T &
v,
int ) ->
decltype(
v -
v)
1409 template <
typename T = ResultType,
typename Dummy =
int>
1410 ResultType NeutralElement(
const T &, Dummy)
1412 return ResultType{};
1416 SumHelper(SumHelper &&) =
default;
1417 SumHelper(
const SumHelper &) =
delete;
1418 SumHelper(
const std::shared_ptr<ResultType> &sumVPtr,
const unsigned int nSlots)
1419 : fResultSum(sumVPtr), fSums(nSlots, NeutralElement(*sumVPtr, -1)),
1420 fCompensations(nSlots, NeutralElement(*sumVPtr, -1))
1425 void Exec(
unsigned int slot, ResultType
x)
1428 ResultType
y =
x - fCompensations[slot];
1429 ResultType t = fSums[slot] +
y;
1430 fCompensations[slot] = (t - fSums[slot]) -
y;
1434 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
1435 void Exec(
unsigned int slot,
const T &vs)
1437 for (
auto &&
v : vs) {
1446 ResultType
sum(NeutralElement(ResultType{}, -1));
1447 ResultType compensation(NeutralElement(ResultType{}, -1));
1448 ResultType
y(NeutralElement(ResultType{}, -1));
1449 ResultType t(NeutralElement(ResultType{}, -1));
1450 for (
auto &
m : fSums) {
1452 y =
m - compensation;
1454 compensation = (t -
sum) -
y;
1463 return std::make_unique<RMergeableSum<ResultType>>(*fResultSum);
1466 ResultType &PartialUpdate(
unsigned int slot) {
return fSums[slot]; }
1468 std::string GetActionName() {
return "Sum"; }
1470 SumHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1472 auto &
result = *
static_cast<std::shared_ptr<ResultType> *
>(newResult);
1474 return SumHelper(
result, fSums.size());
1478class R__CLING_PTRCHECK(off) MeanHelper :
public RActionImpl<MeanHelper> {
1479 std::shared_ptr<double> fResultMean;
1480 std::vector<ULong64_t> fCounts;
1481 std::vector<double> fSums;
1482 std::vector<double> fPartialMeans;
1483 std::vector<double> fCompensations;
1486 MeanHelper(
const std::shared_ptr<double> &meanVPtr,
const unsigned int nSlots);
1487 MeanHelper(MeanHelper &&) =
default;
1488 MeanHelper(
const MeanHelper &) =
delete;
1490 void Exec(
unsigned int slot,
double v);
1492 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
1493 void Exec(
unsigned int slot,
const T &vs)
1495 for (
auto &&
v : vs) {
1499 double y =
v - fCompensations[slot];
1500 double t = fSums[slot] +
y;
1501 fCompensations[slot] = (t - fSums[slot]) -
y;
1513 const ULong64_t counts = std::accumulate(fCounts.begin(), fCounts.end(), 0ull);
1514 return std::make_unique<RMergeableMean>(*fResultMean, counts);
1517 double &PartialUpdate(
unsigned int slot);
1519 std::string GetActionName() {
return "Mean"; }
1521 MeanHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1523 auto &
result = *
static_cast<std::shared_ptr<double> *
>(newResult);
1524 return MeanHelper(
result, fSums.size());
1528class R__CLING_PTRCHECK(off) StdDevHelper :
public RActionImpl<StdDevHelper> {
1530 unsigned int fNSlots;
1531 std::shared_ptr<double> fResultStdDev;
1533 std::vector<ULong64_t> fCounts;
1535 std::vector<double> fMeans;
1537 std::vector<double> fDistancesfromMean;
1540 StdDevHelper(
const std::shared_ptr<double> &meanVPtr,
const unsigned int nSlots);
1541 StdDevHelper(StdDevHelper &&) =
default;
1542 StdDevHelper(
const StdDevHelper &) =
delete;
1544 void Exec(
unsigned int slot,
double v);
1546 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
1547 void Exec(
unsigned int slot,
const T &vs)
1549 for (
auto &&
v : vs) {
1561 const ULong64_t counts = std::accumulate(fCounts.begin(), fCounts.end(), 0ull);
1563 std::inner_product(fMeans.begin(), fMeans.end(), fCounts.begin(), 0.) /
static_cast<Double_t>(counts);
1564 return std::make_unique<RMergeableStdDev>(*fResultStdDev, counts, mean);
1567 std::string GetActionName() {
return "StdDev"; }
1569 StdDevHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1571 auto &
result = *
static_cast<std::shared_ptr<double> *
>(newResult);
1572 return StdDevHelper(
result, fCounts.size());
1576class R__CLING_PTRCHECK(off) MedianHelper :
public RActionImpl<MedianHelper> {
1577 std::shared_ptr<double> fResult;
1578 std::vector<std::vector<double>> fBuffers;
1581 MedianHelper(
const std::shared_ptr<double> &meanVPtr,
const unsigned int nSlots);
1582 MedianHelper(MedianHelper &&) =
default;
1583 MedianHelper &operator=(MedianHelper &&) =
default;
1584 MedianHelper(
const MedianHelper &) =
delete;
1585 MedianHelper &operator=(
const MedianHelper &other) =
delete;
1588 void Exec(
unsigned int slot,
double v);
1590 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
1591 void Exec(
unsigned int slot,
const T &vs)
1593 fBuffers[slot].insert(fBuffers[slot].end(), std::begin(vs), std::end(vs));
1600 std::string GetActionName() {
return "Median"; }
1602 MedianHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1604 auto &
result = *
static_cast<std::shared_ptr<double> *
>(newResult);
1605 return MedianHelper(
result, fBuffers.size());
1608 ~MedianHelper() =
default;
1611template <
typename PrevNodeType>
1612class R__CLING_PTRCHECK(off) DisplayHelper :
public RActionImpl<DisplayHelper<PrevNodeType>> {
1615 std::shared_ptr<Display_t> fDisplayerHelper;
1616 std::shared_ptr<PrevNodeType> fPrevNode;
1617 size_t fEntriesToProcess;
1620 DisplayHelper(
size_t nRows,
const std::shared_ptr<Display_t> &
d,
const std::shared_ptr<PrevNodeType> &prevNode)
1621 : fDisplayerHelper(
d), fPrevNode(prevNode), fEntriesToProcess(nRows)
1624 DisplayHelper(DisplayHelper &&) =
default;
1625 DisplayHelper(
const DisplayHelper &) =
delete;
1628 template <
typename...
Columns>
1629 void Exec(
unsigned int, Columns &... columns)
1631 if (fEntriesToProcess == 0)
1634 fDisplayerHelper->AddRow(columns...);
1635 --fEntriesToProcess;
1637 if (fEntriesToProcess == 0) {
1642 fPrevNode->StopProcessing();
1650 std::string GetActionName() {
return "Display"; }
1653template <
typename Acc,
typename Merge,
typename R,
typename T,
typename U,
1654 bool MustCopyAssign = std::is_same<R, U>::value>
1655class R__CLING_PTRCHECK(off) AggregateHelper
1656 :
public RActionImpl<AggregateHelper<Acc, Merge, R, T, U, MustCopyAssign>> {
1659 std::shared_ptr<U> fResult;
1660 Results<U> fAggregators;
1665 AggregateHelper(Acc &&
f, Merge &&
m,
const std::shared_ptr<U> &
result,
const unsigned int nSlots)
1666 : fAggregate(std::move(
f)), fMerge(std::move(
m)), fResult(
result), fAggregators(nSlots, *
result)
1670 AggregateHelper(Acc &
f, Merge &
m,
const std::shared_ptr<U> &
result,
const unsigned int nSlots)
1671 : fAggregate(
f), fMerge(
m), fResult(
result), fAggregators(nSlots, *
result)
1675 AggregateHelper(AggregateHelper &&) =
default;
1676 AggregateHelper(
const AggregateHelper &) =
delete;
1680 template <
bool MustCopyAssign_ = MustCopyAssign, std::enable_if_t<MustCopyAssign_,
int> = 0>
1681 void Exec(
unsigned int slot,
const T &
value)
1683 fAggregators[slot] = fAggregate(fAggregators[slot],
value);
1686 template <
bool MustCopyAssign_ = MustCopyAssign, std::enable_if_t<!MustCopyAssign_,
int> = 0>
1687 void Exec(
unsigned int slot,
const T &
value)
1689 fAggregate(fAggregators[slot],
value);
1694 template <typename MergeRet = typename CallableTraits<Merge>::ret_type,
1695 bool MergeAll = std::is_same<void, MergeRet>::value>
1696 std::enable_if_t<MergeAll, void> Finalize()
1698 fMerge(fAggregators);
1699 *fResult = fAggregators[0];
1702 template <typename MergeRet = typename CallableTraits<Merge>::ret_type,
1703 bool MergeTwoByTwo = std::is_same<U, MergeRet>::value>
1704 std::enable_if_t<MergeTwoByTwo, void> Finalize(...)
1706 for (
const auto &acc : fAggregators)
1707 *fResult = fMerge(*fResult, acc);
1710 U &PartialUpdate(
unsigned int slot) {
return fAggregators[slot]; }
1712 std::string GetActionName() {
return "Aggregate"; }
1714 AggregateHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1716 auto &
result = *
static_cast<std::shared_ptr<U> *
>(newResult);
1717 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
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.
winID h TVirtualViewer3D TVirtualGLPainter p
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)
Base class for action helpers, see RInterface::Book() for more information.
A histogram data structure to bin data along multiple dimensions.
A histogram for aggregation of data along multiple dimensions.
A profile histogram, computing statistical quantities of an additional variable per bin.
iterator begin() noexcept
This class is the textual representation of the content of a columnar dataset.
typename RemoveFirstParameter< T >::type RemoveFirstParameter_t
A "std::vector"-like collection of values implementing handy operation to analyse them.
Collection abstract base class.
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.
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)
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)
auto FillThreadSafe(T &histo, Args... args) -> decltype(histo.FillThreadSafe(args...), void())
Entrypoint for thread-safe filling from RDataFrame.
ROOT type_traits extensions.
void Initialize(Bool_t useTMVAStyle=kTRUE)
CPYRT_EXTERN bool Exec(const std::string &cmd)
std::string GetName(TCppScope_t)
A weight for filling histograms.
Lightweight storage for a collection of types.
static uint64_t sum(uint64_t i)