yoda is hosted by Hepforge, IPPP Durham
YODA - Yet more Objects for Data Analysis  1.9.0
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-2021 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 
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 
95 
99  size_t dim() { return 2; }
100 
102  size_t fillDim() { return 2; }
103 
105 
106 
109 
111  virtual void reset() {
112  _dbn.reset();
113  }
114 
118  void scaleW(double scalefactor) {
119  _dbn.scaleW(scalefactor);
120  }
121 
125  void scaleXY(double scaleX, double scaleY) {
126  _xedges.first *= scaleX;
127  _xedges.second *= scaleX;
128 
129  _yedges.first *= scaleY;
130  _yedges.second *= scaleY;
131 
132  _dbn.scaleX(scaleX);
133  _dbn.scaleY(scaleY);
134  }
135 
137 
138 
139  public:
140 
143 
145  std::pair<double,double> xEdges() const {
146  return _xedges;
147  }
148 
150  double xMin() const {
151  return _xedges.first;
152  }
153 
155  double xMax() const {
156  return _xedges.second;
157  }
158 
159 
161  std::pair<double,double> yEdges() const {
162  return _yedges;
163  }
164 
166  double yMin() const {
167  return _yedges.first;
168  }
169 
171  double yMax() const {
172  return _yedges.second;
173  }
174 
175 
177  double xMid() const {
178  return (xMax() + xMin())/2.0;
179  }
180 
182  double yMid() const {
183  return (yMax() + yMin())/2.0;
184  }
185 
187  std::pair<double, double> xyMid() const {
188  return std::make_pair(xMid(), yMid());
189  }
190 
191 
193  double xWidth() const {
194  return xMax() - xMin();
195  }
196 
198  double yWidth() const {
199  return yMax() - yMin();
200  }
201 
203  std::pair<double, double> xyWidths() const {
204  return std::make_pair(xWidth(), yWidth());
205  }
206 
207 
209  double area() const {
210  return xWidth() * yWidth();
211  }
212 
213 
215  double xFocus() const {
216  return (!isZero(sumW())) ? xMean() : xMid();
217  }
218 
220  double yFocus() const {
221  return (!isZero(sumW())) ? yMean() : yMid();
222  }
223 
225  std::pair<double, double> xyFocus() const {
226  return std::make_pair(xFocus(), yFocus());
227  }
228 
230 
231 
232  public:
233 
236 
238  double xMean() const {
239  return _dbn.xMean();
240  }
241 
243  double yMean() const {
244  return _dbn.yMean();
245  }
246 
248  double xVariance() const {
249  return _dbn.xVariance();
250  }
251 
253  double yVariance() const {
254  return _dbn.yVariance();
255  }
256 
258  double xStdDev() const {
259  return _dbn.xStdDev();
260  }
261 
263  double yStdDev() const {
264  return _dbn.yStdDev();
265  }
266 
268  double xStdErr() const {
269  return _dbn.xStdErr();
270  }
271 
273  double yStdErr() const {
274  return _dbn.yStdErr();
275  }
276 
278  double xRMS() const {
279  return _dbn.xRMS();
280  }
281 
283  double yRMS() const {
284  return _dbn.yRMS();
285  }
286 
288 
289 
290  public:
291 
294 
296  DBN& dbn() {
297  return _dbn;
298  }
299 
301  const DBN& dbn() const {
302  return _dbn;
303  }
304 
306  double numEntries() const {
307  return _dbn.numEntries();
308  }
309 
311  double effNumEntries() const {
312  return _dbn.effNumEntries();
313  }
314 
316  double sumW() const {
317  return _dbn.sumW();
318  }
319 
321  double sumW2() const {
322  return _dbn.sumW2();
323  }
324 
326  double sumWX() const {
327  return _dbn.sumWX();
328  }
329 
331  double sumWY() const {
332  return _dbn.sumWY();
333  }
334 
336  double sumWXY() const {
337  return _dbn.sumWXY();
338  }
339 
341  double sumWX2() const {
342  return _dbn.sumWX2();
343  }
344 
346  double sumWY2() const {
347  return _dbn.sumWY2();
348  }
349 
351 
352 
353  public:
354 
357 
360  return add(b);
361  }
362 
365  return subtract(b);
366  }
367 
369 
370 
373 
375  /*
376  Bin2D<DBN>& merge(const Bin2D<DBN>& b) {
377 
378  if (fuzzyEquals(_edges.second, b._edges.first)) {
379  _edges.second = b._edges.second;
380  } else if (fuzzyEquals(_edges.second, b._edges.first)) {
381  _edges.first = b._edges.first;
382  } else {
383  throw LogicError("Attempted to merge two non-adjacent bins");
384  }
385  // std::cout << "a " << _dbn.sumW() << std::endl;
386  _dbn += b._dbn;
387  // std::cout << "b " << _dbn.sumW() << std::endl;
388  return *this;
389  }
390  */
391 
392 
397  Bin2D<DBN>& add(const Bin2D<DBN>& b) {
398  if (_xedges != b._xedges || _yedges != b._yedges) {
399  throw LogicError("Attempted to add two bins with different edges");
400  }
401  _dbn += b._dbn;
402  return *this;
403  }
404 
405 
411  if (_xedges != b._xedges || _yedges != b._yedges) {
412  throw LogicError("Attempted to subtract two bins with different edges");
413  }
414  _dbn -= b._dbn;
415  return *this;
416  }
417 
419  bool fitsInside(std::pair<double, double> xrange,
420  std::pair<double, double> yrange) const {
421  return (xMin() >= xrange.first &&
422  yMin() >= yrange.first &&
423  xMax() < xrange.second &&
424  yMax() < yrange.second);
425  }
426 
428  bool bounds(double x, double y) const {
429  return (x >= xMin() && x < xMax() && y >= yMin() && y < yMax());
430  }
431 
432 
434  int adjacentTo(const Bin2D<DBN> &b) const {
435  for (int i = 0; i < 4; i++) {
436  if (_edges_equal(b, i, (i+2) % 4))
437  return i;
438  }
439  return -1;
440  }
441 
443 
444 
445  protected:
446 
448  std::pair<double, double> _edge_par(int i) const {
449  if (i % 2)
450  return xEdges();
451  else
452  return yEdges();
453  }
454 
456  double _edge_perp(size_t i) const {
457  double output = 0.0;
458  switch (i) {
459  case 0: output = xMax(); break;
460  case 1: output = yMax(); break;
461  case 2: output = xMin(); break;
462  case 3: output = yMin(); break;
463  }
464  return output;
465  }
466 
467  // Check if common edge.
469  bool _edges_equal(const Bin2D<DBN>& other, const int i, const int j) const {
470  return other._edges_equal(_edge_perp(i), _edge_par(i), j);
471  }
472 
474  bool _edges_equal(const double perp, const std::pair<double, double> par, int j) const {
475  return (fuzzyEquals(perp, _edge_perp(j)) &&
476  fuzzyEquals(par.first, _edge_par(j).first) &&
477  fuzzyEquals(par.second, _edge_par(j).second));
478  }
479 
480 
481  protected:
482 
484  std::pair<double,double> _xedges;
485  std::pair<double,double> _yedges;
486 
487  // Distribution of weighted x (and perhaps y) values
488  DBN _dbn;
489 
491 
492  };
493 
494 
495 
496 
497 
502  template <class DBN>
503  inline Bin2D<DBN> operator + (const Bin2D<DBN>& a, const Bin2D<DBN>& b) {
504  Bin2D<DBN> rtn = a;
505  rtn += b;
506  return rtn;
507  }
508 
509 
514  template <class DBN>
515  inline Bin2D<DBN> operator - (const Bin2D<DBN>& a, const Bin2D<DBN>& b) {
516  Bin2D<DBN> rtn = a;
517  rtn -= b;
518  return rtn;
519  }
520 
521 
523  template <class DBN>
524  inline bool operator<(const Bin2D<DBN>& a, const Bin2D<DBN>& b) {
525  if (!fuzzyEquals(a.xMin(), b.xMin())) return b.xMin() > a.xMin();
526  return b.yMin() > a.yMin();
527  }
528 
529 
530 
531 }
532 
533 
534 
535 #endif
double yFocus() const
The mean y position in the bin, or the y midpoint if that is not available.
Definition: Bin2D.h:220
DBN & dbn()
Statistical distribution in this bin (non-const)
Definition: Bin2D.h:296
double sumWY() const
The sum of y*weight.
Definition: Bin2D.h:331
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:341
bool isZero(double val, double tolerance=1E-8)
Definition: MathUtils.h:56
double sumW2() const
The sum of weights squared.
Definition: Bin2D.h:321
Bin2D< DBN > & operator+=(const Bin2D< DBN > &b)
Add two bins.
Definition: Bin2D.h:359
int adjacentTo(const Bin2D< DBN > &b) const
Test whether two bins are adjacent and, if so, return how as an integer.
Definition: Bin2D.h:434
double yMax() const
Upper y limit of the bin (exclusive).
Definition: Bin2D.h:171
double yStdErr() const
The standard error on the bin y focus.
Definition: Bin2D.h:273
double xMin() const
Lower x limit of the bin (inclusive).
Definition: Bin2D.h:150
std::pair< double, double > xEdges() const
Get the {low,high} edges as an STL pair.
Definition: Bin2D.h:145
std::pair< double, double > xyFocus() const
The mean position in the bin, or the midpoint if that is not available.
Definition: Bin2D.h:225
double xMean() const
Mean value of x-values in the bin.
Definition: Bin2D.h:238
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:166
double xWidth() const
Width of the bin in x.
Definition: Bin2D.h:193
Bin2D(const Bin2D< DBN > &b)
Copy constructor.
Definition: Bin2D.h:75
double yRMS() const
The y RMS in the bin.
Definition: Bin2D.h:283
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:161
double yVariance() const
The variance of y-values in the bin.
Definition: Bin2D.h:253
size_t dim()
Definition: Bin2D.h:99
Error for e.g. use of invalid bin ranges.
Definition: Exceptions.h:34
void scaleW(double scalefactor)
Definition: Bin2D.h:118
double xRMS() const
The x RMS in the bin.
Definition: Bin2D.h:278
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:73
double xMax() const
Upper x limit of the bin (exclusive).
Definition: Bin2D.h:155
std::pair< double, double > xyMid() const
The geometric centre of the bin.
Definition: Bin2D.h:187
double sumWXY() const
The sum of x*y*weight.
Definition: Bin2D.h:336
double xMid() const
Middle of the bin in x.
Definition: Bin2D.h:177
const DBN & dbn() const
Statistical distribution in this bin (const)
Definition: Bin2D.h:301
std::pair< double, double > xyWidths() const
Widths of the bin in x and y.
Definition: Bin2D.h:203
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:419
double yStdDev() const
The standard deviation (spread) of y-values in the bin.
Definition: Bin2D.h:263
double sumWX() const
The sum of x*weight.
Definition: Bin2D.h:326
Bin2D< DBN > & add(const Bin2D< DBN > &b)
Merge two adjacent bins.
Definition: Bin2D.h:397
double xVariance() const
The variance of x-values in the bin.
Definition: Bin2D.h:248
double sumWY2() const
The sum of y^2 * weight.
Definition: Bin2D.h:346
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:306
size_t fillDim()
Dimension of the fill space.
Definition: Bin2D.h:102
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:215
void scaleXY(double scaleX, double scaleY)
Definition: Bin2D.h:125
double area() const
Area of the bin in x-y.
Definition: Bin2D.h:209
double xStdDev() const
The standard deviation (spread) of x-values in the bin.
Definition: Bin2D.h:258
double effNumEntries() const
The effective number of entries.
Definition: Bin2D.h:311
virtual void reset()
Reset this bin.
Definition: Bin2D.h:111
double sumW() const
The sum of weights.
Definition: Bin2D.h:316
A generic 2D bin type.
Definition: Bin2D.h:25
double yWidth() const
Width of the bin in y.
Definition: Bin2D.h:198
double xStdErr() const
The standard error on the bin x focus.
Definition: Bin2D.h:268
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:182
Bin2D< DBN > & subtract(const Bin2D< DBN > &b)
Definition: Bin2D.h:410
Bin2D< DBN > & operator-=(const Bin2D< DBN > &b)
Subtract one bin from another.
Definition: Bin2D.h:364
double yMean() const
Mean value of y-values in the bin.
Definition: Bin2D.h:243
bool bounds(double x, double y) const
Test whether a point lies within the current bin.
Definition: Bin2D.h:428