YODA is hosted by Hepforge, IPPP Durham
YODA - Yet more Objects for Data Analysis  1.3.1
Bin2D.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // This file is part of YODA -- Yet more Objects for Data Analysis
4 // Copyright (C) 2008-2015 The YODA collaboration (see AUTHORS for details)
5 //
6 #ifndef YODA_Bin2D_h
7 #define YODA_Bin2D_h
8 
9 #include "YODA/Utils/MathUtils.h"
10 #include "YODA/Bin.h"
11 #include <utility>
12 
13 namespace YODA {
14 
15 
24  template <class DBN>
25  class Bin2D : public Bin {
26  public:
27 
29 
30 
31  // /// Make a new, empty bin with two pairs of edges.
32  // Bin2D(double xmin, double ymin, double xmax, double ymax)
33  // : _xedges( std::make_pair(xmin, xmax) ),
34  // _yedges( std::make_pair(ymin, ymax) )
35  // {
36  // if (_xedges.second < _xedges.first) {
37  // throw RangeError("The bin x-edges are wrongly defined!");
38  // }
39  // if (_yedges.second < _yedges.first) {
40  // throw RangeError("The bin y-edges are wrongly defined!");
41  // }
42  // }
43 
44 
46  Bin2D(const std::pair<double, double>& xedges, const std::pair<double, double>& yedges)
47  : _xedges(xedges), _yedges(yedges)
48  {
49  if (_xedges.second < _xedges.first) {
50  throw RangeError("The bin x-edges are wrongly defined!");
51  }
52  if (_yedges.second < _yedges.first) {
53  throw RangeError("The bin y-edges are wrongly defined!");
54  }
55  }
56 
57 
61  Bin2D(const std::pair<double, double>& xedges,
62  const std::pair<double, double>& yedges, const DBN& dbn)
63  : _xedges(xedges), _yedges(yedges), _dbn(dbn)
64  {
65  if (_xedges.second < _xedges.first) {
66  throw RangeError("The bin x-edges are wrongly defined!");
67  }
68  if (_yedges.second < _yedges.first) {
69  throw RangeError("The bin y-edges are wrongly defined!");
70  }
71  }
72 
73 
75  Bin2D(const Bin2D<DBN>& b)
76  : _xedges(b._xedges),
77  _yedges(b._yedges),
78  _dbn(b._dbn)
79  { }
80 
81 
84  _xedges = b._xedges;
85  _yedges = b._yedges;
86  _dbn = b._dbn;
87  return *this;
88  }
89 
91 
92 
94 
95 
97  virtual void reset() {
98  _dbn.reset();
99  }
100 
104  void scaleW(double scalefactor) {
105  _dbn.scaleW(scalefactor);
106  }
107 
111  void scaleXY(double scaleX, double scaleY) {
112  _xedges.first *= scaleX;
113  _xedges.second *= scaleX;
114 
115  _yedges.first *= scaleY;
116  _yedges.second *= scaleY;
117 
118  _dbn.scaleX(scaleX);
119  _dbn.scaleY(scaleY);
120  }
121 
123 
124 
125  public:
126 
128 
129 
131  std::pair<double,double> xEdges() const {
132  return _xedges;
133  }
134 
136  double xMin() const {
137  return _xedges.first;
138  }
139 
141  double xMax() const {
142  return _xedges.second;
143  }
144 
145 
147  std::pair<double,double> yEdges() const {
148  return _yedges;
149  }
150 
152  double yMin() const {
153  return _yedges.first;
154  }
155 
157  double yMax() const {
158  return _yedges.second;
159  }
160 
161 
163  double xMid() const {
164  return (xMax() + xMin())/2.0;
165  }
166 
168  double yMid() const {
169  return (yMax() + yMin())/2.0;
170  }
171 
173  std::pair<double, double> xyMid() const {
174  return std::make_pair(xMid(), yMid());
175  }
176 
177 
179  double xWidth() const {
180  return xMax() - xMin();
181  }
182 
184  double yWidth() const {
185  return yMax() - yMin();
186  }
187 
189  std::pair<double, double> xyWidths() const {
190  return std::make_pair(xWidth(), yWidth());
191  }
192 
193 
195  double xFocus() const {
196  return (!isZero(sumW())) ? xMean() : xMid();
197  }
198 
200  double yFocus() const {
201  return (!isZero(sumW())) ? yMean() : yMid();
202  }
203 
205  std::pair<double, double> xyFocus() const {
206  return std::make_pair(xFocus(), yFocus());
207  }
208 
210 
211 
212  public:
213 
215 
216 
218  double xMean() const {
219  return _dbn.xMean();
220  }
221 
223  double yMean() const {
224  return _dbn.yMean();
225  }
226 
228  double xVariance() const {
229  return _dbn.xVariance();
230  }
231 
233  double yVariance() const {
234  return _dbn.yVariance();
235  }
236 
238  double xStdDev() const {
239  return _dbn.xStdDev();
240  }
241 
243  double yStdDev() const {
244  return _dbn.yStdDev();
245  }
246 
248  double xStdErr() const {
249  return _dbn.xStdErr();
250  }
251 
253  double yStdErr() const {
254  return _dbn.yStdErr();
255  }
256 
258  double xRMS() const {
259  return _dbn.xRMS();
260  }
261 
263  double yRMS() const {
264  return _dbn.yRMS();
265  }
266 
268 
269 
270  public:
271 
273 
274 
276  DBN& dbn() {
277  return _dbn;
278  }
279 
281  const DBN& dbn() const {
282  return _dbn;
283  }
284 
286  unsigned long numEntries() const {
287  return _dbn.numEntries();
288  }
289 
291  double effNumEntries() const {
292  return _dbn.effNumEntries();
293  }
294 
296  double sumW() const {
297  return _dbn.sumW();
298  }
299 
301  double sumW2() const {
302  return _dbn.sumW2();
303  }
304 
306  double sumWX() const {
307  return _dbn.sumWX();
308  }
309 
311  double sumWY() const {
312  return _dbn.sumWY();
313  }
314 
316  double sumWXY() const {
317  return _dbn.sumWXY();
318  }
319 
321  double sumWX2() const {
322  return _dbn.sumWX2();
323  }
324 
326  double sumWY2() const {
327  return _dbn.sumWY2();
328  }
329 
331 
332 
333  public:
334 
336 
337 
340  return add(b);
341  }
342 
345  return subtract(b);
346  }
347 
349 
350 
352 
353 
355  /*
356  Bin2D<DBN>& merge(const Bin2D<DBN>& b) {
357 
358  if (fuzzyEquals(_edges.second, b._edges.first)) {
359  _edges.second = b._edges.second;
360  } else if (fuzzyEquals(_edges.second, b._edges.first)) {
361  _edges.first = b._edges.first;
362  } else {
363  throw LogicError("Attempted to merge two non-adjacent bins");
364  }
365  // std::cout << "a " << _dbn.sumW() << std::endl;
366  _dbn += b._dbn;
367  // std::cout << "b " << _dbn.sumW() << std::endl;
368  return *this;
369  }
370  */
371 
372 
377  Bin2D<DBN>& add(const Bin2D<DBN>& b) {
378  if (_xedges != b._xedges || _yedges != b._yedges) {
379  throw LogicError("Attempted to add two bins with different edges");
380  }
381  _dbn += b._dbn;
382  return *this;
383  }
384 
385 
391  if (_xedges != b._xedges || _yedges != b._yedges) {
392  throw LogicError("Attempted to subtract two bins with different edges");
393  }
394  _dbn -= b._dbn;
395  return *this;
396  }
397 
399  bool fitsInside(std::pair<double, double> xrange,
400  std::pair<double, double> yrange) const {
401  return (xMin() >= xrange.first &&
402  yMin() >= yrange.first &&
403  xMax() < xrange.second &&
404  yMax() < yrange.second);
405  }
406 
408  bool bounds(double x, double y) const {
409  return (x >= xMin() && x < xMax() && y >= yMin() && y < yMax());
410  }
411 
412 
413 
415  int adjacentTo(const Bin2D<DBN> &b) const {
416  for (int i = 0; i < 4; i++) {
417  if (_edges_equal(b, i, (i+2) % 4))
418  return i;
419  }
420  return -1;
421  }
422 
424 
425 
426  protected:
427 
429  std::pair<double, double> _edge_par(int i) const {
430  if (i % 2)
431  return xEdges();
432  else
433  return yEdges();
434  }
435 
437  double _edge_perp(size_t i) const {
438  double output = 0.0;
439  switch (i) {
440  case 0: output = xMax(); break;
441  case 1: output = yMax(); break;
442  case 2: output = xMin(); break;
443  case 3: output = yMin(); break;
444  }
445  return output;
446  }
447 
448  // Check if common edge.
450  bool _edges_equal(const Bin2D<DBN>& other, const int i, const int j) const {
451  return other._edges_equal(_edge_perp(i), _edge_par(i), j);
452  }
453 
455  bool _edges_equal(const double perp, const std::pair<double, double> par, int j) const {
456  return (fuzzyEquals(perp, _edge_perp(j)) &&
457  fuzzyEquals(par.first, _edge_par(j).first) &&
458  fuzzyEquals(par.second, _edge_par(j).second));
459  }
460 
461 
462  protected:
463 
465  std::pair<double,double> _xedges;
466  std::pair<double,double> _yedges;
467 
468  // Distribution of weighted x (and perhaps y) values
469  DBN _dbn;
470 
472 
473  };
474 
475 
476 
477 
478 
483  template <class DBN>
484  inline Bin2D<DBN> operator + (const Bin2D<DBN>& a, const Bin2D<DBN>& b) {
485  Bin2D<DBN> rtn = a;
486  rtn += b;
487  return rtn;
488  }
489 
490 
495  template <class DBN>
496  inline Bin2D<DBN> operator - (const Bin2D<DBN>& a, const Bin2D<DBN>& b) {
497  Bin2D<DBN> rtn = a;
498  rtn -= b;
499  return rtn;
500  }
501 
502 
504  template <class DBN>
505  inline bool operator<(const Bin2D<DBN>& a, const Bin2D<DBN>& b) {
506  if (!fuzzyEquals(a.xMin(), b.xMin())) return b.xMin() > a.xMin();
507  return b.yMin() > a.yMin();
508  }
509 
510 
511 
512 }
513 
514 
515 
516 #endif
DBN & dbn()
Statistical distribution in this bin (non-const)
Definition: Bin2D.h:276
Base class for bins in 1D and 2D histograms.
Definition: Bin.h:20
bool isZero(double val, double tolerance=1E-8)
Definition: MathUtils.h:51
Bin2D< DBN > & operator+=(const Bin2D< DBN > &b)
Add two bins.
Definition: Bin2D.h:339
double xFocus() const
The mean x position in the bin, or the x midpoint if that is not available.
Definition: Bin2D.h:195
unsigned long numEntries() const
The number of entries.
Definition: Bin2D.h:286
std::pair< double, double > xEdges() const
Get the {low,high} edges as an STL pair.
Definition: Bin2D.h:131
double xMean() const
Mean value of x-values in the bin.
Definition: Bin2D.h:218
double xStdDev() const
The standard deviation (spread) of x-values in the bin.
Definition: Bin2D.h:238
std::pair< double, double > xyFocus() const
The mean position in the bin, or the midpoint if that is not available.
Definition: Bin2D.h:205
const DBN & dbn() const
Statistical distribution in this bin (const)
Definition: Bin2D.h:281
Bin2D< DBN > & operator=(const Bin2D< DBN > &b)
Copy assignment.
Definition: Bin2D.h:83
Bin2D(const std::pair< double, double > &xedges, const std::pair< double, double > &yedges)
Make a new, empty bin with two pairs of edges.
Definition: Bin2D.h:46
double xMid() const
Middle of the bin in x.
Definition: Bin2D.h:163
double xRMS() const
The x RMS in the bin.
Definition: Bin2D.h:258
Bin2D(const Bin2D< DBN > &b)
Copy constructor.
Definition: Bin2D.h:75
std::pair< double, double > xyWidths() const
Widths of the bin in x and y.
Definition: Bin2D.h:189
double xMax() const
Upper x limit of the bin (exclusive).
Definition: Bin2D.h:141
Axis1D< BIN1D, DBN > operator-(const Axis1D< BIN1D, DBN > &first, const Axis1D< BIN1D, DBN > &second)
Subtract the statistics on two axis.
Definition: Axis1D.h:494
double yFocus() const
The mean y position in the bin, or the y midpoint if that is not available.
Definition: Bin2D.h:200
double sumW() const
The sum of weights.
Definition: Bin2D.h:296
Error for e.g. use of invalid bin ranges.
Definition: Exceptions.h:34
void scaleW(double scalefactor)
Definition: Bin2D.h:104
bool fuzzyEquals(double a, double b, double tolerance=1E-5)
Compare two floating point numbers for equality with a degree of fuzziness.
Definition: MathUtils.h:68
double xMin() const
Lower x limit of the bin (inclusive).
Definition: Bin2D.h:136
double yStdDev() const
The standard deviation (spread) of y-values in the bin.
Definition: Bin2D.h:243
std::pair< double, double > xyMid() const
The geometric centre of the bin.
Definition: Bin2D.h:173
double sumW2() const
The sum of weights squared.
Definition: Bin2D.h:301
double sumWXY() const
The sum of x*y*weight.
Definition: Bin2D.h:316
double sumWX2() const
The sum of x^2 * weight.
Definition: Bin2D.h:321
std::pair< double, double > yEdges() const
Get the {low,high} edges as an STL pair.
Definition: Bin2D.h:147
bool bounds(double x, double y) const
Test whether a point lies within the current bin.
Definition: Bin2D.h:408
Bin2D< DBN > & add(const Bin2D< DBN > &b)
Merge two adjacent bins.
Definition: Bin2D.h:377
double yMin() const
Lower y limit of the bin (inclusive).
Definition: Bin2D.h:152
double yRMS() const
The y RMS in the bin.
Definition: Bin2D.h:263
Error for places where it should not have been possible to get to!
Definition: Exceptions.h:55
Axis1D< BIN1D, DBN > operator+(const Axis1D< BIN1D, DBN > &first, const Axis1D< BIN1D, DBN > &second)
Add the statistics on two axes.
Definition: Axis1D.h:486
double xStdErr() const
The standard error on the bin x focus.
Definition: Bin2D.h:248
void scaleXY(double scaleX, double scaleY)
Definition: Bin2D.h:111
double yMid() const
Middle of the bin in y.
Definition: Bin2D.h:168
double xWidth() const
Width of the bin in x.
Definition: Bin2D.h:179
double effNumEntries() const
The effective number of entries.
Definition: Bin2D.h:291
virtual void reset()
Reset this bin.
Definition: Bin2D.h:97
double yMean() const
Mean value of y-values in the bin.
Definition: Bin2D.h:223
double sumWY() const
The sum of y*weight.
Definition: Bin2D.h:311
A generic 2D bin type.
Definition: Bin2D.h:25
double yVariance() const
The variance of y-values in the bin.
Definition: Bin2D.h:233
double xVariance() const
The variance of x-values in the bin.
Definition: Bin2D.h:228
double yStdErr() const
The standard error on the bin y focus.
Definition: Bin2D.h:253
double yWidth() const
Width of the bin in y.
Definition: Bin2D.h:184
double yMax() const
Upper y limit of the bin (exclusive).
Definition: Bin2D.h:157
Bin2D(const std::pair< double, double > &xedges, const std::pair< double, double > &yedges, const DBN &dbn)
Make a bin with all the components of a fill history.
Definition: Bin2D.h:61
int adjacentTo(const Bin2D< DBN > &b) const
Test whether two bins are adjacent and, if so, return how as an integer.
Definition: Bin2D.h:415
bool fitsInside(std::pair< double, double > xrange, std::pair< double, double > yrange) const
Test whether this bin would fit inside the given area.
Definition: Bin2D.h:399
Bin2D< DBN > & subtract(const Bin2D< DBN > &b)
Definition: Bin2D.h:390
double sumWX() const
The sum of x*weight.
Definition: Bin2D.h:306
double sumWY2() const
The sum of y^2 * weight.
Definition: Bin2D.h:326
Bin2D< DBN > & operator-=(const Bin2D< DBN > &b)
Subtract one bin from another.
Definition: Bin2D.h:344