CP3-llbb Framework
Histogram.h
1 #pragma once
2 
3 #include <memory>
4 #include <vector>
5 
6 template<typename T, typename _Bin = T>
7 class Histogram {
8  public:
9 
10  virtual std::size_t findBin(const std::vector<_Bin>& values) = 0;
11  virtual std::size_t findClosestBin(const std::vector<_Bin>& values, bool* outOfRange = nullptr) = 0;
12  virtual bool inRange(const std::vector<_Bin>& values) = 0;
13  virtual std::vector<_Bin> clamp(const std::vector<_Bin>& values) = 0;
14 
15  T getBinContent(std::size_t bin) {
16  return m_values[bin - 1];
17  }
18  T getBinErrorLow(std::size_t bin) {
19  return m_errors_low[bin - 1];
20  }
21  T getBinErrorHigh(std::size_t bin) {
22  return m_errors_high[bin - 1];
23  }
24 
25  void setBinContent(std::size_t bin, T value) {
26  m_values[bin - 1] = value;
27  }
28  void setBinErrorLow(std::size_t bin, T value) {
29  m_errors_low[bin - 1] = value;
30  }
31  void setBinErrorHigh(std::size_t bin, T value) {
32  m_errors_high[bin - 1] = value;
33  }
34 
35  void setContent(const std::vector<_Bin>& values, T content) {
36  size_t bin = findBin(values);
37  if (bin == 0)
38  return;
39 
40  setBinContent(bin, content);
41  }
42 
43  size_t size() const {
44  return m_size;
45  }
46 
47  protected:
48  Histogram(std::size_t size) {
49  m_size = size;
50 
51  m_values.reset(new T[m_size]);
52  m_errors_low.reset(new T[m_size]);
53  m_errors_high.reset(new T[m_size]);
54  }
55 
56  static size_t findBin(const std::vector<_Bin>& array, _Bin value) {
57  for (std::size_t i = 0; i < array.size() - 1; i++) {
58  if ((value >= array[i]) && (value < array[i + 1]))
59  return i + 1;
60  }
61 
62  return 0;
63  }
64 
65  static size_t findClosestBin(const std::vector<_Bin>& array, _Bin value, bool* outOfRange = nullptr) {
66  if (outOfRange)
67  *outOfRange = false;
68 
69  if (value < array.front()) {
70  if (outOfRange)
71  *outOfRange = true;
72  return 1;
73  } else if (value >= array.back()) {
74  if (outOfRange)
75  *outOfRange = true;
76  return array.size() - 1;
77  } else {
78  return findBin(array, value);
79  }
80  }
81 
82  static bool inRange(const std::vector<_Bin>& array, _Bin value) {
83  _Bin min = array.front();
84  _Bin max = array.back();
85 
86  return ((value >= min) && (value < max));
87  }
88 
89  static _Bin clamp(const std::vector<_Bin>& array, _Bin value) {
90  _Bin min = array.front();
91  _Bin max = array.back();
92 
93  if (value < min)
94  return min;
95 
96  if (value > max)
97  return max;
98 
99  return value;
100  }
101 
102  std::size_t m_size;
103  std::unique_ptr<T[]> m_values;
104  std::unique_ptr<T[]> m_errors_low;
105  std::unique_ptr<T[]> m_errors_high;
106 
107  private:
108  Histogram() = delete;
109 
110 };
111 
112 template<typename T, typename _Bin = T>
113 class OneDimensionHistogram: public Histogram<T, _Bin> {
114  public:
115  OneDimensionHistogram(const std::vector<_Bin>& bins):
116  Histogram<T, _Bin>(bins.size() - 1) {
117  m_bins = bins;
118  }
119 
120  virtual std::size_t findBin(const std::vector<_Bin>& values) override {
121  if (values.size() != 1)
122  return 0;
123 
124  _Bin value = values[0];
125 
126  return Histogram<T, _Bin>::findBin(m_bins, value);
127  }
128 
129  virtual std::size_t findClosestBin(const std::vector<_Bin>& values, bool* outOfRange = nullptr) override {
130  if (values.size() != 1)
131  return 0;
132 
133  _Bin value = values[0];
134 
135  return Histogram<T, _Bin>::findClosestBin(m_bins, value, outOfRange);
136  }
137 
138  virtual bool inRange(const std::vector<_Bin>& values) override {
139  if (values.size() != 1) {
140  return false;
141  }
142 
143  _Bin value = values.front();
144  return Histogram<T, _Bin>::inRange(m_bins, value);
145  }
146 
147  virtual std::vector<_Bin> clamp(const std::vector<_Bin>& values) override {
148  if (values.size() != 1) {
149  return values;
150  }
151 
152  _Bin value = values.front();
153  return {Histogram<T, _Bin>::clamp(m_bins, value)};
154  }
155 
156  private:
157  std::vector<_Bin> m_bins;
158 };
159 
160 template<typename T, typename _Bin = T>
161 class TwoDimensionsHistogram: public Histogram<T, _Bin> {
162  public:
163  TwoDimensionsHistogram(const std::vector<_Bin>& bins_x, const std::vector<_Bin>& bins_y):
164  Histogram<T, _Bin>((bins_x.size() - 1) * (bins_y.size() - 1)) {
165  m_bins_x = bins_x;
166  m_bins_y = bins_y;
167  }
168 
169  virtual std::size_t findBin(const std::vector<_Bin>& values) override {
170  if (values.size() != 2)
171  return 0;
172 
173  _Bin value_x = values[0];
174  _Bin value_y = values[1];
175 
176  size_t bin_x = Histogram<T, _Bin>::findBin(m_bins_x, value_x);
177  if (bin_x == 0)
178  return 0;
179 
180  size_t bin_y = Histogram<T, _Bin>::findBin(m_bins_y, value_y);
181  if (bin_y == 0)
182  return 0;
183 
184  return bin_x + (m_bins_x.size() - 1) * (bin_y - 1);
185  }
186 
187  virtual std::size_t findClosestBin(const std::vector<_Bin>& values, bool* outOfRange = nullptr) override {
188  if (values.size() != 2)
189  return 0;
190 
191  _Bin value_x = values[0];
192  _Bin value_y = values[1];
193  bool local_outOfRange = false;
194 
195  if (outOfRange)
196  *outOfRange = false;
197 
198  size_t bin_x = Histogram<T, _Bin>::findClosestBin(m_bins_x, value_x, &local_outOfRange);
199 
200  if (outOfRange)
201  *outOfRange |= local_outOfRange;
202 
203  if (bin_x == 0)
204  return 0;
205 
206  size_t bin_y = Histogram<T, _Bin>::findClosestBin(m_bins_y, value_y, &local_outOfRange);
207 
208 
209  if (outOfRange)
210  *outOfRange |= local_outOfRange;
211 
212  if (bin_y == 0)
213  return 0;
214 
215  return bin_x + (m_bins_x.size() - 1) * (bin_y - 1);
216  }
217 
218  virtual bool inRange(const std::vector<_Bin>& values) override {
219  if (values.size() != 2) {
220  return false;
221  }
222 
223  _Bin value_x = values.front();
224  _Bin value_y = values[1];
225 
226  return Histogram<T, _Bin>::inRange(m_bins_x, value_x) && Histogram<T, _Bin>::inRange(m_bins_y, value_y);
227  }
228 
229  virtual std::vector<_Bin> clamp(const std::vector<_Bin>& values) override {
230  if (values.size() != 2) {
231  return values;
232  }
233 
234  _Bin value_x = values.front();
235  _Bin value_y = values[1];
236 
237  return {Histogram<T, _Bin>::clamp(m_bins_x, value_x), Histogram<T, _Bin>::clamp(m_bins_y, value_y)};
238  }
239 
240  private:
241  std::vector<_Bin> m_bins_x;
242  std::vector<_Bin> m_bins_y;
243 };
244 
245 template<typename T, typename _Bin = T>
246 class ThreeDimensionsHistogram: public Histogram<T, _Bin> {
247  public:
248  ThreeDimensionsHistogram(const std::vector<_Bin>& bins_x, const std::vector<_Bin>& bins_y, const std::vector<_Bin>& bins_z):
249  Histogram<T, _Bin>((bins_x.size() - 1) * (bins_y.size() - 1) * (bins_z.size() - 1)) {
250  m_bins_x = bins_x;
251  m_bins_y = bins_y;
252  m_bins_z = bins_z;
253  }
254 
255  virtual std::size_t findBin(const std::vector<_Bin>& values) override {
256  if (values.size() != 3)
257  return 0;
258 
259  _Bin value_x = values[0];
260  _Bin value_y = values[1];
261  _Bin value_z = values[2];
262 
263  size_t bin_x = Histogram<T, _Bin>::findBin(m_bins_x, value_x);
264  if (bin_x == 0)
265  return 0;
266 
267  size_t bin_y = Histogram<T, _Bin>::findBin(m_bins_y, value_y);
268  if (bin_y == 0)
269  return 0;
270 
271  size_t bin_z = Histogram<T, _Bin>::findBin(m_bins_z, value_z);
272  if (bin_z == 0)
273  return 0;
274 
275  return bin_x + (m_bins_x.size() - 1) * ((bin_y - 1) + (m_bins_y.size() - 1) * (bin_z - 1));
276  }
277 
278  virtual std::size_t findClosestBin(const std::vector<_Bin>& values, bool* outOfRange = nullptr) override {
279  if (values.size() != 3)
280  return 0;
281 
282  _Bin value_x = values[0];
283  _Bin value_y = values[1];
284  _Bin value_z = values[2];
285  bool local_outOfRange = false;
286 
287  size_t bin_x = Histogram<T, _Bin>::findClosestBin(m_bins_x, value_x, &local_outOfRange);
288 
289  if (outOfRange)
290  *outOfRange |= local_outOfRange;
291 
292  if (bin_x == 0)
293  return 0;
294 
295  size_t bin_y = Histogram<T, _Bin>::findClosestBin(m_bins_y, value_y, &local_outOfRange);
296 
297  if (outOfRange)
298  *outOfRange |= local_outOfRange;
299 
300  if (bin_y == 0)
301  return 0;
302 
303  size_t bin_z = Histogram<T, _Bin>::findClosestBin(m_bins_z, value_z, &local_outOfRange);
304 
305  if (outOfRange)
306  *outOfRange |= local_outOfRange;
307 
308  if (bin_z == 0)
309  return 0;
310 
311  return bin_x + (m_bins_x.size() - 1) * ((bin_y - 1) + (m_bins_y.size() - 1) * (bin_z - 1));
312  }
313 
314  virtual bool inRange(const std::vector<_Bin>& values) override {
315  if (values.size() != 3) {
316  return false;
317  }
318 
319  _Bin value_x = values[0];
320  _Bin value_y = values[1];
321  _Bin value_z = values[2];
322 
323  return Histogram<T, _Bin>::inRange(m_bins_x, value_x) && Histogram<T, _Bin>::inRange(m_bins_y, value_y) && Histogram<T, _Bin>::inRange(m_bins_z, value_z);
324  }
325 
326  virtual std::vector<_Bin> clamp(const std::vector<_Bin>& values) override {
327  if (values.size() != 3) {
328  return values;
329  }
330 
331  _Bin value_x = values[0];
332  _Bin value_y = values[1];
333  _Bin value_z = values[2];
334 
335  return {Histogram<T, _Bin>::clamp(m_bins_x, value_x), Histogram<T, _Bin>::clamp(m_bins_y, value_y), Histogram<T, _Bin>::clamp(m_bins_z, value_z)};
336  }
337 
338  private:
339  std::vector<_Bin> m_bins_x;
340  std::vector<_Bin> m_bins_y;
341  std::vector<_Bin> m_bins_z;
342 };
343 
344 template <typename _Value, typename _Bin = _Value>
345 std::size_t findBin(const Histogram<_Value, _Bin>& object, const std::vector<_Bin>& values) {
346  return object.findBin(values);
347 }
348 
349 template <typename _Value, typename _Bin = _Value>
350 _Value getBinContent(const Histogram<_Value, _Bin>& object, std::size_t bin) {
351  return object.getBinContent(bin);
352 }
353 
354 template <typename _Value, typename _Bin = _Value>
355 _Value getBinErrorLow(const Histogram<_Value, _Bin>& object, std::size_t bin) {
356  return object.getBinErrorLow(bin);
357 }
358 
359 template <typename _Value, typename _Bin = _Value>
360 _Value getBinErrorHigh(const Histogram<_Value, _Bin>& object, std::size_t bin) {
361  return object.getBinErrorHigh(bin);
362 }
Definition: Histogram.h:7
Definition: Histogram.h:113
Definition: Histogram.h:246
Definition: Histogram.h:161