Logo ROOT   6.14/05
Reference Guide
RDFActionHelpers.cxx
Go to the documentation of this file.
1 // Author: Enrico Guiraud, Danilo Piparo CERN 12/2016
2 
3 /*************************************************************************
4  * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers. *
5  * All rights reserved. *
6  * *
7  * For the licensing terms see $ROOTSYS/LICENSE. *
8  * For the list of contributors see $ROOTSYS/README/CREDITS. *
9  *************************************************************************/
10 
12 
13 namespace ROOT {
14 namespace Internal {
15 namespace RDF {
16 
17 CountHelper::CountHelper(const std::shared_ptr<ULong64_t> &resultCount, const unsigned int nSlots)
18  : fResultCount(resultCount), fCounts(nSlots, 0)
19 {
20 }
21 
22 void CountHelper::Exec(unsigned int slot)
23 {
24  fCounts[slot]++;
25 }
26 
27 void CountHelper::Finalize()
28 {
29  *fResultCount = 0;
30  for (auto &c : fCounts) {
31  *fResultCount += c;
32  }
33 }
34 
35 ULong64_t &CountHelper::PartialUpdate(unsigned int slot)
36 {
37  return fCounts[slot];
38 }
39 
40 void FillHelper::UpdateMinMax(unsigned int slot, double v)
41 {
42  auto &thisMin = fMin[slot];
43  auto &thisMax = fMax[slot];
44  thisMin = std::min(thisMin, v);
45  thisMax = std::max(thisMax, v);
46 }
47 
48 FillHelper::FillHelper(const std::shared_ptr<Hist_t> &h, const unsigned int nSlots)
49  : fResultHist(h), fNSlots(nSlots), fBufSize(fgTotalBufSize / nSlots), fPartialHists(fNSlots),
50  fMin(nSlots, std::numeric_limits<BufEl_t>::max()), fMax(nSlots, std::numeric_limits<BufEl_t>::lowest())
51 {
52  fBuffers.reserve(fNSlots);
53  fWBuffers.reserve(fNSlots);
54  for (unsigned int i = 0; i < fNSlots; ++i) {
55  Buf_t v;
56  v.reserve(fBufSize);
57  fBuffers.emplace_back(v);
58  fWBuffers.emplace_back(v);
59  }
60 }
61 
62 void FillHelper::Exec(unsigned int slot, double v)
63 {
64  UpdateMinMax(slot, v);
65  fBuffers[slot].emplace_back(v);
66 }
67 
68 void FillHelper::Exec(unsigned int slot, double v, double w)
69 {
70  UpdateMinMax(slot, v);
71  fBuffers[slot].emplace_back(v);
72  fWBuffers[slot].emplace_back(w);
73 }
74 
75 Hist_t &FillHelper::PartialUpdate(unsigned int slot)
76 {
77  auto &partialHist = fPartialHists[slot];
78  // TODO it is inefficient to re-create the partial histogram everytime the callback is called
79  // ideally we could incrementally fill it with the latest entries in the buffers
80  partialHist.reset(new Hist_t(*fResultHist));
81  auto weights = fWBuffers[slot].empty() ? nullptr : fWBuffers[slot].data();
82  partialHist->FillN(fBuffers[slot].size(), fBuffers[slot].data(), weights);
83  return *partialHist;
84 }
85 
86 void FillHelper::Finalize()
87 {
88  for (unsigned int i = 0; i < fNSlots; ++i) {
89  if (!fWBuffers[i].empty() && fBuffers[i].size() != fWBuffers[i].size()) {
90  throw std::runtime_error("Cannot fill weighted histogram with values in containers of different sizes.");
91  }
92  }
93 
94  BufEl_t globalMin = *std::min_element(fMin.begin(), fMin.end());
95  BufEl_t globalMax = *std::max_element(fMax.begin(), fMax.end());
96 
97  if (fResultHist->CanExtendAllAxes() && globalMin != std::numeric_limits<BufEl_t>::max() &&
98  globalMax != std::numeric_limits<BufEl_t>::lowest()) {
99  fResultHist->SetBins(fResultHist->GetNbinsX(), globalMin, globalMax);
100  }
101 
102  for (unsigned int i = 0; i < fNSlots; ++i) {
103  auto weights = fWBuffers[i].empty() ? nullptr : fWBuffers[i].data();
104  fResultHist->FillN(fBuffers[i].size(), fBuffers[i].data(), weights);
105  }
106 }
107 
108 template void FillHelper::Exec(unsigned int, const std::vector<float> &);
109 template void FillHelper::Exec(unsigned int, const std::vector<double> &);
110 template void FillHelper::Exec(unsigned int, const std::vector<char> &);
111 template void FillHelper::Exec(unsigned int, const std::vector<int> &);
112 template void FillHelper::Exec(unsigned int, const std::vector<unsigned int> &);
113 template void FillHelper::Exec(unsigned int, const std::vector<float> &, const std::vector<float> &);
114 template void FillHelper::Exec(unsigned int, const std::vector<double> &, const std::vector<double> &);
115 template void FillHelper::Exec(unsigned int, const std::vector<char> &, const std::vector<char> &);
116 template void FillHelper::Exec(unsigned int, const std::vector<int> &, const std::vector<int> &);
117 template void FillHelper::Exec(unsigned int, const std::vector<unsigned int> &, const std::vector<unsigned int> &);
118 
119 // TODO
120 // template void MinHelper::Exec(unsigned int, const std::vector<float> &);
121 // template void MinHelper::Exec(unsigned int, const std::vector<double> &);
122 // template void MinHelper::Exec(unsigned int, const std::vector<char> &);
123 // template void MinHelper::Exec(unsigned int, const std::vector<int> &);
124 // template void MinHelper::Exec(unsigned int, const std::vector<unsigned int> &);
125 
126 // template void MaxHelper::Exec(unsigned int, const std::vector<float> &);
127 // template void MaxHelper::Exec(unsigned int, const std::vector<double> &);
128 // template void MaxHelper::Exec(unsigned int, const std::vector<char> &);
129 // template void MaxHelper::Exec(unsigned int, const std::vector<int> &);
130 // template void MaxHelper::Exec(unsigned int, const std::vector<unsigned int> &);
131 
132 MeanHelper::MeanHelper(const std::shared_ptr<double> &meanVPtr, const unsigned int nSlots)
133  : fResultMean(meanVPtr), fCounts(nSlots, 0), fSums(nSlots, 0), fPartialMeans(nSlots)
134 {
135 }
136 
137 void MeanHelper::Exec(unsigned int slot, double v)
138 {
139  fSums[slot] += v;
140  fCounts[slot]++;
141 }
142 
143 void MeanHelper::Finalize()
144 {
145  double sumOfSums = 0;
146  for (auto &s : fSums)
147  sumOfSums += s;
148  ULong64_t sumOfCounts = 0;
149  for (auto &c : fCounts)
150  sumOfCounts += c;
151  *fResultMean = sumOfSums / (sumOfCounts > 0 ? sumOfCounts : 1);
152 }
153 
154 double &MeanHelper::PartialUpdate(unsigned int slot)
155 {
156  fPartialMeans[slot] = fSums[slot] / fCounts[slot];
157  return fPartialMeans[slot];
158 }
159 
160 template void MeanHelper::Exec(unsigned int, const std::vector<float> &);
161 template void MeanHelper::Exec(unsigned int, const std::vector<double> &);
162 template void MeanHelper::Exec(unsigned int, const std::vector<char> &);
163 template void MeanHelper::Exec(unsigned int, const std::vector<int> &);
164 template void MeanHelper::Exec(unsigned int, const std::vector<unsigned int> &);
165 
166 } // end NS RDF
167 } // end NS Internal
168 } // end NS ROOT
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
STL namespace.
SVector< double, 2 > v
Definition: Dict.h:5
#define h(i)
Definition: RSha256.hxx:106
unsigned long long ULong64_t
Definition: RtypesCore.h:70
static constexpr double s
#define c(i)
Definition: RSha256.hxx:101