yoda is hosted by Hepforge, IPPP Durham
YODA - Yet more Objects for Data Analysis  1.7.2
Histo1D.cc
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 #include "YODA/Histo1D.h"
7 #include "YODA/Profile1D.h"
8 #include "YODA/Scatter2D.h"
10 
11 using namespace std;
12 
13 namespace YODA {
14 
15 
16  void Histo1D::fill(double x, double weight, double fraction) {
17  if ( std::isnan(x) ) throw RangeError("X is NaN");
18 
19  // Fill the overall distribution
20  _axis.totalDbn().fill(x, weight, fraction);
21 
22  // Fill the bins and overflows
24  if (inRange(x, _axis.xMin(), _axis.xMax())) {
25  try {
27  _binAt(x).fill(x, weight, fraction);
28  } catch (const RangeError& re) { }
29  } else if (x < _axis.xMin()) {
30  _axis.underflow().fill(x, weight, fraction);
31  } else if (x >= _axis.xMax()) {
32  _axis.overflow().fill(x, weight, fraction);
33  }
34 
35  // Lock the axis now that a fill has happened
36  _axis._setLock(true);
37  }
38 
39 
40  void Histo1D::fillBin(size_t i, double weight, double fraction) {
41  fill(bin(i).xMid(), weight, fraction);
42  }
43 
44 
45 
47 
48  double Histo1D::numEntries(bool includeoverflows) const {
49  if (includeoverflows) return totalDbn().numEntries();
50  unsigned long n = 0;
51  for (const Bin& b : bins()) n += b.numEntries();
52  return n;
53  }
54 
55 
56  double Histo1D::effNumEntries(bool includeoverflows) const {
57  if (includeoverflows) return totalDbn().effNumEntries();
58  double n = 0;
59  for (const Bin& b : bins()) n += b.effNumEntries();
60  return n;
61  }
62 
63 
64  double Histo1D::sumW(bool includeoverflows) const {
65  if (includeoverflows) return _axis.totalDbn().sumW();
66  double sumw = 0;
67  for (const Bin& b : bins()) sumw += b.sumW();
68  return sumw;
69  }
70 
71 
72  double Histo1D::sumW2(bool includeoverflows) const {
73  if (includeoverflows) return _axis.totalDbn().sumW2();
74  double sumw2 = 0;
75  for (const Bin& b : bins()) sumw2 += b.sumW2();
76  return sumw2;
77  }
78 
79  // ^^^^^^^^^^^^^
80 
81 
82  double Histo1D::xMean(bool includeoverflows) const {
83  if (includeoverflows) return _axis.totalDbn().xMean();
84  Dbn1D dbn;
85  for (const HistoBin1D& b : bins()) dbn += b.dbn();
86  return dbn.xMean();
87  }
88 
89 
90  double Histo1D::xVariance(bool includeoverflows) const {
91  if (includeoverflows) return _axis.totalDbn().xVariance();
92  Dbn1D dbn;
93  for (const HistoBin1D& b : bins()) dbn += b.dbn();
94  return dbn.xVariance();
95  }
96 
97 
98  double Histo1D::xStdErr(bool includeoverflows) const {
99  if (includeoverflows) return _axis.totalDbn().xStdErr();
100  Dbn1D dbn;
101  for (const HistoBin1D& b : bins()) dbn += b.dbn();
102  return dbn.xStdErr();
103  }
104 
105 
106  double Histo1D::xRMS(bool includeoverflows) const {
107  if (includeoverflows) return _axis.totalDbn().xRMS();
108  Dbn1D dbn;
109  for (const HistoBin1D& b : bins()) dbn += b.dbn();
110  return dbn.xRMS();
111  }
112 
113 
115 
116 
118  Histo1D::Histo1D(const Histo1D& h, const std::string& path)
119  : AnalysisObject("Histo1D", (path.size() == 0) ? h.path() : path, h, h.title())
120  {
121  _axis = h._axis;
122  }
123 
124 
126  Histo1D::Histo1D(const Scatter2D& s, const std::string& path)
127  : AnalysisObject("Histo1D", (path.size() == 0) ? s.path() : path, s, s.title())
128  {
129  std::vector<HistoBin1D> bins;
130  for (const Scatter2D::Point& p : s.points()) {
131  bins.push_back(HistoBin1D(p.xMin(), p.xMax()));
132  }
133  _axis = Histo1DAxis(bins);
134  }
135 
136 
138  Histo1D::Histo1D(const Profile1D& p, const std::string& path)
139  : AnalysisObject("Histo1D", (path.size() == 0) ? p.path() : path, p, p.title())
140  {
141  std::vector<HistoBin1D> bins;
142  for (const ProfileBin1D& b : p.bins()) {
143  bins.push_back(HistoBin1D(b.xMin(), b.xMax()));
144  }
145  _axis = Histo1DAxis(bins);
146  }
147 
148 
150 
151 
152  // Divide two histograms
153  Scatter2D divide(const Histo1D& numer, const Histo1D& denom) {
154  Scatter2D rtn;
155 
156  for (size_t i = 0; i < numer.numBins(); ++i) {
157  const HistoBin1D& b1 = numer.bin(i);
158  const HistoBin1D& b2 = denom.bin(i);
159 
161  if (!fuzzyEquals(b1.xMin(), b2.xMin()) || !fuzzyEquals(b1.xMax(), b2.xMax()))
162  throw BinningError("x binnings are not equivalent in " + numer.path() + " / " + denom.path());
163 
164  // Assemble the x value and error
165  // Use the midpoint of the "bin" for the new central x value, in the absence of better information
166  const double x = b1.xMid();
167  const double exminus = x - b1.xMin();
168  const double explus = b1.xMax() - x;
169 
170  // Assemble the y value and error
172  double y, ey;
173  if (b2.height() == 0 || (b1.height() == 0 && b1.heightErr() != 0)) {
174  y = std::numeric_limits<double>::quiet_NaN();
175  ey = std::numeric_limits<double>::quiet_NaN();
176  // throw LowStatsError("Requested division of empty bin");
177  } else {
178  y = b1.height() / b2.height();
180  const double relerr_1 = b1.heightErr() != 0 ? b1.relErr() : 0;
181  const double relerr_2 = b2.heightErr() != 0 ? b2.relErr() : 0;
182  ey = y * sqrt(sqr(relerr_1) + sqr(relerr_2));
183  }
184 
187  //const double eyplus = y * sqrt( sqr(p1.yErrPlus()/p1.y()) + sqr(p2.yErrMinus()/p2.y()) );
188  //const double eyminus = y * sqrt( sqr(p1.yErrMinus()/p1.y()) + sqr(p2.yErrPlus()/p2.y()) );
189  rtn.addPoint(x, y, exminus, explus, ey, ey);
190  }
191 
192  assert(rtn.numPoints() == numer.numBins());
193  return rtn;
194  }
195 
196 
198 
199 
200  Scatter2D add(const Histo1D& histo, const Scatter2D& scatt) {
201  if (histo.numBins() != scatt.numPoints()) throw BinningError("Histogram binning incompatible with number of scatter points");
202 
203  Scatter2D rtn = scatt.clone();
204  if (histo.path() != scatt.path()) rtn.setPath("");
205  if (rtn.hasAnnotation("ScaledBy")) rtn.rmAnnotation("ScaledBy");
206 
207  for (size_t i = 0; i < rtn.numPoints(); ++i) {
208  const HistoBin1D& b = histo.bin(i);
209  const Point2D& s = scatt.point(i);
210 
212  if (!fuzzyEquals(b.xMin(), s.x() - s.xErrMinus()) || !fuzzyEquals(b.xMax(), s.x() + s.xErrPlus()))
213  throw BinningError("x binnings are not equivalent in " + histo.path() + " + " + scatt.path());
214 
215 
216  // convert bin to scatter point
217  double biny;
218  try {
219  biny = b.height();
220  } catch (const Exception&) { // LowStatsError or WeightError
221  biny = 0;
222  }
223  double biney;
224  try {
225  biney = b.heightErr();
226  } catch (const Exception&) { // LowStatsError or WeightError
227  biney = 0;
228  }
229  // combine with scatter values
230  double newy = biny + s.y();
231  double newey_p = sqrt(sqr(biney) + sqr(s.yErrPlus()));
232  double newey_m = sqrt(sqr(biney) + sqr(s.yErrMinus()));
233  // set new values
234  Point2D& t = rtn.point(i);
235  t.setY(newy);
236  t.setYErrMinus(newey_p);
237  t.setYErrPlus(newey_m);
238  }
239 
240  assert(rtn.numPoints() == histo.numBins());
241  return rtn;
242  }
243 
244 
246 
247 
248  Scatter2D subtract(const Histo1D& histo, const Scatter2D& scatt) {
249  if (histo.numBins() != scatt.numPoints()) throw BinningError("Histogram binning incompatible with number of scatter points");
250 
251  Scatter2D rtn = scatt.clone();
252  if (histo.path() != scatt.path()) rtn.setPath("");
253  if (rtn.hasAnnotation("ScaledBy")) rtn.rmAnnotation("ScaledBy");
254 
255  for (size_t i = 0; i < rtn.numPoints(); ++i) {
256  const HistoBin1D& b = histo.bin(i);
257  const Point2D& s = scatt.point(i);
258 
260  if (!fuzzyEquals(b.xMin(), s.x() - s.xErrMinus()) || !fuzzyEquals(b.xMax(), s.x() + s.xErrPlus()))
261  throw BinningError("x binnings are not equivalent in " + histo.path() + " - " + scatt.path());
262 
263 
264  // convert bin to scatter point
265  double biny;
266  try {
267  biny = b.height();
268  } catch (const Exception&) { // LowStatsError or WeightError
269  biny = 0;
270  }
271  double biney;
272  try {
273  biney = b.heightErr();
274  } catch (const Exception&) { // LowStatsError or WeightError
275  biney = 0;
276  }
277  // combine with scatter values
278  double newy = biny - s.y();
279  double newey_p = sqrt(sqr(biney) + sqr(s.yErrPlus()));
280  double newey_m = sqrt(sqr(biney) + sqr(s.yErrMinus()));
281  // set new values
282  Point2D& t = rtn.point(i);
283  t.setY(newy);
284  t.setYErrMinus(newey_p);
285  t.setYErrPlus(newey_m);
286  }
287 
288  assert(rtn.numPoints() == histo.numBins());
289  return rtn;
290  }
291 
292 
294 
295 
296  Scatter2D subtract(const Scatter2D& scatt, const Histo1D& histo) {
297  if (histo.numBins() != scatt.numPoints()) throw BinningError("Histogram binning incompatible with number of scatter points");
298 
299  Scatter2D rtn = scatt.clone();
300  if (histo.path() != scatt.path()) rtn.setPath("");
301  if (rtn.hasAnnotation("ScaledBy")) rtn.rmAnnotation("ScaledBy");
302 
303  for (size_t i = 0; i < rtn.numPoints(); ++i) {
304  const HistoBin1D& b = histo.bin(i);
305  const Point2D& s = scatt.point(i);
306 
308  if (!fuzzyEquals(b.xMin(), s.x() - s.xErrMinus()) || !fuzzyEquals(b.xMax(), s.x() + s.xErrPlus()))
309  throw BinningError("x binnings are not equivalent in " + scatt.path() + " - " + histo.path());
310 
311 
312  // convert bin to scatter point
313  double biny;
314  try {
315  biny = b.height();
316  } catch (const Exception&) { // LowStatsError or WeightError
317  biny = 0;
318  }
319  double biney;
320  try {
321  biney = b.heightErr();
322  } catch (const Exception&) { // LowStatsError or WeightError
323  biney = 0;
324  }
325  // combine with scatter values
326  double newy = s.y() - biny;
327  double newey_p = sqrt(sqr(biney) + sqr(s.yErrPlus()));
328  double newey_m = sqrt(sqr(biney) + sqr(s.yErrMinus()));
329  // set new values
330  Point2D& t = rtn.point(i);
331  t.setY(newy);
332  t.setYErrMinus(newey_p);
333  t.setYErrPlus(newey_m);
334  }
335 
336  assert(rtn.numPoints() == histo.numBins());
337  return rtn;
338  }
339 
340 
342 
343 
344  Scatter2D multiply(const Histo1D& histo, const Scatter2D& scatt) {
345  if (histo.numBins() != scatt.numPoints()) throw BinningError("Histogram binning incompatible with number of scatter points");
346 
347  Scatter2D rtn = scatt.clone();
348  if (histo.path() != scatt.path()) rtn.setPath("");
349  if (rtn.hasAnnotation("ScaledBy")) rtn.rmAnnotation("ScaledBy");
350 
351  for (size_t i = 0; i < rtn.numPoints(); ++i) {
352  const HistoBin1D& b = histo.bin(i);
353  const Point2D& s = scatt.point(i);
354 
356  if (!fuzzyEquals(b.xMin(), s.x() - s.xErrMinus()) || !fuzzyEquals(b.xMax(), s.x() + s.xErrPlus()))
357  throw BinningError("x binnings are not equivalent in " + histo.path() + " * " + scatt.path());
358 
359 
360  // convert bin to scatter point
361  double biny;
362  try {
363  biny = b.height();
364  } catch (const Exception&) { // LowStatsError or WeightError
365  biny = 0;
366  }
367  double biney;
368  try {
369  biney = b.relErr();
370  } catch (const Exception&) { // LowStatsError or WeightError
371  biney = 0;
372  }
373  // combine with scatter values
374  double newy = biny * s.y();
375  double newey_p = newy * sqrt(sqr(biney) + sqr(s.yErrPlus() / s.y()));
376  double newey_m = newy * sqrt(sqr(biney) + sqr(s.yErrMinus() / s.y()));
377  // set new values
378  Point2D& t = rtn.point(i);
379  t.setY(newy);
380  t.setYErrMinus(newey_p);
381  t.setYErrPlus(newey_m);
382  }
383 
384  assert(rtn.numPoints() == histo.numBins());
385  return rtn;
386  }
387 
388 
390 
391 
392  Scatter2D divide(const Histo1D& numer, const Scatter2D& denom) {
393  if (numer.numBins() != denom.numPoints()) throw BinningError("Histogram binning incompatible with number of scatter points");
394 
395  Scatter2D rtn = denom.clone();
396  if (numer.path() != denom.path()) rtn.setPath("");
397  if (rtn.hasAnnotation("ScaledBy")) rtn.rmAnnotation("ScaledBy");
398 
399  for (size_t i = 0; i < rtn.numPoints(); ++i) {
400  const HistoBin1D& b = numer.bin(i);
401  const Point2D& s = denom.point(i);
402 
404  if (!fuzzyEquals(b.xMin(), s.x() - s.xErrMinus()) || !fuzzyEquals(b.xMax(), s.x() + s.xErrPlus()))
405  throw BinningError("x binnings are not equivalent in " + numer.path() + " / " + denom.path());
406 
407 
408  // convert bin to scatter point
409  double biny;
410  try {
411  biny = b.height();
412  } catch (const Exception&) { // LowStatsError or WeightError
413  biny = 0;
414  }
415  double biney;
416  try {
417  biney = b.relErr();
418  } catch (const Exception&) { // LowStatsError or WeightError
419  biney = 0;
420  }
421  // combine with scatter values
422  double newy, newey_p, newey_m;
423  if (s.y() == 0 || (b.height() == 0 && b.heightErr() != 0)) {
424  newy = std::numeric_limits<double>::quiet_NaN();
425  newey_m = newey_p = std::numeric_limits<double>::quiet_NaN();
426  // throw LowStatsError("Requested division of empty bin");
427  } else {
428  newy = biny / s.y();
429  newey_p = newy * sqrt(sqr(biney) + sqr(s.yErrPlus() / s.y()));
430  newey_m = newy * sqrt(sqr(biney) + sqr(s.yErrMinus() / s.y()));
431  }
432  // set new values
433  Point2D& t = rtn.point(i);
434  t.setY(newy);
435  t.setYErrMinus(newey_p);
436  t.setYErrPlus(newey_m);
437  }
438 
439  assert(rtn.numPoints() == numer.numBins());
440  return rtn;
441  }
442 
443 
445 
446 
447  Scatter2D divide(const Scatter2D& numer, const Histo1D& denom) {
448  if (numer.numPoints() != denom.numBins()) throw BinningError("Histogram binning incompatible with number of scatter points");
449 
450  Scatter2D rtn = numer.clone();
451  if (numer.path() != denom.path()) rtn.setPath("");
452  if (rtn.hasAnnotation("ScaledBy")) rtn.rmAnnotation("ScaledBy");
453 
454  for (size_t i = 0; i < rtn.numPoints(); ++i) {
455  const Point2D& s = numer.point(i);
456  const HistoBin1D& b = denom.bin(i);
457 
459  if (!fuzzyEquals(b.xMin(), s.x() - s.xErrMinus()) || !fuzzyEquals(b.xMax(), s.x() + s.xErrPlus()))
460  throw BinningError("x binnings are not equivalent in " + numer.path() + " / " + denom.path());
461 
462 
463  // convert bin to scatter point
464  double biny;
465  try {
466  biny = b.height();
467  } catch (const Exception&) { // LowStatsError or WeightError
468  biny = 0;
469  }
470  double biney;
471  try {
472  biney = b.relErr();
473  } catch (const Exception&) { // LowStatsError or WeightError
474  biney = 0;
475  }
476  // combine with scatter values
477  double newy, newey_p, newey_m;
478  if (b.height() == 0 || (s.y() == 0 && s.yErrAvg() != 0)) {
479  newy = std::numeric_limits<double>::quiet_NaN();
480  newey_m = newey_p = std::numeric_limits<double>::quiet_NaN();
481  // throw LowStatsError("Requested division of empty bin");
482  } else {
483  newy = s.y() / biny;
484  newey_p = newy * sqrt(sqr(biney) + sqr(s.yErrPlus() / s.y()));
485  newey_m = newy * sqrt(sqr(biney) + sqr(s.yErrMinus() / s.y()));
486  }
487  // set new values
488  Point2D& t = rtn.point(i);
489  t.setY(newy);
490  t.setYErrMinus(newey_p);
491  t.setYErrPlus(newey_m);
492  }
493 
494  assert(rtn.numPoints() == denom.numBins());
495  return rtn;
496  }
497 
498 
500 
501 
502  // Calculate a histogrammed efficiency ratio of two histograms
503  Scatter2D efficiency(const Histo1D& accepted, const Histo1D& total) {
504  Scatter2D tmp = divide(accepted, total);
505  for (size_t i = 0; i < accepted.numBins(); ++i) {
506  const HistoBin1D& b_acc = accepted.bin(i);
507  const HistoBin1D& b_tot = total.bin(i);
508  Point2D& point = tmp.point(i);
509 
511 
512  // Check that the numerator is consistent with being a subset of the denominator
514  if (b_acc.numEntries() > b_tot.numEntries())
515  throw UserError("Attempt to calculate an efficiency when the numerator is not a subset of the denominator: "
516  + Utils::toStr(b_acc.numEntries()) + " entries / " + Utils::toStr(b_tot.numEntries()) + " entries");
517 
518  // If no entries on the denominator, set eff = err = 0 and move to the next bin
519  double eff = std::numeric_limits<double>::quiet_NaN();
520  double err = std::numeric_limits<double>::quiet_NaN();
521  try {
522  if (b_tot.sumW() != 0) {
523  eff = b_acc.sumW() / b_tot.sumW(); //< Actually this is already calculated by the division...
524  err = sqrt(abs( ((1-2*eff)*b_acc.sumW2() + sqr(eff)*b_tot.sumW2()) / sqr(b_tot.sumW()) ));
525  }
526  } catch (const LowStatsError& e) {
527  //
528  }
529 
531 
532  point.setY(eff, err);
533  }
534  return tmp;
535  }
536 
537 
538  // Convert a Histo1D to a Scatter2D representing the integral of the histogram
539  Scatter2D toIntegralHisto(const Histo1D& h, bool includeunderflow) {
541  Scatter2D tmp = mkScatter(h);
542  double integral = includeunderflow ? h.underflow().sumW() : 0.0;
543  for (size_t i = 0; i < h.numBins(); ++i) {
544  Point2D& point = tmp.point(i);
545  integral += h.bin(i).sumW();
546  const double err = sqrt(integral); //< @todo Should be sqrt(sumW2)? Or more complex, cf. Simon etc.?
547  point.setY(integral, err);
548  }
549  return tmp;
550  }
551 
552 
553  Scatter2D toIntegralEfficiencyHisto(const Histo1D& h, bool includeunderflow, bool includeoverflow) {
554  Scatter2D rtn = toIntegralHisto(h, includeunderflow);
555  const double integral = h.integral() - (includeoverflow ? 0 : h.overflow().sumW());
556 
557  // If the integral is empty, the (integrated) efficiency values may as well all be zero, so return here
561  if (integral == 0) return rtn;
562 
564  const double integral_err = sqrt(integral);
565 
566  // Normalize and compute binomial errors
567  for (Point2D& p : rtn.points()) {
568  const double eff = p.y() / integral;
569  const double ey = sqrt(abs( ((1-2*eff)*sqr(p.y()/p.yErrAvg()) + sqr(eff)*sqr(integral_err)) / sqr(integral) ));
570  p.setY(eff, ey);
571  }
572 
573  return rtn;
574  }
575 
576 
577 }
void setY(double y)
Set y value.
Definition: Point2D.h:115
Scatter2D toIntegralHisto(const Histo1D &h, bool includeunderflow=true)
Convert a Histo1D to a Scatter2D representing the integral of the histogram.
Definition: Histo1D.cc:539
void rmAnnotation(const std::string &name)
Delete an annotation by name.
bool inRange(NUM value, NUM low, NUM high, RangeBoundary lowbound=CLOSED, RangeBoundary highbound=OPEN)
Determine if value is in the range low to high, for floating point numbers.
Definition: MathUtils.h:155
double x() const
Get x value.
Definition: Point2D.h:106
Scatter1D divide(const Counter &numer, const Counter &denom)
Definition: Counter.cc:25
const std::string path() const
Get the AO path.
void addPoint(const Point2D &pt)
Insert a new point.
Definition: Scatter2D.h:216
double xMean() const
Weighted mean, , of distribution.
Definition: Dbn1D.cc:11
A very generic data type which is just a collection of 2D data points with errors.
Definition: Scatter2D.h:24
void setYErrPlus(double eyplus, std::string source="")
Set positive y error.
Definition: Point2D.h:241
double integral(bool includeoverflows=true) const
Get the total area (sumW) of the histogram.
Definition: Histo1D.h:287
double y() const
Get y value.
Definition: Point2D.h:112
Generic unspecialised YODA runtime error.
Definition: Exceptions.h:20
void setPath(const std::string &path)
double sumW() const
The sum of weights.
Definition: Dbn1D.h:152
STL namespace.
Error for e.g. use of invalid bin ranges.
Definition: Exceptions.h:34
double xVariance() const
Weighted variance, , of distribution.
Definition: Dbn1D.cc:20
Dbn1D & underflow()
Access underflow (non-const version)
Definition: Histo1D.h:241
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
Dbn1D & overflow()
Access overflow (non-const version)
Definition: Histo1D.h:249
std::vector< YODA::HistoBin1D > & bins()
Access the bin vector.
Definition: Histo1D.h:211
A one-dimensional histogram.
Definition: Histo1D.h:26
double heightErr() const
Definition: HistoBin1D.h:116
double yErrPlus(std::string source="") const
Get positive y-error value.
Definition: Point2D.h:223
Counter add(const Counter &first, const Counter &second)
Add two counters.
Definition: Counter.h:236
A Bin1D specialised for handling histogram-type information.
Definition: HistoBin1D.h:21
double yErrMinus(std::string source="") const
Get negative y-error value.
Definition: Point2D.h:217
double sumW2() const
The sum of weights squared.
Definition: Bin1D.h:223
Axis1D< HistoBin1D, Dbn1D > Histo1DAxis
Convenience typedef.
Definition: Histo1D.h:23
double xRMS() const
Weighted RMS, , of distribution.
Definition: Dbn1D.cc:58
double relErr() const
The relative size of the error (same for either area or height errors)
Definition: HistoBin1D.h:121
Error for problems introduced outside YODA, to put it nicely.
Definition: Exceptions.h:100
double xMid() const
Geometric centre of the bin, i.e. high+low/2.0.
Definition: Bin1D.h:136
double xStdErr() const
Weighted standard error on the mean, , of distribution.
Definition: Dbn1D.cc:48
Scatter2D clone() const
Make a copy on the stack.
Definition: Scatter2D.h:122
NUM sqr(NUM a)
Named number-type squaring operation.
Definition: MathUtils.h:207
Scatter2D toIntegralEfficiencyHisto(const Histo1D &h, bool includeunderflow=true, bool includeoverflow=true)
Convert a Histo1D to a Scatter2D where each bin is a fraction of the total.
Definition: Histo1D.cc:553
Point2D & point(size_t index)
Get a reference to the point with index index (non-const)
Definition: Scatter2D.h:197
Histo1D(const std::string &path="", const std::string &title="")
Default constructor.
Definition: Histo1D.h:42
Errors relating to insufficient (effective) statistics.
Definition: Exceptions.h:72
size_t numPoints() const
Number of points in the scatter.
Definition: Scatter2D.h:179
double yErrAvg(std::string source="") const
Get average y-error value.
Definition: Point2D.h:229
void setYErrMinus(double eyminus, std::string source="")
Set negative y error.
Definition: Point2D.h:235
Error for general binning problems.
Definition: Exceptions.h:27
std::vector< YODA::ProfileBin1D > & bins()
Access the bin vector.
Definition: Profile1D.h:235
Counter subtract(const Counter &first, const Counter &second)
Subtract two counters.
Definition: Counter.h:249
Scatter1D mkScatter(const Counter &c)
Make a Scatter1D representation of a Histo1D.
Definition: Scatter1D.cc:9
const std::string title() const
Get the AO title.
A Bin1D specialised for handling profile-type information.
Definition: ProfileBin1D.h:23
HistoBin1D & bin(size_t index)
Access a bin by index (non-const version)
Definition: Histo1D.h:217
AnalysisObject is the base class for histograms and scatters.
size_t numBins() const
Number of bins on this axis (not counting under/overflow)
Definition: Histo1D.h:195
Scatter2D multiply(const Histo1D &histo, const Scatter2D &scatt)
Multiply histogram with scatter.
Definition: Histo1D.cc:344
double height() const
The height is defined as area/width.
Definition: HistoBin1D.h:98
bool hasAnnotation(const std::string &name) const
Check if an annotation is defined.
double xMin() const
Lower limit of the bin (inclusive).
Definition: Bin1D.h:126
double sumW() const
The sum of weights.
Definition: Bin1D.h:218
A one-dimensional profile histogram.
Definition: Profile1D.h:33
double xMax() const
Upper limit of the bin (exclusive).
Definition: Bin1D.h:131
A 1D distribution.
Definition: Dbn1D.h:28
double xErrMinus() const
Get negative x-error value.
Definition: Point2D.h:141
double xErrPlus() const
Get positive x-error value.
Definition: Point2D.h:146
Scatter1D efficiency(const Counter &accepted, const Counter &total)
Calculate an efficiency ratio of two counters.
Definition: Counter.cc:40
double numEntries() const
The number of entries.
Definition: Bin1D.h:208
Points & points()
Get the collection of points (non-const)
Definition: Scatter2D.h:185
A 2D data point to be contained in a Scatter2D.
Definition: Point2D.h:18