19#ifndef ROOT_RDFOPERATIONS
20#define ROOT_RDFOPERATIONS
66template <
typename Helper>
67class R__CLING_PTRCHECK(off) RActionImpl {
69 virtual ~RActionImpl() =
default;
71 template <
typename T = Helper>
72 auto CallFinalizeTask(
unsigned int slot) ->
decltype(std::declval<T>().FinalizeTask(slot))
74 static_cast<Helper *
>(
this)->FinalizeTask(slot);
77 template <
typename... Args>
78 void CallFinalizeTask(
unsigned int, Args...) {}
80 template <
typename H = Helper>
81 auto CallPartialUpdate(
unsigned int slot) ->
decltype(std::declval<H>().PartialUpdate(slot), (
void *)(
nullptr))
83 return &
static_cast<Helper *
>(
this)->PartialUpdate(slot);
86 template <
typename... Args>
87 [[noreturn]]
void *CallPartialUpdate(...)
89 throw std::logic_error(
"This action does not support callbacks!");
92 template <
typename T = Helper>
93 auto CallMakeNew(
void *typeErasedResSharedPtr) ->
decltype(std::declval<T>().MakeNew(typeErasedResSharedPtr))
95 return static_cast<Helper *
>(
this)->MakeNew(typeErasedResSharedPtr);
98 template <
typename... Args>
99 [[noreturn]]
Helper CallMakeNew(
void *, Args...)
101 const auto &actionName =
static_cast<Helper *
>(
this)->GetActionName();
102 throw std::logic_error(
"The MakeNew method is not implemented for this action helper (" + actionName +
103 "). Cannot Vary its result.");
109 throw std::logic_error(
"`GetMergeableValue` is not implemented for this type of action.");
112 virtual std::function<
void(
unsigned int)> GetDataBlockCallback()
R__DEPRECATED(6, 28, "Use GetSampleCallback.")
132 std::vector<TBranch *> fBranches;
133 std::vector<std::string> fNames;
138 auto it = std::find(fNames.begin(), fNames.end(),
name);
139 if (it == fNames.end())
141 return fBranches[std::distance(fNames.begin(), it)];
144 void Insert(
const std::string &
name,
TBranch *address)
146 if (address ==
nullptr) {
147 throw std::logic_error(
"Trying to insert a null branch address.");
149 if (std::find(fBranches.begin(), fBranches.end(), address) != fBranches.end()) {
150 throw std::logic_error(
"Trying to insert a branch address that's already present.");
152 if (std::find(fNames.begin(), fNames.end(),
name) != fNames.end()) {
153 throw std::logic_error(
"Trying to insert a branch name that's already present.");
155 fNames.emplace_back(
name);
156 fBranches.emplace_back(address);
165 void AssertNoNullBranchAddresses()
167 std::vector<TBranch *> branchesWithNullAddress;
168 std::copy_if(fBranches.begin(), fBranches.end(), std::back_inserter(branchesWithNullAddress),
169 [](
TBranch *
b) { return b->GetAddress() == nullptr; });
171 if (branchesWithNullAddress.empty())
175 std::vector<std::string> missingBranchNames;
176 std::transform(branchesWithNullAddress.begin(), branchesWithNullAddress.end(),
177 std::back_inserter(missingBranchNames), [](
TBranch *
b) { return b->GetName(); });
178 std::string msg =
"RDataFrame::Snapshot:";
179 if (missingBranchNames.size() == 1) {
180 msg +=
" branch " + missingBranchNames[0] +
181 " is needed as it provides the size for one or more branches containing dynamically sized arrays, but "
185 for (
const auto &bName : missingBranchNames)
187 msg.resize(msg.size() - 2);
189 " are needed as they provide the size of other branches containing dynamically sized arrays, but they are";
191 msg +=
" not part of the set of branches that are being written out.";
192 throw std::runtime_error(msg);
201using Results = std::conditional_t<std::is_same<T, bool>::value, std::deque<T>, std::vector<T>>;
204class R__CLING_PTRCHECK(off) ForeachSlotHelper :
public RActionImpl<ForeachSlotHelper<F>> {
210 ForeachSlotHelper(ForeachSlotHelper &&) =
default;
211 ForeachSlotHelper(
const ForeachSlotHelper &) =
delete;
215 template <
typename... Args>
216 void Exec(
unsigned int slot, Args &&... args)
219 static_assert(std::is_same<TypeList<std::decay_t<Args>...>, ColumnTypes_t>::value,
"");
220 fCallable(slot, std::forward<Args>(args)...);
227 std::string GetActionName() {
return "ForeachSlot"; }
230class R__CLING_PTRCHECK(off) CountHelper :
public RActionImpl<CountHelper> {
231 const std::shared_ptr<ULong64_t> fResultCount;
232 Results<ULong64_t> fCounts;
236 CountHelper(
const std::shared_ptr<ULong64_t> &resultCount,
const unsigned int nSlots);
237 CountHelper(CountHelper &&) =
default;
238 CountHelper(
const CountHelper &) =
delete;
240 void Exec(
unsigned int slot);
247 return std::make_unique<RMergeableCount>(*fResultCount);
250 ULong64_t &PartialUpdate(
unsigned int slot);
252 std::string GetActionName() {
return "Count"; }
254 CountHelper MakeNew(
void *newResult)
256 auto &result = *
static_cast<std::shared_ptr<ULong64_t> *
>(newResult);
257 return CountHelper(result, fCounts.size());
261template <
typename ProxiedVal_t>
262class R__CLING_PTRCHECK(off) ReportHelper :
public RActionImpl<ReportHelper<ProxiedVal_t>> {
263 const std::shared_ptr<RCutFlowReport> fReport;
268 std::weak_ptr<ProxiedVal_t> fProxiedWPtr;
269 bool fReturnEmptyReport;
273 ReportHelper(
const std::shared_ptr<RCutFlowReport> &report,
const std::shared_ptr<ProxiedVal_t> &pp,
bool emptyRep)
274 : fReport(report), fProxiedWPtr(pp), fReturnEmptyReport(emptyRep){};
275 ReportHelper(ReportHelper &&) =
default;
276 ReportHelper(
const ReportHelper &) =
delete;
278 void Exec(
unsigned int ) {}
283 if (!fReturnEmptyReport && !fProxiedWPtr.expired())
284 fProxiedWPtr.lock()->Report(*fReport);
287 std::string GetActionName() {
return "Report"; }
292class R__CLING_PTRCHECK(off) FillHelper :
public RActionImpl<FillHelper> {
294 static constexpr unsigned int fgTotalBufSize = 2097152;
296 using Buf_t = std::vector<BufEl_t>;
298 std::vector<Buf_t> fBuffers;
299 std::vector<Buf_t> fWBuffers;
300 const std::shared_ptr<Hist_t> fResultHist;
301 unsigned int fNSlots;
302 unsigned int fBufSize;
304 Results<std::unique_ptr<Hist_t>> fPartialHists;
308 void UpdateMinMax(
unsigned int slot,
double v);
311 FillHelper(
const std::shared_ptr<Hist_t> &
h,
const unsigned int nSlots);
312 FillHelper(FillHelper &&) =
default;
313 FillHelper(
const FillHelper &) =
delete;
315 void Exec(
unsigned int slot,
double v);
316 void Exec(
unsigned int slot,
double v,
double w);
318 template <typename T, std::enable_if_t<IsDataContainer<T>::value || std::is_same<T, std::string>::value,
int> = 0>
319 void Exec(
unsigned int slot,
const T &vs)
321 auto &thisBuf = fBuffers[slot];
323 for (
auto v = vs.begin();
v != vs.end(); ++
v) {
324 UpdateMinMax(slot, *
v);
325 thisBuf.emplace_back(*
v);
329 template <typename T, typename W, std::enable_if_t<IsDataContainer<T>::value && IsDataContainer<W>::value,
int> = 0>
330 void Exec(
unsigned int slot,
const T &vs,
const W &
ws)
332 auto &thisBuf = fBuffers[slot];
335 UpdateMinMax(slot,
v);
336 thisBuf.emplace_back(
v);
339 auto &thisWBuf = fWBuffers[slot];
341 thisWBuf.emplace_back(w);
345 template <typename T, typename W, std::enable_if_t<IsDataContainer<T>::value && !IsDataContainer<W>::value,
int> = 0>
346 void Exec(
unsigned int slot,
const T &vs,
const W w)
348 auto &thisBuf = fBuffers[slot];
350 UpdateMinMax(slot,
v);
351 thisBuf.emplace_back(
v);
354 auto &thisWBuf = fWBuffers[slot];
355 thisWBuf.insert(thisWBuf.end(), vs.size(), w);
359 template <typename T, typename W, std::enable_if_t<IsDataContainer<W>::value && !IsDataContainer<T>::value,
int> = 0>
360 void Exec(
unsigned int,
const T &,
const W &)
362 throw std::runtime_error(
363 "Cannot fill object if the type of the first column is a scalar and the one of the second a container.");
366 Hist_t &PartialUpdate(
unsigned int);
375 return std::make_unique<RMergeableFill<Hist_t>>(*fResultHist);
378 std::string GetActionName() {
return "FillWithUnknownAxes"; }
380 FillHelper MakeNew(
void *newResult)
382 auto &result = *
static_cast<std::shared_ptr<Hist_t> *
>(newResult);
384 result->SetDirectory(
nullptr);
385 return FillHelper(result, fNSlots);
389extern template void FillHelper::Exec(
unsigned int,
const std::vector<float> &);
390extern template void FillHelper::Exec(
unsigned int,
const std::vector<double> &);
391extern template void FillHelper::Exec(
unsigned int,
const std::vector<char> &);
392extern template void FillHelper::Exec(
unsigned int,
const std::vector<int> &);
393extern template void FillHelper::Exec(
unsigned int,
const std::vector<unsigned int> &);
394extern template void FillHelper::Exec(
unsigned int,
const std::vector<float> &,
const std::vector<float> &);
395extern template void FillHelper::Exec(
unsigned int,
const std::vector<double> &,
const std::vector<double> &);
396extern template void FillHelper::Exec(
unsigned int,
const std::vector<char> &,
const std::vector<char> &);
397extern template void FillHelper::Exec(
unsigned int,
const std::vector<int> &,
const std::vector<int> &);
399FillHelper::Exec(
unsigned int,
const std::vector<unsigned int> &,
const std::vector<unsigned int> &);
401template <
typename HIST = Hist_t>
403 std::vector<HIST *> fObjects;
405 void UnsetDirectoryIfPossible(
TH1 *
h) {
406 h->SetDirectory(
nullptr);
409 void UnsetDirectoryIfPossible(...) {}
412 template <typename H, typename = std::enable_if_t<std::is_base_of<TObject, H>::value,
int>>
413 auto Merge(std::vector<H *> &objs,
int )
417 for (
auto it = ++objs.begin(); it != objs.end(); ++it)
423 template <
typename H>
424 auto Merge(std::vector<H *> &objs,
double )
425 ->
decltype(objs[0]->Merge(std::vector<HIST *>{}),
void())
427 objs[0]->Merge({++objs.begin(), objs.end()});
431 template <
typename T>
434 static_assert(
sizeof(
T) < 0,
435 "The type passed to Fill does not provide a Merge(TCollection*) or Merge(const std::vector&) method.");
439 template <
typename T>
440 class ScalarConstIterator {
444 ScalarConstIterator(
const T *obj) : obj_(obj) {}
446 ScalarConstIterator<T> &operator++() {
return *
this; }
454 template <typename T, typename std::enable_if<!IsDataContainer<T>::value,
int>
::type = 0>
455 ScalarConstIterator<T> MakeBegin(
const T &val)
457 return ScalarConstIterator<T>(&val);
461 template <typename T, typename std::enable_if<IsDataContainer<T>::value,
int>
::type = 0>
462 auto MakeBegin(
const T &val)
464 return std::begin(val);
468 template <typename T, typename std::enable_if<!IsDataContainer<T>::value,
int>
::type = 0>
469 std::size_t GetSize(
const T &)
475 template <typename T, typename std::enable_if<IsDataContainer<T>::value,
int>
::type = 0>
476 std::size_t GetSize(
const T &val)
478#if __cplusplus >= 201703L
479 return std::size(val);
485 template <std::size_t ColIdx,
typename End_t,
typename... Its>
486 void ExecLoop(
unsigned int slot, End_t end, Its... its)
488 auto *thisSlotH = fObjects[slot];
491 auto nop = [](
auto &&...) {};
492 for (; GetNthElement<ColIdx>(its...) != end; nop(++its...)) {
493 thisSlotH->Fill(*its...);
498 FillParHelper(FillParHelper &&) =
default;
499 FillParHelper(
const FillParHelper &) =
delete;
501 FillParHelper(
const std::shared_ptr<HIST> &
h,
const unsigned int nSlots) : fObjects(nSlots, nullptr)
503 fObjects[0] =
h.get();
505 for (
unsigned int i = 1; i < nSlots; ++i) {
506 fObjects[i] =
new HIST(*fObjects[0]);
507 UnsetDirectoryIfPossible(fObjects[i]);
514 template <
typename... ValTypes,
515 typename std::enable_if<!Disjunction<IsDataContainer<ValTypes>...>::value,
int>
::type = 0>
516 void Exec(
unsigned int slot,
const ValTypes &...
x)
518 fObjects[slot]->Fill(
x...);
522 template <
typename... Xs,
typename std::enable_if<Disjunction<IsDataContainer<Xs>...>::value,
int>
::type = 0>
523 void Exec(
unsigned int slot,
const Xs &...xs)
526 constexpr std::array<
bool,
sizeof...(Xs)> isContainer{IsDataContainer<Xs>::value...};
529 constexpr std::size_t colidx =
FindIdxTrue(isContainer);
531 static_assert(colidx <
sizeof...(Xs),
"Error: index of collection-type argument not found.");
534 auto const xrefend = std::end(GetNthElement<colidx>(xs...));
537 std::array<std::size_t,
sizeof...(xs)> sizes = {{GetSize(xs)...}};
539 for (std::size_t i = 0; i <
sizeof...(xs); ++i) {
540 if (isContainer[i] && sizes[i] != sizes[colidx]) {
541 throw std::runtime_error(
"Cannot fill histogram with values in containers of different sizes.");
545 ExecLoop<colidx>(slot, xrefend, MakeBegin(xs)...);
552 if (fObjects.size() == 1)
558 for (
auto it = ++fObjects.begin(); it != fObjects.end(); ++it)
562 HIST &PartialUpdate(
unsigned int slot) {
return *fObjects[slot]; }
567 return std::make_unique<RMergeableFill<HIST>>(*fObjects[0]);
570 std::string GetActionName() {
return "Fill"; }
575 template <typename H = HIST, typename = decltype(std::declval<H>().Reset())>
576 FillParHelper MakeNew(
void *newResult)
578 auto &result = *
static_cast<std::shared_ptr<H> *
>(newResult);
580 UnsetDirectoryIfPossible(result.get());
581 return FillParHelper(result, fObjects.size());
587 template <
typename H = HIST,
typename... ExtraArgs>
588 FillParHelper MakeNew(
void *, ExtraArgs...)
590 throw std::runtime_error(
591 "A systematic variation was requested for a custom Fill action, but the type of the object to be filled does "
592 "not implement a Reset method, so we cannot safely re-initialize variations of the result. Aborting.");
601 std::vector<::TGraph *> fGraphs;
604 FillTGraphHelper(FillTGraphHelper &&) =
default;
605 FillTGraphHelper(
const FillTGraphHelper &) =
delete;
609 FillTGraphHelper(
const std::shared_ptr<::TGraph> &
g,
const unsigned int nSlots) : fGraphs(nSlots, nullptr)
611 fGraphs[0] =
g.get();
613 for (
unsigned int i = 1; i < nSlots; ++i) {
614 fGraphs[i] =
new TGraph(*fGraphs[0]);
621 template <
typename X0,
typename X1,
622 std::enable_if_t<IsDataContainer<X0>::value && IsDataContainer<X1>::value,
int> = 0>
623 void Exec(
unsigned int slot,
const X0 &x0s,
const X1 &x1s)
625 if (x0s.size() != x1s.size()) {
626 throw std::runtime_error(
"Cannot fill Graph with values in containers of different sizes.");
628 auto thisSlotG = fGraphs[slot];
629 auto x0sIt = std::begin(x0s);
630 const auto x0sEnd = std::end(x0s);
631 auto x1sIt = std::begin(x1s);
632 for (; x0sIt != x0sEnd; x0sIt++, x1sIt++) {
633 thisSlotG->SetPoint(thisSlotG->GetN(), *x0sIt, *x1sIt);
637 template <
typename X0,
typename X1>
638 void Exec(
unsigned int slot, X0 x0, X1
x1)
640 auto thisSlotG = fGraphs[slot];
641 thisSlotG->SetPoint(thisSlotG->GetN(), x0,
x1);
646 const auto nSlots = fGraphs.size();
647 auto resGraph = fGraphs[0];
650 for (
unsigned int slot = 1; slot < nSlots; ++slot) {
651 l.Add(fGraphs[slot]);
659 return std::make_unique<RMergeableFill<Result_t>>(*fGraphs[0]);
662 std::string GetActionName() {
return "Graph"; }
664 Result_t &PartialUpdate(
unsigned int slot) {
return *fGraphs[slot]; }
666 FillTGraphHelper MakeNew(
void *newResult)
668 auto &result = *
static_cast<std::shared_ptr<TGraph> *
>(newResult);
670 return FillTGraphHelper(result, fGraphs.size());
680template <
typename V,
typename COLL>
681void FillColl(V&&
v, COLL&
c) {
686template <
typename COLL>
687void FillColl(
bool v, COLL&
c) {
693template <
typename RealT_t,
typename T,
typename COLL>
694class R__CLING_PTRCHECK(off) TakeHelper :
public RActionImpl<TakeHelper<RealT_t, T, COLL>> {
695 Results<std::shared_ptr<COLL>> fColls;
699 TakeHelper(
const std::shared_ptr<COLL> &resultColl,
const unsigned int nSlots)
701 fColls.emplace_back(resultColl);
702 for (
unsigned int i = 1; i < nSlots; ++i)
703 fColls.emplace_back(std::make_shared<COLL>());
705 TakeHelper(TakeHelper &&);
706 TakeHelper(
const TakeHelper &) =
delete;
710 void Exec(
unsigned int slot, T &
v) { FillColl(
v, *fColls[slot]); }
716 auto rColl = fColls[0];
717 for (
unsigned int i = 1; i < fColls.size(); ++i) {
718 const auto &coll = fColls[i];
719 const auto end = coll->end();
722 for (
auto j = coll->begin(); j != end; j++) {
723 FillColl(*j, *rColl);
728 COLL &PartialUpdate(
unsigned int slot) {
return *fColls[slot].get(); }
730 std::string GetActionName() {
return "Take"; }
732 TakeHelper MakeNew(
void *newResult)
734 auto &result = *
static_cast<std::shared_ptr<COLL> *
>(newResult);
736 return TakeHelper(result, fColls.size());
742template <
typename RealT_t,
typename T>
743class R__CLING_PTRCHECK(off) TakeHelper<RealT_t,
T, std::vector<T>>
744 :
public RActionImpl<TakeHelper<RealT_t, T, std::vector<T>>> {
745 Results<std::shared_ptr<std::vector<T>>> fColls;
749 TakeHelper(
const std::shared_ptr<std::vector<T>> &resultColl,
const unsigned int nSlots)
751 fColls.emplace_back(resultColl);
752 for (
unsigned int i = 1; i < nSlots; ++i) {
753 auto v = std::make_shared<std::vector<T>>();
755 fColls.emplace_back(
v);
758 TakeHelper(TakeHelper &&);
759 TakeHelper(
const TakeHelper &) =
delete;
763 void Exec(
unsigned int slot, T &
v) { FillColl(
v, *fColls[slot]); }
771 for (
auto &coll : fColls)
772 totSize += coll->
size();
773 auto rColl = fColls[0];
774 rColl->reserve(totSize);
775 for (
unsigned int i = 1; i < fColls.size(); ++i) {
776 auto &coll = fColls[i];
777 rColl->insert(rColl->end(), coll->begin(), coll->end());
781 std::vector<T> &PartialUpdate(
unsigned int slot) {
return *fColls[slot]; }
783 std::string GetActionName() {
return "Take"; }
785 TakeHelper MakeNew(
void *newResult)
787 auto &result = *
static_cast<std::shared_ptr<std::vector<T>
> *>(newResult);
789 return TakeHelper(result, fColls.size());
795template <
typename RealT_t,
typename COLL>
796class R__CLING_PTRCHECK(off) TakeHelper<RealT_t,
RVec<RealT_t>, COLL>
797 :
public RActionImpl<TakeHelper<RealT_t, RVec<RealT_t>, COLL>> {
798 Results<std::shared_ptr<COLL>> fColls;
802 TakeHelper(
const std::shared_ptr<COLL> &resultColl,
const unsigned int nSlots)
804 fColls.emplace_back(resultColl);
805 for (
unsigned int i = 1; i < nSlots; ++i)
806 fColls.emplace_back(std::make_shared<COLL>());
808 TakeHelper(TakeHelper &&);
809 TakeHelper(
const TakeHelper &) =
delete;
819 auto rColl = fColls[0];
820 for (
unsigned int i = 1; i < fColls.size(); ++i) {
821 auto &coll = fColls[i];
822 for (
auto &
v : *coll) {
823 rColl->emplace_back(
v);
828 std::string GetActionName() {
return "Take"; }
830 TakeHelper MakeNew(
void *newResult)
832 auto &result = *
static_cast<std::shared_ptr<COLL> *
>(newResult);
834 return TakeHelper(result, fColls.size());
840template <
typename RealT_t>
841class R__CLING_PTRCHECK(off) TakeHelper<RealT_t,
RVec<RealT_t>, std::vector<RealT_t>>
842 :
public RActionImpl<TakeHelper<RealT_t, RVec<RealT_t>, std::vector<RealT_t>>> {
844 Results<std::shared_ptr<std::vector<std::vector<RealT_t>>>> fColls;
848 TakeHelper(
const std::shared_ptr<std::vector<std::vector<RealT_t>>> &resultColl,
const unsigned int nSlots)
850 fColls.emplace_back(resultColl);
851 for (
unsigned int i = 1; i < nSlots; ++i) {
852 auto v = std::make_shared<std::vector<RealT_t>>();
854 fColls.emplace_back(
v);
857 TakeHelper(TakeHelper &&);
858 TakeHelper(
const TakeHelper &) =
delete;
870 for (
auto &coll : fColls)
871 totSize += coll->
size();
872 auto rColl = fColls[0];
873 rColl->reserve(totSize);
874 for (
unsigned int i = 1; i < fColls.size(); ++i) {
875 auto &coll = fColls[i];
876 rColl->insert(rColl->end(), coll->begin(), coll->end());
880 std::string GetActionName() {
return "Take"; }
882 TakeHelper MakeNew(
void *newResult)
884 auto &result = *
static_cast<typename decltype(fColls)::value_type *
>(newResult);
886 return TakeHelper(result, fColls.size());
893template <
typename RealT_t,
typename T,
typename COLL>
894TakeHelper<RealT_t, T, COLL>::TakeHelper(TakeHelper<RealT_t, T, COLL> &&) =
default;
895template <
typename RealT_t,
typename T>
896TakeHelper<RealT_t, T, std::vector<T>>::TakeHelper(TakeHelper<RealT_t, T, std::vector<T>> &&) =
default;
897template <
typename RealT_t,
typename COLL>
898TakeHelper<RealT_t, RVec<RealT_t>, COLL>::TakeHelper(TakeHelper<RealT_t,
RVec<RealT_t>, COLL> &&) =
default;
899template <
typename RealT_t>
900TakeHelper<RealT_t, RVec<RealT_t>, std::vector<RealT_t>>::TakeHelper(TakeHelper<RealT_t,
RVec<RealT_t>, std::vector<RealT_t>> &&) =
default;
904extern template class TakeHelper<bool, bool, std::vector<bool>>;
905extern template class TakeHelper<unsigned int, unsigned int, std::vector<unsigned int>>;
906extern template class TakeHelper<unsigned long, unsigned long, std::vector<unsigned long>>;
907extern template class TakeHelper<unsigned long long, unsigned long long, std::vector<unsigned long long>>;
908extern template class TakeHelper<int, int, std::vector<int>>;
909extern template class TakeHelper<long, long, std::vector<long>>;
910extern template class TakeHelper<long long, long long, std::vector<long long>>;
911extern template class TakeHelper<float, float, std::vector<float>>;
912extern template class TakeHelper<double, double, std::vector<double>>;
915template <
typename ResultType>
916class R__CLING_PTRCHECK(off) MinHelper :
public RActionImpl<MinHelper<ResultType>> {
917 const std::shared_ptr<ResultType> fResultMin;
918 Results<ResultType> fMins;
921 MinHelper(MinHelper &&) =
default;
922 MinHelper(
const std::shared_ptr<ResultType> &minVPtr,
const unsigned int nSlots)
923 : fResultMin(minVPtr), fMins(nSlots, std::numeric_limits<ResultType>::max())
927 void Exec(
unsigned int slot, ResultType
v) { fMins[slot] = std::min(
v, fMins[slot]); }
931 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
932 void Exec(
unsigned int slot,
const T &vs)
935 fMins[slot] = std::min(static_cast<ResultType>(
v), fMins[slot]);
942 *fResultMin = std::numeric_limits<ResultType>::max();
943 for (
auto &
m : fMins)
944 *fResultMin = std::min(
m, *fResultMin);
950 return std::make_unique<RMergeableMin<ResultType>>(*fResultMin);
953 ResultType &PartialUpdate(
unsigned int slot) {
return fMins[slot]; }
955 std::string GetActionName() {
return "Min"; }
957 MinHelper MakeNew(
void *newResult)
959 auto &result = *
static_cast<std::shared_ptr<ResultType> *
>(newResult);
960 return MinHelper(result, fMins.size());
971template <
typename ResultType>
972class R__CLING_PTRCHECK(off) MaxHelper :
public RActionImpl<MaxHelper<ResultType>> {
973 const std::shared_ptr<ResultType> fResultMax;
974 Results<ResultType> fMaxs;
977 MaxHelper(MaxHelper &&) =
default;
978 MaxHelper(
const MaxHelper &) =
delete;
979 MaxHelper(
const std::shared_ptr<ResultType> &maxVPtr,
const unsigned int nSlots)
980 : fResultMax(maxVPtr), fMaxs(nSlots, std::numeric_limits<ResultType>::lowest())
985 void Exec(
unsigned int slot, ResultType
v) { fMaxs[slot] = std::max(
v, fMaxs[slot]); }
987 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
988 void Exec(
unsigned int slot,
const T &vs)
991 fMaxs[slot] = std::max(static_cast<ResultType>(
v), fMaxs[slot]);
998 *fResultMax = std::numeric_limits<ResultType>::lowest();
999 for (
auto &
m : fMaxs) {
1000 *fResultMax = std::max(
m, *fResultMax);
1007 return std::make_unique<RMergeableMax<ResultType>>(*fResultMax);
1010 ResultType &PartialUpdate(
unsigned int slot) {
return fMaxs[slot]; }
1012 std::string GetActionName() {
return "Max"; }
1014 MaxHelper MakeNew(
void *newResult)
1016 auto &result = *
static_cast<std::shared_ptr<ResultType> *
>(newResult);
1017 return MaxHelper(result, fMaxs.size());
1028template <
typename ResultType>
1029class R__CLING_PTRCHECK(off) SumHelper :
public RActionImpl<SumHelper<ResultType>> {
1030 const std::shared_ptr<ResultType> fResultSum;
1031 Results<ResultType> fSums;
1036 template <
typename T = ResultType>
1037 auto NeutralElement(
const T &
v,
int ) ->
decltype(
v -
v)
1042 template <
typename T = ResultType,
typename Dummy =
int>
1043 ResultType NeutralElement(
const T &, Dummy)
1045 return ResultType{};
1049 SumHelper(SumHelper &&) =
default;
1050 SumHelper(
const SumHelper &) =
delete;
1051 SumHelper(
const std::shared_ptr<ResultType> &sumVPtr,
const unsigned int nSlots)
1052 : fResultSum(sumVPtr), fSums(nSlots, NeutralElement(*sumVPtr, -1))
1057 void Exec(
unsigned int slot, ResultType
v) { fSums[slot] +=
v; }
1059 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
1060 void Exec(
unsigned int slot,
const T &vs)
1063 fSums[slot] += static_cast<ResultType>(
v);
1070 for (
auto &
m : fSums)
1077 return std::make_unique<RMergeableSum<ResultType>>(*fResultSum);
1080 ResultType &PartialUpdate(
unsigned int slot) {
return fSums[slot]; }
1082 std::string GetActionName() {
return "Sum"; }
1084 SumHelper MakeNew(
void *newResult)
1086 auto &result = *
static_cast<std::shared_ptr<ResultType> *
>(newResult);
1087 *result = NeutralElement(*result, -1);
1088 return SumHelper(result, fSums.size());
1092class R__CLING_PTRCHECK(off) MeanHelper :
public RActionImpl<MeanHelper> {
1093 const std::shared_ptr<double> fResultMean;
1094 std::vector<ULong64_t> fCounts;
1095 std::vector<double> fSums;
1096 std::vector<double> fPartialMeans;
1099 MeanHelper(
const std::shared_ptr<double> &meanVPtr,
const unsigned int nSlots);
1100 MeanHelper(MeanHelper &&) =
default;
1101 MeanHelper(
const MeanHelper &) =
delete;
1103 void Exec(
unsigned int slot,
double v);
1105 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
1106 void Exec(
unsigned int slot,
const T &vs)
1108 for (
auto &&
v : vs) {
1121 const ULong64_t counts = std::accumulate(fCounts.begin(), fCounts.end(), 0ull);
1122 return std::make_unique<RMergeableMean>(*fResultMean, counts);
1125 double &PartialUpdate(
unsigned int slot);
1127 std::string GetActionName() {
return "Mean"; }
1129 MeanHelper MakeNew(
void *newResult)
1131 auto &result = *
static_cast<std::shared_ptr<double> *
>(newResult);
1132 return MeanHelper(result, fSums.size());
1136extern template void MeanHelper::Exec(
unsigned int,
const std::vector<float> &);
1137extern template void MeanHelper::Exec(
unsigned int,
const std::vector<double> &);
1138extern template void MeanHelper::Exec(
unsigned int,
const std::vector<char> &);
1139extern template void MeanHelper::Exec(
unsigned int,
const std::vector<int> &);
1140extern template void MeanHelper::Exec(
unsigned int,
const std::vector<unsigned int> &);
1144 const unsigned int fNSlots;
1145 const std::shared_ptr<double> fResultStdDev;
1147 std::vector<ULong64_t> fCounts;
1149 std::vector<double> fMeans;
1151 std::vector<double> fDistancesfromMean;
1154 StdDevHelper(
const std::shared_ptr<double> &meanVPtr,
const unsigned int nSlots);
1155 StdDevHelper(StdDevHelper &&) =
default;
1156 StdDevHelper(
const StdDevHelper &) =
delete;
1158 void Exec(
unsigned int slot,
double v);
1160 template <typename T, std::enable_if_t<IsDataContainer<T>::value,
int> = 0>
1161 void Exec(
unsigned int slot,
const T &vs)
1163 for (
auto &&
v : vs) {
1175 const ULong64_t counts = std::accumulate(fCounts.begin(), fCounts.end(), 0ull);
1177 std::inner_product(fMeans.begin(), fMeans.end(), fCounts.begin(), 0.) /
static_cast<Double_t>(counts);
1178 return std::make_unique<RMergeableStdDev>(*fResultStdDev, counts, mean);
1181 std::string GetActionName() {
return "StdDev"; }
1183 StdDevHelper MakeNew(
void *newResult)
1185 auto &result = *
static_cast<std::shared_ptr<double> *
>(newResult);
1186 return StdDevHelper(result, fCounts.size());
1190extern template void StdDevHelper::Exec(
unsigned int,
const std::vector<float> &);
1191extern template void StdDevHelper::Exec(
unsigned int,
const std::vector<double> &);
1192extern template void StdDevHelper::Exec(
unsigned int,
const std::vector<char> &);
1193extern template void StdDevHelper::Exec(
unsigned int,
const std::vector<int> &);
1194extern template void StdDevHelper::Exec(
unsigned int,
const std::vector<unsigned int> &);
1196template <
typename PrevNodeType>
1200 const std::shared_ptr<Display_t> fDisplayerHelper;
1201 const std::shared_ptr<PrevNodeType> fPrevNode;
1202 size_t fEntriesToProcess;
1205 DisplayHelper(
size_t nRows,
const std::shared_ptr<Display_t> &
d,
const std::shared_ptr<PrevNodeType> &prevNode)
1206 : fDisplayerHelper(
d), fPrevNode(prevNode), fEntriesToProcess(nRows)
1209 DisplayHelper(DisplayHelper &&) =
default;
1210 DisplayHelper(
const DisplayHelper &) =
delete;
1213 template <
typename...
Columns>
1214 void Exec(
unsigned int, Columns &... columns)
1216 if (fEntriesToProcess == 0)
1219 fDisplayerHelper->AddRow(columns...);
1220 --fEntriesToProcess;
1222 if (fEntriesToProcess == 0) {
1227 fPrevNode->StopProcessing();
1235 std::string GetActionName() {
return "Display"; }
1238template <
typename T>
1244template <
typename T>
1250template <
typename T>
1251void SetBranchesHelper(
TTree *inputTree,
TTree &outputTree,
const std::string &inName,
const std::string &
name,
1252 TBranch *&branch,
void *&branchAddress, T *address, RBranchSet &outputBranches,
1255 static TClassRef TBOClRef(
"TBranchObject");
1257 TBranch *inputBranch =
nullptr;
1259 inputBranch = inputTree->
GetBranch(inName.c_str());
1261 inputBranch = inputTree->
FindBranch(inName.c_str());
1264 auto *outputBranch = outputBranches.Get(
name);
1267 if (inputBranch && inputBranch->IsA() == TBOClRef) {
1268 outputBranch->SetAddress(
reinterpret_cast<T **
>(inputBranch->
GetAddress()));
1269 }
else if (outputBranch->IsA() != TBranch::Class()) {
1270 branchAddress = address;
1271 outputBranch->SetAddress(&branchAddress);
1273 outputBranch->SetAddress(address);
1274 branchAddress = address;
1287 if (inputBranch->IsA() == TBOClRef) {
1290 outputTree.
Branch(
name.c_str(),
reinterpret_cast<T **
>(inputBranch->
GetAddress()), bufSize, splitLevel);
1292 outputBranch = outputTree.
Branch(
name.c_str(), address, bufSize, splitLevel);
1295 outputBranch = outputTree.
Branch(
name.c_str(), address);
1297 outputBranches.Insert(
name, outputBranch);
1300 branchAddress =
nullptr;
1313template <
typename T>
1314void SetBranchesHelper(
TTree *inputTree,
TTree &outputTree,
const std::string &inName,
const std::string &outName,
1315 TBranch *&branch,
void *&branchAddress,
RVec<T> *ab, RBranchSet &outputBranches,
bool isDefine)
1317 TBranch *inputBranch =
nullptr;
1319 inputBranch = inputTree->
GetBranch(inName.c_str());
1321 inputBranch = inputTree->
FindBranch(inName.c_str());
1323 auto *outputBranch = outputBranches.Get(outName);
1326 bool mustWriteRVec = (inputBranch ==
nullptr || isDefine);
1328 if (!mustWriteRVec && std::string_view(inputBranch->
GetClassName()) ==
"TClonesArray") {
1329 mustWriteRVec =
true;
1331 "Branch \"%s\" contains TClonesArrays but the type specified to Snapshot was RVec<T>. The branch will "
1332 "be written out as a RVec instead of a TClonesArray. Specify that the type of the branch is "
1333 "TClonesArray as a Snapshot template parameter to write out a TClonesArray instead.",
1337 if (!mustWriteRVec) {
1340 mustWriteRVec =
true;
1343 if (mustWriteRVec) {
1350 outputBranch->SetObject(ab);
1352 auto *
b = outputTree.
Branch(outName.c_str(), ab);
1353 outputBranches.Insert(outName,
b);
1359 auto dataPtr = ab->
data();
1362 if (outputBranch->IsA() != TBranch::Class()) {
1363 branchAddress = dataPtr;
1364 outputBranch->SetAddress(&branchAddress);
1366 outputBranch->SetAddress(dataPtr);
1371 const auto bname = leaf->
GetName();
1372 auto *sizeLeaf = leaf->GetLeafCount();
1373 const auto sizeLeafName = sizeLeaf ? std::string(sizeLeaf->GetName()) : std::to_string(leaf->GetLenStatic());
1375 if (sizeLeaf && !outputBranches.Get(sizeLeafName)) {
1380 const auto sizeBufSize = sizeLeaf->GetBranch()->GetBasketSize();
1382 auto *sizeBranch = outputTree.
Branch(sizeLeafName.c_str(), (
void *)
nullptr,
1383 (sizeLeafName +
'/' + sizeTypeStr).c_str(), sizeBufSize);
1384 outputBranches.Insert(sizeLeafName, sizeBranch);
1387 const auto btype = leaf->GetTypeName();
1389 if (rootbtype ==
' ') {
1391 "RDataFrame::Snapshot: could not correctly construct a leaflist for C-style array in column %s. This "
1392 "column will not be written out.",
1395 const auto leaflist = std::string(bname) +
"[" + sizeLeafName +
"]/" + rootbtype;
1396 outputBranch = outputTree.
Branch(outName.c_str(), dataPtr, leaflist.c_str());
1398 outputBranches.Insert(outName, outputBranch);
1399 branch = outputBranch;
1400 branchAddress = ab->
data();
1408template <
typename... ColTypes>
1409class R__CLING_PTRCHECK(off) SnapshotHelper :
public RActionImpl<SnapshotHelper<ColTypes...>> {
1410 const std::string fFileName;
1411 const std::string fDirName;
1412 const std::string fTreeName;
1414 std::unique_ptr<TFile> fOutputFile;
1415 std::unique_ptr<TTree> fOutputTree;
1416 bool fBranchAddressesNeedReset{
true};
1419 TTree *fInputTree =
nullptr;
1421 std::vector<TBranch *> fBranches;
1422 std::vector<void *> fBranchAddresses;
1423 RBranchSet fOutputBranches;
1424 std::vector<bool> fIsDefine;
1427 using ColumnTypes_t =
TypeList<ColTypes...>;
1428 SnapshotHelper(std::string_view filename, std::string_view dirname, std::string_view treename,
1430 std::vector<bool> &&isDefine)
1431 : fFileName(filename), fDirName(dirname), fTreeName(treename), fOptions(options), fInputBranchNames(vbnames),
1433 fBranchAddresses(vbnames.
size(), nullptr), fIsDefine(std::move(isDefine))
1438 SnapshotHelper(
const SnapshotHelper &) =
delete;
1439 SnapshotHelper(SnapshotHelper &&) =
default;
1444 fInputTree =
r->GetTree();
1445 fBranchAddressesNeedReset =
true;
1448 void Exec(
unsigned int , ColTypes &... values)
1450 using ind_t = std::index_sequence_for<ColTypes...>;
1451 if (!fBranchAddressesNeedReset) {
1452 UpdateCArraysPtrs(values..., ind_t{});
1454 SetBranches(values..., ind_t{});
1455 fBranchAddressesNeedReset =
false;
1457 fOutputTree->Fill();
1460 template <std::size_t...
S>
1461 void UpdateCArraysPtrs(ColTypes &... values, std::index_sequence<S...> )
1469 int expander[] = {(fBranches[
S] && fBranchAddresses[
S] != GetData(values)
1470 ? fBranches[
S]->SetAddress(GetData(values)),
1471 fBranchAddresses[
S] = GetData(values), 0 : 0, 0)...,
1476 template <std::size_t...
S>
1477 void SetBranches(ColTypes &... values, std::index_sequence<S...> )
1480 int expander[] = {(SetBranchesHelper(fInputTree, *fOutputTree, fInputBranchNames[S], fOutputBranchNames[S],
1481 fBranches[S], fBranchAddresses[S], &values, fOutputBranches, fIsDefine[S]),
1484 fOutputBranches.AssertNoNullBranchAddresses();
1494 throw std::runtime_error(
"Snapshot: could not create output file " + fFileName);
1497 if (!fDirName.empty()) {
1500 if (checkupdate ==
"update")
1501 outputDir = fOutputFile->
mkdir(fDirName.c_str(),
"",
true);
1503 outputDir = fOutputFile->
mkdir(fDirName.c_str());
1507 std::make_unique<TTree>(fTreeName.c_str(), fTreeName.c_str(), fOptions.
fSplitLevel, outputDir);
1510 fOutputTree->SetAutoFlush(fOptions.
fAutoFlush);
1515 assert(fOutputTree !=
nullptr);
1516 assert(fOutputFile !=
nullptr);
1519 fOutputTree->AutoSave(
"flushbaskets");
1521 fOutputTree.reset();
1522 fOutputFile->Close();
1525 std::string GetActionName() {
return "Snapshot"; }
1529 return [
this](
unsigned int,
const RSampleInfo &)
mutable { fBranchAddressesNeedReset =
true; };
1534template <
typename... ColTypes>
1535class R__CLING_PTRCHECK(off) SnapshotHelperMT :
public RActionImpl<SnapshotHelperMT<ColTypes...>> {
1536 const unsigned int fNSlots;
1537 std::unique_ptr<ROOT::TBufferMerger> fMerger;
1538 std::vector<std::shared_ptr<ROOT::TBufferMergerFile>> fOutputFiles;
1539 std::vector<std::unique_ptr<TTree>> fOutputTrees;
1540 std::vector<int> fBranchAddressesNeedReset;
1541 const std::string fFileName;
1542 const std::string fDirName;
1543 const std::string fTreeName;
1547 std::vector<TTree *> fInputTrees;
1549 std::vector<std::vector<TBranch *>> fBranches;
1551 std::vector<std::vector<void *>> fBranchAddresses;
1552 std::vector<RBranchSet> fOutputBranches;
1553 std::vector<bool> fIsDefine;
1556 using ColumnTypes_t =
TypeList<ColTypes...>;
1557 SnapshotHelperMT(
const unsigned int nSlots, std::string_view filename, std::string_view dirname,
1560 : fNSlots(nSlots), fOutputFiles(fNSlots), fOutputTrees(fNSlots), fBranchAddressesNeedReset(fNSlots, 1),
1561 fFileName(filename), fDirName(dirname), fTreeName(treename), fOptions(options), fInputBranchNames(vbnames),
1563 fBranches(fNSlots, std::vector<
TBranch *>(vbnames.
size(), nullptr)),
1564 fBranchAddresses(fNSlots, std::vector<
void *>(vbnames.
size(), nullptr)), fOutputBranches(fNSlots),
1565 fIsDefine(std::move(isDefine))
1569 SnapshotHelperMT(
const SnapshotHelperMT &) =
delete;
1570 SnapshotHelperMT(SnapshotHelperMT &&) =
default;
1575 if (!fOutputFiles[slot]) {
1577 fOutputFiles[slot] = fMerger->GetFile();
1579 TDirectory *treeDirectory = fOutputFiles[slot].get();
1580 if (!fDirName.empty()) {
1582 treeDirectory = fOutputFiles[slot]->
mkdir(fDirName.c_str(),
"",
true);
1586 fOutputTrees[slot] =
1587 std::make_unique<TTree>(fTreeName.c_str(), fTreeName.c_str(), fOptions.
fSplitLevel, treeDirectory);
1590 fOutputTrees[slot]->SetImplicitMT(
false);
1592 fOutputTrees[slot]->SetAutoFlush(fOptions.
fAutoFlush);
1595 fInputTrees[slot] =
r->GetTree();
1597 fBranchAddressesNeedReset[slot] = 1;
1600 void FinalizeTask(
unsigned int slot)
1602 if (fOutputTrees[slot]->GetEntries() > 0)
1603 fOutputFiles[slot]->
Write();
1605 fOutputTrees[slot].reset(
nullptr);
1606 fOutputBranches[slot].Clear();
1609 void Exec(
unsigned int slot, ColTypes &... values)
1611 using ind_t = std::index_sequence_for<ColTypes...>;
1612 if (fBranchAddressesNeedReset[slot] == 0) {
1613 UpdateCArraysPtrs(slot, values..., ind_t{});
1615 SetBranches(slot, values..., ind_t{});
1616 fBranchAddressesNeedReset[slot] = 0;
1618 fOutputTrees[slot]->Fill();
1619 auto entries = fOutputTrees[slot]->GetEntries();
1620 auto autoFlush = fOutputTrees[slot]->GetAutoFlush();
1621 if ((autoFlush > 0) && (entries % autoFlush == 0))
1622 fOutputFiles[slot]->Write();
1625 template <std::size_t...
S>
1626 void UpdateCArraysPtrs(
unsigned int slot, ColTypes &... values, std::index_sequence<S...> )
1635 int expander[] = {(fBranches[slot][
S] && fBranchAddresses[slot][
S] != GetData(values)
1636 ? fBranches[slot][
S]->SetAddress(GetData(values)),
1637 fBranchAddresses[slot][
S] = GetData(values), 0 : 0, 0)...,
1642 template <std::size_t...
S>
1643 void SetBranches(
unsigned int slot, ColTypes &... values, std::index_sequence<S...> )
1646 int expander[] = {(SetBranchesHelper(fInputTrees[slot], *fOutputTrees[slot], fInputBranchNames[S],
1647 fOutputBranchNames[S], fBranches[slot][S], fBranchAddresses[slot][S],
1648 &values, fOutputBranches[slot], fIsDefine[S]),
1651 fOutputBranches[slot].AssertNoNullBranchAddresses();
1659 auto out_file =
TFile::Open(fFileName.c_str(), fOptions.
fMode.c_str(), fFileName.c_str(), cs);
1661 throw std::runtime_error(
"Snapshot: could not create output file " + fFileName);
1662 fMerger = std::make_unique<ROOT::TBufferMerger>(std::unique_ptr<TFile>(out_file));
1667 assert(std::any_of(fOutputFiles.begin(), fOutputFiles.end(), [](
const auto &ptr) { return ptr != nullptr; }));
1669 auto fileWritten =
false;
1670 for (
auto &
file : fOutputFiles) {
1680 "No input entries (input TTree was empty or no entry passed the Filters). Output TTree is empty.");
1684 fOutputFiles.clear();
1688 std::string GetActionName() {
return "Snapshot"; }
1692 return [
this](
unsigned int slot,
const RSampleInfo &)
mutable { fBranchAddressesNeedReset[slot] = 1; };
1696template <
typename Acc,
typename Merge,
typename R,
typename T,
typename U,
1697 bool MustCopyAssign = std::is_same<R, U>::value>
1698class R__CLING_PTRCHECK(off) AggregateHelper
1699 :
public RActionImpl<AggregateHelper<Acc, Merge, R, T, U, MustCopyAssign>> {
1702 const std::shared_ptr<U> fResult;
1703 Results<U> fAggregators;
1708 AggregateHelper(Acc &&
f, Merge &&
m,
const std::shared_ptr<U> &result,
const unsigned int nSlots)
1709 : fAggregate(std::move(
f)), fMerge(std::move(
m)), fResult(result), fAggregators(nSlots, *result)
1713 AggregateHelper(Acc &
f, Merge &
m,
const std::shared_ptr<U> &result,
const unsigned int nSlots)
1714 : fAggregate(
f), fMerge(
m), fResult(result), fAggregators(nSlots, *result)
1718 AggregateHelper(AggregateHelper &&) =
default;
1719 AggregateHelper(
const AggregateHelper &) =
delete;
1723 template <
bool MustCopyAssign_ = MustCopyAssign, std::enable_if_t<MustCopyAssign_,
int> = 0>
1724 void Exec(
unsigned int slot,
const T &value)
1726 fAggregators[slot] = fAggregate(fAggregators[slot], value);
1729 template <
bool MustCopyAssign_ = MustCopyAssign, std::enable_if_t<!MustCopyAssign_,
int> = 0>
1730 void Exec(
unsigned int slot,
const T &value)
1732 fAggregate(fAggregators[slot], value);
1737 template <typename MergeRet = typename CallableTraits<Merge>::ret_type,
1738 bool MergeAll = std::is_same<void, MergeRet>::value>
1739 std::enable_if_t<MergeAll, void> Finalize()
1741 fMerge(fAggregators);
1742 *fResult = fAggregators[0];
1745 template <typename MergeRet = typename CallableTraits<Merge>::ret_type,
1746 bool MergeTwoByTwo = std::is_same<U, MergeRet>::value>
1747 std::enable_if_t<MergeTwoByTwo, void> Finalize(...)
1749 for (
const auto &acc : fAggregators)
1750 *fResult = fMerge(*fResult, acc);
1753 U &PartialUpdate(
unsigned int slot) {
return fAggregators[slot]; }
1755 std::string GetActionName() {
return "Aggregate"; }
1757 AggregateHelper MakeNew(
void *newResult)
1759 auto &result = *
static_cast<std::shared_ptr<U> *
>(newResult);
1760 return AggregateHelper(fAggregate, fMerge, result, fAggregators.size());
typedef void(GLAPIENTRYP _GLUfuncptr)(void)
Handle_t Display_t
Display handle.
#define R__DEPRECATED(MAJOR, MINOR, REASON)
#define R(a, b, c, d, e, f, g, h, i)
static const double x1[5]
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
unsigned long long ULong64_t
#define R__CLING_PTRCHECK(ONOFF)
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
TTime operator*(const TTime &t1, const TTime &t2)
iterator begin() noexcept
pointer data() noexcept
Return a pointer to the vector's buffer, even if empty().
This class is the textual representation of the content of a columnar dataset.
This type represents a sample identifier, to be used in conjunction with RDataFrame features such as ...
typename RemoveFirstParameter< T >::type RemoveFirstParameter_t
A "std::vector"-like collection of values implementing handy operation to analyse them.
A TTree is a list of TBranches.
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any.
virtual char * GetAddress() const
Int_t GetSplitLevel() const
virtual Int_t GetBasketSize() const
TObjArray * GetListOfLeaves()
TClassRef is used to implement a permanent reference to a TClass object.
Collection abstract base class.
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
TDirectory::TContext keeps track and restore the current directory.
Describe directory structure in memory.
virtual TDirectory * mkdir(const char *name, const char *title="", Bool_t returnExistingDirectory=kFALSE)
Create a sub-directory "a" or a hierarchy of sub-directories "a/b/c/...".
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
A TGraph is an object made of two arrays X and Y with npoints each.
1-D histogram with a double per channel (see TH1 documentation)}
TH1 is the base class of all histogram classes in ROOT.
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
virtual void Add(TObject *obj)
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
virtual const char * GetTitle() const
Returns title of object.
virtual const char * GetName() const
Returns name of object.
TObject * UncheckedAt(Int_t i) const
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
void ToLower()
Change string to lower-case.
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
A TTree represents a columnar dataset.
virtual TBranch * FindBranch(const char *name)
Return the branch that correspond to the path 'branchname', which can include the name of the tree or...
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
TBranch * Branch(const char *name, T *obj, Int_t bufsize=32000, Int_t splitlevel=99)
Add a new branch, and infer the data type from the type of obj being passed.
@ kEntriesReshuffled
If set, signals that this TTree is the output of the processing of another TTree, and the entries are...
RooCmdArg Columns(Int_t ncol)
CPYCPPYY_EXTERN bool Exec(const std::string &cmd)
std::unique_ptr< RMergeableValue< T > > GetMergeableValue(RResultPtr< T > &rptr)
Retrieve a mergeable value from an RDataFrame action.
std::vector< std::string > ReplaceDotWithUnderscore(const std::vector< std::string > &columnNames)
Replace occurrences of '.
void ValidateSnapshotOutput(const RSnapshotOptions &opts, const std::string &treeName, const std::string &fileName)
char TypeName2ROOTTypeName(const std::string &b)
Convert type name (e.g.
constexpr std::size_t FindIdxTrue(const T &arr)
std::vector< std::string > ColumnNames_t
std::function< void(unsigned int, const ROOT::RDF::RSampleInfo &)> SampleCallback_t
The type of a data-block callback, registered with a RDataFrame computation graph via e....
ROOT type_traits extensions.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
int CompressionSettings(RCompressionSetting::EAlgorithm algorithm, int compressionLevel)
RooArgSet S(Args_t &&... args)
ROOT::ESTLType STLKind(std::string_view type)
Converts STL container name to number.
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container code of cont...
void Initialize(Bool_t useTMVAStyle=kTRUE)
A collection of options to steer the creation of the dataset on file.
int fAutoFlush
AutoFlush value for output tree.
std::string fMode
Mode of creation of output file.
ECAlgo fCompressionAlgorithm
Compression algorithm of output file.
int fSplitLevel
Split level of output tree.
int fCompressionLevel
Compression level of output file.
Lightweight storage for a collection of types.