11 #ifndef ROOT_RDFOPERATIONS 12 #define ROOT_RDFOPERATIONS 20 #include <type_traits> 52 template <
typename Helper>
57 template <
typename T = Helper>
58 auto CallFinalizeTask(
unsigned int slot) -> decltype(&T::FinalizeTask,
void())
60 static_cast<Helper*
>(
this)->FinalizeTask(slot);
63 template <
typename... Args>
64 void CallFinalizeTask(
unsigned int, Args...) {}
84 using Results =
typename std::conditional<std::is_same<T, bool>::value, std::deque<T>, std::vector<T>>
::type;
88 class ForeachSlotHelper :
public RActionImpl<ForeachSlotHelper<F>> {
92 using ColumnTypes_t = RemoveFirstParameter_t<typename CallableTraits<F>::arg_types>;
93 ForeachSlotHelper(
F &&
f) : fCallable(
f) {}
94 ForeachSlotHelper(ForeachSlotHelper &&) =
default;
95 ForeachSlotHelper(
const ForeachSlotHelper &) =
delete;
99 template <
typename... Args>
100 void Exec(
unsigned int slot, Args &&... args)
104 fCallable(slot, std::forward<Args>(args)...);
112 class CountHelper :
public RActionImpl<CountHelper> {
113 const std::shared_ptr<ULong64_t> fResultCount;
114 Results<ULong64_t> fCounts;
118 CountHelper(
const std::shared_ptr<ULong64_t> &resultCount,
const unsigned int nSlots);
119 CountHelper(CountHelper &&) =
default;
120 CountHelper(
const CountHelper &) =
delete;
122 void Exec(
unsigned int slot);
125 ULong64_t &PartialUpdate(
unsigned int slot);
128 template <
typename ProxiedVal_t>
129 class ReportHelper :
public RActionImpl<ReportHelper<ProxiedVal_t>> {
130 const std::shared_ptr<RCutFlowReport> fReport;
135 std::weak_ptr<ProxiedVal_t> fProxiedWPtr;
136 bool fReturnEmptyReport;
140 ReportHelper(
const std::shared_ptr<RCutFlowReport> &report,
const std::shared_ptr<ProxiedVal_t> &pp,
bool emptyRep)
141 : fReport(report), fProxiedWPtr(pp), fReturnEmptyReport(emptyRep){};
142 ReportHelper(ReportHelper &&) =
default;
143 ReportHelper(
const ReportHelper &) =
delete;
145 void Exec(
unsigned int ) {}
150 if (!fReturnEmptyReport && !fProxiedWPtr.expired())
151 fProxiedWPtr.lock()->Report(*fReport);
155 class FillHelper :
public RActionImpl<FillHelper> {
157 static constexpr
unsigned int fgTotalBufSize = 2097152;
158 using BufEl_t = double;
159 using Buf_t = std::vector<BufEl_t>;
161 std::vector<Buf_t> fBuffers;
162 std::vector<Buf_t> fWBuffers;
163 const std::shared_ptr<Hist_t> fResultHist;
164 unsigned int fNSlots;
165 unsigned int fBufSize;
167 Results<std::unique_ptr<Hist_t>> fPartialHists;
171 void UpdateMinMax(
unsigned int slot,
double v);
174 FillHelper(
const std::shared_ptr<Hist_t> &
h,
const unsigned int nSlots);
175 FillHelper(FillHelper &&) =
default;
176 FillHelper(
const FillHelper &) =
delete;
178 void Exec(
unsigned int slot,
double v);
179 void Exec(
unsigned int slot,
double v,
double w);
181 template <typename T, typename std::enable_if<IsContainer<T>::value,
int>::type = 0>
182 void Exec(
unsigned int slot,
const T &vs)
184 auto &thisBuf = fBuffers[slot];
186 UpdateMinMax(slot,
v);
187 thisBuf.emplace_back(
v);
191 template <
typename T,
typename W,
193 void Exec(
unsigned int slot,
const T &vs,
const W &
ws)
195 auto &thisBuf = fBuffers[slot];
197 UpdateMinMax(slot,
v);
198 thisBuf.emplace_back(
v);
201 auto &thisWBuf = fWBuffers[slot];
203 thisWBuf.emplace_back(w);
207 Hist_t &PartialUpdate(
unsigned int);
214 extern template void FillHelper::Exec(
unsigned int,
const std::vector<float> &);
215 extern template void FillHelper::Exec(
unsigned int,
const std::vector<double> &);
216 extern template void FillHelper::Exec(
unsigned int,
const std::vector<char> &);
217 extern template void FillHelper::Exec(
unsigned int,
const std::vector<int> &);
218 extern template void FillHelper::Exec(
unsigned int,
const std::vector<unsigned int> &);
219 extern template void FillHelper::Exec(
unsigned int,
const std::vector<float> &,
const std::vector<float> &);
220 extern template void FillHelper::Exec(
unsigned int,
const std::vector<double> &,
const std::vector<double> &);
221 extern template void FillHelper::Exec(
unsigned int,
const std::vector<char> &,
const std::vector<char> &);
222 extern template void FillHelper::Exec(
unsigned int,
const std::vector<int> &,
const std::vector<int> &);
224 FillHelper::Exec(
unsigned int,
const std::vector<unsigned int> &,
const std::vector<unsigned int> &);
226 template <
typename HIST = Hist_t>
227 class FillTOHelper :
public RActionImpl<FillTOHelper<HIST>> {
228 std::unique_ptr<TThreadedObject<HIST>> fTo;
231 FillTOHelper(FillTOHelper &&) =
default;
232 FillTOHelper(
const FillTOHelper &) =
delete;
234 FillTOHelper(
const std::shared_ptr<HIST> &
h,
const unsigned int nSlots) : fTo(new TThreadedObject<HIST>(*h))
236 fTo->SetAtSlot(0, h);
238 for (
unsigned int i = 0; i < nSlots; ++i) {
245 void Exec(
unsigned int slot,
double x0)
247 fTo->GetAtSlotRaw(slot)->Fill(x0);
250 void Exec(
unsigned int slot,
double x0,
double x1)
252 fTo->GetAtSlotRaw(slot)->Fill(x0, x1);
255 void Exec(
unsigned int slot,
double x0,
double x1,
double x2)
257 fTo->GetAtSlotRaw(slot)->Fill(x0, x1, x2);
260 void Exec(
unsigned int slot,
double x0,
double x1,
double x2,
double x3)
262 fTo->GetAtSlotRaw(slot)->Fill(x0, x1, x2, x3);
265 template <typename X0, typename std::enable_if<IsContainer<X0>::value,
int>::type = 0>
266 void Exec(
unsigned int slot,
const X0 &x0s)
268 auto thisSlotH = fTo->GetAtSlotRaw(slot);
269 for (
auto &x0 : x0s) {
274 template <
typename X0,
typename X1,
276 void Exec(
unsigned int slot,
const X0 &x0s,
const X1 &x1s)
278 auto thisSlotH = fTo->GetAtSlotRaw(slot);
279 if (x0s.size() != x1s.size()) {
280 throw std::runtime_error(
"Cannot fill histogram with values in containers of different sizes.");
282 auto x0sIt = std::begin(x0s);
283 const auto x0sEnd = std::end(x0s);
284 auto x1sIt = std::begin(x1s);
285 for (; x0sIt != x0sEnd; x0sIt++, x1sIt++) {
286 thisSlotH->Fill(*x0sIt, *x1sIt);
290 template <
typename X0,
typename X1,
typename X2,
293 void Exec(
unsigned int slot,
const X0 &x0s,
const X1 &x1s,
const X2 &x2s)
295 auto thisSlotH = fTo->GetAtSlotRaw(slot);
296 if (!(x0s.size() == x1s.size() && x1s.size() == x2s.size())) {
297 throw std::runtime_error(
"Cannot fill histogram with values in containers of different sizes.");
299 auto x0sIt = std::begin(x0s);
300 const auto x0sEnd = std::end(x0s);
301 auto x1sIt = std::begin(x1s);
302 auto x2sIt = std::begin(x2s);
303 for (; x0sIt != x0sEnd; x0sIt++, x1sIt++, x2sIt++) {
304 thisSlotH->Fill(*x0sIt, *x1sIt, *x2sIt);
307 template <
typename X0,
typename X1,
typename X2,
typename X3,
308 typename std::enable_if<IsContainer<X0>::value && IsContainer<X1>::value && IsContainer<X2>::value &&
311 void Exec(
unsigned int slot,
const X0 &x0s,
const X1 &x1s,
const X2 &x2s,
const X3 &x3s)
313 auto thisSlotH = fTo->GetAtSlotRaw(slot);
314 if (!(x0s.size() == x1s.size() && x1s.size() == x2s.size() && x1s.size() == x3s.size())) {
315 throw std::runtime_error(
"Cannot fill histogram with values in containers of different sizes.");
317 auto x0sIt = std::begin(x0s);
318 const auto x0sEnd = std::end(x0s);
319 auto x1sIt = std::begin(x1s);
320 auto x2sIt = std::begin(x2s);
321 auto x3sIt = std::begin(x3s);
322 for (; x0sIt != x0sEnd; x0sIt++, x1sIt++, x2sIt++, x3sIt++) {
323 thisSlotH->Fill(*x0sIt, *x1sIt, *x2sIt, *x3sIt);
329 void Finalize() { fTo->Merge(); }
331 HIST &PartialUpdate(
unsigned int slot) {
return *fTo->GetAtSlotRaw(slot); }
342 template <
typename RealT_t,
typename T,
typename COLL>
343 class TakeHelper :
public RActionImpl<TakeHelper<RealT_t, T, COLL>> {
344 Results<std::shared_ptr<COLL>> fColls;
348 TakeHelper(
const std::shared_ptr<COLL> &resultColl,
const unsigned int nSlots)
350 fColls.emplace_back(resultColl);
351 for (
unsigned int i = 1; i < nSlots; ++i)
352 fColls.emplace_back(std::make_shared<COLL>());
354 TakeHelper(TakeHelper &&) =
default;
355 TakeHelper(
const TakeHelper &) =
delete;
359 void Exec(
unsigned int slot,
T &
v) { fColls[slot]->emplace_back(v); }
365 auto rColl = fColls[0];
366 for (
unsigned int i = 1; i < fColls.size(); ++i) {
367 auto &coll = fColls[i];
369 rColl->emplace_back(v);
374 COLL &PartialUpdate(
unsigned int slot) {
return *fColls[slot].get(); }
379 template <
typename RealT_t,
typename T>
380 class TakeHelper<RealT_t,
T,
std::vector<T>> :
public RActionImpl<TakeHelper<RealT_t, T, std::vector<T>>> {
381 Results<std::shared_ptr<std::vector<T>>> fColls;
385 TakeHelper(
const std::shared_ptr<std::vector<T>> &resultColl,
const unsigned int nSlots)
387 fColls.emplace_back(resultColl);
388 for (
unsigned int i = 1; i < nSlots; ++i) {
389 auto v = std::make_shared<std::vector<T>>();
391 fColls.emplace_back(v);
394 TakeHelper(TakeHelper &&) =
default;
395 TakeHelper(
const TakeHelper &) =
delete;
399 void Exec(
unsigned int slot,
T &v) { fColls[slot]->emplace_back(v); }
407 for (
auto &coll : fColls)
408 totSize += coll->size();
409 auto rColl = fColls[0];
410 rColl->reserve(totSize);
411 for (
unsigned int i = 1; i < fColls.size(); ++i) {
412 auto &coll = fColls[i];
413 rColl->insert(rColl->end(), coll->begin(), coll->end());
417 std::vector<T> &PartialUpdate(
unsigned int slot) {
return *fColls[slot]; }
422 template <
typename RealT_t,
typename COLL>
423 class TakeHelper<RealT_t,
RVec<RealT_t>, COLL> :
public RActionImpl<TakeHelper<RealT_t, RVec<RealT_t>, COLL>> {
424 Results<std::shared_ptr<COLL>> fColls;
428 TakeHelper(
const std::shared_ptr<COLL> &resultColl,
const unsigned int nSlots)
430 fColls.emplace_back(resultColl);
431 for (
unsigned int i = 1; i < nSlots; ++i)
432 fColls.emplace_back(std::make_shared<COLL>());
434 TakeHelper(TakeHelper &&) =
default;
435 TakeHelper(
const TakeHelper &) =
delete;
445 auto rColl = fColls[0];
446 for (
unsigned int i = 1; i < fColls.size(); ++i) {
447 auto &coll = fColls[i];
448 for (
auto &v : *coll) {
449 rColl->emplace_back(v);
457 template <
typename RealT_t>
458 class TakeHelper<RealT_t,
RVec<RealT_t>,
std::vector<RealT_t>>
459 :
public RActionImpl<TakeHelper<RealT_t, RVec<RealT_t>, std::vector<RealT_t>>> {
461 Results<std::shared_ptr<std::vector<std::vector<RealT_t>>>> fColls;
465 TakeHelper(
const std::shared_ptr<std::vector<std::vector<RealT_t>>> &resultColl,
const unsigned int nSlots)
467 fColls.emplace_back(resultColl);
468 for (
unsigned int i = 1; i < nSlots; ++i) {
469 auto v = std::make_shared<std::vector<RealT_t>>();
471 fColls.emplace_back(v);
474 TakeHelper(TakeHelper &&) =
default;
475 TakeHelper(
const TakeHelper &) =
delete;
487 for (
auto &coll : fColls)
488 totSize += coll->size();
489 auto rColl = fColls[0];
490 rColl->reserve(totSize);
491 for (
unsigned int i = 1; i < fColls.size(); ++i) {
492 auto &coll = fColls[i];
493 rColl->insert(rColl->end(), coll->begin(), coll->end());
498 template <
typename ResultType>
499 class MinHelper :
public RActionImpl<MinHelper<ResultType>> {
500 const std::shared_ptr<ResultType> fResultMin;
501 Results<ResultType> fMins;
504 MinHelper(MinHelper &&) =
default;
505 MinHelper(
const std::shared_ptr<ResultType> &minVPtr,
const unsigned int nSlots)
506 : fResultMin(minVPtr), fMins(nSlots,
std::numeric_limits<ResultType>::max())
510 void Exec(
unsigned int slot, ResultType v) { fMins[slot] = std::min(v, fMins[slot]); }
514 template <typename T, typename std::enable_if<IsContainer<T>::value,
int>::type = 0>
515 void Exec(
unsigned int slot,
const T &vs)
518 fMins[slot] = std::min(v, fMins[slot]);
525 *fResultMin = std::numeric_limits<ResultType>::max();
526 for (
auto &
m : fMins)
527 *fResultMin = std::min(
m, *fResultMin);
530 ResultType &PartialUpdate(
unsigned int slot) {
return fMins[slot]; }
540 template <
typename ResultType>
541 class MaxHelper :
public RActionImpl<MaxHelper<ResultType>> {
542 const std::shared_ptr<ResultType> fResultMax;
543 Results<ResultType> fMaxs;
546 MaxHelper(MaxHelper &&) =
default;
547 MaxHelper(
const MaxHelper &) =
delete;
548 MaxHelper(
const std::shared_ptr<ResultType> &maxVPtr,
const unsigned int nSlots)
549 : fResultMax(maxVPtr), fMaxs(nSlots,
std::numeric_limits<ResultType>::lowest())
554 void Exec(
unsigned int slot, ResultType v) { fMaxs[slot] = std::max(v, fMaxs[slot]); }
556 template <typename T, typename std::enable_if<IsContainer<T>::value,
int>::type = 0>
557 void Exec(
unsigned int slot,
const T &vs)
560 fMaxs[slot] = std::max((ResultType)v, fMaxs[slot]);
567 *fResultMax = std::numeric_limits<ResultType>::lowest();
568 for (
auto &
m : fMaxs) {
569 *fResultMax = std::max(
m, *fResultMax);
573 ResultType &PartialUpdate(
unsigned int slot) {
return fMaxs[slot]; }
583 template <
typename ResultType>
584 class SumHelper :
public RActionImpl<SumHelper<ResultType>> {
585 const std::shared_ptr<ResultType> fResultSum;
586 Results<ResultType> fSums;
591 template <
typename T = ResultType>
592 auto NeutralElement(
const T &v,
int ) -> decltype(v - v)
597 template <
typename T = ResultType,
typename Dummy =
int>
598 ResultType NeutralElement(
const T &, Dummy)
604 SumHelper(SumHelper &&) =
default;
605 SumHelper(
const SumHelper &) =
delete;
606 SumHelper(
const std::shared_ptr<ResultType> &sumVPtr,
const unsigned int nSlots)
607 : fResultSum(sumVPtr), fSums(nSlots, NeutralElement(*sumVPtr, -1))
612 void Exec(
unsigned int slot, ResultType v) { fSums[slot] +=
v; }
614 template <typename T, typename std::enable_if<IsContainer<T>::value,
int>::type = 0>
615 void Exec(
unsigned int slot,
const T &vs)
618 fSums[slot] +=
static_cast<ResultType
>(
v);
625 for (
auto &
m : fSums)
629 ResultType &PartialUpdate(
unsigned int slot) {
return fSums[slot]; }
632 class MeanHelper :
public RActionImpl<MeanHelper> {
633 const std::shared_ptr<double> fResultMean;
634 std::vector<ULong64_t> fCounts;
635 std::vector<double> fSums;
636 std::vector<double> fPartialMeans;
639 MeanHelper(
const std::shared_ptr<double> &meanVPtr,
const unsigned int nSlots);
640 MeanHelper(MeanHelper &&) =
default;
641 MeanHelper(
const MeanHelper &) =
delete;
643 void Exec(
unsigned int slot,
double v);
645 template <typename T, typename std::enable_if<IsContainer<T>::value,
int>::type = 0>
646 void Exec(
unsigned int slot,
const T &vs)
648 for (
auto &&v : vs) {
658 double &PartialUpdate(
unsigned int slot);
661 extern template void MeanHelper::Exec(
unsigned int,
const std::vector<float> &);
662 extern template void MeanHelper::Exec(
unsigned int,
const std::vector<double> &);
663 extern template void MeanHelper::Exec(
unsigned int,
const std::vector<char> &);
664 extern template void MeanHelper::Exec(
unsigned int,
const std::vector<int> &);
665 extern template void MeanHelper::Exec(
unsigned int,
const std::vector<unsigned int> &);
668 template <
typename T>
669 void SetBranchesHelper(TTree * , TTree &outputTree,
const std::string & ,
670 const std::string &
name,
T *address)
672 outputTree.Branch(name.c_str(), address);
680 template <
typename T>
681 void SetBranchesHelper(TTree *inputTree, TTree &outputTree,
const std::string &validName,
const std::string &name,
687 auto *
const inputBranch = inputTree ? inputTree->GetBranch(validName.c_str()) :
nullptr;
691 outputTree.Branch(name.c_str(),
reinterpret_cast<typename
RVec<T>::Impl_t *
>(ab));
696 auto *
const leaf =
static_cast<TLeaf *
>(inputBranch->GetListOfLeaves()->UncheckedAt(0));
697 const auto bname = leaf->
GetName();
698 const auto counterStr =
699 leaf->GetLeafCount() ? std::string(leaf->GetLeafCount()->GetName()) : std::to_string(leaf->GetLenStatic());
700 const auto btype = leaf->GetTypeName();
702 const auto leaflist = std::string(bname) +
"[" + counterStr +
"]/" + rootbtype;
703 auto *
const outputBranch = outputTree.Branch(name.c_str(), ab->
data(), leaflist.c_str());
704 outputBranch->SetTitle(inputBranch->GetTitle());
708 template <
typename... BranchTypes>
709 class SnapshotHelper :
public RActionImpl<SnapshotHelper<BranchTypes...>> {
710 const std::string fFileName;
711 const std::string fDirName;
712 const std::string fTreeName;
714 std::unique_ptr<TFile> fOutputFile;
715 std::unique_ptr<TTree> fOutputTree;
716 bool fIsFirstEvent{
true};
717 const ColumnNames_t fInputBranchNames;
718 const ColumnNames_t fOutputBranchNames;
719 TTree *fInputTree =
nullptr;
723 const ColumnNames_t &vbnames,
const ColumnNames_t &bnames,
const RSnapshotOptions &options)
724 : fFileName(filename), fDirName(dirname), fTreeName(treename), fOptions(options), fInputBranchNames(vbnames),
729 SnapshotHelper(
const SnapshotHelper &) =
delete;
730 SnapshotHelper(SnapshotHelper &&) =
default;
739 fInputTree->AddClone(fOutputTree.get());
742 void Exec(
unsigned int , BranchTypes &... values)
746 SetBranches(values..., ind_t());
751 template <std::size_t...
S>
756 (SetBranchesHelper(fInputTree, *fOutputTree, fInputBranchNames[
S], fOutputBranchNames[S], &values), 0)..., 0};
758 fIsFirstEvent =
false;
767 if (!fDirName.empty()) {
768 fOutputFile->mkdir(fDirName.c_str());
769 fOutputFile->cd(fDirName.c_str());
773 new TTree(fTreeName.c_str(), fTreeName.c_str(), fOptions.
fSplitLevel, fOutputFile.get()));
776 fOutputTree->SetAutoFlush(fOptions.
fAutoFlush);
781 if (fOutputFile && fOutputTree) {
783 fOutputTree->Write();
785 Warning(
"Snapshot",
"A lazy Snapshot action was booked but never triggered.");
792 template <
typename... BranchTypes>
793 class SnapshotHelperMT :
public RActionImpl<SnapshotHelperMT<BranchTypes...>> {
794 const unsigned int fNSlots;
795 std::unique_ptr<ROOT::Experimental::TBufferMerger> fMerger;
796 std::vector<std::shared_ptr<ROOT::Experimental::TBufferMergerFile>> fOutputFiles;
797 std::vector<std::stack<std::unique_ptr<TTree>>> fOutputTrees;
798 std::vector<int> fIsFirstEvent;
799 const std::string fFileName;
800 const std::string fDirName;
801 const std::string fTreeName;
803 const ColumnNames_t fInputBranchNames;
804 const ColumnNames_t fOutputBranchNames;
805 std::vector<TTree *> fInputTrees;
808 using ColumnTypes_t =
TypeList<BranchTypes...>;
810 std::string_view treename,
const ColumnNames_t &vbnames,
const ColumnNames_t &bnames,
812 : fNSlots(nSlots), fOutputFiles(fNSlots), fOutputTrees(fNSlots), fIsFirstEvent(fNSlots, 1), fFileName(filename),
813 fDirName(dirname), fTreeName(treename), fOptions(options), fInputBranchNames(vbnames),
817 SnapshotHelperMT(
const SnapshotHelperMT &) =
delete;
818 SnapshotHelperMT(SnapshotHelperMT &&) =
default;
823 if (!fOutputFiles[slot]) {
825 fOutputFiles[slot] = fMerger->
GetFile();
827 TDirectory *treeDirectory = fOutputFiles[slot].get();
828 if (!fDirName.empty()) {
829 treeDirectory = fOutputFiles[slot]->mkdir(fDirName.c_str());
833 fOutputTrees[slot].emplace(
834 std::make_unique<TTree>(fTreeName.c_str(), fTreeName.c_str(), fOptions.
fSplitLevel, treeDirectory));
836 fOutputTrees[slot].top()->SetAutoFlush(fOptions.
fAutoFlush);
839 fInputTrees[slot] = r->
GetTree();
844 const auto friendsListPtr = fInputTrees[slot]->GetListOfFriends();
845 if (friendsListPtr && friendsListPtr->GetEntries() > 0)
846 fInputTrees[slot]->AddClone(fOutputTrees[slot].top().get());
848 fIsFirstEvent[slot] = 1;
851 void FinalizeTask(
unsigned int slot)
853 if (fOutputTrees[slot].top()->GetEntries() > 0)
854 fOutputFiles[slot]->Write();
856 fOutputTrees[slot].pop();
859 void Exec(
unsigned int slot, BranchTypes &... values)
861 if (fIsFirstEvent[slot]) {
863 SetBranches(slot, values..., ind_t());
864 fIsFirstEvent[slot] = 0;
866 fOutputTrees[slot].top()->Fill();
867 auto entries = fOutputTrees[slot].top()->GetEntries();
868 auto autoFlush = fOutputTrees[slot].top()->GetAutoFlush();
869 if ((autoFlush > 0) && (entries % autoFlush == 0))
870 fOutputFiles[slot]->Write();
873 template <std::size_t...
S>
877 int expander[] = {(SetBranchesHelper(fInputTrees[slot], *fOutputTrees[slot].top(), fInputBranchNames[
S],
878 fOutputBranchNames[S], &values),
893 auto fileWritten =
false;
894 for (
auto &
file : fOutputFiles) {
902 Warning(
"Snapshot",
"A lazy Snapshot action was booked but never triggered.");
908 template <
typename Acc,
typename Merge,
typename R,
typename T,
typename U,
909 bool MustCopyAssign = std::is_same<R, U>::value>
910 class AggregateHelper :
public RActionImpl<AggregateHelper<Acc, Merge, R, T, U, MustCopyAssign>> {
913 const std::shared_ptr<U> fResult;
914 Results<U> fAggregators;
918 AggregateHelper(Acc &&
f, Merge &&
m,
const std::shared_ptr<U> &result,
const unsigned int nSlots)
919 : fAggregate(
std::move(
f)), fMerge(
std::move(
m)), fResult(result), fAggregators(nSlots, *result)
922 AggregateHelper(AggregateHelper &&) =
default;
923 AggregateHelper(
const AggregateHelper &) =
delete;
928 void Exec(
unsigned int slot,
const T &value)
930 fAggregators[slot] = fAggregate(fAggregators[slot], value);
934 void Exec(
unsigned int slot,
const T &value)
936 fAggregate(fAggregators[slot], value);
941 template <typename MergeRet = typename CallableTraits<Merge>::ret_type,
942 bool MergeAll = std::is_same<void, MergeRet>::value>
945 fMerge(fAggregators);
946 *fResult = fAggregators[0];
949 template <typename MergeRet = typename CallableTraits<Merge>::ret_type,
950 bool MergeTwoByTwo = std::is_same<U, MergeRet>::value>
953 for (
auto &acc : fAggregators)
954 *fResult = fMerge(*fResult, acc);
957 U &PartialUpdate(
unsigned int slot) {
return fAggregators[slot]; }
virtual const char * GetName() const
Returns name of object.
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container code of cont...
TTreeReader is a simple, robust and fast interface to read values from a TTree, TChain or TNtuple...
Namespace for new ROOT classes and functions.
iterator begin() noexcept
#define R(a, b, c, d, e, f, g, h, i)
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=1, Int_t netopt=0)
Create / open a file.
typename std::vector< T, ::ROOT::Detail::VecOps::RAdoptAllocator< T > > Impl_t
static const double x2[5]
A collection of options to steer the creation of the dataset on file.
std::vector< std::string > ReplaceDotWithUnderscore(const std::vector< std::string > &columnNames)
Replace occurrences of '.
A "std::vector"-like collection of values implementing handy operation to analyse them...
char TypeName2ROOTTypeName(const std::string &b)
Convert type name (e.g.
RooArgSet S(const RooAbsArg &v1)
void Initialize(Bool_t useTMVAStyle=kTRUE)
TBufferMerger is a class to facilitate writing data in parallel from multiple threads, while writing to a single output file.
void Warning(const char *location, const char *msgfmt,...)
Lightweight storage for a collection of types.
ECAlgo fCompressionAlgorithm
static const double x1[5]
Describe directory structure in memory.
unsigned long long ULong64_t
basic_string_view< char > string_view
ROOT type_traits extensions.
make_index_sequence< sizeof...(_Tp)> index_sequence_for
typedef void((*Func_t)())
std::shared_ptr< TBufferMergerFile > GetFile()
Returns a TBufferMergerFile to which data can be written.
THist< 1, double, THistStatContent, THistStatUncertainty > TH1D
Check for container traits.
static const double x3[11]