Logo ROOT   6.10/09
Reference Guide
RooHist.cxx
Go to the documentation of this file.
1 /*****************************************************************************
2  * Project: RooFit *
3  * Package: RooFitCore *
4  * @(#)root/roofitcore:$Id$
5  * Authors: *
6  * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7  * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8  * *
9  * Copyright (c) 2000-2005, Regents of the University of California *
10  * and Stanford University. All rights reserved. *
11  * *
12  * Redistribution and use in source and binary forms, *
13  * with or without modification, are permitted according to the terms *
14  * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15  *****************************************************************************/
16 
17 /**
18 \file RooHist.cxx
19 \class RooHist
20 \ingroup Roofitcore
21 
22 A RooHist is a graphical representation of binned data based on the
23 TGraphAsymmErrors class. Error bars are calculated using either Poisson
24 or Binomial statistics. A RooHist is used to represent histograms in
25 a RooPlot.
26 **/
27 
28 #include "RooFit.h"
29 
30 #include "RooHist.h"
31 #include "RooHist.h"
32 #include "RooHistError.h"
33 #include "RooCurve.h"
34 #include "RooMsgService.h"
35 
36 #include "TH1.h"
37 #include "TClass.h"
38 #include "Riostream.h"
39 #include <iomanip>
40 #include <math.h>
41 
42 using namespace std;
43 
45  ;
46 
47 
48 ////////////////////////////////////////////////////////////////////////////////
49 /// Default constructor
50 
52  _nominalBinWidth(1),
53  _nSigma(1),
54  _entries(0),
55  _rawEntries(0)
56 {
57 }
58 
59 
60 
61 ////////////////////////////////////////////////////////////////////////////////
62 /// Create an empty histogram that can be filled with the addBin()
63 /// and addAsymmetryBin() methods. Use the optional parameter to
64 /// specify the confidence level in units of sigma to use for
65 /// calculating error bars. The nominal bin width specifies the
66 /// default used by addBin(), and is used to set the relative
67 /// normalization of bins with different widths.
68 
69  RooHist::RooHist(Double_t nominalBinWidth, Double_t nSigma, Double_t /*xErrorFrac*/, Double_t /*scaleFactor*/) :
70  TGraphAsymmErrors(), _nominalBinWidth(nominalBinWidth), _nSigma(nSigma), _rawEntries(-1)
71 {
72  initialize();
73 }
74 
75 
76 ////////////////////////////////////////////////////////////////////////////////
77 /// Create a histogram from the contents of the specified TH1 object
78 /// which may have fixed or variable bin widths. Error bars are
79 /// calculated using Poisson statistics. Prints a warning and rounds
80 /// any bins with non-integer contents. Use the optional parameter to
81 /// specify the confidence level in units of sigma to use for
82 /// calculating error bars. The nominal bin width specifies the
83 /// default used by addBin(), and is used to set the relative
84 /// normalization of bins with different widths. If not set, the
85 /// nominal bin width is calculated as range/nbins.
86 
87 RooHist::RooHist(const TH1 &data, Double_t nominalBinWidth, Double_t nSigma, RooAbsData::ErrorType etype, Double_t xErrorFrac,
88  Bool_t correctForBinWidth, Double_t scaleFactor) :
89  TGraphAsymmErrors(), _nominalBinWidth(nominalBinWidth), _nSigma(nSigma), _rawEntries(-1)
90 {
91  initialize();
92  // copy the input histogram's name and title
93  SetName(data.GetName());
94  SetTitle(data.GetTitle());
95  // calculate our nominal bin width if necessary
96  if(_nominalBinWidth == 0) {
97  const TAxis *axis= ((TH1&)data).GetXaxis();
98  if(axis->GetNbins() > 0) _nominalBinWidth= (axis->GetXmax() - axis->GetXmin())/axis->GetNbins();
99  }
100  setYAxisLabel(data.GetYaxis()->GetTitle());
101 
102  // initialize our contents from the input histogram's contents
103  Int_t nbin= data.GetNbinsX();
104  for(Int_t bin= 1; bin <= nbin; bin++) {
105  Axis_t x= data.GetBinCenter(bin);
106  Stat_t y= data.GetBinContent(bin);
107  Stat_t dy = data.GetBinError(bin) ;
108  if (etype==RooAbsData::Poisson) {
109  addBin(x,y,data.GetBinWidth(bin),xErrorFrac,scaleFactor);
110  } else if (etype==RooAbsData::SumW2) {
111  addBinWithError(x,y,dy,dy,data.GetBinWidth(bin),xErrorFrac,correctForBinWidth,scaleFactor);
112  } else {
113  addBinWithError(x,y,0,0,data.GetBinWidth(bin),xErrorFrac,correctForBinWidth,scaleFactor);
114  }
115  }
116  // add over/underflow bins to our event count
117  _entries+= data.GetBinContent(0) + data.GetBinContent(nbin+1);
118 }
119 
120 
121 
122 ////////////////////////////////////////////////////////////////////////////////
123 /// Create a histogram from the asymmetry between the specified TH1 objects
124 /// which may have fixed or variable bin widths, but which must both have
125 /// the same binning. The asymmetry is calculated as (1-2)/(1+2). Error bars are
126 /// calculated using Binomial statistics. Prints a warning and rounds
127 /// any bins with non-integer contents. Use the optional parameter to
128 /// specify the confidence level in units of sigma to use for
129 /// calculating error bars. The nominal bin width specifies the
130 /// default used by addAsymmetryBin(), and is used to set the relative
131 /// normalization of bins with different widths. If not set, the
132 /// nominal bin width is calculated as range/nbins.
133 
134 RooHist::RooHist(const TH1 &data1, const TH1 &data2, Double_t nominalBinWidth, Double_t nSigma,
135  RooAbsData::ErrorType etype, Double_t xErrorFrac, Bool_t efficiency, Double_t scaleFactor) :
136  TGraphAsymmErrors(), _nominalBinWidth(nominalBinWidth), _nSigma(nSigma), _rawEntries(-1)
137 {
138  initialize();
139  // copy the first input histogram's name and title
140  SetName(data1.GetName());
141  SetTitle(data1.GetTitle());
142  // calculate our nominal bin width if necessary
143  if(_nominalBinWidth == 0) {
144  const TAxis *axis= ((TH1&)data1).GetXaxis();
145  if(axis->GetNbins() > 0) _nominalBinWidth= (axis->GetXmax() - axis->GetXmin())/axis->GetNbins();
146  }
147 
148  if (!efficiency) {
149  setYAxisLabel(Form("Asymmetry (%s - %s)/(%s + %s)",
150  data1.GetName(),data2.GetName(),data1.GetName(),data2.GetName()));
151  } else {
152  setYAxisLabel(Form("Efficiency (%s)/(%s + %s)",
153  data1.GetName(),data1.GetName(),data2.GetName()));
154  }
155  // initialize our contents from the input histogram contents
156  Int_t nbin= data1.GetNbinsX();
157  if(data2.GetNbinsX() != nbin) {
158  coutE(InputArguments) << "RooHist::RooHist: histograms have different number of bins" << endl;
159  return;
160  }
161  for(Int_t bin= 1; bin <= nbin; bin++) {
162  Axis_t x= data1.GetBinCenter(bin);
163  if(fabs(data2.GetBinCenter(bin)-x)>1e-10) {
164  coutW(InputArguments) << "RooHist::RooHist: histograms have different centers for bin " << bin << endl;
165  }
166  Stat_t y1= data1.GetBinContent(bin);
167  Stat_t y2= data2.GetBinContent(bin);
168  if (!efficiency) {
169 
170  if (etype==RooAbsData::Poisson) {
171  addAsymmetryBin(x,roundBin(y1),roundBin(y2),data1.GetBinWidth(bin),xErrorFrac,scaleFactor);
172  } else if (etype==RooAbsData::SumW2) {
173  Stat_t dy1= data1.GetBinError(bin);
174  Stat_t dy2= data2.GetBinError(bin);
175  addAsymmetryBinWithError(x,y1,y2,dy1,dy2,data1.GetBinWidth(bin),xErrorFrac,scaleFactor);
176  } else {
177  addAsymmetryBinWithError(x,y1,y2,0,0,data1.GetBinWidth(bin),xErrorFrac,scaleFactor);
178  }
179 
180  } else {
181 
182  if (etype==RooAbsData::Poisson) {
183  addEfficiencyBin(x,roundBin(y1),roundBin(y2),data1.GetBinWidth(bin),xErrorFrac,scaleFactor);
184  } else if (etype==RooAbsData::SumW2) {
185  Stat_t dy1= data1.GetBinError(bin);
186  Stat_t dy2= data2.GetBinError(bin);
187  addEfficiencyBinWithError(x,y1,y2,dy1,dy2,data1.GetBinWidth(bin),xErrorFrac,scaleFactor);
188  } else {
189  addEfficiencyBinWithError(x,y1,y2,0,0,data1.GetBinWidth(bin),xErrorFrac,scaleFactor);
190  }
191 
192  }
193 
194  }
195  // we do not have a meaningful number of entries
196  _entries= -1;
197 }
198 
199 
200 
201 ////////////////////////////////////////////////////////////////////////////////
202 /// Create histogram as sum of two existing histograms. If Poisson errors are selected the histograms are
203 /// added and Poisson confidence intervals are calculated for the summed content. If wgt1 and wgt2 are not
204 /// 1 in this mode, a warning message is printed. If SumW2 errors are selected the histograms are added
205 /// and the histograms errors are added in quadrature, taking the weights into account.
206 
207 RooHist::RooHist(const RooHist& hist1, const RooHist& hist2, Double_t wgt1, Double_t wgt2,
208  RooAbsData::ErrorType etype, Double_t xErrorFrac) : _rawEntries(-1)
209 {
210  // Initialize the histogram
211  initialize() ;
212 
213  // Copy all non-content properties from hist1
214  SetName(hist1.GetName()) ;
215  SetTitle(hist1.GetTitle()) ;
217  _nSigma=hist1._nSigma ;
218  setYAxisLabel(hist1.getYAxisLabel()) ;
219 
220  if (!hist1.hasIdenticalBinning(hist2)) {
221  coutE(InputArguments) << "RooHist::RooHist input histograms have incompatible binning, combined histogram will remain empty" << endl ;
222  return ;
223  }
224 
225  if (etype==RooAbsData::Poisson) {
226  // Add histograms with Poisson errors
227 
228  // Issue warning if weights are not 1
229  if (wgt1!=1.0 || wgt2 != 1.0) {
230  coutW(InputArguments) << "RooHist::RooHist: WARNING: Poisson errors of weighted sum of two histograms is not well defined! " << endl
231  << " Summed histogram bins will rounded to nearest integer for Poisson confidence interval calculation" << endl ;
232  }
233 
234  // Add histograms, calculate Poisson confidence interval on sum value
235  Int_t i,n=hist1.GetN() ;
236  for(i=0 ; i<n ; i++) {
237  Double_t x1,y1,x2,y2,dx1 ;
238 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
239  hist1.GetPoint(i,x1,y1) ;
240 #else
241  const_cast<RooHist&>(hist1).GetPoint(i,x1,y1) ;
242 #endif
243  dx1 = hist1.GetErrorX(i) ;
244 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
245  hist2.GetPoint(i,x2,y2) ;
246 #else
247  const_cast<RooHist&>(hist2).GetPoint(i,x2,y2) ;
248 #endif
249  addBin(x1,roundBin(wgt1*y1+wgt2*y2),2*dx1/xErrorFrac,xErrorFrac) ;
250  }
251 
252  } else {
253  // Add histograms with SumW2 errors
254 
255  // Add histograms, calculate combined sum-of-weights error
256  Int_t i,n=hist1.GetN() ;
257  for(i=0 ; i<n ; i++) {
258  Double_t x1,y1,x2,y2,dx1,dy1,dy2 ;
259 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
260  hist1.GetPoint(i,x1,y1) ;
261 #else
262  const_cast<RooHist&>(hist1).GetPoint(i,x1,y1) ;
263 #endif
264  dx1 = hist1.GetErrorX(i) ;
265  dy1 = hist1.GetErrorY(i) ;
266  dy2 = hist2.GetErrorY(i) ;
267 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
268  hist2.GetPoint(i,x2,y2) ;
269 #else
270  const_cast<RooHist&>(hist2).GetPoint(i,x2,y2) ;
271 #endif
272  Double_t dy = sqrt(wgt1*wgt1*dy1*dy1+wgt2*wgt2*dy2*dy2) ;
273  addBinWithError(x1,wgt1*y1+wgt2*y2,dy,dy,2*dx1/xErrorFrac,xErrorFrac) ;
274  }
275  }
276 
277 }
278 
279 
280 ////////////////////////////////////////////////////////////////////////////////
281 /// Perform common initialization for all constructors.
282 
284 {
285  SetMarkerStyle(8);
286  _entries= 0;
287 }
288 
289 
290 ////////////////////////////////////////////////////////////////////////////////
291 /// Return the number of events of the dataset associated with this RooHist.
292 /// This is the number of events in the RooHist itself, unless a different
293 /// value was specified through setRawEntries()
294 
296 {
297  return (_rawEntries==-1 ? _entries : _rawEntries) ;
298 }
299 
300 
301 ////////////////////////////////////////////////////////////////////////////////
302 /// Calculate integral of histogram in given range
303 
305 {
306  Double_t sum(0) ;
307  for (int i=0 ; i<GetN() ; i++) {
308  Double_t x,y ;
309 
310 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
311  GetPoint(i,x,y) ;
312 #else
313  const_cast<RooHist*>(this)->GetPoint(i,x,y) ;
314 #endif
315 
316  if (x>=xlo && x<=xhi) {
317  sum += y ;
318  }
319  }
320 
321  if (_rawEntries!=-1) {
322  coutW(Plotting) << "RooHist::getFitRangeNEvt() WARNING: Number of normalization events associated to histogram is not equal to number of events in histogram" << endl
323  << " due cut made in RooAbsData::plotOn() call. Automatic normalization over sub-range of plot variable assumes" << endl
324  << " that the effect of that cut is uniform across the plot, which may be an incorrect assumption. To be sure of" << endl
325  << " correct normalization explicit pass normalization information to RooAbsPdf::plotOn() call using Normalization()" << endl ;
326  sum *= _rawEntries / _entries ;
327  }
328 
329  return sum ;
330 }
331 
332 
333 
334 ////////////////////////////////////////////////////////////////////////////////
335 /// Return (average) bin width of this RooHist
336 
338 {
339  return _nominalBinWidth ;
340 }
341 
342 
343 
344 ////////////////////////////////////////////////////////////////////////////////
345 /// Return the nearest positive integer to the input value
346 /// and print a warning if an adjustment is required.
347 
349 {
350  if(y < 0) {
351  coutW(Plotting) << fName << "::roundBin: rounding negative bin contents to zero: " << y << endl;
352  return 0;
353  }
354  Int_t n= (Int_t)(y+0.5);
355  if(fabs(y-n)>1e-6) {
356  coutW(Plotting) << fName << "::roundBin: rounding non-integer bin contents: " << y << endl;
357  }
358  return n;
359 }
360 
361 
362 
363 ////////////////////////////////////////////////////////////////////////////////
364 /// Add a bin to this histogram with the specified integer bin contents
365 /// and using an error bar calculated with Poisson statistics. The bin width
366 /// is used to set the relative scale of bins with different widths.
367 
368 void RooHist::addBin(Axis_t binCenter, Double_t n, Double_t binWidth, Double_t xErrorFrac, Double_t scaleFactor)
369 {
370  if (n<0) {
371  coutW(Plotting) << "RooHist::addBin(" << GetName() << ") WARNING: negative entry set to zero when Poisson error bars are requested" << endl ;
372  }
373 
374  Double_t scale= 1;
375  if(binWidth > 0) {
376  scale= _nominalBinWidth/binWidth;
377  }
378  _entries+= n;
379  Int_t index= GetN();
380 
381  // calculate Poisson errors for this bin
382  Double_t ym,yp,dx(0.5*binWidth);
383 
384  if (fabs((double)((n-Int_t(n))>1e-5))) {
385  // need interpolation
386  Double_t ym1(0),yp1(0),ym2(0),yp2(0) ;
387  Int_t n1 = Int_t(n) ;
388  Int_t n2 = n1+1 ;
389  if(!RooHistError::instance().getPoissonInterval(n1,ym1,yp1,_nSigma) ||
390  !RooHistError::instance().getPoissonInterval(n2,ym2,yp2,_nSigma)) {
391  coutE(Plotting) << "RooHist::addBin: unable to add bin with " << n << " events" << endl;
392  }
393  ym = ym1 + (n-n1)*(ym2-ym1) ;
394  yp = yp1 + (n-n1)*(yp2-yp1) ;
395  coutW(Plotting) << "RooHist::addBin(" << GetName()
396  << ") WARNING: non-integer bin entry " << n << " with Poisson errors, interpolating between Poisson errors of adjacent integer" << endl ;
397  } else {
398  // integer case
399  if(!RooHistError::instance().getPoissonInterval(Int_t(n),ym,yp,_nSigma)) {
400  coutE(Plotting) << "RooHist::addBin: unable to add bin with " << n << " events" << endl;
401  return;
402  }
403  }
404 
405  SetPoint(index,binCenter,n*scale*scaleFactor);
406  SetPointError(index,dx*xErrorFrac,dx*xErrorFrac,scale*(n-ym)*scaleFactor,scale*(yp-n)*scaleFactor);
407  updateYAxisLimits(scale*yp);
408  updateYAxisLimits(scale*ym);
409 }
410 
411 
412 
413 ////////////////////////////////////////////////////////////////////////////////
414 /// Add a bin to this histogram with the specified bin contents
415 /// and error. The bin width is used to set the relative scale of
416 /// bins with different widths.
417 
418 void RooHist::addBinWithError(Axis_t binCenter, Double_t n, Double_t elow, Double_t ehigh, Double_t binWidth,
419  Double_t xErrorFrac, Bool_t correctForBinWidth, Double_t scaleFactor)
420 {
421  Double_t scale= 1;
422  if(binWidth > 0 && correctForBinWidth) {
423  scale= _nominalBinWidth/binWidth;
424  }
425  _entries+= n;
426  Int_t index= GetN();
427 
428  Double_t dx(0.5*binWidth) ;
429  SetPoint(index,binCenter,n*scale*scaleFactor);
430  SetPointError(index,dx*xErrorFrac,dx*xErrorFrac,elow*scale*scaleFactor,ehigh*scale*scaleFactor);
431  updateYAxisLimits(scale*(n-elow));
432  updateYAxisLimits(scale*(n+ehigh));
433 }
434 
435 
436 
437 
438 ////////////////////////////////////////////////////////////////////////////////
439 /// Add a bin to this histogram with the specified bin contents
440 /// and error. The bin width is used to set the relative scale of
441 /// bins with different widths.
442 
443 void RooHist::addBinWithXYError(Axis_t binCenter, Double_t n, Double_t exlow, Double_t exhigh, Double_t eylow, Double_t eyhigh,
444  Double_t scaleFactor)
445 {
446  _entries+= n;
447  Int_t index= GetN();
448 
449  SetPoint(index,binCenter,n*scaleFactor);
450  SetPointError(index,exlow,exhigh,eylow*scaleFactor,eyhigh*scaleFactor);
451  updateYAxisLimits(scaleFactor*(n-eylow));
452  updateYAxisLimits(scaleFactor*(n+eyhigh));
453 }
454 
455 
456 
457 
458 
459 ////////////////////////////////////////////////////////////////////////////////
460 /// Add a bin to this histogram with the value (n1-n2)/(n1+n2)
461 /// using an error bar calculated with Binomial statistics.
462 
463 void RooHist::addAsymmetryBin(Axis_t binCenter, Int_t n1, Int_t n2, Double_t binWidth, Double_t xErrorFrac, Double_t scaleFactor)
464 {
465  Double_t scale= 1;
466  if(binWidth > 0) scale= _nominalBinWidth/binWidth;
467  Int_t index= GetN();
468 
469  // calculate Binomial errors for this bin
470  Double_t ym,yp,dx(0.5*binWidth);
471  if(!RooHistError::instance().getBinomialIntervalAsym(n1,n2,ym,yp,_nSigma)) {
472  coutE(Plotting) << "RooHist::addAsymmetryBin: unable to calculate binomial error for bin with " << n1 << "," << n2 << " events" << endl;
473  return;
474  }
475 
476  Double_t a= (Double_t)(n1-n2)/(n1+n2);
477  SetPoint(index,binCenter,a*scaleFactor);
478  SetPointError(index,dx*xErrorFrac,dx*xErrorFrac,(a-ym)*scaleFactor,(yp-a)*scaleFactor);
479  updateYAxisLimits(scale*yp);
480  updateYAxisLimits(scale*ym);
481 }
482 
483 
484 
485 ////////////////////////////////////////////////////////////////////////////////
486 /// Add a bin to this histogram with the value (n1-n2)/(n1+n2)
487 /// using an error bar calculated with Binomial statistics.
488 
489 void RooHist::addAsymmetryBinWithError(Axis_t binCenter, Double_t n1, Double_t n2, Double_t en1, Double_t en2, Double_t binWidth, Double_t xErrorFrac, Double_t scaleFactor)
490 {
491  Double_t scale= 1;
492  if(binWidth > 0) scale= _nominalBinWidth/binWidth;
493  Int_t index= GetN();
494 
495  // calculate Binomial errors for this bin
496  Double_t ym,yp,dx(0.5*binWidth);
497  Double_t a= (Double_t)(n1-n2)/(n1+n2);
498 
499  Double_t error = 2*sqrt( pow(en1,2)*pow(n2,2) + pow(en2,2)*pow(n1,2) ) / pow(n1+n2,2) ;
500  ym=a-error ;
501  yp=a+error ;
502 
503  SetPoint(index,binCenter,a*scaleFactor);
504  SetPointError(index,dx*xErrorFrac,dx*xErrorFrac,(a-ym)*scaleFactor,(yp-a)*scaleFactor);
505  updateYAxisLimits(scale*yp);
506  updateYAxisLimits(scale*ym);
507 }
508 
509 
510 
511 ////////////////////////////////////////////////////////////////////////////////
512 /// Add a bin to this histogram with the value n1/(n1+n2)
513 /// using an error bar calculated with Binomial statistics.
514 
515 void RooHist::addEfficiencyBin(Axis_t binCenter, Int_t n1, Int_t n2, Double_t binWidth, Double_t xErrorFrac, Double_t scaleFactor)
516 {
517  Double_t scale= 1;
518  if(binWidth > 0) scale= _nominalBinWidth/binWidth;
519  Int_t index= GetN();
520 
521  Double_t a= (Double_t)(n1)/(n1+n2);
522 
523  // calculate Binomial errors for this bin
524  Double_t ym,yp,dx(0.5*binWidth);
525  if(!RooHistError::instance().getBinomialIntervalEff(n1,n2,ym,yp,_nSigma)) {
526  coutE(Plotting) << "RooHist::addEfficiencyBin: unable to calculate binomial error for bin with " << n1 << "," << n2 << " events" << endl;
527  return;
528  }
529 
530  SetPoint(index,binCenter,a*scaleFactor);
531  SetPointError(index,dx*xErrorFrac,dx*xErrorFrac,(a-ym)*scaleFactor,(yp-a)*scaleFactor);
532  updateYAxisLimits(scale*yp);
533  updateYAxisLimits(scale*ym);
534 }
535 
536 
537 
538 ////////////////////////////////////////////////////////////////////////////////
539 /// Add a bin to this histogram with the value n1/(n1+n2)
540 /// using an error bar calculated with Binomial statistics.
541 
542 void RooHist::addEfficiencyBinWithError(Axis_t binCenter, Double_t n1, Double_t n2, Double_t en1, Double_t en2, Double_t binWidth, Double_t xErrorFrac, Double_t scaleFactor)
543 {
544  Double_t scale= 1;
545  if(binWidth > 0) scale= _nominalBinWidth/binWidth;
546  Int_t index= GetN();
547 
548  Double_t a= (Double_t)(n1)/(n1+n2);
549 
550  Double_t error = sqrt( pow(en1,2)*pow(n2,2) + pow(en2,2)*pow(n1,2) ) / pow(n1+n2,2) ;
551 
552  // calculate Binomial errors for this bin
553  Double_t ym,yp,dx(0.5*binWidth);
554  ym=a-error ;
555  yp=a+error ;
556 
557 
558  SetPoint(index,binCenter,a*scaleFactor);
559  SetPointError(index,dx*xErrorFrac,dx*xErrorFrac,(a-ym)*scaleFactor,(yp-a)*scaleFactor);
560  updateYAxisLimits(scale*yp);
561  updateYAxisLimits(scale*ym);
562 }
563 
564 
565 
566 ////////////////////////////////////////////////////////////////////////////////
567 /// Destructor
568 
570 {
571 }
572 
573 
574 
575 ////////////////////////////////////////////////////////////////////////////////
576 /// Return kTRUE if binning of this RooHist is identical to that of 'other'
577 
579 {
580  // First check if number of bins is the same
581  if (GetN() != other.GetN()) {
582  return kFALSE ;
583  }
584 
585  // Next require that all bin centers are the same
586  Int_t i ;
587  for (i=0 ; i<GetN() ; i++) {
588  Double_t x1,x2,y1,y2 ;
589 
590 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
591  GetPoint(i,x1,y1) ;
592  other.GetPoint(i,x2,y2) ;
593 #else
594  const_cast<RooHist&>(*this).GetPoint(i,x1,y1) ;
595  const_cast<RooHist&>(other).GetPoint(i,x2,y2) ;
596 #endif
597 
598  if (fabs(x1-x2)>1e-10) {
599  return kFALSE ;
600  }
601 
602  }
603 
604  return kTRUE ;
605 }
606 
607 
608 
609 ////////////////////////////////////////////////////////////////////////////////
610 /// Return kTRUE if contents of this RooHist is identical within given
611 /// relative tolerance to that of 'other'
612 
614 {
615  // Make temporary TH1s output of RooHists to perform Kolmogorov test
617  TH1F h_self("h_self","h_self",GetN(),0,1) ;
618  TH1F h_other("h_other","h_other",GetN(),0,1) ;
620 
621  for (Int_t i=0 ; i<GetN() ; i++) {
622  h_self.SetBinContent(i+1,GetY()[i]) ;
623  h_other.SetBinContent(i+1,other.GetY()[i]) ;
624  }
625 
626  Double_t M = h_self.KolmogorovTest(&h_other,"M") ;
627  if (M>tol) {
628  Double_t kprob = h_self.KolmogorovTest(&h_other) ;
629  cout << "RooHist::isIdentical() tolerance exceeded M=" << M << " (tol=" << tol << "), corresponding prob = " << kprob << endl ;
630  return kFALSE ;
631  }
632 
633  return kTRUE ;
634 }
635 
636 
637 
638 ////////////////////////////////////////////////////////////////////////////////
639 /// Print info about this histogram to the specified output stream.
640 ///
641 /// Standard: number of entries
642 /// Shape: error CL and maximum value
643 /// Verbose: print our bin contents and errors
644 
645 void RooHist::printMultiline(ostream& os, Int_t contents, Bool_t verbose, TString indent) const
646 {
647  RooPlotable::printMultiline(os,contents,verbose,indent);
648  os << indent << "--- RooHist ---" << endl;
649  Int_t n= GetN();
650  os << indent << " Contains " << n << " bins" << endl;
651  if(verbose) {
652  os << indent << " Errors calculated at" << _nSigma << "-sigma CL" << endl;
653  os << indent << " Bin Contents:" << endl;
654  for(Int_t i= 0; i < n; i++) {
655  os << indent << setw(3) << i << ") x= " << fX[i];
656  if(fEXhigh[i] > 0 || fEXlow[i] > 0) {
657  os << " +" << fEXhigh[i] << " -" << fEXlow[i];
658  }
659  os << " , y = " << fY[i] << " +" << fEYhigh[i] << " -" << fEYlow[i] << endl;
660  }
661  }
662 }
663 
664 
665 
666 ////////////////////////////////////////////////////////////////////////////////
667 /// Print name of RooHist
668 
669 void RooHist::printName(ostream& os) const
670 {
671  os << GetName() ;
672 }
673 
674 
675 
676 ////////////////////////////////////////////////////////////////////////////////
677 /// Print title of RooHist
678 
679 void RooHist::printTitle(ostream& os) const
680 {
681  os << GetTitle() ;
682 }
683 
684 
685 
686 ////////////////////////////////////////////////////////////////////////////////
687 /// Print class name of RooHist
688 
689 void RooHist::printClassName(ostream& os) const
690 {
691  os << IsA()->GetName() ;
692 }
693 
694 
695 
696 ////////////////////////////////////////////////////////////////////////////////
697 /// Create and return RooHist containing residuals w.r.t to given curve.
698 /// If normalize is true, the residuals are normalized by the histogram
699 /// errors creating a RooHist with pull values
700 
701 RooHist* RooHist::makeResidHist(const RooCurve& curve, bool normalize, bool useAverage) const
702 {
703 
704  // Copy all non-content properties from hist1
705  RooHist* hist = new RooHist(_nominalBinWidth) ;
706  if (normalize) {
707  hist->SetName(Form("pull_%s_%s",GetName(),curve.GetName())) ;
708  hist->SetTitle(Form("Pull of %s and %s",GetTitle(),curve.GetTitle())) ;
709  } else {
710  hist->SetName(Form("resid_%s_%s",GetName(),curve.GetName())) ;
711  hist->SetTitle(Form("Residual of %s and %s",GetTitle(),curve.GetTitle())) ;
712  }
713 
714  // Determine range of curve
715  Double_t xstart,xstop,y ;
716 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
717  curve.GetPoint(0,xstart,y) ;
718  curve.GetPoint(curve.GetN()-1,xstop,y) ;
719 #else
720  const_cast<RooCurve&>(curve).GetPoint(0,xstart,y) ;
721  const_cast<RooCurve&>(curve).GetPoint(curve.GetN()-1,xstop,y) ;
722 #endif
723 
724  // Add histograms, calculate Poisson confidence interval on sum value
725  for(Int_t i=0 ; i<GetN() ; i++) {
726  Double_t x,point;
727 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
728  GetPoint(i,x,point) ;
729 #else
730  const_cast<RooHist&>(*this).GetPoint(i,x,point) ;
731 #endif
732 
733  // Only calculate pull for bins inside curve range
734  if (x<xstart || x>xstop) continue ;
735 
736  Double_t yy ;
737  if (useAverage) {
738  Double_t exl = GetErrorXlow(i);
739  Double_t exh = GetErrorXhigh(i) ;
740  if (exl<=0 ) exl = GetErrorX(i);
741  if (exh<=0 ) exh = GetErrorX(i);
742  if (exl<=0 ) exl = 0.5*getNominalBinWidth();
743  if (exh<=0 ) exh = 0.5*getNominalBinWidth();
744  yy = point - curve.average(x-exl,x+exh) ;
745  } else {
746  yy = point - curve.interpolate(x) ;
747  }
748 
749  Double_t dyl = GetErrorYlow(i) ;
750  Double_t dyh = GetErrorYhigh(i) ;
751  if (normalize) {
752  Double_t norm = (yy>0?dyl:dyh);
753  if (norm==0.) {
754  coutW(Plotting) << "RooHist::makeResisHist(" << GetName() << ") WARNING: point " << i << " has zero error, setting residual to zero" << endl ;
755  yy=0 ;
756  dyh=0 ;
757  dyl=0 ;
758  } else {
759  yy /= norm;
760  dyh /= norm;
761  dyl /= norm;
762  }
763  }
764  hist->addBinWithError(x,yy,dyl,dyh);
765  }
766  return hist ;
767 }
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Double_t getNominalBinWidth() const
Definition: RooHist.h:69
static long int sum(long int i)
Definition: Factory.cxx:2162
#define coutE(a)
Definition: RooMsgService.h:34
Double_t * fX
[fNpoints] array of X points
Definition: TGraph.h:47
virtual void printTitle(std::ostream &os) const
Print title of RooHist.
Definition: RooHist.cxx:679
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition: TH1.cxx:8253
A RooCurve is a one-dimensional graphical representation of a real-valued function.
Definition: RooCurve.h:32
Double_t GetErrorY(Int_t bin) const
This function is called by GraphFitChisquare.
Double_t GetErrorX(Int_t bin) const
This function is called by GraphFitChisquare.
Double_t GetErrorYlow(Int_t i) const
Get low error on Y.
double Axis_t
Definition: RtypesCore.h:72
Double_t * fEXhigh
[fNpoints] array of X high errors
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:131
Double_t _nominalBinWidth
Definition: RooHist.h:87
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4639
Double_t GetErrorYhigh(Int_t i) const
Get high error on Y.
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Print detailed information.
Definition: RooPlotable.cxx:43
tomato 1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:551
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TArc * a
Definition: textangle.C:12
virtual void SetTitle(const char *title="")
Set graph title.
Definition: TGraph.cxx:2180
STL namespace.
#define coutW(a)
Definition: RooMsgService.h:33
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition: TH1.cxx:1218
void addAsymmetryBinWithError(Axis_t binCenter, Double_t n1, Double_t n2, Double_t en1, Double_t en2, Double_t binWidth=0, Double_t xErrorFrac=1.0, Double_t scaleFactor=1.0)
Add a bin to this histogram with the value (n1-n2)/(n1+n2) using an error bar calculated with Binomia...
Definition: RooHist.cxx:489
double sqrt(double)
Double_t GetErrorXhigh(Int_t i) const
Get high error on X.
TGraph with asymmetric error bars.
Int_t roundBin(Double_t y)
Return the nearest positive integer to the input value and print a warning if an adjustment is requir...
Definition: RooHist.cxx:348
Double_t _entries
Definition: RooHist.h:89
Double_t GetXmin() const
Definition: TAxis.h:133
static const double x2[5]
A RooHist is a graphical representation of binned data based on the TGraphAsymmErrors class...
Definition: RooHist.h:26
void addEfficiencyBinWithError(Axis_t binCenter, Double_t n1, Double_t n2, Double_t en1, Double_t en2, Double_t binWidth=0, Double_t xErrorFrac=1.0, Double_t scaleFactor=1.0)
Add a bin to this histogram with the value n1/(n1+n2) using an error bar calculated with Binomial sta...
Definition: RooHist.cxx:542
Double_t x[n]
Definition: legend1.C:17
double pow(double, double)
void addAsymmetryBin(Axis_t binCenter, Int_t n1, Int_t n2, Double_t binWidth=0, Double_t xErrorFrac=1.0, Double_t scaleFactor=1.0)
Add a bin to this histogram with the value (n1-n2)/(n1+n2) using an error bar calculated with Binomia...
Definition: RooHist.cxx:463
Double_t getFitRangeBinW() const
Return (average) bin width of this RooHist.
Definition: RooHist.cxx:337
void initialize()
Perform common initialization for all constructors.
Definition: RooHist.cxx:283
RooHist()
Default constructor.
Definition: RooHist.cxx:51
virtual Double_t KolmogorovTest(const TH1 *h2, Option_t *option="") const
Statistical test of compatibility in shape between this histogram and h2, using Kolmogorov test...
Definition: TH1.cxx:7362
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
const double tol
virtual Int_t GetPoint(Int_t i, Double_t &x, Double_t &y) const
Get x and y values for point number i.
Definition: TGraph.cxx:1580
const char * GetTitle() const
Returns title of object.
Definition: TAxis.h:129
Class to manage histogram axis.
Definition: TAxis.h:30
RooHist * makeResidHist(const RooCurve &curve, bool normalize=false, bool useAverage=false) const
Create and return RooHist containing residuals w.r.t to given curve.
Definition: RooHist.cxx:701
virtual void SetBinContent(Int_t bin, Double_t content)
Set bin content see convention for numbering bins in TH1::GetBin In case the bin number is greater th...
Definition: TH1.cxx:8325
Double_t interpolate(Double_t x, Double_t tolerance=1e-10) const
Return linearly interpolated value of curve at xvalue.
Definition: RooCurve.cxx:685
Double_t getFitRangeNEvt() const
Return the number of events of the dataset associated with this RooHist.
Definition: RooHist.cxx:295
bool verbose
char * Form(const char *fmt,...)
Double_t _rawEntries
Definition: RooHist.h:90
void updateYAxisLimits(Double_t y)
Definition: RooPlotable.h:33
static const RooHistError & instance()
Return a reference to a singleton object that is created the first time this method is called...
Int_t GetN() const
Definition: TGraph.h:122
Double_t * fEYlow
[fNpoints] array of Y low errors
void addBin(Axis_t binCenter, Double_t n, Double_t binWidth=0, Double_t xErrorFrac=1.0, Double_t scaleFactor=1.0)
Add a bin to this histogram with the specified integer bin contents and using an error bar calculated...
Definition: RooHist.cxx:368
Bool_t hasIdenticalBinning(const RooHist &other) const
Return kTRUE if binning of this RooHist is identical to that of &#39;other&#39;.
Definition: RooHist.cxx:578
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition: TAttMarker.h:40
TAxis * GetYaxis()
Definition: TH1.h:301
Double_t _nSigma
Definition: RooHist.h:88
TString fName
Definition: TNamed.h:32
const char * getYAxisLabel() const
Definition: RooPlotable.h:31
const Bool_t kFALSE
Definition: RtypesCore.h:92
Double_t GetErrorXlow(Int_t i) const
Get low error on X.
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition: TH1.cxx:8275
static const double x1[5]
#define ClassImp(name)
Definition: Rtypes.h:336
virtual void printName(std::ostream &os) const
Print name of RooHist.
Definition: RooHist.cxx:669
double Double_t
Definition: RtypesCore.h:55
Double_t y[n]
Definition: legend1.C:17
The TH1 histogram class.
Definition: TH1.h:56
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
Bool_t isIdentical(const RooHist &other, Double_t tol=1e-6) const
Return kTRUE if contents of this RooHist is identical within given relative tolerance to that of &#39;oth...
Definition: RooHist.cxx:613
double Stat_t
Definition: RtypesCore.h:73
virtual ~RooHist()
Destructor.
Definition: RooHist.cxx:569
void addBinWithError(Axis_t binCenter, Double_t n, Double_t elow, Double_t ehigh, Double_t binWidth=0, Double_t xErrorFrac=1.0, Bool_t correctForBinWidth=kTRUE, Double_t scaleFactor=1.0)
Add a bin to this histogram with the specified bin contents and error.
Definition: RooHist.cxx:418
virtual void printClassName(std::ostream &os) const
Print class name of RooHist.
Definition: RooHist.cxx:689
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Set x and y values for point number i.
Definition: TGraph.cxx:2156
Double_t * fY
[fNpoints] array of Y points
Definition: TGraph.h:48
Double_t * GetY() const
Definition: TGraph.h:130
Double_t average(Double_t lo, Double_t hi) const
Return average curve value in [xFirst,xLast] by integrating curve between points and dividing by xLas...
Definition: RooCurve.cxx:599
void addBinWithXYError(Axis_t binCenter, Double_t n, Double_t exlow, Double_t exhigh, Double_t eylow, Double_t eyhigh, Double_t scaleFactor=1.0)
Add a bin to this histogram with the specified bin contents and error.
Definition: RooHist.cxx:443
void setYAxisLabel(const char *label)
Definition: RooPlotable.h:32
virtual Int_t GetNbinsX() const
Definition: TH1.h:277
Int_t GetNbins() const
Definition: TAxis.h:121
virtual void printMultiline(std::ostream &os, Int_t content, Bool_t verbose=kFALSE, TString indent="") const
Print info about this histogram to the specified output stream.
Definition: RooHist.cxx:645
void addEfficiencyBin(Axis_t binCenter, Int_t n1, Int_t n2, Double_t binWidth=0, Double_t xErrorFrac=1.0, Double_t scaleFactor=1.0)
Add a bin to this histogram with the value n1/(n1+n2) using an error bar calculated with Binomial sta...
Definition: RooHist.cxx:515
const Bool_t kTRUE
Definition: RtypesCore.h:91
double norm(double *x, double *p)
Definition: unuranDistr.cxx:40
Double_t GetXmax() const
Definition: TAxis.h:134
const Int_t n
Definition: legend1.C:16
Double_t * fEXlow
[fNpoints] array of X low errors
Double_t * fEYhigh
[fNpoints] array of Y high errors
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition: TH1.cxx:8175
virtual void SetPointError(Double_t exl, Double_t exh, Double_t eyl, Double_t eyh)
Set ex and ey values for point pointed by the mouse.