18#ifndef ROOT_RDFOPERATIONS
19#define ROOT_RDFOPERATIONS
37#include "RConfigure.h"
84using Results = std::conditional_t<std::is_same<T, bool>::value, std::deque<T>, std::vector<T>>;
87class R__CLING_PTRCHECK(off) ForeachSlotHelper :
public RActionImpl<ForeachSlotHelper<F>> {
93 ForeachSlotHelper(ForeachSlotHelper &&) =
default;
94 ForeachSlotHelper(
const ForeachSlotHelper &) =
delete;
98 template <
typename... Args>
99 void Exec(
unsigned int slot, Args &&... args)
102 static_assert(std::is_same<TypeList<std::decay_t<Args>...>, ColumnTypes_t>
::value,
"");
103 fCallable(slot, std::forward<Args>(args)...);
110 std::string GetActionName() {
return "ForeachSlot"; }
113class R__CLING_PTRCHECK(off) CountHelper :
public RActionImpl<CountHelper> {
114 std::shared_ptr<ULong64_t> fResultCount;
115 Results<ULong64_t> fCounts;
119 CountHelper(
const std::shared_ptr<ULong64_t> &resultCount,
const unsigned int nSlots);
120 CountHelper(CountHelper &&) =
default;
121 CountHelper(
const CountHelper &) =
delete;
123 void Exec(
unsigned int slot);
130 return std::make_unique<RMergeableCount>(*fResultCount);
133 ULong64_t &PartialUpdate(
unsigned int slot);
135 std::string GetActionName() {
return "Count"; }
137 CountHelper MakeNew(
void *newResult, std::string_view =
"nominal")
139 auto &
result = *
static_cast<std::shared_ptr<ULong64_t> *
>(newResult);
140 return CountHelper(
result, fCounts.size());
144template <
typename RNode_t>
145class R__CLING_PTRCHECK(off) ReportHelper :
public RActionImpl<ReportHelper<RNode_t>> {
146 std::shared_ptr<RCutFlowReport> fReport;
150 bool fReturnEmptyReport;
154 ReportHelper(
const std::shared_ptr<RCutFlowReport> &report, RNode_t *node,
bool emptyRep)
155 : fReport(report), fNode(node), fReturnEmptyReport(emptyRep){};
156 ReportHelper(ReportHelper &&) =
default;
157 ReportHelper(
const ReportHelper &) =
delete;
159 void Exec(
unsigned int ) {}
163 if (!fReturnEmptyReport)
164 fNode->Report(*fReport);
169 auto cutinfo_vec = fReport->fCutInfos;
170 return std::make_unique<RMergeableReport>(*fReport, cutinfo_vec);
173 std::string GetActionName() {
return "Report"; }
175 ReportHelper MakeNew(
void *newResult, std::string_view variation =
"nominal")
177 auto &&
result = *
static_cast<std::shared_ptr<RCutFlowReport> *
>(newResult);
178 return ReportHelper{
result,
179 std::static_pointer_cast<RNode_t>(fNode->GetVariedFilter(std::string(variation))).get(),
191class R__CLING_PTRCHECK(off) BufferedFillHelper :
public RActionImpl<BufferedFillHelper> {
193 static constexpr unsigned int fgTotalBufSize = 2097152;
195 using Buf_t = std::vector<BufEl_t>;
197 std::vector<Buf_t> fBuffers;
198 std::vector<Buf_t> fWBuffers;
199 std::shared_ptr<Hist_t> fResultHist;
200 unsigned int fNSlots;
201 unsigned int fBufSize;
203 Results<std::unique_ptr<Hist_t>> fPartialHists;
207 void UpdateMinMax(
unsigned int slot,
double v);
210 BufferedFillHelper(
const std::shared_ptr<Hist_t> &
h,
const unsigned int nSlots);
211 BufferedFillHelper(BufferedFillHelper &&) =
default;
212 BufferedFillHelper(
const BufferedFillHelper &) =
delete;
214 void Exec(
unsigned int slot,
double v);
215 void Exec(
unsigned int slot,
double v,
double w);
217 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
218 void Exec(
unsigned int slot,
const T &vs)
220 auto &thisBuf = fBuffers[slot];
222 for (
auto v = vs.begin();
v != vs.end(); ++
v) {
223 UpdateMinMax(slot, *
v);
224 thisBuf.emplace_back(*
v);
228 template <typename T, typename W, std::enable_if_t<IsDataContainer<T>::value && IsDataContainer<W>::value,
int> = 0>
229 void Exec(
unsigned int slot,
const T &vs,
const W &ws)
231 auto &thisBuf = fBuffers[slot];
234 UpdateMinMax(slot,
v);
235 thisBuf.emplace_back(
v);
238 auto &thisWBuf = fWBuffers[slot];
240 thisWBuf.emplace_back(
w);
244 template <typename T, typename W, std::enable_if_t<IsDataContainer<T>::value && !IsDataContainer<W>::value,
int> = 0>
245 void Exec(
unsigned int slot,
const T &vs,
const W
w)
247 auto &thisBuf = fBuffers[slot];
249 UpdateMinMax(slot,
v);
250 thisBuf.emplace_back(
v);
253 auto &thisWBuf = fWBuffers[slot];
254 thisWBuf.insert(thisWBuf.end(), vs.size(),
w);
257 template <typename T, typename W, std::enable_if_t<IsDataContainer<W>::value && !IsDataContainer<T>::value,
int> = 0>
258 void Exec(
unsigned int slot,
const T
v,
const W &ws)
260 UpdateMinMax(slot,
v);
261 auto &thisBuf = fBuffers[slot];
262 thisBuf.insert(thisBuf.end(), ws.size(),
v);
264 auto &thisWBuf = fWBuffers[slot];
265 thisWBuf.insert(thisWBuf.end(), ws.begin(), ws.end());
268 Hist_t &PartialUpdate(
unsigned int);
277 return std::make_unique<RMergeableFill<Hist_t>>(*fResultHist);
280 std::string GetActionName()
282 return std::string(fResultHist->IsA()->GetName()) +
"\\n" + std::string(fResultHist->GetName());
285 BufferedFillHelper MakeNew(
void *newResult, std::string_view =
"nominal")
287 auto &
result = *
static_cast<std::shared_ptr<Hist_t> *
>(newResult);
289 result->SetDirectory(
nullptr);
290 return BufferedFillHelper(
result, fNSlots);
296class ScalarConstIterator {
300 using iterator_category = std::forward_iterator_tag;
301 using difference_type = std::ptrdiff_t;
302 using value_type = T;
304 using reference = T &;
305 ScalarConstIterator(
const T *obj) : obj_(obj) {}
306 const T &
operator*()
const {
return *obj_; }
307 ScalarConstIterator<T> &operator++() {
return *
this; }
312auto MakeBegin(
const T &val)
314 if constexpr (IsDataContainer<T>::value) {
315 return std::begin(val);
317 return ScalarConstIterator<T>(&val);
323std::size_t GetSize(
const T &val)
325 if constexpr (IsDataContainer<T>::value) {
326 return std::size(val);
333template <
typename Helper>
334class R__CLING_PTRCHECK(off) ExecLoopTrait {
336 template <
typename... Iterators>
337 void ExecLoop(
unsigned int slot, std::size_t elements, Iterators... its)
339 for (std::size_t i = 0; i < elements; i++) {
341 (std::advance(its, 1), ...);
346 template <
typename... ColumnTypes>
347 void Exec(
unsigned int slot,
const ColumnTypes &...columnValues)
349 if constexpr (std::disjunction_v<IsDataContainer<ColumnTypes>...>) {
350 constexpr std::array<
bool,
sizeof...(ColumnTypes)> isContainer{IsDataContainer<ColumnTypes>::value...};
351 constexpr std::size_t firstContainerIdx =
FindIdxTrue(isContainer);
352 std::array<std::size_t,
sizeof...(columnValues)> sizes = {{GetSize(columnValues)...}};
353 std::size_t elements = 0;
354 for (std::size_t i = 0; i < isContainer.size(); i++) {
355 if (isContainer[i]) {
356 if (i == firstContainerIdx) {
358 }
else if (elements != sizes[i]) {
359 throw std::runtime_error(
"Cannot fill values in containers of different sizes.");
363 ExecLoop(slot, elements, MakeBegin(columnValues)...);
365 static_cast<Helper *
>(
this)->ExecSingle(slot, columnValues...);
371template <typename H, typename = decltype(std::declval<H>().Reset())>
385template <
typename HIST = Hist_t>
386class R__CLING_PTRCHECK(off) FillHelper :
public RActionImpl<FillHelper<HIST>> {
387 std::vector<HIST *> fObjects;
390 template <typename H, typename = std::enable_if_t<std::is_base_of<TObject, H>::value,
int>>
391 auto Merge(std::vector<H *> &objs,
int )
392 ->
decltype(objs[0]->Merge((
TCollection *)
nullptr), void())
395 for (
auto it = ++objs.begin(); it != objs.end(); ++it)
401 template <
typename H>
402 auto Merge(std::vector<H *> &objs,
double )
403 ->
decltype(objs[0]->Merge(std::vector<HIST *>{}),
void())
405 objs[0]->Merge({++objs.begin(), objs.end()});
409 template <
typename T>
412 static_assert(
sizeof(T) < 0,
413 "The type passed to Fill does not provide a Merge(TCollection*) or Merge(const std::vector&) method.");
416 template <std::size_t ColIdx,
typename End_t,
typename... Its>
417 void ExecLoop(
unsigned int slot, End_t end, Its... its)
419 for (
auto *thisSlotH = fObjects[slot]; GetNthElement<ColIdx>(its...) != end; (std::advance(its, 1), ...)) {
420 thisSlotH->Fill(*its...);
425 FillHelper(FillHelper &&) =
default;
426 FillHelper(
const FillHelper &) =
delete;
428 FillHelper(
const std::shared_ptr<HIST> &
h,
const unsigned int nSlots) : fObjects(nSlots, nullptr)
430 fObjects[0] =
h.get();
432 for (
unsigned int i = 1; i < nSlots; ++i) {
433 fObjects[i] =
new HIST(*fObjects[0]);
441 template <
typename... ValTypes, std::enable_if_t<!std::disjunction<IsDataContainer<ValTypes>...>
::value,
int> = 0>
442 auto Exec(
unsigned int slot,
const ValTypes &...
x) ->
decltype(fObjects[slot]->Fill(
x...), void())
444 fObjects[slot]->Fill(
x...);
448 template <
typename... Xs, std::enable_if_t<std::disjunction<IsDataContainer<Xs>...>
::value,
int> = 0>
449 auto Exec(
unsigned int slot,
const Xs &...xs) ->
decltype(fObjects[slot]->Fill(*MakeBegin(xs)...), void())
452 constexpr std::array<
bool,
sizeof...(Xs)> isContainer{IsDataContainer<Xs>::value...};
455 constexpr std::size_t colidx =
FindIdxTrue(isContainer);
457 static_assert(colidx <
sizeof...(Xs),
"Error: index of collection-type argument not found.");
460 auto const xrefend = std::end(GetNthElement<colidx>(xs...));
463 std::array<std::size_t,
sizeof...(xs)> sizes = {{GetSize(xs)...}};
465 for (std::size_t i = 0; i <
sizeof...(xs); ++i) {
466 if (isContainer[i] && sizes[i] != sizes[colidx]) {
467 throw std::runtime_error(
"Cannot fill histogram with values in containers of different sizes.");
471 ExecLoop<colidx>(slot, xrefend, MakeBegin(xs)...);
474 template <
typename T = HIST>
477 static_assert(
sizeof(T) < 0,
478 "When filling an object with RDataFrame (e.g. via a Fill action) the number or types of the "
479 "columns passed did not match the signature of the object's `Fill` method.");
486 if (fObjects.size() == 1)
492 for (
auto it = ++fObjects.begin(); it != fObjects.end(); ++it)
496 HIST &PartialUpdate(
unsigned int slot) {
return *fObjects[slot]; }
501 return std::make_unique<RMergeableFill<HIST>>(*fObjects[0]);
505 template <typename T = HIST, std::enable_if_t<std::is_base_of<TObject, T>::value,
int> = 0>
506 std::string GetActionName()
508 return std::string(fObjects[0]->IsA()->
GetName()) +
"\\n" + std::string(fObjects[0]->
GetName());
512 template <typename T = HIST, std::enable_if_t<!std::is_base_of<TObject, T>::value,
int> = 0>
513 std::string GetActionName()
515 return "Fill custom object";
518 template <
typename H = HIST>
519 FillHelper MakeNew(
void *newResult, std::string_view =
"nominal")
521 auto &
result = *
static_cast<std::shared_ptr<H> *
>(newResult);
524 return FillHelper(
result, fObjects.size());
529template <
typename BinContentType,
bool WithWeight = false>
530class R__CLING_PTRCHECK(off) RHistFillHelper :
public RActionImpl<RHistFillHelper<BinContentType, WithWeight>>,
531 public ExecLoopTrait<RHistFillHelper<BinContentType, WithWeight>> {
536 std::unique_ptr<ROOT::Experimental::RHistConcurrentFiller<BinContentType>> fFiller;
537 std::vector<std::shared_ptr<ROOT::Experimental::RHistFillContext<BinContentType>>> fContexts;
541 : fFiller(new
ROOT::Experimental::RHistConcurrentFiller<BinContentType>(
h)), fContexts(nSlots)
543 for (
unsigned int i = 0; i < nSlots; i++) {
544 fContexts[i] = fFiller->CreateFillContext();
547 RHistFillHelper(
const RHistFillHelper &) =
delete;
548 RHistFillHelper(RHistFillHelper &&) =
default;
549 RHistFillHelper &operator=(
const RHistFillHelper &) =
delete;
550 RHistFillHelper &operator=(RHistFillHelper &&) =
default;
551 ~RHistFillHelper() =
default;
553 std::shared_ptr<Result_t> GetResultPtr()
const {
return fFiller.GetHist(); }
558 template <
typename... ColumnTypes,
const std::size_t... I>
560 ExecWithWeight(
unsigned int slot,
const std::tuple<const ColumnTypes &...> &columnValues, std::index_sequence<I...>)
563 std::tuple<
const std::tuple_element_t<I, std::tuple<ColumnTypes...>> &...> args(std::get<I>(columnValues)...);
565 fContexts[slot]->Fill(args, weight);
568 template <
typename... ColumnTypes>
569 void ExecSingle(
unsigned int slot,
const ColumnTypes &...columnValues)
571 if constexpr (WithWeight) {
572 auto t = std::forward_as_tuple(columnValues...);
573 ExecWithWeight(slot, t, std::make_index_sequence<
sizeof...(ColumnTypes) - 1>());
575 fContexts[slot]->Fill(columnValues...);
581 for (
auto &&context : fContexts) {
586 RHistFillHelper MakeNew(
void *newResult, std::string_view =
"nominal")
588 auto &
result = *
static_cast<std::shared_ptr<Result_t> *
>(newResult);
590 return RHistFillHelper(
result, fContexts.size());
593 std::string GetActionName() {
return "Hist"; }
596template <
typename BinContentType,
bool WithWeight = false>
597class R__CLING_PTRCHECK(off) RHistEngineFillHelper
598 :
public RActionImpl<RHistEngineFillHelper<BinContentType, WithWeight>>,
599 public ExecLoopTrait<RHistEngineFillHelper<BinContentType, WithWeight>> {
604 std::shared_ptr<Result_t> fHist;
608 RHistEngineFillHelper(
const RHistEngineFillHelper &) =
delete;
609 RHistEngineFillHelper(RHistEngineFillHelper &&) =
default;
610 RHistEngineFillHelper &operator=(
const RHistEngineFillHelper &) =
delete;
611 RHistEngineFillHelper &operator=(RHistEngineFillHelper &&) =
default;
612 ~RHistEngineFillHelper() =
default;
614 std::shared_ptr<Result_t> GetResultPtr()
const {
return fHist; }
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"; }
657 std::vector<::TGraph *> fGraphs;
660 FillTGraphHelper(FillTGraphHelper &&) =
default;
661 FillTGraphHelper(
const FillTGraphHelper &) =
delete;
663 FillTGraphHelper(
const std::shared_ptr<::TGraph> &
g,
const unsigned int nSlots) : fGraphs(nSlots, nullptr)
665 fGraphs[0] =
g.get();
667 for (
unsigned int i = 1; i < nSlots; ++i) {
668 fGraphs[i] =
new TGraph(*fGraphs[0]);
676 template <
typename X0,
typename X1,
677 std::enable_if_t<IsDataContainer<X0>::value && IsDataContainer<X1>::value,
int> = 0>
678 void Exec(
unsigned int slot,
const X0 &x0s,
const X1 &x1s)
680 if (x0s.size() != x1s.size()) {
681 throw std::runtime_error(
"Cannot fill Graph with values in containers of different sizes.");
683 auto *thisSlotG = fGraphs[slot];
684 auto x0sIt = std::begin(x0s);
685 const auto x0sEnd = std::end(x0s);
686 auto x1sIt = std::begin(x1s);
687 for (; x0sIt != x0sEnd; x0sIt++, x1sIt++) {
688 thisSlotG->SetPoint(thisSlotG->GetN(), *x0sIt, *x1sIt);
693 template <
typename X0,
typename X1,
694 std::enable_if_t<!IsDataContainer<X0>::value && !IsDataContainer<X1>::value,
int> = 0>
695 void Exec(
unsigned int slot, X0 x0, X1
x1)
697 auto thisSlotG = fGraphs[slot];
698 thisSlotG->SetPoint(thisSlotG->GetN(), x0,
x1);
703 template <
typename X0,
typename X1,
typename... ExtraArgsToLowerPriority>
704 void Exec(
unsigned int, X0, X1, ExtraArgsToLowerPriority...)
706 throw std::runtime_error(
"Graph was applied to a mix of scalar values and collections. This is not supported.");
711 const auto nSlots = fGraphs.size();
712 auto resGraph = fGraphs[0];
715 for (
unsigned int slot = 1; slot < nSlots; ++slot) {
716 l.Add(fGraphs[slot]);
724 return std::make_unique<RMergeableFill<Result_t>>(*fGraphs[0]);
727 std::string GetActionName() {
return "Graph"; }
729 Result_t &PartialUpdate(
unsigned int slot) {
return *fGraphs[slot]; }
731 FillTGraphHelper MakeNew(
void *newResult, std::string_view =
"nominal")
733 auto &
result = *
static_cast<std::shared_ptr<TGraph> *
>(newResult);
735 return FillTGraphHelper(
result, fGraphs.size());
739class R__CLING_PTRCHECK(off) FillTGraphAsymmErrorsHelper
745 std::vector<::TGraphAsymmErrors *> fGraphAsymmErrors;
748 FillTGraphAsymmErrorsHelper(FillTGraphAsymmErrorsHelper &&) =
default;
749 FillTGraphAsymmErrorsHelper(
const FillTGraphAsymmErrorsHelper &) =
delete;
751 FillTGraphAsymmErrorsHelper(
const std::shared_ptr<::TGraphAsymmErrors> &
g,
const unsigned int nSlots)
752 : fGraphAsymmErrors(nSlots, nullptr)
754 fGraphAsymmErrors[0] =
g.get();
756 for (
unsigned int i = 1; i < nSlots; ++i) {
766 typename X,
typename Y,
typename EXL,
typename EXH,
typename EYL,
typename EYH,
767 std::enable_if_t<IsDataContainer<X>::value && IsDataContainer<Y>::value && IsDataContainer<EXL>::value &&
768 IsDataContainer<EXH>::value && IsDataContainer<EYL>::value && IsDataContainer<EYH>::value,
771 Exec(
unsigned int slot,
const X &xs,
const Y &ys,
const EXL &exls,
const EXH &exhs,
const EYL &eyls,
const EYH &eyhs)
773 if ((xs.size() != ys.size()) || (xs.size() != exls.size()) || (xs.size() != exhs.size()) ||
774 (xs.size() != eyls.size()) || (xs.size() != eyhs.size())) {
775 throw std::runtime_error(
"Cannot fill GraphAsymmErrors with values in containers of different sizes.");
777 auto *thisSlotG = fGraphAsymmErrors[slot];
778 auto xsIt = std::begin(xs);
779 auto ysIt = std::begin(ys);
780 auto exlsIt = std::begin(exls);
781 auto exhsIt = std::begin(exhs);
782 auto eylsIt = std::begin(eyls);
783 auto eyhsIt = std::begin(eyhs);
784 while (xsIt != std::end(xs)) {
785 const auto n = thisSlotG->GetN();
786 thisSlotG->SetPoint(
n, *xsIt++, *ysIt++);
787 thisSlotG->SetPointError(
n, *exlsIt++, *exhsIt++, *eylsIt++, *eyhsIt++);
793 typename X,
typename Y,
typename EXL,
typename EXH,
typename EYL,
typename EYH,
794 std::enable_if_t<!IsDataContainer<X>::value && !IsDataContainer<Y>::value && !IsDataContainer<EXL>::value &&
795 !IsDataContainer<EXH>::value && !IsDataContainer<EYL>::value && !IsDataContainer<EYH>::value,
797 void Exec(
unsigned int slot,
X x, Y
y, EXL exl, EXH exh, EYL eyl, EYH eyh)
799 auto thisSlotG = fGraphAsymmErrors[slot];
800 const auto n = thisSlotG->GetN();
801 thisSlotG->SetPoint(
n,
x,
y);
802 thisSlotG->SetPointError(
n, exl, exh, eyl, eyh);
807 template <
typename X,
typename Y,
typename EXL,
typename EXH,
typename EYL,
typename EYH,
808 typename... ExtraArgsToLowerPriority>
809 void Exec(
unsigned int,
X, Y, EXL, EXH, EYL, EYH, ExtraArgsToLowerPriority...)
811 throw std::runtime_error(
812 "GraphAsymmErrors was applied to a mix of scalar values and collections. This is not supported.");
817 const auto nSlots = fGraphAsymmErrors.size();
818 auto resGraphAsymmErrors = fGraphAsymmErrors[0];
821 for (
unsigned int slot = 1; slot < nSlots; ++slot) {
822 l.Add(fGraphAsymmErrors[slot]);
824 resGraphAsymmErrors->Merge(&
l);
830 return std::make_unique<RMergeableFill<Result_t>>(*fGraphAsymmErrors[0]);
833 std::string GetActionName() {
return "GraphAsymmErrors"; }
835 Result_t &PartialUpdate(
unsigned int slot) {
return *fGraphAsymmErrors[slot]; }
837 FillTGraphAsymmErrorsHelper MakeNew(
void *newResult, std::string_view =
"nominal")
839 auto &
result = *
static_cast<std::shared_ptr<TGraphAsymmErrors> *
>(newResult);
841 return FillTGraphAsymmErrorsHelper(
result, fGraphAsymmErrors.size());
846template <
typename HIST>
847class R__CLING_PTRCHECK(off) ThreadSafeFillHelper :
public RActionImpl<ThreadSafeFillHelper<HIST>> {
848 std::vector<std::shared_ptr<HIST>> fObjects;
849 std::vector<std::unique_ptr<std::mutex>> fMutexPtrs;
852 template <
typename T,
typename... Args>
853 auto TryCallFillThreadSafe(T &
object, std::mutex &,
int , Args... args)
859 template <
typename T,
typename... Args>
860 auto TryCallFillThreadSafe(T &
object, std::mutex &mutex,
char , Args... args)
862 std::scoped_lock lock{mutex};
863 object.Fill(args...);
866 template <std::size_t ColIdx,
typename End_t,
typename... Its>
867 void ExecLoop(
unsigned int slot, End_t end, Its... its)
869 const auto localSlot = slot % fObjects.size();
870 for (; GetNthElement<ColIdx>(its...) != end; (std::advance(its, 1), ...)) {
871 TryCallFillThreadSafe(*fObjects[localSlot], *fMutexPtrs[localSlot], 0, *its...);
876 ThreadSafeFillHelper(ThreadSafeFillHelper &&) =
default;
877 ThreadSafeFillHelper(
const ThreadSafeFillHelper &) =
delete;
879 ThreadSafeFillHelper(
const std::shared_ptr<HIST> &
h,
const unsigned int nSlots)
881 fObjects.resize(nSlots);
882 fObjects.front() =
h;
884 std::generate(fObjects.begin() + 1, fObjects.end(), [
h]() {
885 auto hist = std::make_shared<HIST>(*h);
886 UnsetDirectoryIfPossible(hist.get());
889 fMutexPtrs.resize(nSlots);
890 std::generate(fMutexPtrs.begin(), fMutexPtrs.end(), []() { return std::make_unique<std::mutex>(); });
896 template <
typename... ValTypes, std::enable_if_t<!std::disjunction<IsDataContainer<ValTypes>...>
::value,
int> = 0>
897 void Exec(
unsigned int slot,
const ValTypes &...
x)
899 const auto localSlot = slot % fObjects.size();
900 TryCallFillThreadSafe(*fObjects[localSlot], *fMutexPtrs[localSlot], 0,
x...);
904 template <
typename... Xs, std::enable_if_t<std::disjunction<IsDataContainer<Xs>...>
::value,
int> = 0>
905 void Exec(
unsigned int slot,
const Xs &...xs)
908 constexpr std::array<
bool,
sizeof...(Xs)> isContainer{IsDataContainer<Xs>::value...};
911 constexpr std::size_t colidx =
FindIdxTrue(isContainer);
913 static_assert(colidx <
sizeof...(Xs),
"Error: index of collection-type argument not found.");
916 auto const xrefend = std::end(GetNthElement<colidx>(xs...));
919 std::array<std::size_t,
sizeof...(xs)> sizes = {{GetSize(xs)...}};
921 for (std::size_t i = 0; i <
sizeof...(xs); ++i) {
922 if (isContainer[i] && sizes[i] != sizes[colidx]) {
923 throw std::runtime_error(
"Cannot fill histogram with values in containers of different sizes.");
927 ExecLoop<colidx>(slot, xrefend, MakeBegin(xs)...);
930 template <
typename T = HIST>
933 static_assert(
sizeof(T) < 0,
934 "When filling an object with RDataFrame (e.g. via a Fill action) the number or types of the "
935 "columns passed did not match the signature of the object's `FillThreadSafe` method.");
942 if (fObjects.size() > 1) {
944 for (
auto it = fObjects.cbegin() + 1; it != fObjects.end(); ++it) {
947 fObjects[0]->Merge(&list);
957 return std::make_unique<RMergeableFill<HIST>>(*fObjects[0]);
961 template <typename T = HIST, std::enable_if_t<std::is_base_of<TObject, T>::value,
int> = 0>
962 std::string GetActionName()
964 return std::string(fObjects[0]->IsA()->
GetName()) +
"\\n" + std::string(fObjects[0]->
GetName());
967 template <
typename H = HIST>
968 ThreadSafeFillHelper MakeNew(
void *newResult, std::string_view =
"nominal")
970 auto &
result = *
static_cast<std::shared_ptr<H> *
>(newResult);
973 return ThreadSafeFillHelper(
result, fObjects.size());
983template <
typename V,
typename COLL>
984void FillColl(V&&
v, COLL&
c) {
989template <
typename COLL>
990void FillColl(
bool v, COLL&
c) {
996template <
typename RealT_t,
typename T,
typename COLL>
997class R__CLING_PTRCHECK(off) TakeHelper :
public RActionImpl<TakeHelper<RealT_t, T, COLL>> {
998 Results<std::shared_ptr<COLL>> fColls;
1002 TakeHelper(
const std::shared_ptr<COLL> &resultColl,
const unsigned int nSlots)
1004 fColls.emplace_back(resultColl);
1005 for (
unsigned int i = 1; i < nSlots; ++i)
1006 fColls.emplace_back(std::make_shared<COLL>());
1008 TakeHelper(TakeHelper &&);
1009 TakeHelper(
const TakeHelper &) =
delete;
1013 void Exec(
unsigned int slot, T &
v) { FillColl(
v, *fColls[slot]); }
1019 auto rColl = fColls[0];
1020 for (
unsigned int i = 1; i < fColls.size(); ++i) {
1021 const auto &coll = fColls[i];
1022 const auto end = coll->end();
1025 for (
auto j = coll->begin(); j != end; j++) {
1026 FillColl(*j, *rColl);
1031 COLL &PartialUpdate(
unsigned int slot) {
return *fColls[slot].get(); }
1033 std::string GetActionName() {
return "Take"; }
1035 TakeHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1037 auto &
result = *
static_cast<std::shared_ptr<COLL> *
>(newResult);
1039 return TakeHelper(
result, fColls.size());
1045template <
typename RealT_t,
typename T>
1046class R__CLING_PTRCHECK(off) TakeHelper<RealT_t, T, std::vector<T>>
1047 :
public RActionImpl<TakeHelper<RealT_t, T, std::vector<T>>> {
1048 Results<std::shared_ptr<std::vector<T>>> fColls;
1052 TakeHelper(
const std::shared_ptr<std::vector<T>> &resultColl,
const unsigned int nSlots)
1054 fColls.emplace_back(resultColl);
1055 for (
unsigned int i = 1; i < nSlots; ++i) {
1056 auto v = std::make_shared<std::vector<T>>();
1058 fColls.emplace_back(
v);
1061 TakeHelper(TakeHelper &&);
1062 TakeHelper(
const TakeHelper &) =
delete;
1066 void Exec(
unsigned int slot, T &
v) { FillColl(
v, *fColls[slot]); }
1074 for (
auto &coll : fColls)
1075 totSize += coll->
size();
1076 auto rColl = fColls[0];
1077 rColl->reserve(totSize);
1078 for (
unsigned int i = 1; i < fColls.size(); ++i) {
1079 auto &coll = fColls[i];
1080 rColl->insert(rColl->end(), coll->begin(), coll->end());
1084 std::vector<T> &PartialUpdate(
unsigned int slot) {
return *fColls[slot]; }
1086 std::string GetActionName() {
return "Take"; }
1088 TakeHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1090 auto &
result = *
static_cast<std::shared_ptr<std::vector<T>
> *>(newResult);
1092 return TakeHelper(
result, fColls.size());
1098template <
typename RealT_t,
typename COLL>
1099class R__CLING_PTRCHECK(off) TakeHelper<RealT_t,
RVec<RealT_t>, COLL>
1100 :
public RActionImpl<TakeHelper<RealT_t, RVec<RealT_t>, COLL>> {
1101 Results<std::shared_ptr<COLL>> fColls;
1105 TakeHelper(
const std::shared_ptr<COLL> &resultColl,
const unsigned int nSlots)
1107 fColls.emplace_back(resultColl);
1108 for (
unsigned int i = 1; i < nSlots; ++i)
1109 fColls.emplace_back(std::make_shared<COLL>());
1111 TakeHelper(TakeHelper &&);
1112 TakeHelper(
const TakeHelper &) =
delete;
1122 auto rColl = fColls[0];
1123 for (
unsigned int i = 1; i < fColls.size(); ++i) {
1124 auto &coll = fColls[i];
1125 for (
auto &
v : *coll) {
1126 rColl->emplace_back(
v);
1131 std::string GetActionName() {
return "Take"; }
1133 TakeHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1135 auto &
result = *
static_cast<std::shared_ptr<COLL> *
>(newResult);
1137 return TakeHelper(
result, fColls.size());
1143template <
typename RealT_t>
1144class R__CLING_PTRCHECK(off) TakeHelper<RealT_t,
RVec<RealT_t>, std::vector<RealT_t>>
1145 :
public RActionImpl<TakeHelper<RealT_t, RVec<RealT_t>, std::vector<RealT_t>>> {
1147 Results<std::shared_ptr<std::vector<std::vector<RealT_t>>>> fColls;
1151 TakeHelper(
const std::shared_ptr<std::vector<std::vector<RealT_t>>> &resultColl,
const unsigned int nSlots)
1153 fColls.emplace_back(resultColl);
1154 for (
unsigned int i = 1; i < nSlots; ++i) {
1155 auto v = std::make_shared<std::vector<RealT_t>>();
1157 fColls.emplace_back(
v);
1160 TakeHelper(TakeHelper &&);
1161 TakeHelper(
const TakeHelper &) =
delete;
1173 for (
auto &coll : fColls)
1174 totSize += coll->
size();
1175 auto rColl = fColls[0];
1176 rColl->reserve(totSize);
1177 for (
unsigned int i = 1; i < fColls.size(); ++i) {
1178 auto &coll = fColls[i];
1179 rColl->insert(rColl->end(), coll->begin(), coll->end());
1183 std::string GetActionName() {
return "Take"; }
1185 TakeHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1187 auto &
result = *
static_cast<typename decltype(fColls)::value_type *
>(newResult);
1189 return TakeHelper(
result, fColls.size());
1196template <
typename RealT_t,
typename T,
typename COLL>
1197TakeHelper<RealT_t, T, COLL>::TakeHelper(TakeHelper<RealT_t, T, COLL> &&) =
default;
1198template <
typename RealT_t,
typename T>
1199TakeHelper<RealT_t, T, std::vector<T>>::TakeHelper(TakeHelper<RealT_t, T, std::vector<T>> &&) =
default;
1200template <
typename RealT_t,
typename COLL>
1201TakeHelper<RealT_t, RVec<RealT_t>, COLL>::TakeHelper(TakeHelper<RealT_t,
RVec<RealT_t>, COLL> &&) =
default;
1202template <
typename RealT_t>
1203TakeHelper<RealT_t, RVec<RealT_t>, std::vector<RealT_t>>::TakeHelper(TakeHelper<RealT_t,
RVec<RealT_t>, std::vector<RealT_t>> &&) =
default;
1207extern template class TakeHelper<bool, bool, std::vector<bool>>;
1208extern template class TakeHelper<unsigned int, unsigned int, std::vector<unsigned int>>;
1209extern template class TakeHelper<unsigned long, unsigned long, std::vector<unsigned long>>;
1210extern template class TakeHelper<unsigned long long, unsigned long long, std::vector<unsigned long long>>;
1211extern template class TakeHelper<int, int, std::vector<int>>;
1212extern template class TakeHelper<long, long, std::vector<long>>;
1213extern template class TakeHelper<long long, long long, std::vector<long long>>;
1214extern template class TakeHelper<float, float, std::vector<float>>;
1215extern template class TakeHelper<double, double, std::vector<double>>;
1218template <
typename ResultType>
1219class R__CLING_PTRCHECK(off) MinHelper :
public RActionImpl<MinHelper<ResultType>> {
1220 std::shared_ptr<ResultType> fResultMin;
1221 Results<ResultType> fMins;
1224 MinHelper(MinHelper &&) =
default;
1225 MinHelper(
const std::shared_ptr<ResultType> &minVPtr,
const unsigned int nSlots)
1226 : fResultMin(minVPtr), fMins(nSlots, std::numeric_limits<ResultType>::max())
1230 void Exec(
unsigned int slot, ResultType
v) { fMins[slot] = std::min(
v, fMins[slot]); }
1234 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
1235 void Exec(
unsigned int slot,
const T &vs)
1238 fMins[slot] = std::min(static_cast<ResultType>(
v), fMins[slot]);
1245 *fResultMin = std::numeric_limits<ResultType>::max();
1246 for (
auto &
m : fMins)
1247 *fResultMin = std::min(
m, *fResultMin);
1253 return std::make_unique<RMergeableMin<ResultType>>(*fResultMin);
1256 ResultType &PartialUpdate(
unsigned int slot) {
return fMins[slot]; }
1258 std::string GetActionName() {
return "Min"; }
1260 MinHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1262 auto &
result = *
static_cast<std::shared_ptr<ResultType> *
>(newResult);
1263 return MinHelper(
result, fMins.size());
1267template <
typename ResultType>
1268class R__CLING_PTRCHECK(off) MaxHelper :
public RActionImpl<MaxHelper<ResultType>> {
1269 std::shared_ptr<ResultType> fResultMax;
1270 Results<ResultType> fMaxs;
1273 MaxHelper(MaxHelper &&) =
default;
1274 MaxHelper(
const MaxHelper &) =
delete;
1275 MaxHelper(
const std::shared_ptr<ResultType> &maxVPtr,
const unsigned int nSlots)
1276 : fResultMax(maxVPtr), fMaxs(nSlots, std::numeric_limits<ResultType>::lowest())
1281 void Exec(
unsigned int slot, ResultType
v) { fMaxs[slot] = std::max(
v, fMaxs[slot]); }
1283 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
1284 void Exec(
unsigned int slot,
const T &vs)
1287 fMaxs[slot] = std::max(static_cast<ResultType>(
v), fMaxs[slot]);
1294 *fResultMax = std::numeric_limits<ResultType>::lowest();
1295 for (
auto &
m : fMaxs) {
1296 *fResultMax = std::max(
m, *fResultMax);
1303 return std::make_unique<RMergeableMax<ResultType>>(*fResultMax);
1306 ResultType &PartialUpdate(
unsigned int slot) {
return fMaxs[slot]; }
1308 std::string GetActionName() {
return "Max"; }
1310 MaxHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1312 auto &
result = *
static_cast<std::shared_ptr<ResultType> *
>(newResult);
1313 return MaxHelper(
result, fMaxs.size());
1317template <
typename ResultType>
1318class R__CLING_PTRCHECK(off) SumHelper :
public RActionImpl<SumHelper<ResultType>> {
1319 std::shared_ptr<ResultType> fResultSum;
1320 Results<ResultType> fSums;
1321 Results<ResultType> fCompensations;
1326 template <
typename T = ResultType>
1327 auto NeutralElement(
const T &
v,
int ) ->
decltype(
v -
v)
1332 template <
typename T = ResultType,
typename Dummy =
int>
1333 ResultType NeutralElement(
const T &, Dummy)
1335 return ResultType{};
1339 SumHelper(SumHelper &&) =
default;
1340 SumHelper(
const SumHelper &) =
delete;
1341 SumHelper(
const std::shared_ptr<ResultType> &sumVPtr,
const unsigned int nSlots)
1342 : fResultSum(sumVPtr), fSums(nSlots, NeutralElement(*sumVPtr, -1)),
1343 fCompensations(nSlots, NeutralElement(*sumVPtr, -1))
1348 void Exec(
unsigned int slot, ResultType
x)
1351 ResultType
y =
x - fCompensations[slot];
1352 ResultType t = fSums[slot] +
y;
1353 fCompensations[slot] = (t - fSums[slot]) -
y;
1357 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
1358 void Exec(
unsigned int slot,
const T &vs)
1360 for (
auto &&
v : vs) {
1369 ResultType
sum(NeutralElement(ResultType{}, -1));
1370 ResultType compensation(NeutralElement(ResultType{}, -1));
1371 ResultType
y(NeutralElement(ResultType{}, -1));
1372 ResultType t(NeutralElement(ResultType{}, -1));
1373 for (
auto &
m : fSums) {
1375 y =
m - compensation;
1377 compensation = (t -
sum) -
y;
1386 return std::make_unique<RMergeableSum<ResultType>>(*fResultSum);
1389 ResultType &PartialUpdate(
unsigned int slot) {
return fSums[slot]; }
1391 std::string GetActionName() {
return "Sum"; }
1393 SumHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1395 auto &
result = *
static_cast<std::shared_ptr<ResultType> *
>(newResult);
1397 return SumHelper(
result, fSums.size());
1401class R__CLING_PTRCHECK(off) MeanHelper :
public RActionImpl<MeanHelper> {
1402 std::shared_ptr<double> fResultMean;
1403 std::vector<ULong64_t> fCounts;
1404 std::vector<double> fSums;
1405 std::vector<double> fPartialMeans;
1406 std::vector<double> fCompensations;
1409 MeanHelper(
const std::shared_ptr<double> &meanVPtr,
const unsigned int nSlots);
1410 MeanHelper(MeanHelper &&) =
default;
1411 MeanHelper(
const MeanHelper &) =
delete;
1413 void Exec(
unsigned int slot,
double v);
1415 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
1416 void Exec(
unsigned int slot,
const T &vs)
1418 for (
auto &&
v : vs) {
1422 double y =
v - fCompensations[slot];
1423 double t = fSums[slot] +
y;
1424 fCompensations[slot] = (t - fSums[slot]) -
y;
1436 const ULong64_t counts = std::accumulate(fCounts.begin(), fCounts.end(), 0ull);
1437 return std::make_unique<RMergeableMean>(*fResultMean, counts);
1440 double &PartialUpdate(
unsigned int slot);
1442 std::string GetActionName() {
return "Mean"; }
1444 MeanHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1446 auto &
result = *
static_cast<std::shared_ptr<double> *
>(newResult);
1447 return MeanHelper(
result, fSums.size());
1451class R__CLING_PTRCHECK(off) StdDevHelper :
public RActionImpl<StdDevHelper> {
1453 unsigned int fNSlots;
1454 std::shared_ptr<double> fResultStdDev;
1456 std::vector<ULong64_t> fCounts;
1458 std::vector<double> fMeans;
1460 std::vector<double> fDistancesfromMean;
1463 StdDevHelper(
const std::shared_ptr<double> &meanVPtr,
const unsigned int nSlots);
1464 StdDevHelper(StdDevHelper &&) =
default;
1465 StdDevHelper(
const StdDevHelper &) =
delete;
1467 void Exec(
unsigned int slot,
double v);
1469 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
1470 void Exec(
unsigned int slot,
const T &vs)
1472 for (
auto &&
v : vs) {
1484 const ULong64_t counts = std::accumulate(fCounts.begin(), fCounts.end(), 0ull);
1486 std::inner_product(fMeans.begin(), fMeans.end(), fCounts.begin(), 0.) /
static_cast<Double_t>(counts);
1487 return std::make_unique<RMergeableStdDev>(*fResultStdDev, counts, mean);
1490 std::string GetActionName() {
return "StdDev"; }
1492 StdDevHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1494 auto &
result = *
static_cast<std::shared_ptr<double> *
>(newResult);
1495 return StdDevHelper(
result, fCounts.size());
1499class R__CLING_PTRCHECK(off) MedianHelper :
public RActionImpl<MedianHelper> {
1500 std::shared_ptr<double> fResult;
1501 std::vector<std::vector<double>> fBuffers;
1504 MedianHelper(
const std::shared_ptr<double> &meanVPtr,
const unsigned int nSlots);
1505 MedianHelper(MedianHelper &&) =
default;
1506 MedianHelper &operator=(MedianHelper &&) =
default;
1507 MedianHelper(
const MedianHelper &) =
delete;
1508 MedianHelper &operator=(
const MedianHelper &other) =
delete;
1511 void Exec(
unsigned int slot,
double v);
1513 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
1514 void Exec(
unsigned int slot,
const T &vs)
1516 fBuffers[slot].insert(fBuffers[slot].end(), std::begin(vs), std::end(vs));
1523 std::string GetActionName() {
return "Median"; }
1525 std::shared_ptr<double> GetResultPtr()
const {
return fResult; }
1527 MedianHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1529 auto &
result = *
static_cast<std::shared_ptr<double> *
>(newResult);
1530 return MedianHelper(
result, fBuffers.size());
1533 ~MedianHelper() =
default;
1536template <
typename PrevNodeType>
1537class R__CLING_PTRCHECK(off) DisplayHelper :
public RActionImpl<DisplayHelper<PrevNodeType>> {
1540 std::shared_ptr<Display_t> fDisplayerHelper;
1541 std::shared_ptr<PrevNodeType> fPrevNode;
1542 size_t fEntriesToProcess;
1545 DisplayHelper(
size_t nRows,
const std::shared_ptr<Display_t> &
d,
const std::shared_ptr<PrevNodeType> &prevNode)
1546 : fDisplayerHelper(
d), fPrevNode(prevNode), fEntriesToProcess(nRows)
1549 DisplayHelper(DisplayHelper &&) =
default;
1550 DisplayHelper(
const DisplayHelper &) =
delete;
1553 template <
typename...
Columns>
1554 void Exec(
unsigned int, Columns &... columns)
1556 if (fEntriesToProcess == 0)
1559 fDisplayerHelper->AddRow(columns...);
1560 --fEntriesToProcess;
1562 if (fEntriesToProcess == 0) {
1567 fPrevNode->StopProcessing();
1575 std::string GetActionName() {
return "Display"; }
1578template <
typename Acc,
typename Merge,
typename R,
typename T,
typename U,
1579 bool MustCopyAssign = std::is_same<R, U>::value>
1580class R__CLING_PTRCHECK(off) AggregateHelper
1581 :
public RActionImpl<AggregateHelper<Acc, Merge, R, T, U, MustCopyAssign>> {
1584 std::shared_ptr<U> fResult;
1585 Results<U> fAggregators;
1590 AggregateHelper(Acc &&
f, Merge &&
m,
const std::shared_ptr<U> &
result,
const unsigned int nSlots)
1591 : fAggregate(std::move(
f)), fMerge(std::move(
m)), fResult(
result), fAggregators(nSlots, *
result)
1595 AggregateHelper(Acc &
f, Merge &
m,
const std::shared_ptr<U> &
result,
const unsigned int nSlots)
1596 : fAggregate(
f), fMerge(
m), fResult(
result), fAggregators(nSlots, *
result)
1600 AggregateHelper(AggregateHelper &&) =
default;
1601 AggregateHelper(
const AggregateHelper &) =
delete;
1605 template <
bool MustCopyAssign_ = MustCopyAssign, std::enable_if_t<MustCopyAssign_,
int> = 0>
1606 void Exec(
unsigned int slot,
const T &
value)
1608 fAggregators[slot] = fAggregate(fAggregators[slot],
value);
1611 template <
bool MustCopyAssign_ = MustCopyAssign, std::enable_if_t<!MustCopyAssign_,
int> = 0>
1612 void Exec(
unsigned int slot,
const T &
value)
1614 fAggregate(fAggregators[slot],
value);
1619 template <typename MergeRet = typename CallableTraits<Merge>::ret_type,
1620 bool MergeAll = std::is_same<void, MergeRet>::value>
1621 std::enable_if_t<MergeAll, void> Finalize()
1623 fMerge(fAggregators);
1624 *fResult = fAggregators[0];
1627 template <typename MergeRet = typename CallableTraits<Merge>::ret_type,
1628 bool MergeTwoByTwo = std::is_same<U, MergeRet>::value>
1629 std::enable_if_t<MergeTwoByTwo, void> Finalize(...)
1631 for (
const auto &acc : fAggregators)
1632 *fResult = fMerge(*fResult, acc);
1635 U &PartialUpdate(
unsigned int slot) {
return fAggregators[slot]; }
1637 std::string GetActionName() {
return "Aggregate"; }
1639 AggregateHelper MakeNew(
void *newResult, std::string_view =
"nominal")
1641 auto &
result = *
static_cast<std::shared_ptr<U> *
>(newResult);
1642 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.
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.
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)