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