yoda is hosted by Hepforge, IPPP Durham
YODA - Yet more Objects for Data Analysis  1.7.2
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-2017 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 
93 
95  size_t dim() { return 2; }
96 
97 
98 
100 
101 
103  virtual void reset() {
104  _dbn.reset();
105  }
106 
110  void scaleW(double scalefactor) {
111  _dbn.scaleW(scalefactor);
112  }
113 
117  void scaleXY(double scaleX, double scaleY) {
118  _xedges.first *= scaleX;
119  _xedges.second *= scaleX;
120 
121  _yedges.first *= scaleY;
122  _yedges.second *= scaleY;
123 
124  _dbn.scaleX(scaleX);
125  _dbn.scaleY(scaleY);
126  }
127 
129 
130 
131  public:
132 
134 
135 
137  std::pair<double,double> xEdges() const {
138  return _xedges;
139  }
140 
142  double xMin() const {
143  return _xedges.first;
144  }
145 
147  double xMax() const {
148  return _xedges.second;
149  }
150 
151 
153  std::pair<double,double> yEdges() const {
154  return _yedges;
155  }
156 
158  double yMin() const {
159  return _yedges.first;
160  }
161 
163  double yMax() const {
164  return _yedges.second;
165  }
166 
167 
169  double xMid() const {
170  return (xMax() + xMin())/2.0;
171  }
172 
174  double yMid() const {
175  return (yMax() + yMin())/2.0;
176  }
177 
179  std::pair<double, double> xyMid() const {
180  return std::make_pair(xMid(), yMid());
181  }
182 
183 
185  double xWidth() const {
186  return xMax() - xMin();
187  }
188 
190  double yWidth() const {
191  return yMax() - yMin();
192  }
193 
195  std::pair<double, double> xyWidths() const {
196  return std::make_pair(xWidth(), yWidth());
197  }
198 
199 
201  double area() const {
202  return xWidth() * yWidth();
203  }
204 
205 
207  double xFocus() const {
208  return (!isZero(sumW())) ? xMean() : xMid();
209  }
210 
212  double yFocus() const {
213  return (!isZero(sumW())) ? yMean() : yMid();
214  }
215 
217  std::pair<double, double> xyFocus() const {
218  return std::make_pair(xFocus(), yFocus());
219  }
220 
222 
223 
224  public:
225 
227 
228 
230  double xMean() const {
231  return _dbn.xMean();
232  }
233 
235  double yMean() const {
236  return _dbn.yMean();
237  }
238 
240  double xVariance() const {
241  return _dbn.xVariance();
242  }
243 
245  double yVariance() const {
246  return _dbn.yVariance();
247  }
248 
250  double xStdDev() const {
251  return _dbn.xStdDev();
252  }
253 
255  double yStdDev() const {
256  return _dbn.yStdDev();
257  }
258 
260  double xStdErr() const {
261  return _dbn.xStdErr();
262  }
263 
265  double yStdErr() const {
266  return _dbn.yStdErr();
267  }
268 
270  double xRMS() const {
271  return _dbn.xRMS();
272  }
273 
275  double yRMS() const {
276  return _dbn.yRMS();
277  }
278 
280 
281 
282  public:
283 
285 
286 
288  DBN& dbn() {
289  return _dbn;
290  }
291 
293  const DBN& dbn() const {
294  return _dbn;
295  }
296 
298  double numEntries() const {
299  return _dbn.numEntries();
300  }
301 
303  double effNumEntries() const {
304  return _dbn.effNumEntries();
305  }
306 
308  double sumW() const {
309  return _dbn.sumW();
310  }
311 
313  double sumW2() const {
314  return _dbn.sumW2();
315  }
316 
318  double sumWX() const {
319  return _dbn.sumWX();
320  }
321 
323  double sumWY() const {
324  return _dbn.sumWY();
325  }
326 
328  double sumWXY() const {
329  return _dbn.sumWXY();
330  }
331 
333  double sumWX2() const {
334  return _dbn.sumWX2();
335  }
336 
338  double sumWY2() const {
339  return _dbn.sumWY2();
340  }
341 
343 
344 
345  public:
346 
348 
349 
352  return add(b);
353  }
354 
357  return subtract(b);
358  }
359 
361 
362 
364 
365 
367  /*
368  Bin2D<DBN>& merge(const Bin2D<DBN>& b) {
369 
370  if (fuzzyEquals(_edges.second, b._edges.first)) {
371  _edges.second = b._edges.second;
372  } else if (fuzzyEquals(_edges.second, b._edges.first)) {
373  _edges.first = b._edges.first;
374  } else {
375  throw LogicError("Attempted to merge two non-adjacent bins");
376  }
377  // std::cout << "a " << _dbn.sumW() << std::endl;
378  _dbn += b._dbn;
379  // std::cout << "b " << _dbn.sumW() << std::endl;
380  return *this;
381  }
382  */
383 
384 
389  Bin2D<DBN>& add(const Bin2D<DBN>& b) {
390  if (_xedges != b._xedges || _yedges != b._yedges) {
391  throw LogicError("Attempted to add two bins with different edges");
392  }
393  _dbn += b._dbn;
394  return *this;
395  }
396 
397 
403  if (_xedges != b._xedges || _yedges != b._yedges) {
404  throw LogicError("Attempted to subtract two bins with different edges");
405  }
406  _dbn -= b._dbn;
407  return *this;
408  }
409 
411  bool fitsInside(std::pair<double, double> xrange,
412  std::pair<double, double> yrange) const {
413  return (xMin() >= xrange.first &&
414  yMin() >= yrange.first &&
415  xMax() < xrange.second &&
416  yMax() < yrange.second);
417  }
418 
420  bool bounds(double x, double y) const {
421  return (x >= xMin() && x < xMax() && y >= yMin() && y < yMax());
422  }
423 
424 
426  int adjacentTo(const Bin2D<DBN> &b) const {
427  for (int i = 0; i < 4; i++) {
428  if (_edges_equal(b, i, (i+2) % 4))
429  return i;
430  }
431  return -1;
432  }
433 
435 
436 
437  protected:
438 
440  std::pair<double, double> _edge_par(int i) const {
441  if (i % 2)
442  return xEdges();
443  else
444  return yEdges();
445  }
446 
448  double _edge_perp(size_t i) const {
449  double output = 0.0;
450  switch (i) {
451  case 0: output = xMax(); break;
452  case 1: output = yMax(); break;
453  case 2: output = xMin(); break;
454  case 3: output = yMin(); break;
455  }
456  return output;
457  }
458 
459  // Check if common edge.
461  bool _edges_equal(const Bin2D<DBN>& other, const int i, const int j) const {
462  return other._edges_equal(_edge_perp(i), _edge_par(i), j);
463  }
464 
466  bool _edges_equal(const double perp, const std::pair<double, double> par, int j) const {
467  return (fuzzyEquals(perp, _edge_perp(j)) &&
468  fuzzyEquals(par.first, _edge_par(j).first) &&
469  fuzzyEquals(par.second, _edge_par(j).second));
470  }
471 
472 
473  protected:
474 
476  std::pair<double,double> _xedges;
477  std::pair<double,double> _yedges;
478 
479  // Distribution of weighted x (and perhaps y) values
480  DBN _dbn;
481 
483 
484  };
485 
486 
487 
488 
489 
494  template <class DBN>
495  inline Bin2D<DBN> operator + (const Bin2D<DBN>& a, const Bin2D<DBN>& b) {
496  Bin2D<DBN> rtn = a;
497  rtn += b;
498  return rtn;
499  }
500 
501 
506  template <class DBN>
507  inline Bin2D<DBN> operator - (const Bin2D<DBN>& a, const Bin2D<DBN>& b) {
508  Bin2D<DBN> rtn = a;
509  rtn -= b;
510  return rtn;
511  }
512 
513 
515  template <class DBN>
516  inline bool operator<(const Bin2D<DBN>& a, const Bin2D<DBN>& b) {
517  if (!fuzzyEquals(a.xMin(), b.xMin())) return b.xMin() > a.xMin();
518  return b.yMin() > a.yMin();
519  }
520 
521 
522 
523 }
524 
525 
526 
527 #endif
double yFocus() const
The mean y position in the bin, or the y midpoint if that is not available.
Definition: Bin2D.h:212
DBN & dbn()
Statistical distribution in this bin (non-const)
Definition: Bin2D.h:288
double sumWY() const
The sum of y*weight.
Definition: Bin2D.h:323
Base class for bins in 1D and 2D histograms.
Definition: Bin.h:20
double sumWX2() const
The sum of x^2 * weight.
Definition: Bin2D.h:333
bool isZero(double val, double tolerance=1E-8)
Definition: MathUtils.h:55
double sumW2() const
The sum of weights squared.
Definition: Bin2D.h:313
Bin2D< DBN > & operator+=(const Bin2D< DBN > &b)
Add two bins.
Definition: Bin2D.h:351
int adjacentTo(const Bin2D< DBN > &b) const
Test whether two bins are adjacent and, if so, return how as an integer.
Definition: Bin2D.h:426
double yMax() const
Upper y limit of the bin (exclusive).
Definition: Bin2D.h:163
double yStdErr() const
The standard error on the bin y focus.
Definition: Bin2D.h:265
double xMin() const
Lower x limit of the bin (inclusive).
Definition: Bin2D.h:142
std::pair< double, double > xEdges() const
Get the {low,high} edges as an STL pair.
Definition: Bin2D.h:137
std::pair< double, double > xyFocus() const
The mean position in the bin, or the midpoint if that is not available.
Definition: Bin2D.h:217
double xMean() const
Mean value of x-values in the bin.
Definition: Bin2D.h:230
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 yMin() const
Lower y limit of the bin (inclusive).
Definition: Bin2D.h:158
double xWidth() const
Width of the bin in x.
Definition: Bin2D.h:185
Bin2D(const Bin2D< DBN > &b)
Copy constructor.
Definition: Bin2D.h:75
double yRMS() const
The y RMS in the bin.
Definition: Bin2D.h:275
Axis1D< BIN1D, DBN > operator-(const Axis1D< BIN1D, DBN > &first, const Axis1D< BIN1D, DBN > &second)
Subtract the statistics on two axis.
Definition: Axis1D.h:597
std::pair< double, double > yEdges() const
Get the {low,high} edges as an STL pair.
Definition: Bin2D.h:153
double yVariance() const
The variance of y-values in the bin.
Definition: Bin2D.h:245
size_t dim()
Dimension of the fill space.
Definition: Bin2D.h:95
Error for e.g. use of invalid bin ranges.
Definition: Exceptions.h:34
void scaleW(double scalefactor)
Definition: Bin2D.h:110
double xRMS() const
The x RMS in the bin.
Definition: Bin2D.h:270
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:72
double xMax() const
Upper x limit of the bin (exclusive).
Definition: Bin2D.h:147
std::pair< double, double > xyMid() const
The geometric centre of the bin.
Definition: Bin2D.h:179
double sumWXY() const
The sum of x*y*weight.
Definition: Bin2D.h:328
double xMid() const
Middle of the bin in x.
Definition: Bin2D.h:169
const DBN & dbn() const
Statistical distribution in this bin (const)
Definition: Bin2D.h:293
std::pair< double, double > xyWidths() const
Widths of the bin in x and y.
Definition: Bin2D.h:195
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:411
double yStdDev() const
The standard deviation (spread) of y-values in the bin.
Definition: Bin2D.h:255
double sumWX() const
The sum of x*weight.
Definition: Bin2D.h:318
Bin2D< DBN > & add(const Bin2D< DBN > &b)
Merge two adjacent bins.
Definition: Bin2D.h:389
double xVariance() const
The variance of x-values in the bin.
Definition: Bin2D.h:240
double sumWY2() const
The sum of y^2 * weight.
Definition: Bin2D.h:338
Error for places where it should not have been possible to get to!
Definition: Exceptions.h:55
double numEntries() const
The number of entries.
Definition: Bin2D.h:298
Axis1D< BIN1D, DBN > operator+(const Axis1D< BIN1D, DBN > &first, const Axis1D< BIN1D, DBN > &second)
Add the statistics on two axes.
Definition: Axis1D.h:589
double xFocus() const
The mean x position in the bin, or the x midpoint if that is not available.
Definition: Bin2D.h:207
void scaleXY(double scaleX, double scaleY)
Definition: Bin2D.h:117
double area() const
Area of the bin in x-y.
Definition: Bin2D.h:201
double xStdDev() const
The standard deviation (spread) of x-values in the bin.
Definition: Bin2D.h:250
double effNumEntries() const
The effective number of entries.
Definition: Bin2D.h:303
virtual void reset()
Reset this bin.
Definition: Bin2D.h:103
double sumW() const
The sum of weights.
Definition: Bin2D.h:308
A generic 2D bin type.
Definition: Bin2D.h:25
double yWidth() const
Width of the bin in y.
Definition: Bin2D.h:190
double xStdErr() const
The standard error on the bin x focus.
Definition: Bin2D.h:260
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
double yMid() const
Middle of the bin in y.
Definition: Bin2D.h:174
Bin2D< DBN > & subtract(const Bin2D< DBN > &b)
Definition: Bin2D.h:402
Bin2D< DBN > & operator-=(const Bin2D< DBN > &b)
Subtract one bin from another.
Definition: Bin2D.h:356
double yMean() const
Mean value of y-values in the bin.
Definition: Bin2D.h:235
bool bounds(double x, double y) const
Test whether a point lies within the current bin.
Definition: Bin2D.h:420