11 #ifndef ROOT_TDFOPERATIONS
12 #define ROOT_TDFOPERATIONS
21 #include <type_traits>
30 using Count_t =
unsigned long;
34 class ForeachSlotHelper {
38 using BranchTypes_t =
typename TRemoveFirst<typename TFunctionTraits<F>::Args_t>::Types_t;
39 ForeachSlotHelper(
F &&
f) : fCallable(
f) {}
43 template <
typename... Args>
44 void Exec(
unsigned int slot, Args &&... args)
48 fCallable(slot, std::forward<Args>(args)...);
55 std::shared_ptr<unsigned int> fResultCount;
56 std::vector<Count_t> fCounts;
59 using BranchTypes_t = TTypeList<>;
60 CountHelper(
const std::shared_ptr<unsigned int> &resultCount,
unsigned int nSlots);
62 void Exec(
unsigned int slot);
68 static constexpr
unsigned int fgTotalBufSize = 2097152;
69 using BufEl_t = double;
70 using Buf_t = std::vector<BufEl_t>;
72 std::vector<Buf_t> fBuffers;
73 std::vector<Buf_t> fWBuffers;
74 std::shared_ptr<Hist_t> fResultHist;
76 unsigned int fBufSize;
80 void UpdateMinMax(
unsigned int slot,
double v);
83 FillHelper(
const std::shared_ptr<Hist_t> &
h,
unsigned int nSlots);
85 void Exec(
unsigned int slot,
double v);
86 void Exec(
unsigned int slot,
double v,
double w);
88 template <typename T, typename std::enable_if<TIsContainer<T>::fgValue,
int>
::type = 0>
89 void Exec(
unsigned int slot,
const T &vs)
91 auto &thisBuf = fBuffers[slot];
93 UpdateMinMax(slot,
v);
94 thisBuf.emplace_back(
v);
98 template <
typename T,
typename W,
99 typename std::enable_if<TIsContainer<T>::fgValue && TIsContainer<W>::fgValue,
int>
::type = 0>
100 void Exec(
unsigned int slot,
const T &vs,
const W &ws)
102 auto &thisBuf = fBuffers[slot];
104 UpdateMinMax(slot,
v);
105 thisBuf.emplace_back(
v);
108 auto &thisWBuf = fWBuffers[slot];
110 thisWBuf.emplace_back(w);
117 extern template void FillHelper::Exec(
unsigned int,
const std::vector<float> &);
118 extern template void FillHelper::Exec(
unsigned int,
const std::vector<double> &);
119 extern template void FillHelper::Exec(
unsigned int,
const std::vector<char> &);
120 extern template void FillHelper::Exec(
unsigned int,
const std::vector<int> &);
121 extern template void FillHelper::Exec(
unsigned int,
const std::vector<unsigned int> &);
122 extern template void FillHelper::Exec(
unsigned int,
const std::vector<float> &,
const std::vector<float> &);
123 extern template void FillHelper::Exec(
unsigned int,
const std::vector<double> &,
const std::vector<double> &);
124 extern template void FillHelper::Exec(
unsigned int,
const std::vector<char> &,
const std::vector<char> &);
125 extern template void FillHelper::Exec(
unsigned int,
const std::vector<int> &,
const std::vector<int> &);
126 extern template void FillHelper::Exec(
unsigned int,
const std::vector<unsigned int> &,
127 const std::vector<unsigned int> &);
129 template <
typename HIST = Hist_t>
131 std::unique_ptr<TThreadedObject<HIST>> fTo;
134 FillTOHelper(FillTOHelper &&) =
default;
136 FillTOHelper(
const std::shared_ptr<HIST> &
h,
unsigned int nSlots) : fTo(new TThreadedObject<HIST>(*h))
138 fTo->SetAtSlot(0, h);
140 for (
unsigned int i = 0; i < nSlots; ++i) {
147 void Exec(
unsigned int slot,
double x0)
149 fTo->GetAtSlotUnchecked(slot)->Fill(x0);
152 void Exec(
unsigned int slot,
double x0,
double x1)
154 fTo->GetAtSlotUnchecked(slot)->Fill(x0, x1);
157 void Exec(
unsigned int slot,
double x0,
double x1,
double x2)
159 fTo->GetAtSlotUnchecked(slot)->Fill(x0, x1, x2);
162 void Exec(
unsigned int slot,
double x0,
double x1,
double x2,
double x3)
164 fTo->GetAtSlotUnchecked(slot)->Fill(x0, x1, x2, x3);
167 template <typename X0, typename std::enable_if<TIsContainer<X0>::fgValue,
int>
::type = 0>
168 void Exec(
unsigned int slot,
const X0 &x0s)
170 auto thisSlotH = fTo->GetAtSlotUnchecked(slot);
171 for (
auto &x0 : x0s) {
176 template <
typename X0,
typename X1,
177 typename std::enable_if<TIsContainer<X0>::fgValue && TIsContainer<X1>::fgValue,
int>::type = 0>
178 void Exec(
unsigned int slot,
const X0 &x0s,
const X1 &x1s)
180 auto thisSlotH = fTo->GetAtSlotUnchecked(slot);
181 if (x0s.size() != x1s.size()) {
182 throw std::runtime_error(
"Cannot fill histogram with values in containers of different sizes.");
184 auto x0sIt = std::begin(x0s);
185 const auto x0sEnd = std::end(x0s);
186 auto x1sIt = std::begin(x1s);
187 for (; x0sIt != x0sEnd; x0sIt++, x1sIt++) {
188 thisSlotH->Fill(*x0sIt, *x1sIt);
192 template <
typename X0,
typename X1,
typename X2,
193 typename std::enable_if<
194 TIsContainer<X0>::fgValue && TIsContainer<X1>::fgValue && TIsContainer<X2>::fgValue,
int>::type = 0>
195 void Exec(
unsigned int slot,
const X0 &x0s,
const X1 &x1s,
const X2 &x2s)
197 auto thisSlotH = fTo->GetAtSlotUnchecked(slot);
198 if (!(x0s.size() == x1s.size() && x1s.size() == x2s.size())) {
199 throw std::runtime_error(
"Cannot fill histogram with values in containers of different sizes.");
201 auto x0sIt = std::begin(x0s);
202 const auto x0sEnd = std::end(x0s);
203 auto x1sIt = std::begin(x1s);
204 auto x2sIt = std::begin(x2s);
205 for (; x0sIt != x0sEnd; x0sIt++, x1sIt++, x2sIt++) {
206 thisSlotH->Fill(*x0sIt, *x1sIt, *x2sIt);
209 template <
typename X0,
typename X1,
typename X2,
typename X3,
210 typename std::enable_if<TIsContainer<X0>::fgValue && TIsContainer<X1>::fgValue &&
211 TIsContainer<X2>::fgValue && TIsContainer<X3>::fgValue,
213 void Exec(
unsigned int slot,
const X0 &x0s,
const X1 &x1s,
const X2 &x2s,
const X3 &x3s)
215 auto thisSlotH = fTo->GetAtSlotUnchecked(slot);
216 if (!(x0s.size() == x1s.size() && x1s.size() == x2s.size() && x1s.size() == x3s.size())) {
217 throw std::runtime_error(
"Cannot fill histogram with values in containers of different sizes.");
219 auto x0sIt = std::begin(x0s);
220 const auto x0sEnd = std::end(x0s);
221 auto x1sIt = std::begin(x1s);
222 auto x2sIt = std::begin(x2s);
223 auto x3sIt = std::begin(x3s);
224 for (; x0sIt != x0sEnd; x0sIt++, x1sIt++, x2sIt++, x3sIt++) {
225 thisSlotH->Fill(*x0sIt, *x1sIt, *x2sIt, *x3sIt);
228 void Finalize() { fTo->Merge(); }
233 template <
typename T,
typename COLL>
235 std::vector<std::shared_ptr<COLL>> fColls;
238 using BranchTypes_t = TTypeList<T>;
239 TakeHelper(
const std::shared_ptr<COLL> &resultColl,
unsigned int nSlots)
241 fColls.emplace_back(resultColl);
242 for (
unsigned int i = 1; i < nSlots; ++i) fColls.emplace_back(std::make_shared<COLL>());
247 template <typename V, typename std::enable_if<!TIsContainer<V>::fgValue,
int>::type = 0>
248 void Exec(
unsigned int slot, V
v)
250 fColls[slot]->emplace_back(v);
253 template <typename V, typename std::enable_if<TIsContainer<V>::fgValue,
int>::type = 0>
254 void Exec(
unsigned int slot,
const V &vs)
256 auto thisColl = fColls[slot];
257 thisColl.insert(std::begin(thisColl), std::begin(vs), std::begin(vs));
262 auto rColl = fColls[0];
263 for (
unsigned int i = 1; i < fColls.size(); ++i) {
264 auto &coll = fColls[i];
266 rColl->emplace_back(v);
274 template <
typename T>
275 class TakeHelper<
T, std::vector<T>> {
276 std::vector<std::shared_ptr<std::vector<T>>> fColls;
279 using BranchTypes_t = TTypeList<T>;
280 TakeHelper(
const std::shared_ptr<std::vector<T>> &resultColl,
unsigned int nSlots)
282 fColls.emplace_back(resultColl);
283 for (
unsigned int i = 1; i < nSlots; ++i) {
284 auto v = std::make_shared<std::vector<T>>();
286 fColls.emplace_back(v);
292 template <typename V, typename std::enable_if<!TIsContainer<V>::fgValue,
int>::type = 0>
293 void Exec(
unsigned int slot, V v)
295 fColls[slot]->emplace_back(v);
298 template <typename V, typename std::enable_if<TIsContainer<V>::fgValue,
int>::type = 0>
299 void Exec(
unsigned int slot,
const V &vs)
301 auto thisColl = fColls[slot];
302 thisColl->insert(std::begin(thisColl), std::begin(vs), std::begin(vs));
308 for (
auto &coll : fColls) totSize += coll->size();
309 auto rColl = fColls[0];
310 rColl->reserve(totSize);
311 for (
unsigned int i = 1; i < fColls.size(); ++i) {
312 auto &coll = fColls[i];
313 rColl->insert(rColl->end(), coll->begin(), coll->end());
318 template <
typename F,
typename T>
321 std::shared_ptr<T> fReduceRes;
322 std::vector<T> fReduceObjs;
325 using BranchTypes_t = TTypeList<T>;
326 ReduceHelper(
F &&
f,
const std::shared_ptr<T> &reduceRes,
unsigned int nSlots)
327 : fReduceFun(std::move(
f)), fReduceRes(reduceRes), fReduceObjs(nSlots, *reduceRes)
333 void Exec(
unsigned int slot,
const T &value) { fReduceObjs[slot] = fReduceFun(fReduceObjs[slot], value); }
337 for (
auto &t : fReduceObjs) *fReduceRes = fReduceFun(*fReduceRes, t);
342 std::shared_ptr<double> fResultMin;
343 std::vector<double> fMins;
346 MinHelper(
const std::shared_ptr<double> &minVPtr,
unsigned int nSlots);
350 void Exec(
unsigned int slot,
double v);
352 template <typename T, typename std::enable_if<TIsContainer<T>::fgValue,
int>::type = 0>
353 void Exec(
unsigned int slot,
const T &vs)
355 for (
auto &&v : vs) fMins[slot] = std::min((
double)v, fMins[slot]);
361 extern template void MinHelper::Exec(
unsigned int,
const std::vector<float> &);
362 extern template void MinHelper::Exec(
unsigned int,
const std::vector<double> &);
363 extern template void MinHelper::Exec(
unsigned int,
const std::vector<char> &);
364 extern template void MinHelper::Exec(
unsigned int,
const std::vector<int> &);
365 extern template void MinHelper::Exec(
unsigned int,
const std::vector<unsigned int> &);
368 std::shared_ptr<double> fResultMax;
369 std::vector<double> fMaxs;
372 MaxHelper(
const std::shared_ptr<double> &maxVPtr,
unsigned int nSlots);
374 void Exec(
unsigned int slot,
double v);
376 template <typename T, typename std::enable_if<TIsContainer<T>::fgValue,
int>::type = 0>
377 void Exec(
unsigned int slot,
const T &vs)
379 for (
auto &&v : vs) fMaxs[slot] = std::max((
double)v, fMaxs[slot]);
385 extern template void MaxHelper::Exec(
unsigned int,
const std::vector<float> &);
386 extern template void MaxHelper::Exec(
unsigned int,
const std::vector<double> &);
387 extern template void MaxHelper::Exec(
unsigned int,
const std::vector<char> &);
388 extern template void MaxHelper::Exec(
unsigned int,
const std::vector<int> &);
389 extern template void MaxHelper::Exec(
unsigned int,
const std::vector<unsigned int> &);
392 std::shared_ptr<double> fResultMean;
393 std::vector<Count_t> fCounts;
394 std::vector<double> fSums;
397 MeanHelper(
const std::shared_ptr<double> &meanVPtr,
unsigned int nSlots);
399 void Exec(
unsigned int slot,
double v);
401 template <typename T, typename std::enable_if<TIsContainer<T>::fgValue,
int>::type = 0>
402 void Exec(
unsigned int slot,
const T &vs)
404 for (
auto &&v : vs) {
413 extern template void MeanHelper::Exec(
unsigned int,
const std::vector<float> &);
414 extern template void MeanHelper::Exec(
unsigned int,
const std::vector<double> &);
415 extern template void MeanHelper::Exec(
unsigned int,
const std::vector<char> &);
416 extern template void MeanHelper::Exec(
unsigned int,
const std::vector<int> &);
417 extern template void MeanHelper::Exec(
unsigned int,
const std::vector<unsigned int> &);
419 template <
typename F1,
typename F2>
420 class SnapshotHelper {
425 using BranchTypes_t =
typename TRemoveFirst<typename TFunctionTraits<F2>::Args_t>::Types_t;
426 SnapshotHelper(
F1 &&
f1,
F2 &&
f2) : fInitFunc(
f1), fExecFunc(
f2) {}
428 void Init(
TTreeReader *
r,
unsigned int slot) { fInitFunc(r, slot); }
430 template <
typename... Args>
431 void Exec(
unsigned int slot, Args &&... args)
435 fExecFunc(slot, std::forward<Args>(args)...);
TTreeReader is a simple, robust and fast interface to read values from a TTree, TChain or TNtuple...
THist< 1, float, THistStatContent, THistStatUncertainty > TH1F
static const double x2[5]
static const double x1[5]
fNSlots(TDFInternal::GetNSlots())
unsigned long long ULong64_t
double f2(const double *x)
static const double x3[11]