19#ifndef ROOT_RDFOPERATIONS
20#define ROOT_RDFOPERATIONS
64template <
typename Helper>
67 virtual ~RActionImpl() =
default;
69 template <
typename T = Helper>
70 auto CallFinalizeTask(
unsigned int slot) ->
decltype(&T::FinalizeTask,
void())
72 static_cast<Helper *
>(
this)->FinalizeTask(slot);
75 template <
typename... Args>
76 void CallFinalizeTask(
unsigned int, Args...) {}
81 throw std::logic_error(
"`GetMergeableValue` is not implemented for this type of action.");
84 virtual std::function<
void(
unsigned int)> GetDataBlockCallback() {
return {}; }
100 std::vector<TBranch *> fBranches;
101 std::vector<std::string> fNames;
106 auto it = std::find(fNames.begin(), fNames.end(),
name);
107 if (it == fNames.end())
109 return fBranches[std::distance(fNames.begin(), it)];
112 void Insert(
const std::string &
name,
TBranch *address)
114 if (address ==
nullptr) {
115 throw std::logic_error(
"Trying to insert a null branch address.");
117 if (std::find(fBranches.begin(), fBranches.end(), address) != fBranches.end()) {
118 throw std::logic_error(
"Trying to insert a branch address that's already present.");
120 if (std::find(fNames.begin(), fNames.end(),
name) != fNames.end()) {
121 throw std::logic_error(
"Trying to insert a branch name that's already present.");
123 fNames.emplace_back(
name);
124 fBranches.emplace_back(address);
139using Results =
typename std::conditional<std::is_same<T, bool>::value, std::deque<T>, std::vector<T>>
::type;
142class ForeachSlotHelper :
public RActionImpl<ForeachSlotHelper<F>> {
148 ForeachSlotHelper(ForeachSlotHelper &&) =
default;
149 ForeachSlotHelper(
const ForeachSlotHelper &) =
delete;
153 template <
typename... Args>
154 void Exec(
unsigned int slot, Args &&... args)
157 static_assert(std::is_same<TypeList<typename std::decay<Args>::type...>, ColumnTypes_t>::value,
"");
158 fCallable(slot, std::forward<Args>(args)...);
165 std::string GetActionName() {
return "ForeachSlot"; }
168class CountHelper :
public RActionImpl<CountHelper> {
169 const std::shared_ptr<ULong64_t> fResultCount;
170 Results<ULong64_t> fCounts;
174 CountHelper(
const std::shared_ptr<ULong64_t> &resultCount,
const unsigned int nSlots);
175 CountHelper(CountHelper &&) =
default;
176 CountHelper(
const CountHelper &) =
delete;
178 void Exec(
unsigned int slot);
185 return std::make_unique<RMergeableCount>(*fResultCount);
188 ULong64_t &PartialUpdate(
unsigned int slot);
190 std::string GetActionName() {
return "Count"; }
193template <
typename ProxiedVal_t>
194class ReportHelper :
public RActionImpl<ReportHelper<ProxiedVal_t>> {
195 const std::shared_ptr<RCutFlowReport> fReport;
200 std::weak_ptr<ProxiedVal_t> fProxiedWPtr;
201 bool fReturnEmptyReport;
205 ReportHelper(
const std::shared_ptr<RCutFlowReport> &report,
const std::shared_ptr<ProxiedVal_t> &pp,
bool emptyRep)
206 : fReport(report), fProxiedWPtr(pp), fReturnEmptyReport(emptyRep){};
207 ReportHelper(ReportHelper &&) =
default;
208 ReportHelper(
const ReportHelper &) =
delete;
210 void Exec(
unsigned int ) {}
215 if (!fReturnEmptyReport && !fProxiedWPtr.expired())
216 fProxiedWPtr.lock()->Report(*fReport);
219 std::string GetActionName() {
return "Report"; }
222class FillHelper :
public RActionImpl<FillHelper> {
224 static constexpr unsigned int fgTotalBufSize = 2097152;
226 using Buf_t = std::vector<BufEl_t>;
228 std::vector<Buf_t> fBuffers;
229 std::vector<Buf_t> fWBuffers;
230 const std::shared_ptr<Hist_t> fResultHist;
231 unsigned int fNSlots;
232 unsigned int fBufSize;
234 Results<std::unique_ptr<Hist_t>> fPartialHists;
238 void UpdateMinMax(
unsigned int slot,
double v);
241 FillHelper(
const std::shared_ptr<Hist_t> &
h,
const unsigned int nSlots);
242 FillHelper(FillHelper &&) =
default;
243 FillHelper(
const FillHelper &) =
delete;
245 void Exec(
unsigned int slot,
double v);
246 void Exec(
unsigned int slot,
double v,
double w);
248 template <typename T, typename std::enable_if<IsDataContainer<T>::value || std::is_same<T, std::string>::value,
int>
::type = 0>
249 void Exec(
unsigned int slot,
const T &vs)
251 auto &thisBuf = fBuffers[slot];
253 for (
auto v = vs.begin();
v != vs.end(); ++
v) {
254 UpdateMinMax(slot, *
v);
255 thisBuf.emplace_back(*
v);
259 template <
typename T,
typename W,
260 typename std::enable_if<IsDataContainer<T>::value && IsDataContainer<W>::value,
int>
::type = 0>
261 void Exec(
unsigned int slot,
const T &vs,
const W &
ws)
263 auto &thisBuf = fBuffers[slot];
266 UpdateMinMax(slot,
v);
267 thisBuf.emplace_back(
v);
270 auto &thisWBuf = fWBuffers[slot];
272 thisWBuf.emplace_back(w);
276 template <
typename T,
typename W,
277 typename std::enable_if<IsDataContainer<T>::value && !IsDataContainer<W>::value,
int>
::type = 0>
278 void Exec(
unsigned int slot,
const T &vs,
const W w)
280 auto &thisBuf = fBuffers[slot];
282 UpdateMinMax(slot,
v);
283 thisBuf.emplace_back(
v);
286 auto &thisWBuf = fWBuffers[slot];
287 thisWBuf.insert(thisWBuf.end(), vs.size(), w);
291 template <
typename T,
typename W,
292 typename std::enable_if<IsDataContainer<W>::value && !IsDataContainer<T>::value,
int>
::type = 0>
293 void Exec(
unsigned int,
const T &,
const W &)
295 throw std::runtime_error(
296 "Cannot fill object if the type of the first column is a scalar and the one of the second a container.");
299 Hist_t &PartialUpdate(
unsigned int);
308 return std::make_unique<RMergeableFill<Hist_t>>(*fResultHist);
311 std::string GetActionName() {
return "Fill"; }
314extern template void FillHelper::Exec(
unsigned int,
const std::vector<float> &);
315extern template void FillHelper::Exec(
unsigned int,
const std::vector<double> &);
316extern template void FillHelper::Exec(
unsigned int,
const std::vector<char> &);
317extern template void FillHelper::Exec(
unsigned int,
const std::vector<int> &);
318extern template void FillHelper::Exec(
unsigned int,
const std::vector<unsigned int> &);
319extern template void FillHelper::Exec(
unsigned int,
const std::vector<float> &,
const std::vector<float> &);
320extern template void FillHelper::Exec(
unsigned int,
const std::vector<double> &,
const std::vector<double> &);
321extern template void FillHelper::Exec(
unsigned int,
const std::vector<char> &,
const std::vector<char> &);
322extern template void FillHelper::Exec(
unsigned int,
const std::vector<int> &,
const std::vector<int> &);
324FillHelper::Exec(
unsigned int,
const std::vector<unsigned int> &,
const std::vector<unsigned int> &);
326template <
typename HIST = Hist_t>
327class FillParHelper :
public RActionImpl<FillParHelper<HIST>> {
328 std::vector<HIST *> fObjects;
331 FillParHelper(FillParHelper &&) =
default;
332 FillParHelper(
const FillParHelper &) =
delete;
334 FillParHelper(
const std::shared_ptr<HIST> &
h,
const unsigned int nSlots) : fObjects(nSlots, nullptr)
336 fObjects[0] =
h.get();
338 for (
unsigned int i = 1; i < nSlots; ++i) {
339 fObjects[i] =
new HIST(*fObjects[0]);
340 if (
auto objAsHist =
dynamic_cast<TH1*
>(fObjects[i])) {
341 objAsHist->SetDirectory(
nullptr);
348 void Exec(
unsigned int slot,
double x0)
350 fObjects[slot]->Fill(x0);
353 void Exec(
unsigned int slot,
double x0,
double x1)
355 fObjects[slot]->Fill(x0,
x1);
358 void Exec(
unsigned int slot,
double x0,
double x1,
double x2)
360 fObjects[slot]->Fill(x0,
x1,
x2);
363 void Exec(
unsigned int slot,
double x0,
double x1,
double x2,
double x3)
365 fObjects[slot]->Fill(x0,
x1,
x2,
x3);
368 template <typename X0, typename std::enable_if<IsDataContainer<X0>::value || std::is_same<X0, std::string>::value,
int>
::type = 0>
369 void Exec(
unsigned int slot,
const X0 &x0s)
371 auto thisSlotH = fObjects[slot];
372 for (
auto x0 = x0s.begin(); x0 != x0s.end(); x0++) {
373 thisSlotH->Fill(*x0);
378 template <
typename X0,
typename X1,
379 typename std::enable_if<IsDataContainer<X1>::value && !IsDataContainer<X0>::value,
int>
::type = 0>
380 void Exec(
unsigned int ,
const X0 &,
const X1 &)
382 throw std::runtime_error(
383 "Cannot fill object if the type of the first column is a scalar and the one of the second a container.");
386 template <
typename X0,
typename X1,
387 typename std::enable_if<IsDataContainer<X0>::value && IsDataContainer<X1>::value,
int>
::type = 0>
388 void Exec(
unsigned int slot,
const X0 &x0s,
const X1 &x1s)
390 auto thisSlotH = fObjects[slot];
391 if (x0s.size() != x1s.size()) {
392 throw std::runtime_error(
"Cannot fill histogram with values in containers of different sizes.");
394 auto x0sIt = std::begin(x0s);
395 const auto x0sEnd = std::end(x0s);
396 auto x1sIt = std::begin(x1s);
397 for (; x0sIt != x0sEnd; x0sIt++, x1sIt++) {
398 thisSlotH->Fill(*x0sIt, *x1sIt);
402 template <
typename X0,
typename W,
403 typename std::enable_if<IsDataContainer<X0>::value && !IsDataContainer<W>::value,
int>
::type = 0>
404 void Exec(
unsigned int slot,
const X0 &x0s,
const W w)
406 auto thisSlotH = fObjects[slot];
407 for (
auto &&
x : x0s) {
408 thisSlotH->Fill(
x, w);
412 template <
typename X0,
typename X1,
typename X2,
413 typename std::enable_if<IsDataContainer<X0>::value && IsDataContainer<X1>::value && IsDataContainer<X2>::value,
415 void Exec(
unsigned int slot,
const X0 &x0s,
const X1 &x1s,
const X2 &x2s)
417 auto thisSlotH = fObjects[slot];
418 if (!(x0s.size() == x1s.size() && x1s.size() == x2s.size())) {
419 throw std::runtime_error(
"Cannot fill histogram with values in containers of different sizes.");
421 auto x0sIt = std::begin(x0s);
422 const auto x0sEnd = std::end(x0s);
423 auto x1sIt = std::begin(x1s);
424 auto x2sIt = std::begin(x2s);
425 for (; x0sIt != x0sEnd; x0sIt++, x1sIt++, x2sIt++) {
426 thisSlotH->Fill(*x0sIt, *x1sIt, *x2sIt);
430 template <
typename X0,
typename X1,
typename W,
431 typename std::enable_if<IsDataContainer<X0>::value && IsDataContainer<X1>::value && !IsDataContainer<W>::value,
433 void Exec(
unsigned int slot,
const X0 &x0s,
const X1 &x1s,
const W w)
435 auto thisSlotH = fObjects[slot];
436 if (x0s.size() != x1s.size()) {
437 throw std::runtime_error(
"Cannot fill histogram with values in containers of different sizes.");
439 auto x0sIt = std::begin(x0s);
440 const auto x0sEnd = std::end(x0s);
441 auto x1sIt = std::begin(x1s);
442 for (; x0sIt != x0sEnd; x0sIt++, x1sIt++) {
443 thisSlotH->Fill(*x0sIt, *x1sIt, w);
447 template <
typename X0,
typename X1,
typename X2,
typename X3,
448 typename std::enable_if<IsDataContainer<X0>::value && IsDataContainer<X1>::value && IsDataContainer<X2>::value &&
449 IsDataContainer<X3>::value,
451 void Exec(
unsigned int slot,
const X0 &x0s,
const X1 &x1s,
const X2 &x2s,
const X3 &x3s)
453 auto thisSlotH = fObjects[slot];
454 if (!(x0s.size() == x1s.size() && x1s.size() == x2s.size() && x1s.size() == x3s.size())) {
455 throw std::runtime_error(
"Cannot fill histogram with values in containers of different sizes.");
457 auto x0sIt = std::begin(x0s);
458 const auto x0sEnd = std::end(x0s);
459 auto x1sIt = std::begin(x1s);
460 auto x2sIt = std::begin(x2s);
461 auto x3sIt = std::begin(x3s);
462 for (; x0sIt != x0sEnd; x0sIt++, x1sIt++, x2sIt++, x3sIt++) {
463 thisSlotH->Fill(*x0sIt, *x1sIt, *x2sIt, *x3sIt);
467 template <
typename X0,
typename X1,
typename X2,
typename W,
468 typename std::enable_if<IsDataContainer<X0>::value && IsDataContainer<X1>::value && IsDataContainer<X2>::value &&
469 !IsDataContainer<W>::value,
471 void Exec(
unsigned int slot,
const X0 &x0s,
const X1 &x1s,
const X2 &x2s,
const W w)
473 auto thisSlotH = fObjects[slot];
474 if (!(x0s.size() == x1s.size() && x1s.size() == x2s.size())) {
475 throw std::runtime_error(
"Cannot fill histogram with values in containers of different sizes.");
477 auto x0sIt = std::begin(x0s);
478 const auto x0sEnd = std::end(x0s);
479 auto x1sIt = std::begin(x1s);
480 auto x2sIt = std::begin(x2s);
481 for (; x0sIt != x0sEnd; x0sIt++, x1sIt++, x2sIt++) {
482 thisSlotH->Fill(*x0sIt, *x1sIt, *x2sIt, w);
490 auto resObj = fObjects[0];
491 const auto nSlots = fObjects.size();
494 for (
unsigned int slot = 1; slot < nSlots; ++slot) {
495 l.Add(fObjects[slot]);
501 HIST &PartialUpdate(
unsigned int slot) {
return *fObjects[slot]; }
506 return std::make_unique<RMergeableFill<HIST>>(*fObjects[0]);
509 std::string GetActionName() {
return "FillPar"; }
512class FillTGraphHelper :
public ROOT::Detail::RDF::RActionImpl<FillTGraphHelper> {
517 std::vector<::TGraph *> fGraphs;
520 FillTGraphHelper(FillTGraphHelper &&) =
default;
521 FillTGraphHelper(
const FillTGraphHelper &) =
delete;
525 FillTGraphHelper(
const std::shared_ptr<::TGraph> &
g,
const unsigned int nSlots) : fGraphs(nSlots, nullptr)
527 fGraphs[0] =
g.get();
529 for (
unsigned int i = 1; i < nSlots; ++i) {
530 fGraphs[i] =
new TGraph(*fGraphs[0]);
537 template <
typename X0,
typename X1,
538 typename std::enable_if<IsDataContainer<X0>::value && IsDataContainer<X1>::value,
int>
::type = 0>
539 void Exec(
unsigned int slot,
const X0 &x0s,
const X1 &x1s)
541 if (x0s.size() != x1s.size()) {
542 throw std::runtime_error(
"Cannot fill Graph with values in containers of different sizes.");
544 auto thisSlotG = fGraphs[slot];
545 auto x0sIt = std::begin(x0s);
546 const auto x0sEnd = std::end(x0s);
547 auto x1sIt = std::begin(x1s);
548 for (; x0sIt != x0sEnd; x0sIt++, x1sIt++) {
549 thisSlotG->SetPoint(thisSlotG->GetN(), *x0sIt, *x1sIt);
553 template <
typename X0,
typename X1>
554 void Exec(
unsigned int slot, X0 x0, X1
x1)
556 auto thisSlotG = fGraphs[slot];
557 thisSlotG->SetPoint(thisSlotG->GetN(), x0,
x1);
562 const auto nSlots = fGraphs.size();
563 auto resGraph = fGraphs[0];
566 for (
unsigned int slot = 1; slot < nSlots; ++slot) {
567 l.Add(fGraphs[slot]);
575 return std::make_unique<RMergeableFill<Result_t>>(*fGraphs[0]);
578 std::string GetActionName() {
return "Graph"; }
580 Result_t &PartialUpdate(
unsigned int slot) {
return *fGraphs[slot]; }
589template <
typename V,
typename COLL>
590void FillColl(V&&
v, COLL&
c) {
595template <
typename COLL>
596void FillColl(
bool v, COLL&
c) {
602template <
typename RealT_t,
typename T,
typename COLL>
603class TakeHelper :
public RActionImpl<TakeHelper<RealT_t, T, COLL>> {
604 Results<std::shared_ptr<COLL>> fColls;
608 TakeHelper(
const std::shared_ptr<COLL> &resultColl,
const unsigned int nSlots)
610 fColls.emplace_back(resultColl);
611 for (
unsigned int i = 1; i < nSlots; ++i)
612 fColls.emplace_back(std::make_shared<COLL>());
614 TakeHelper(TakeHelper &&);
615 TakeHelper(
const TakeHelper &) =
delete;
619 void Exec(
unsigned int slot, T &
v) { FillColl(
v, *fColls[slot]); }
625 auto rColl = fColls[0];
626 for (
unsigned int i = 1; i < fColls.size(); ++i) {
627 const auto &coll = fColls[i];
628 const auto end = coll->end();
631 for (
auto j = coll->begin(); j != end; j++) {
632 FillColl(*j, *rColl);
637 COLL &PartialUpdate(
unsigned int slot) {
return *fColls[slot].get(); }
639 std::string GetActionName() {
return "Take"; }
644template <
typename RealT_t,
typename T>
645class TakeHelper<RealT_t,
T, std::vector<T>> :
public RActionImpl<TakeHelper<RealT_t, T, std::vector<T>>> {
646 Results<std::shared_ptr<std::vector<T>>> fColls;
650 TakeHelper(
const std::shared_ptr<std::vector<T>> &resultColl,
const unsigned int nSlots)
652 fColls.emplace_back(resultColl);
653 for (
unsigned int i = 1; i < nSlots; ++i) {
654 auto v = std::make_shared<std::vector<T>>();
656 fColls.emplace_back(
v);
659 TakeHelper(TakeHelper &&);
660 TakeHelper(
const TakeHelper &) =
delete;
664 void Exec(
unsigned int slot, T &
v) { FillColl(
v, *fColls[slot]); }
672 for (
auto &coll : fColls)
673 totSize += coll->size();
674 auto rColl = fColls[0];
675 rColl->reserve(totSize);
676 for (
unsigned int i = 1; i < fColls.size(); ++i) {
677 auto &coll = fColls[i];
678 rColl->insert(rColl->end(), coll->begin(), coll->end());
682 std::vector<T> &PartialUpdate(
unsigned int slot) {
return *fColls[slot]; }
684 std::string GetActionName() {
return "Take"; }
689template <
typename RealT_t,
typename COLL>
690class TakeHelper<RealT_t,
RVec<RealT_t>, COLL> :
public RActionImpl<TakeHelper<RealT_t, RVec<RealT_t>, COLL>> {
691 Results<std::shared_ptr<COLL>> fColls;
695 TakeHelper(
const std::shared_ptr<COLL> &resultColl,
const unsigned int nSlots)
697 fColls.emplace_back(resultColl);
698 for (
unsigned int i = 1; i < nSlots; ++i)
699 fColls.emplace_back(std::make_shared<COLL>());
701 TakeHelper(TakeHelper &&);
702 TakeHelper(
const TakeHelper &) =
delete;
712 auto rColl = fColls[0];
713 for (
unsigned int i = 1; i < fColls.size(); ++i) {
714 auto &coll = fColls[i];
715 for (
auto &
v : *coll) {
716 rColl->emplace_back(
v);
721 std::string GetActionName() {
return "Take"; }
726template <
typename RealT_t>
727class TakeHelper<RealT_t,
RVec<RealT_t>, std::vector<RealT_t>>
728 :
public RActionImpl<TakeHelper<RealT_t, RVec<RealT_t>, std::vector<RealT_t>>> {
730 Results<std::shared_ptr<std::vector<std::vector<RealT_t>>>> fColls;
734 TakeHelper(
const std::shared_ptr<std::vector<std::vector<RealT_t>>> &resultColl,
const unsigned int nSlots)
736 fColls.emplace_back(resultColl);
737 for (
unsigned int i = 1; i < nSlots; ++i) {
738 auto v = std::make_shared<std::vector<RealT_t>>();
740 fColls.emplace_back(
v);
743 TakeHelper(TakeHelper &&);
744 TakeHelper(
const TakeHelper &) =
delete;
756 for (
auto &coll : fColls)
757 totSize += coll->size();
758 auto rColl = fColls[0];
759 rColl->reserve(totSize);
760 for (
unsigned int i = 1; i < fColls.size(); ++i) {
761 auto &coll = fColls[i];
762 rColl->insert(rColl->end(), coll->begin(), coll->end());
766 std::string GetActionName() {
return "Take"; }
772template <
typename RealT_t,
typename T,
typename COLL>
773TakeHelper<RealT_t, T, COLL>::TakeHelper(TakeHelper<RealT_t, T, COLL> &&) =
default;
774template <
typename RealT_t,
typename T>
775TakeHelper<RealT_t, T, std::vector<T>>::TakeHelper(TakeHelper<RealT_t, T, std::vector<T>> &&) =
default;
776template <
typename RealT_t,
typename COLL>
777TakeHelper<RealT_t, RVec<RealT_t>, COLL>::TakeHelper(TakeHelper<RealT_t,
RVec<RealT_t>, COLL> &&) =
default;
778template <
typename RealT_t>
779TakeHelper<RealT_t, RVec<RealT_t>, std::vector<RealT_t>>::TakeHelper(TakeHelper<RealT_t,
RVec<RealT_t>, std::vector<RealT_t>> &&) =
default;
783extern template class TakeHelper<bool, bool, std::vector<bool>>;
784extern template class TakeHelper<unsigned int, unsigned int, std::vector<unsigned int>>;
785extern template class TakeHelper<unsigned long, unsigned long, std::vector<unsigned long>>;
786extern template class TakeHelper<unsigned long long, unsigned long long, std::vector<unsigned long long>>;
787extern template class TakeHelper<int, int, std::vector<int>>;
788extern template class TakeHelper<long, long, std::vector<long>>;
789extern template class TakeHelper<long long, long long, std::vector<long long>>;
790extern template class TakeHelper<float, float, std::vector<float>>;
791extern template class TakeHelper<double, double, std::vector<double>>;
795template <
typename ResultType>
796class MinHelper :
public RActionImpl<MinHelper<ResultType>> {
797 const std::shared_ptr<ResultType> fResultMin;
798 Results<ResultType> fMins;
801 MinHelper(MinHelper &&) =
default;
802 MinHelper(
const std::shared_ptr<ResultType> &minVPtr,
const unsigned int nSlots)
803 : fResultMin(minVPtr), fMins(nSlots, std::numeric_limits<ResultType>::max())
807 void Exec(
unsigned int slot, ResultType
v) { fMins[slot] = std::min(
v, fMins[slot]); }
811 template <typename T, typename std::enable_if<IsDataContainer<T>::value,
int>
::type = 0>
812 void Exec(
unsigned int slot,
const T &vs)
815 fMins[slot] = std::min(static_cast<ResultType>(
v), fMins[slot]);
822 *fResultMin = std::numeric_limits<ResultType>::max();
823 for (
auto &
m : fMins)
824 *fResultMin = std::min(
m, *fResultMin);
830 return std::make_unique<RMergeableMin<ResultType>>(*fResultMin);
833 ResultType &PartialUpdate(
unsigned int slot) {
return fMins[slot]; }
835 std::string GetActionName() {
return "Min"; }
845template <
typename ResultType>
846class MaxHelper :
public RActionImpl<MaxHelper<ResultType>> {
847 const std::shared_ptr<ResultType> fResultMax;
848 Results<ResultType> fMaxs;
851 MaxHelper(MaxHelper &&) =
default;
852 MaxHelper(
const MaxHelper &) =
delete;
853 MaxHelper(
const std::shared_ptr<ResultType> &maxVPtr,
const unsigned int nSlots)
854 : fResultMax(maxVPtr), fMaxs(nSlots, std::numeric_limits<ResultType>::lowest())
859 void Exec(
unsigned int slot, ResultType
v) { fMaxs[slot] = std::max(
v, fMaxs[slot]); }
861 template <typename T, typename std::enable_if<IsDataContainer<T>::value,
int>
::type = 0>
862 void Exec(
unsigned int slot,
const T &vs)
865 fMaxs[slot] = std::max(static_cast<ResultType>(
v), fMaxs[slot]);
872 *fResultMax = std::numeric_limits<ResultType>::lowest();
873 for (
auto &
m : fMaxs) {
874 *fResultMax = std::max(
m, *fResultMax);
881 return std::make_unique<RMergeableMax<ResultType>>(*fResultMax);
884 ResultType &PartialUpdate(
unsigned int slot) {
return fMaxs[slot]; }
886 std::string GetActionName() {
return "Max"; }
896template <
typename ResultType>
897class SumHelper :
public RActionImpl<SumHelper<ResultType>> {
898 const std::shared_ptr<ResultType> fResultSum;
899 Results<ResultType> fSums;
904 template <
typename T = ResultType>
905 auto NeutralElement(
const T &
v,
int ) ->
decltype(
v -
v)
910 template <
typename T = ResultType,
typename Dummy =
int>
911 ResultType NeutralElement(
const T &, Dummy)
917 SumHelper(SumHelper &&) =
default;
918 SumHelper(
const SumHelper &) =
delete;
919 SumHelper(
const std::shared_ptr<ResultType> &sumVPtr,
const unsigned int nSlots)
920 : fResultSum(sumVPtr), fSums(nSlots, NeutralElement(*sumVPtr, -1))
925 void Exec(
unsigned int slot, ResultType
v) { fSums[slot] +=
v; }
927 template <typename T, typename std::enable_if<IsDataContainer<T>::value,
int>
::type = 0>
928 void Exec(
unsigned int slot,
const T &vs)
931 fSums[slot] += static_cast<ResultType>(
v);
938 for (
auto &
m : fSums)
945 return std::make_unique<RMergeableSum<ResultType>>(*fResultSum);
948 ResultType &PartialUpdate(
unsigned int slot) {
return fSums[slot]; }
950 std::string GetActionName() {
return "Sum"; }
953class MeanHelper :
public RActionImpl<MeanHelper> {
954 const std::shared_ptr<double> fResultMean;
955 std::vector<ULong64_t> fCounts;
956 std::vector<double> fSums;
957 std::vector<double> fPartialMeans;
960 MeanHelper(
const std::shared_ptr<double> &meanVPtr,
const unsigned int nSlots);
961 MeanHelper(MeanHelper &&) =
default;
962 MeanHelper(
const MeanHelper &) =
delete;
964 void Exec(
unsigned int slot,
double v);
966 template <typename T, typename std::enable_if<IsDataContainer<T>::value,
int>
::type = 0>
967 void Exec(
unsigned int slot,
const T &vs)
969 for (
auto &&
v : vs) {
982 const ULong64_t counts = std::accumulate(fCounts.begin(), fCounts.end(), 0ull);
983 return std::make_unique<RMergeableMean>(*fResultMean, counts);
986 double &PartialUpdate(
unsigned int slot);
988 std::string GetActionName() {
return "Mean"; }
991extern template void MeanHelper::Exec(
unsigned int,
const std::vector<float> &);
992extern template void MeanHelper::Exec(
unsigned int,
const std::vector<double> &);
993extern template void MeanHelper::Exec(
unsigned int,
const std::vector<char> &);
994extern template void MeanHelper::Exec(
unsigned int,
const std::vector<int> &);
995extern template void MeanHelper::Exec(
unsigned int,
const std::vector<unsigned int> &);
997class StdDevHelper :
public RActionImpl<StdDevHelper> {
999 const unsigned int fNSlots;
1000 const std::shared_ptr<double> fResultStdDev;
1002 std::vector<ULong64_t> fCounts;
1004 std::vector<double> fMeans;
1006 std::vector<double> fDistancesfromMean;
1009 StdDevHelper(
const std::shared_ptr<double> &meanVPtr,
const unsigned int nSlots);
1010 StdDevHelper(StdDevHelper &&) =
default;
1011 StdDevHelper(
const StdDevHelper &) =
delete;
1013 void Exec(
unsigned int slot,
double v);
1015 template <typename T, typename std::enable_if<IsDataContainer<T>::value,
int>
::type = 0>
1016 void Exec(
unsigned int slot,
const T &vs)
1018 for (
auto &&
v : vs) {
1030 const ULong64_t counts = std::accumulate(fCounts.begin(), fCounts.end(), 0ull);
1032 std::inner_product(fMeans.begin(), fMeans.end(), fCounts.begin(), 0.) /
static_cast<Double_t>(counts);
1033 return std::make_unique<RMergeableStdDev>(*fResultStdDev, counts, mean);
1036 std::string GetActionName() {
return "StdDev"; }
1039extern template void StdDevHelper::Exec(
unsigned int,
const std::vector<float> &);
1040extern template void StdDevHelper::Exec(
unsigned int,
const std::vector<double> &);
1041extern template void StdDevHelper::Exec(
unsigned int,
const std::vector<char> &);
1042extern template void StdDevHelper::Exec(
unsigned int,
const std::vector<int> &);
1043extern template void StdDevHelper::Exec(
unsigned int,
const std::vector<unsigned int> &);
1045template <
typename PrevNodeType>
1046class DisplayHelper :
public RActionImpl<DisplayHelper<PrevNodeType>> {
1049 const std::shared_ptr<Display_t> fDisplayerHelper;
1050 const std::shared_ptr<PrevNodeType> fPrevNode;
1053 DisplayHelper(
const std::shared_ptr<Display_t> &
d,
const std::shared_ptr<PrevNodeType> &prevNode)
1054 : fDisplayerHelper(
d), fPrevNode(prevNode)
1057 DisplayHelper(DisplayHelper &&) =
default;
1058 DisplayHelper(
const DisplayHelper &) =
delete;
1061 template <
typename...
Columns>
1062 void Exec(
unsigned int, Columns &... columns)
1064 fDisplayerHelper->AddRow(columns...);
1065 if (!fDisplayerHelper->HasNext()) {
1066 fPrevNode->StopProcessing();
1074 std::string GetActionName() {
return "Display"; }
1084 std::size_t
fSize = 0;
1085 bool *fBools =
nullptr;
1089 auto b =
new bool[
fSize];
1090 std::copy(
v.begin(),
v.end(),
b);
1095 BoolArray() =
default;
1097 BoolArray(
const BoolArray &
b) =
delete;
1098 BoolArray &
operator=(
const BoolArray &
b) =
delete;
1099 BoolArray(BoolArray &&
b)
1115 ~BoolArray() {
delete[] fBools; }
1116 std::size_t
Size()
const {
return fSize; }
1117 bool *Data() {
return fBools; }
1124 boolArrays[outName] = BoolArray(
v);
1125 return boolArrays[outName].Data();
1128template <
typename T>
1141template <
typename T>
1147template <
typename T>
1153template <
typename T>
1155 const std::string &
name,
TBranch *&branch,
void *&branchAddress, T *address,
1156 RBranchSet &outputBranches)
1158 static TClassRef TBOClRef(
"TBranchObject");
1160 TBranch *inputBranch = inputTree ? inputTree->
GetBranch(inName.c_str()) :
nullptr;
1162 auto *outputBranch = outputBranches.Get(
name);
1165 if (inputBranch && inputBranch->IsA() == TBOClRef) {
1166 outputBranch->SetAddress(
reinterpret_cast<T **
>(inputBranch->
GetAddress()));
1167 }
else if (outputBranch->IsA() != TBranch::Class()) {
1168 branchAddress = address;
1169 outputBranch->SetAddress(&branchAddress);
1171 outputBranch->SetAddress(address);
1172 branchAddress = address;
1185 if (inputBranch->IsA() == TBOClRef) {
1188 outputTree.
Branch(
name.c_str(),
reinterpret_cast<T **
>(inputBranch->
GetAddress()), bufSize, splitLevel);
1190 outputBranch = outputTree.
Branch(
name.c_str(), address, bufSize, splitLevel);
1193 outputBranch = outputTree.
Branch(
name.c_str(), address);
1195 outputBranches.Insert(
name, outputBranch);
1198 branchAddress =
nullptr;
1210template <
typename T>
1212 const std::string &outName,
TBranch *&branch,
void *&branchAddress,
RVec<T> *ab,
1213 RBranchSet &outputBranches)
1215 TBranch *inputBranch =
nullptr;
1217 inputBranch = inputTree->
GetBranch(inName.c_str());
1220 inputBranch = inputTree->
FindBranch(inName.c_str());
1223 auto *outputBranch = outputBranches.Get(outName);
1224 const bool isTClonesArray = inputBranch !=
nullptr && std::string(inputBranch->
GetClassName()) ==
"TClonesArray";
1225 const auto mustWriteStdVec = !inputBranch || isTClonesArray ||
1228 if (mustWriteStdVec) {
1234 if (isTClonesArray) {
1236 "Branch \"%s\" contains TClonesArrays but the type specified to Snapshot was RVec<T>. The branch will "
1237 "be written out as a std::vector instead of a TClonesArray. Specify that the type of the branch is "
1238 "TClonesArray as a Snapshot template parameter to write out a TClonesArray instead.", inName.c_str());
1241 branchAddress = &(ab->
fData);
1242 outputBranch->SetAddress(&branchAddress);
1244 auto *
b = outputTree.
Branch(outName.c_str(), &(ab->
fData));
1245 outputBranches.Insert(outName,
b);
1252 const auto bname = leaf->
GetName();
1253 const auto counterStr =
1254 leaf->GetLeafCount() ? std::string(leaf->GetLeafCount()->GetName()) : std::to_string(leaf->GetLenStatic());
1255 const auto btype = leaf->GetTypeName();
1257 const auto leaflist = std::string(bname) +
"[" + counterStr +
"]/" + rootbtype;
1261 auto dataPtr = UpdateBoolArrayIfBool(boolArrays, *ab, outName);
1264 if (outputBranch->IsA() != TBranch::Class()) {
1265 branchAddress = dataPtr;
1266 outputBranch->SetAddress(&branchAddress);
1268 outputBranch->SetAddress(dataPtr);
1271 outputBranch = outputTree.
Branch(outName.c_str(), dataPtr, leaflist.c_str());
1273 outputBranches.Insert(outName, outputBranch);
1275 if (!std::is_same<bool, T>::value) {
1276 branch = outputBranch;
1277 branchAddress = GetData(*ab);
1283template <
typename T>
1290 if (boolArrays.find(outName) == boolArrays.end())
1293 if (
v.size() > boolArrays[outName].Size()) {
1294 boolArrays[outName] = BoolArray(
v);
1298 std::copy(
v.begin(),
v.end(), boolArrays[outName].Data());
1305template <
typename... ColTypes>
1306class SnapshotHelper :
public RActionImpl<SnapshotHelper<ColTypes...>> {
1307 const std::string fFileName;
1308 const std::string fDirName;
1309 const std::string fTreeName;
1311 std::unique_ptr<TFile> fOutputFile;
1312 std::unique_ptr<TTree> fOutputTree;
1313 bool fBranchAddressesNeedReset{
true};
1316 TTree *fInputTree =
nullptr;
1319 std::vector<TBranch *> fBranches;
1320 std::vector<void *> fBranchAddresses;
1321 RBranchSet fOutputBranches;
1324 using ColumnTypes_t =
TypeList<ColTypes...>;
1325 SnapshotHelper(std::string_view filename, std::string_view dirname, std::string_view treename,
1327 : fFileName(filename), fDirName(dirname), fTreeName(treename), fOptions(options), fInputBranchNames(vbnames),
1329 fBranchAddresses(vbnames.size(), nullptr)
1334 SnapshotHelper(
const SnapshotHelper &) =
delete;
1335 SnapshotHelper(SnapshotHelper &&) =
default;
1340 fInputTree =
r->GetTree();
1341 fBranchAddressesNeedReset =
true;
1344 void Exec(
unsigned int , ColTypes &... values)
1346 using ind_t = std::index_sequence_for<ColTypes...>;
1347 if (!fBranchAddressesNeedReset) {
1348 UpdateCArraysPtrs(values..., ind_t{});
1350 SetBranches(values..., ind_t{});
1351 fBranchAddressesNeedReset =
false;
1353 UpdateBoolArrays(values..., ind_t{});
1354 fOutputTree->Fill();
1357 template <std::size_t...
S>
1358 void UpdateCArraysPtrs(ColTypes &... values, std::index_sequence<S...> )
1366 int expander[] = {(fBranches[
S] && fBranchAddresses[
S] != GetData(values)
1367 ? fBranches[
S]->SetAddress(GetData(values)),
1368 fBranchAddresses[
S] = GetData(values), 0 : 0, 0)...,
1373 template <std::size_t...
S>
1374 void SetBranches(ColTypes &... values, std::index_sequence<S...> )
1378 (
SetBranchesHelper(fBoolArrays, fInputTree, *fOutputTree, fInputBranchNames[S], fOutputBranchNames[S],
1379 fBranches[S], fBranchAddresses[S], &values, fOutputBranches),
1385 template <std::size_t...
S>
1386 void UpdateBoolArrays(ColTypes &...values, std::index_sequence<S...> )
1388 int expander[] = {(UpdateBoolArray(fBoolArrays, values, fOutputBranchNames[S], *fOutputTree), 0)..., 0};
1398 throw std::runtime_error(
"Snapshot: could not create output file " + fFileName);
1401 if (!fDirName.empty()) {
1404 if (checkupdate ==
"update")
1405 outputDir = fOutputFile->
mkdir(fDirName.c_str(),
"",
true);
1407 outputDir = fOutputFile->
mkdir(fDirName.c_str());
1411 std::make_unique<TTree>(fTreeName.c_str(), fTreeName.c_str(), fOptions.
fSplitLevel, outputDir);
1414 fOutputTree->SetAutoFlush(fOptions.
fAutoFlush);
1423 fOutputTree->AutoSave(
"flushbaskets");
1425 fOutputTree.reset();
1426 fOutputFile->Close();
1429 std::string GetActionName() {
return "Snapshot"; }
1431 std::function<
void(
unsigned int)> GetDataBlockCallback() final
1433 return [
this](
unsigned int)
mutable { fBranchAddressesNeedReset =
true; };
1438template <
typename... ColTypes>
1439class SnapshotHelperMT :
public RActionImpl<SnapshotHelperMT<ColTypes...>> {
1440 const unsigned int fNSlots;
1441 std::unique_ptr<ROOT::Experimental::TBufferMerger> fMerger;
1442 std::vector<std::shared_ptr<ROOT::Experimental::TBufferMergerFile>> fOutputFiles;
1443 std::vector<std::unique_ptr<TTree>> fOutputTrees;
1444 std::vector<int> fBranchAddressesNeedReset;
1445 const std::string fFileName;
1446 const std::string fDirName;
1447 const std::string fTreeName;
1451 std::vector<TTree *> fInputTrees;
1452 std::vector<BoolArrayMap> fBoolArrays;
1454 std::vector<std::vector<TBranch *>> fBranches;
1456 std::vector<std::vector<void *>> fBranchAddresses;
1457 std::vector<RBranchSet> fOutputBranches;
1460 using ColumnTypes_t =
TypeList<ColTypes...>;
1461 SnapshotHelperMT(
const unsigned int nSlots, std::string_view filename, std::string_view dirname,
1464 : fNSlots(nSlots), fOutputFiles(fNSlots), fOutputTrees(fNSlots), fBranchAddressesNeedReset(fNSlots, 1),
1465 fFileName(filename), fDirName(dirname), fTreeName(treename), fOptions(options), fInputBranchNames(vbnames),
1467 fBranches(fNSlots, std::vector<
TBranch *>(vbnames.size(), nullptr)),
1468 fBranchAddresses(fNSlots, std::vector<
void *>(vbnames.size(), nullptr)), fOutputBranches(fNSlots)
1472 SnapshotHelperMT(
const SnapshotHelperMT &) =
delete;
1473 SnapshotHelperMT(SnapshotHelperMT &&) =
default;
1478 if (!fOutputFiles[slot]) {
1480 fOutputFiles[slot] = fMerger->GetFile();
1482 TDirectory *treeDirectory = fOutputFiles[slot].get();
1483 if (!fDirName.empty()) {
1485 treeDirectory = fOutputFiles[slot]->
mkdir(fDirName.c_str(),
"",
true);
1489 fOutputTrees[slot] =
1490 std::make_unique<TTree>(fTreeName.c_str(), fTreeName.c_str(), fOptions.
fSplitLevel, treeDirectory);
1493 fOutputTrees[slot]->SetImplicitMT(
false);
1495 fOutputTrees[slot]->SetAutoFlush(fOptions.
fAutoFlush);
1498 fInputTrees[slot] =
r->GetTree();
1500 fBranchAddressesNeedReset[slot] = 1;
1503 void FinalizeTask(
unsigned int slot)
1505 if (fOutputTrees[slot]->GetEntries() > 0)
1506 fOutputFiles[slot]->
Write();
1508 fOutputTrees[slot].reset(
nullptr);
1509 fOutputBranches[slot].Clear();
1512 void Exec(
unsigned int slot, ColTypes &... values)
1514 using ind_t = std::index_sequence_for<ColTypes...>;
1515 if (fBranchAddressesNeedReset[slot] == 0) {
1516 UpdateCArraysPtrs(slot, values..., ind_t{});
1518 SetBranches(slot, values..., ind_t{});
1519 fBranchAddressesNeedReset[slot] = 0;
1521 UpdateBoolArrays(slot, values..., ind_t{});
1522 fOutputTrees[slot]->Fill();
1523 auto entries = fOutputTrees[slot]->GetEntries();
1524 auto autoFlush = fOutputTrees[slot]->GetAutoFlush();
1525 if ((autoFlush > 0) && (entries % autoFlush == 0))
1526 fOutputFiles[slot]->Write();
1529 template <std::size_t...
S>
1530 void UpdateCArraysPtrs(
unsigned int slot, ColTypes &... values, std::index_sequence<S...> )
1539 int expander[] = {(fBranches[slot][
S] && fBranchAddresses[slot][
S] != GetData(values)
1540 ? fBranches[slot][
S]->SetAddress(GetData(values)),
1541 fBranchAddresses[slot][
S] = GetData(values), 0 : 0, 0)...,
1546 template <std::size_t...
S>
1547 void SetBranches(
unsigned int slot, ColTypes &... values, std::index_sequence<S...> )
1550 int expander[] = {(
SetBranchesHelper(fBoolArrays[slot], fInputTrees[slot], *fOutputTrees[slot],
1551 fInputBranchNames[S], fOutputBranchNames[S], fBranches[slot][S],
1552 fBranchAddresses[slot][S], &values, fOutputBranches[slot]),
1559 template <std::size_t...
S>
1560 void UpdateBoolArrays(
unsigned int slot, ColTypes &... values, std::index_sequence<S...> )
1564 (UpdateBoolArray(fBoolArrays[slot], values, fOutputBranchNames[S], *fOutputTrees[slot]), 0)..., 0};
1571 auto out_file =
TFile::Open(fFileName.c_str(), fOptions.
fMode.c_str(), fFileName.c_str(), cs);
1573 throw std::runtime_error(
"Snapshot: could not create output file " + fFileName);
1574 fMerger = std::make_unique<ROOT::Experimental::TBufferMerger>(std::unique_ptr<TFile>(out_file));
1579 const bool allNullFiles =
1580 std::all_of(fOutputFiles.begin(), fOutputFiles.end(),
1581 [](
const std::shared_ptr<ROOT::Experimental::TBufferMergerFile> &ptr) { return ptr == nullptr; });
1584 auto fileWritten =
false;
1585 for (
auto &
file : fOutputFiles) {
1595 "No input entries (input TTree was empty or no entry passed the Filters). Output TTree is empty.");
1599 fOutputFiles.clear();
1603 std::string GetActionName() {
return "Snapshot"; }
1605 std::function<
void(
unsigned int)> GetDataBlockCallback() final
1607 return [
this](
unsigned int slot)
mutable { fBranchAddressesNeedReset[slot] = 1; };
1611template <
typename Acc,
typename Merge,
typename R,
typename T,
typename U,
1612 bool MustCopyAssign = std::is_same<R, U>::value>
1613class AggregateHelper :
public RActionImpl<AggregateHelper<Acc, Merge, R, T, U, MustCopyAssign>> {
1616 const std::shared_ptr<U> fResult;
1617 Results<U> fAggregators;
1621 AggregateHelper(Acc &&
f, Merge &&
m,
const std::shared_ptr<U> &result,
const unsigned int nSlots)
1622 : fAggregate(std::move(
f)), fMerge(std::move(
m)), fResult(result), fAggregators(nSlots, *result)
1625 AggregateHelper(AggregateHelper &&) =
default;
1626 AggregateHelper(
const AggregateHelper &) =
delete;
1630 template <bool MustCopyAssign_ = MustCopyAssign, typename std::enable_if<MustCopyAssign_, int>::type = 0>
1631 void Exec(
unsigned int slot,
const T &value)
1633 fAggregators[slot] = fAggregate(fAggregators[slot], value);
1636 template <bool MustCopyAssign_ = MustCopyAssign, typename std::enable_if<!MustCopyAssign_, int>::type = 0>
1637 void Exec(
unsigned int slot,
const T &value)
1639 fAggregate(fAggregators[slot], value);
1644 template <typename MergeRet = typename CallableTraits<Merge>::ret_type,
1645 bool MergeAll = std::is_same<void, MergeRet>::value>
1646 typename std::enable_if<MergeAll, void>::type Finalize()
1648 fMerge(fAggregators);
1649 *fResult = fAggregators[0];
1652 template <typename MergeRet = typename CallableTraits<Merge>::ret_type,
1653 bool MergeTwoByTwo = std::is_same<U, MergeRet>::value>
1654 typename std::enable_if<MergeTwoByTwo, void>::type Finalize(...)
1656 for (
const auto &acc : fAggregators)
1657 *fResult = fMerge(*fResult, acc);
1660 U &PartialUpdate(
unsigned int slot) {
return fAggregators[slot]; }
1662 std::string GetActionName() {
return "Aggregate"; }
Handle_t Display_t
Display handle.
static const double x2[5]
static const double x1[5]
static const double x3[11]
unsigned long long ULong64_t
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Binding & operator=(OUT(*fun)(void))
typedef void((*Func_t)())
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.
iterator begin() noexcept
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.
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
Small helper to keep current directory context.
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 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.
virtual Int_t SetBranchAddress(const char *bname, void *add, TBranch **ptr=0)
Change branch address, dealing with clone trees properly.
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::vector< std::string > ColumnNames_t
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)
void SetBranchesHelper(BoolArrayMap &boolArrays, TTree *inputTree, TTree &outputTree, const std::string &inName, const std::string &outName, TBranch *&branch, void *&branchAddress, ROOT::VecOps::RVec< T > *ab, RBranchSet &outputBranches)
char TypeName2ROOTTypeName(const std::string &b)
Convert type name (e.g.
std::map< std::string, BoolArray > BoolArrayMap
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(const RooAbsArg &v1)
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.