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