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 void Exec(
unsigned int slot,
T v)
249 fColls[slot]->emplace_back(v);
254 auto rColl = fColls[0];
255 for (
unsigned int i = 1; i < fColls.size(); ++i) {
256 auto &coll = fColls[i];
258 rColl->emplace_back(v);
266 template <
typename T>
267 class TakeHelper<
T,
std::vector<T>> {
268 std::vector<std::shared_ptr<std::vector<T>>> fColls;
271 using BranchTypes_t = TTypeList<T>;
272 TakeHelper(
const std::shared_ptr<std::vector<T>> &resultColl,
unsigned int nSlots)
274 fColls.emplace_back(resultColl);
275 for (
unsigned int i = 1; i < nSlots; ++i) {
276 auto v = std::make_shared<std::vector<T>>();
278 fColls.emplace_back(v);
284 void Exec(
unsigned int slot,
T v)
286 fColls[slot]->emplace_back(v);
292 for (
auto &coll : fColls) totSize += coll->size();
293 auto rColl = fColls[0];
294 rColl->reserve(totSize);
295 for (
unsigned int i = 1; i < fColls.size(); ++i) {
296 auto &coll = fColls[i];
297 rColl->insert(rColl->end(), coll->begin(), coll->end());
302 template <
typename F,
typename T>
305 std::shared_ptr<T> fReduceRes;
306 std::vector<T> fReduceObjs;
309 using BranchTypes_t = TTypeList<T>;
310 ReduceHelper(
F &&
f,
const std::shared_ptr<T> &reduceRes,
unsigned int nSlots)
311 : fReduceFun(
std::move(
f)), fReduceRes(reduceRes), fReduceObjs(nSlots, *reduceRes)
317 void Exec(
unsigned int slot,
const T &value) { fReduceObjs[slot] = fReduceFun(fReduceObjs[slot], value); }
321 for (
auto &t : fReduceObjs) *fReduceRes = fReduceFun(*fReduceRes, t);
326 std::shared_ptr<double> fResultMin;
327 std::vector<double> fMins;
330 MinHelper(
const std::shared_ptr<double> &minVPtr,
unsigned int nSlots);
334 void Exec(
unsigned int slot,
double v);
336 template <typename T, typename std::enable_if<TIsContainer<T>::fgValue,
int>::type = 0>
337 void Exec(
unsigned int slot,
const T &vs)
339 for (
auto &&v : vs) fMins[slot] = std::min((
double)v, fMins[slot]);
345 extern template void MinHelper::Exec(
unsigned int,
const std::vector<float> &);
346 extern template void MinHelper::Exec(
unsigned int,
const std::vector<double> &);
347 extern template void MinHelper::Exec(
unsigned int,
const std::vector<char> &);
348 extern template void MinHelper::Exec(
unsigned int,
const std::vector<int> &);
349 extern template void MinHelper::Exec(
unsigned int,
const std::vector<unsigned int> &);
352 std::shared_ptr<double> fResultMax;
353 std::vector<double> fMaxs;
356 MaxHelper(
const std::shared_ptr<double> &maxVPtr,
unsigned int nSlots);
358 void Exec(
unsigned int slot,
double v);
360 template <typename T, typename std::enable_if<TIsContainer<T>::fgValue,
int>::type = 0>
361 void Exec(
unsigned int slot,
const T &vs)
363 for (
auto &&v : vs) fMaxs[slot] = std::max((
double)v, fMaxs[slot]);
369 extern template void MaxHelper::Exec(
unsigned int,
const std::vector<float> &);
370 extern template void MaxHelper::Exec(
unsigned int,
const std::vector<double> &);
371 extern template void MaxHelper::Exec(
unsigned int,
const std::vector<char> &);
372 extern template void MaxHelper::Exec(
unsigned int,
const std::vector<int> &);
373 extern template void MaxHelper::Exec(
unsigned int,
const std::vector<unsigned int> &);
376 std::shared_ptr<double> fResultMean;
377 std::vector<Count_t> fCounts;
378 std::vector<double> fSums;
381 MeanHelper(
const std::shared_ptr<double> &meanVPtr,
unsigned int nSlots);
383 void Exec(
unsigned int slot,
double v);
385 template <typename T, typename std::enable_if<TIsContainer<T>::fgValue,
int>::type = 0>
386 void Exec(
unsigned int slot,
const T &vs)
388 for (
auto &&v : vs) {
397 extern template void MeanHelper::Exec(
unsigned int,
const std::vector<float> &);
398 extern template void MeanHelper::Exec(
unsigned int,
const std::vector<double> &);
399 extern template void MeanHelper::Exec(
unsigned int,
const std::vector<char> &);
400 extern template void MeanHelper::Exec(
unsigned int,
const std::vector<int> &);
401 extern template void MeanHelper::Exec(
unsigned int,
const std::vector<unsigned int> &);
403 template <
typename F1,
typename F2>
404 class SnapshotHelper {
409 using BranchTypes_t =
typename TRemoveFirst<typename TFunctionTraits<F2>::Args_t>::Types_t;
410 SnapshotHelper(
F1 &&
f1,
F2 &&
f2) : fInitFunc(
f1), fExecFunc(
f2) {}
412 void Init(
TTreeReader *
r,
unsigned int slot) { fInitFunc(r, slot); }
414 template <
typename... Args>
415 void Exec(
unsigned int slot, Args &&... args)
419 fExecFunc(slot, std::forward<Args>(args)...);
TTreeReader is a simple, robust and fast interface to read values from a TTree, TChain or TNtuple...
Namespace for new ROOT classes and functions.
THist< 1, float, THistStatContent, THistStatUncertainty > TH1F
static const double x2[5]
static const double x1[5]
unsigned long long ULong64_t
double f2(const double *x)
static const double x3[11]