Histogram.h
Go to the documentation of this file.
1 #ifndef _utl_Histogram_h_
2 #define _utl_Histogram_h_
3 
4 #include <utl/ErrorLogger.h>
5 #include <utl/AugerException.h>
6 
7 #include <boost/type_traits.hpp>
8 
9 #include <vector>
10 #include <sstream>
11 #include <algorithm>
12 
13 
14 namespace utl {
15 
16  // this is missing from the boost::type_traits
17  template<typename T>
18  struct identity {
19  typedef T type;
20  };
21 
22 
23  template<typename T>
25  typedef typename boost::add_const<T>::type const_type;
26  public:
27  typedef typename boost::add_reference<const_type>::type type;
28  };
29 
30 
32  class EqualBinning {
33  public:
34  typedef double BinEdgeType;
35  typedef const double& ConstBinLowerEdgesRefType;
36 
37  EqualBinning(const size_t nBins, const double start, const double stop)
38  : fNBins(nBins), fStart(start), fStop(stop), fBinSize((stop-start)/nBins) { }
39 
40  size_t GetNBins() const { return fNBins; }
41 
42  double GetStart() const { return fStart; }
43 
44  double GetStop() const { return fStop; }
45 
46  bool IsUnderflow(const double x) const { return x < fStart; }
47 
48  bool IsOverflow(const double x) const { return x >= fStop; }
49 
50  double GetBinLowerEdge(const size_t bin) const
51  { return fStart + bin*fBinSize; }
52 
53  double GetBinUpperEdge(const size_t bin) const
54  { return fStart + (bin+1)*fBinSize; }
55 
56  double GetBinSize(const size_t) const
57  { return fBinSize; }
58 
59  size_t GetBinIndexUnchecked(const double x) const
60  { return (size_t)((x - fStart) / fBinSize); }
61 
62  private:
63  const size_t fNBins;
64  const double fStart;
65  const double fStop;
66  const double fBinSize;
67  };
68 
69 
71  template<typename T = double,
72  template<typename> class ContainerPolicy = boost::add_const>
74  public:
75  typedef T BinEdgeType;
76  typedef typename ContainerPolicy<std::vector<BinEdgeType>>::type BinLowerEdgesType;
77  typedef typename boost::add_reference<BinLowerEdgesType>::type BinLowerEdgesRefType;
79 
81 
83  : fBinLowerEdges(edges) { }
84 
85  size_t GetNBins() const { return fBinLowerEdges.size() - 1; }
86 
87  BinEdgeType GetStart() const { return fBinLowerEdges.front(); }
88 
89  BinEdgeType GetStop() const { return fBinLowerEdges.back(); }
90 
91  bool IsUnderflow(const double x) const { return x < GetStart(); }
92 
93  bool IsOverflow(const double x) const { return x >= GetStop(); }
94 
95  BinEdgeType GetBinLowerEdge(const size_t bin) const
96  { return fBinLowerEdges[bin]; }
97 
98  BinEdgeType GetBinUpperEdge(const size_t bin) const
99  { return fBinLowerEdges[bin+1]; }
100 
101  BinEdgeType GetBinSize(const size_t bin) const
102  { return GetBinUpperEdge(bin) - GetBinLowerEdge(bin); }
103 
104  size_t
105  GetBinIndexUnchecked(const double x)
106  const
107  {
108  return size_t(std::upper_bound(fBinLowerEdges.begin(),
109  fBinLowerEdges.end(), x)
110  - fBinLowerEdges.begin()) - 1;
111  }
112 
114 
116 
117  private:
119  };
120 
121 
148  template<typename T = double,
149  class BinningPolicy = EqualBinning,
150  template<typename> class ContainerPolicy = identity>
151  class Histogram : public BinningPolicy {
152  public:
153  typedef typename BinningPolicy::BinEdgeType BinEdgeType;
154  typedef typename ContainerPolicy<std::vector<T>>::type BinContainerType;
155  typedef T BinType;
156  typedef typename boost::add_reference<BinContainerType>::type BinContainerRefType;
158  typedef typename BinningPolicy::ConstBinLowerEdgesRefType ConstBinLowerEdgesRefType;
159 
160  enum OutOfBounds {
163  };
164 
165  // equal binning
166  Histogram(const size_t nBins, const BinEdgeType start, const BinEdgeType stop)
167  : BinningPolicy(nBins, start, stop),
169  { fBinContainer.resize(nBins); }
170 
171  Histogram(const BinEdgeType start, const BinEdgeType stop,
172  ConstBinContainerRefType dataBins)
173  : BinningPolicy(dataBins.size(), start, stop),
174  fUnderflow(0), fOverflow(0), fBinContainer(dataBins)
175  { }
176 
177  // variable binning
179  : BinningPolicy(binEdges),
181  { fBinContainer.resize(binEdges.size()-1); }
182 
184  ConstBinContainerRefType dataBins)
185  : BinningPolicy(binEdges),
186  fUnderflow(0), fOverflow(0), fBinContainer(dataBins)
187  {
188  if (binEdges.size()-1 != dataBins.size()) {
189  std::ostringstream err;
190  err << "Initializing Histogram with number of bin edges "
191  << binEdges.size() << " but number of bins "
192  << dataBins.size() << '!';
193  ERROR(err);
194  throw OutOfBoundException(err.str());
195  }
196  }
197 
198  size_t
199  GetBinIndex(const double x)
200  const
201  {
202  if (BinningPolicy::IsUnderflow(x))
203  return eUnderflow;
204  else if (BinningPolicy::IsOverflow(x))
205  return eOverflow;
206  else
207  return BinningPolicy::GetBinIndexUnchecked(x);
208  }
209 
210  void Fill(const double x) { ++GetDataBin(x); }
211 
212  void Fill(const double x, const BinType weight)
213  { GetDataBin(x) += weight; }
214 
215  void
217  {
219  std::fill(fBinContainer.begin(), fBinContainer.end(), BinType());
220  }
221 
222  const BinType& GetBin(const size_t i) const { return fBinContainer[i]; }
223 
224  double GetBinAverage(const size_t i) const
225  { return double(GetBin(i)) / BinningPolicy::GetBinSize(i); }
226 
227  double GetBinCenter(const size_t bin) const
228  { return BinningPolicy::GetBinLowerEdge(bin) +
229  0.5*BinningPolicy::GetBinSize(bin); }
230 
232  const BinType& GetUnderflow() const { return fUnderflow; }
233 
235  const BinType& GetOverflow() const { return fOverflow; }
236 
237  void SetBin(const size_t i, const BinType value)
238  { fBinContainer[i] = value; }
239 
240  BinType
241  GetMaximum()
242  const
243  {
245  const size_t n = BinningPolicy::GetNBins();
246  for (size_t i = 1; i < n; ++i)
247  if (max < fBinContainer[i])
248  max = fBinContainer[i];
249  return max;
250  }
251 
252  BinType
253  GetSumEntries()
254  const
255  {
256  BinType sum = 0;
257  for (const auto& entry : fBinContainer)
258  sum += entry;
259  return sum;
260  }
261 
263 
264  double
265  GetEntropy()
266  const
267  {
268  double n = 0;
269  double clnc = 0;
270  for (size_t bin = 0; bin < BinningPolicy::GetNBins(); ++bin) {
271  if (const double c = GetBinAverage(bin)) {
272  n += c;
273  if (c > 0)
274  clnc -= c * std::log(c);
275  }
276  }
277  return (n > 0) ? clnc / n + std::log(n) : 0;
278  }
279 
280  std::vector<double>
281  GetDensityVector()
282  const
283  {
284  const auto n = BinningPolicy::GetNBins();
285  std::vector<double> density;
286  density.reserve(n + 1);
287  density.push_back(GetBinAverage(0));
288  for (size_t i = 1; i < n - 2; ++i) {
289  const double value1 = GetBinAverage(i - 1);
290  const double value2 = GetBinAverage(i);
291  const double value3 = GetBinAverage(i + 1);
292  density.push_back((1/3.)*(value1 + value2 + value3));
293  }
294  density.push_back(0);
295  density.push_back(0);
296  return density;
297  }
298 
299  std::vector<double>
300  GetDensityErrorVector()
301  const
302  {
303  const auto n = BinningPolicy::GetNBins();
304  std::vector<double> densityError;
305  densityError.reserve(n + 1);
306  densityError.push_back(sqrt(GetBinAverage(0) / BinningPolicy::GetBinSize(0)));
307  for (size_t i = 1; i < n - 2; ++i) {
308  const double value1 = GetBinAverage(i - 1) / BinningPolicy::GetBinSize(i - 1);
309  const double value2 = GetBinAverage(i) / BinningPolicy::GetBinSize(i);
310  const double value3 = GetBinAverage(i + 1) / BinningPolicy::GetBinSize(i + 1);
311  densityError.push_back((1/3.)*sqrt(value1 + value2 + value3));
312  }
313  densityError.push_back(0);
314  densityError.push_back(0);
315  return densityError;
316  }
317 
318  private:
319  BinType&
320  GetDataBin(const double x)
321  {
322  if (BinningPolicy::IsUnderflow(x))
323  return fUnderflow;
324  if (BinningPolicy::IsOverflow(x))
325  return fOverflow;
326  return fBinContainer[BinningPolicy::GetBinIndexUnchecked(x)];
327  }
328 
332  };
333 
334 
335  //===========================================================================
336 
337 
338  template<typename BinEdgesT, typename BinT = double>
340  : public Histogram<BinT,
341  VariableBinning<BinEdgesT, boost::add_const>,
342  identity> {
343  public:
344  VariableBinHistogram(const std::vector<BinEdgesT>& edges)
345  : Histogram<BinT,
346  VariableBinning<BinEdgesT, boost::add_const>,
347  identity>(edges)
348  { }
349 
350  VariableBinHistogram(const std::vector<BinEdgesT>& edges,
351  const std::vector<BinT>& data)
352  : Histogram<BinT,
353  VariableBinning<BinEdgesT, boost::add_const>,
354  identity>(edges, data)
355  { }
356  };
357 
358 
359  template<typename BinEdgesT, typename BinT = double>
361  : public Histogram<BinT,
362  VariableBinning<BinEdgesT, add_const_reference>,
363  identity> {
364  public:
365  SharedBinHistogram(const std::vector<BinEdgesT>& edges)
366  : Histogram<BinT,
368  identity>(edges)
369  { }
370 
371  SharedBinHistogram(const std::vector<BinEdgesT>& edges,
372  const std::vector<BinT>& data)
373  : Histogram<BinT,
375  identity>(edges, data)
376  { }
377  };
378 
379 
380  template<typename BinT>
382  : public Histogram<BinT,
383  EqualBinning,
384  add_const_reference> {
385  public:
387  const EqualBinning::BinEdgeType stop,
388  const std::vector<BinT>& data)
389  : Histogram<BinT,
390  EqualBinning,
391  add_const_reference>(start, stop, data) { }
392  };
393 
394 
395  template<typename BinEdgesT, typename BinT>
397  : public Histogram<BinT,
398  VariableBinning<BinEdgesT, add_const_reference>,
399  add_const_reference> {
400  public:
401  VariableBinHistogramWrap(const std::vector<BinEdgesT>& edges,
402  const std::vector<BinT>& data)
403  : Histogram<BinT,
405  add_const_reference>(edges, data)
406  { }
407  };
408 
409 }
410 
411 
412 #endif
void SetBin(const size_t i, const BinType value)
Definition: Histogram.h:237
const BinLowerEdgesType fBinLowerEdges
Definition: Histogram.h:118
ContainerPolicy< std::vector< T > >::type BinContainerType
Definition: Histogram.h:154
void Clear()
Definition: Histogram.h:216
boost::add_reference< BinLowerEdgesType >::type BinLowerEdgesRefType
Definition: Histogram.h:77
BinType fUnderflow
Definition: Histogram.h:329
Histogram.
Definition: Histogram.h:151
VariableBinning(ConstBinLowerEdgesRefType edges)
Definition: Histogram.h:82
bool IsOverflow(const double x) const
Definition: Histogram.h:93
VariableBinHistogram(const std::vector< BinEdgesT > &edges, const std::vector< BinT > &data)
Definition: Histogram.h:350
bool IsUnderflow(const double x) const
Definition: Histogram.h:91
size_t GetBinIndexUnchecked(const double x) const
Definition: Histogram.h:59
double GetBinSize(const size_t) const
Definition: Histogram.h:56
const double & ConstBinLowerEdgesRefType
Definition: Histogram.h:35
bool IsUnderflow(const double x) const
Definition: Histogram.h:46
Histogram(const size_t nBins, const BinEdgeType start, const BinEdgeType stop)
Definition: Histogram.h:166
return densityError
Definition: Histogram.h:315
bool IsOverflow(const double x) const
Definition: Histogram.h:48
equal binning policy for Histogram
Definition: Histogram.h:32
Histogram(ConstBinLowerEdgesRefType binEdges)
Definition: Histogram.h:178
BinContainerType fBinContainer
Definition: Histogram.h:331
BinType & GetOverflow()
Definition: Histogram.h:234
size_t GetNBins() const
Definition: Histogram.h:40
BinLowerEdgesRefType GetBinLowerEdges()
Definition: Histogram.h:113
BinningPolicy::BinEdgeType BinEdgeType
Definition: Histogram.h:153
std::vector< double > density
Definition: Histogram.h:285
double GetBinAverage(const size_t i) const
Definition: Histogram.h:224
add_const_reference< BinLowerEdgesType >::type ConstBinLowerEdgesRefType
Definition: Histogram.h:78
boost::add_reference< const_type >::type type
Definition: Histogram.h:27
void Fill(const double x)
Definition: Histogram.h:210
Exception for reporting variable out of valid range.
EqualBinning(const size_t nBins, const double start, const double stop)
Definition: Histogram.h:37
const BinType & GetBin(const size_t i) const
Definition: Histogram.h:222
SharedBinHistogram(const std::vector< BinEdgesT > &edges, const std::vector< BinT > &data)
Definition: Histogram.h:371
Histogram(ConstBinLowerEdgesRefType binEdges, ConstBinContainerRefType dataBins)
Definition: Histogram.h:183
BinEdgeType GetBinUpperEdge(const size_t bin) const
Definition: Histogram.h:98
BinType & GetDataBin(const double x)
Definition: Histogram.h:320
double GetBinUpperEdge(const size_t bin) const
Definition: Histogram.h:53
VariableBinHistogramWrap(const std::vector< BinEdgesT > &edges, const std::vector< BinT > &data)
Definition: Histogram.h:401
const size_t fNBins
Definition: Histogram.h:63
const size_t n
Definition: Histogram.h:245
BinEdgeType GetBinSize(const size_t bin) const
Definition: Histogram.h:101
policy for the variable bin boundaries in Histogram
Definition: Histogram.h:73
double GetStop() const
Definition: Histogram.h:44
const BinType & GetUnderflow() const
Definition: Histogram.h:232
boost::add_const< T >::type const_type
Definition: Histogram.h:25
ConstBinContainerRefType GetBins() const
Definition: Histogram.h:262
ConstBinLowerEdgesRefType GetBinLowerEdges() const
Definition: Histogram.h:115
std::vector< double > densityError
Definition: Histogram.h:304
const double fStop
Definition: Histogram.h:65
void Fill(const double x, const BinType weight)
Definition: Histogram.h:212
return density
Definition: Histogram.h:296
const double fStart
Definition: Histogram.h:64
double GetBinLowerEdge(const size_t bin) const
Definition: Histogram.h:50
BinEdgeType GetStart() const
Definition: Histogram.h:87
uint16_t * data
Definition: dump1090.h:228
BinType fOverflow
Definition: Histogram.h:330
double BinEdgeType
Definition: Histogram.h:34
add_const_reference< BinContainerType >::type ConstBinContainerRefType
Definition: Histogram.h:157
Histogram(const BinEdgeType start, const BinEdgeType stop, ConstBinContainerRefType dataBins)
Definition: Histogram.h:171
VariableBinHistogram(const std::vector< BinEdgesT > &edges)
Definition: Histogram.h:344
BinEdgeType GetStop() const
Definition: Histogram.h:89
size_t GetNBins() const
Definition: Histogram.h:85
BinningPolicy::ConstBinLowerEdgesRefType ConstBinLowerEdgesRefType
Definition: Histogram.h:158
boost::add_reference< BinContainerType >::type BinContainerRefType
Definition: Histogram.h:156
const BinType & GetOverflow() const
Definition: Histogram.h:235
BinEdgeType GetBinLowerEdge(const size_t bin) const
Definition: Histogram.h:95
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
ContainerPolicy< std::vector< BinEdgeType > >::type BinLowerEdgesType
Definition: Histogram.h:76
double GetBinCenter(const size_t bin) const
Definition: Histogram.h:227
BinType & GetUnderflow()
Definition: Histogram.h:231
SharedBinHistogram(const std::vector< BinEdgesT > &edges)
Definition: Histogram.h:365
HistogramWrap(const EqualBinning::BinEdgeType start, const EqualBinning::BinEdgeType stop, const std::vector< BinT > &data)
Definition: Histogram.h:386
const double fBinSize
Definition: Histogram.h:66
double GetStart() const
Definition: Histogram.h:42

, generated on Tue Sep 26 2023.