Logo ROOT  
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 "RooScaledFunc.h"
35#include "RooMsgService.h"
36
37#include "TH1.h"
38#include "TClass.h"
39#include "Riostream.h"
40#include <iomanip>
41
42using 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
87RooHist::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 }
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
134RooHist::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
207RooHist::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 ;
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 hist1.GetPoint(i,x1,y1) ;
239 dx1 = hist1.GetErrorX(i) ;
240 hist2.GetPoint(i,x2,y2) ;
241 addBin(x1,roundBin(wgt1*y1+wgt2*y2),2*dx1/xErrorFrac,xErrorFrac) ;
242 }
243
244 } else {
245 // Add histograms with SumW2 errors
246
247 // Add histograms, calculate combined sum-of-weights error
248 Int_t i,n=hist1.GetN() ;
249 for(i=0 ; i<n ; i++) {
250 Double_t x1,y1,x2,y2,dx1,dy1,dy2 ;
251 hist1.GetPoint(i,x1,y1) ;
252 dx1 = hist1.GetErrorX(i) ;
253 dy1 = hist1.GetErrorY(i) ;
254 dy2 = hist2.GetErrorY(i) ;
255 hist2.GetPoint(i,x2,y2) ;
256 Double_t dy = sqrt(wgt1*wgt1*dy1*dy1+wgt2*wgt2*dy2*dy2) ;
257 addBinWithError(x1,wgt1*y1+wgt2*y2,dy,dy,2*dx1/xErrorFrac,xErrorFrac) ;
258 }
259 }
260
261}
262
263
264////////////////////////////////////////////////////////////////////////////////
265/// Create histogram from a pdf or function. Errors are computed based on the fit result provided.
266///
267/// This signature is intended for unfolding/deconvolution scenarios,
268/// where a pdf is constructed as "data minus background" and is thus
269/// intended to be displayed as "data" (or at least data-like).
270/// Usage of this signature is triggered by the draw style "P" in RooAbsReal::plotOn.
271///
272/// More details.
273/// \param[in] f The function to be plotted.
274/// \param[in] x The variable on the x-axis
275/// \param[in] xErrorFrac Size of the errror in x as a fraction of the bin width
276/// \param[in] scaleFactor arbitrary scaling of the y-values
277/// \param[in] normVars variables over which to normalize
278RooHist::RooHist(const RooAbsReal &f, RooAbsRealLValue &x, Double_t xErrorFrac, Double_t scaleFactor, const RooArgSet *normVars, const RooFitResult* fr) :
279 TGraphAsymmErrors(), _nSigma(1), _rawEntries(-1)
280{
281 // grab the function's name and title
282 TString name(f.GetName());
283 SetName(name.Data());
284 TString title(f.GetTitle());
285 SetTitle(title.Data());
286 // append " ( [<funit> ][/ <xunit> ])" to our y-axis label if necessary
287 if(0 != strlen(f.getUnit()) || 0 != strlen(x.getUnit())) {
288 title.Append(" ( ");
289 if(0 != strlen(f.getUnit())) {
290 title.Append(f.getUnit());
291 title.Append(" ");
292 }
293 if(0 != strlen(x.getUnit())) {
294 title.Append("/ ");
295 title.Append(x.getUnit());
296 title.Append(" ");
297 }
298 title.Append(")");
299 }
300 setYAxisLabel(title.Data());
301
302 RooAbsFunc *funcPtr = nullptr;
303 RooAbsFunc *rawPtr = nullptr;
304 funcPtr= f.bindVars(x,normVars,kTRUE);
305
306 // apply a scale factor if necessary
307 if(scaleFactor != 1) {
308 rawPtr= funcPtr;
309 funcPtr= new RooScaledFunc(*rawPtr,scaleFactor);
310 }
311
312 // apply a scale factor if necessary
313 assert(funcPtr);
314
315 // calculate the points to add to our curve
316 int xbins = x.numBins();
317 RooArgSet nset;
318 if(normVars) nset.add(*normVars);
319 for(int i=0; i<xbins; ++i){
320 double xval = x.getBinning().binCenter(i);
321 double xwidth = x.getBinning().binWidth(i);
322 Axis_t xval_ax = xval;
323 double yval = (*funcPtr)(&xval);
324 double yerr = sqrt(yval);
325 if(fr) yerr = f.getPropagatedError(*fr,nset);
326 addBinWithError(xval_ax,yval,yerr,yerr,xwidth,xErrorFrac,false,scaleFactor) ;
327 _entries += yval;
328 }
329 _nominalBinWidth = 1.;
330
331 // cleanup
332 delete funcPtr;
333 if(rawPtr) delete rawPtr;
334}
335
336
337////////////////////////////////////////////////////////////////////////////////
338/// Perform common initialization for all constructors.
339
341{
343 _entries= 0;
344}
345
346
347////////////////////////////////////////////////////////////////////////////////
348/// Return the number of events of the dataset associated with this RooHist.
349/// This is the number of events in the RooHist itself, unless a different
350/// value was specified through setRawEntries()
351
353{
354 return (_rawEntries==-1 ? _entries : _rawEntries) ;
355}
356
357
358////////////////////////////////////////////////////////////////////////////////
359/// Calculate integral of histogram in given range
360
362{
363 Double_t sum(0) ;
364 for (int i=0 ; i<GetN() ; i++) {
365 Double_t x,y ;
366
367 GetPoint(i,x,y) ;
368
369 if (x>=xlo && x<=xhi) {
370 sum += y ;
371 }
372 }
373
374 if (_rawEntries!=-1) {
375 coutW(Plotting) << "RooHist::getFitRangeNEvt() WARNING: The number of normalisation events associated to histogram " << GetName() << " is not equal to number of events in this histogram."
376 << "\n\t\t This is due a cut being applied while plotting the data. Automatic normalisation over a sub-range of a plot variable assumes"
377 << "\n\t\t that the effect of that cut is uniform across the plot, which may be an incorrect assumption. To obtain a correct normalisation, it needs to be passed explicitly:"
378 << "\n\t\t\t data->plotOn(frame01,CutRange(\"SB1\"));"
379 << "\n\t\t\t const double nData = data->sumEntries(\"\", \"SB1\"); //or the cut string such as sumEntries(\"x > 0.\");"
380 << "\n\t\t\t model.plotOn(frame01, RooFit::Normalization(nData, RooAbsReal::NumEvent), ProjectionRange(\"SB1\"));" << endl ;
382 }
383
384 return sum ;
385}
386
387
388
389////////////////////////////////////////////////////////////////////////////////
390/// Return (average) bin width of this RooHist
391
393{
394 return _nominalBinWidth ;
395}
396
397
398
399////////////////////////////////////////////////////////////////////////////////
400/// Return the nearest positive integer to the input value
401/// and print a warning if an adjustment is required.
402
404{
405 if(y < 0) {
406 coutW(Plotting) << fName << "::roundBin: rounding negative bin contents to zero: " << y << endl;
407 return 0;
408 }
409 Int_t n= (Int_t)(y+0.5);
410 if(fabs(y-n)>1e-6) {
411 coutW(Plotting) << fName << "::roundBin: rounding non-integer bin contents: " << y << endl;
412 }
413 return n;
414}
415
416
417
418////////////////////////////////////////////////////////////////////////////////
419/// Add a bin to this histogram with the specified integer bin contents
420/// and using an error bar calculated with Poisson statistics. The bin width
421/// is used to set the relative scale of bins with different widths.
422
423void RooHist::addBin(Axis_t binCenter, Double_t n, Double_t binWidth, Double_t xErrorFrac, Double_t scaleFactor)
424{
425 if (n<0) {
426 coutW(Plotting) << "RooHist::addBin(" << GetName() << ") WARNING: negative entry set to zero when Poisson error bars are requested" << endl ;
427 }
428
429 Double_t scale= 1;
430 if(binWidth > 0) {
431 scale= _nominalBinWidth/binWidth;
432 }
433 _entries+= n;
434 Int_t index= GetN();
435
436 // calculate Poisson errors for this bin
437 Double_t ym,yp,dx(0.5*binWidth);
438
439 if (fabs((double)((n-Int_t(n))>1e-5))) {
440 // need interpolation
441 Double_t ym1(0),yp1(0),ym2(0),yp2(0) ;
442 Int_t n1 = Int_t(n) ;
443 Int_t n2 = n1+1 ;
444 if(!RooHistError::instance().getPoissonInterval(n1,ym1,yp1,_nSigma) ||
445 !RooHistError::instance().getPoissonInterval(n2,ym2,yp2,_nSigma)) {
446 coutE(Plotting) << "RooHist::addBin: unable to add bin with " << n << " events" << endl;
447 }
448 ym = ym1 + (n-n1)*(ym2-ym1) ;
449 yp = yp1 + (n-n1)*(yp2-yp1) ;
450 coutW(Plotting) << "RooHist::addBin(" << GetName()
451 << ") WARNING: non-integer bin entry " << n << " with Poisson errors, interpolating between Poisson errors of adjacent integer" << endl ;
452 } else {
453 // integer case
454 if(!RooHistError::instance().getPoissonInterval(Int_t(n),ym,yp,_nSigma)) {
455 coutE(Plotting) << "RooHist::addBin: unable to add bin with " << n << " events" << endl;
456 return;
457 }
458 }
459
460 SetPoint(index,binCenter,n*scale*scaleFactor);
461 SetPointError(index,dx*xErrorFrac,dx*xErrorFrac,scale*(n-ym)*scaleFactor,scale*(yp-n)*scaleFactor);
462 updateYAxisLimits(scale*yp);
463 updateYAxisLimits(scale*ym);
464}
465
466
467
468////////////////////////////////////////////////////////////////////////////////
469/// Add a bin to this histogram with the specified bin contents
470/// and error. The bin width is used to set the relative scale of
471/// bins with different widths.
472
473void RooHist::addBinWithError(Axis_t binCenter, Double_t n, Double_t elow, Double_t ehigh, Double_t binWidth,
474 Double_t xErrorFrac, Bool_t correctForBinWidth, Double_t scaleFactor)
475{
476 Double_t scale= 1;
477 if(binWidth > 0 && correctForBinWidth) {
478 scale= _nominalBinWidth/binWidth;
479 }
480 _entries+= n;
481 Int_t index= GetN();
482
483 Double_t dx(0.5*binWidth) ;
484 SetPoint(index,binCenter,n*scale*scaleFactor);
485 SetPointError(index,dx*xErrorFrac,dx*xErrorFrac,elow*scale*scaleFactor,ehigh*scale*scaleFactor);
486 updateYAxisLimits(scale*(n-elow));
487 updateYAxisLimits(scale*(n+ehigh));
488}
489
490
491
492
493////////////////////////////////////////////////////////////////////////////////
494/// Add a bin to this histogram with the specified bin contents
495/// and error. The bin width is used to set the relative scale of
496/// bins with different widths.
497
498void RooHist::addBinWithXYError(Axis_t binCenter, Double_t n, Double_t exlow, Double_t exhigh, Double_t eylow, Double_t eyhigh,
499 Double_t scaleFactor)
500{
501 _entries+= n;
502 Int_t index= GetN();
503
504 SetPoint(index,binCenter,n*scaleFactor);
505 SetPointError(index,exlow,exhigh,eylow*scaleFactor,eyhigh*scaleFactor);
506 updateYAxisLimits(scaleFactor*(n-eylow));
507 updateYAxisLimits(scaleFactor*(n+eyhigh));
508}
509
510
511
512
513
514////////////////////////////////////////////////////////////////////////////////
515/// Add a bin to this histogram with the value (n1-n2)/(n1+n2)
516/// using an error bar calculated with Binomial statistics.
517
518void RooHist::addAsymmetryBin(Axis_t binCenter, Int_t n1, Int_t n2, Double_t binWidth, Double_t xErrorFrac, Double_t scaleFactor)
519{
520 Double_t scale= 1;
521 if(binWidth > 0) scale= _nominalBinWidth/binWidth;
522 Int_t index= GetN();
523
524 // calculate Binomial errors for this bin
525 Double_t ym,yp,dx(0.5*binWidth);
526 if(!RooHistError::instance().getBinomialIntervalAsym(n1,n2,ym,yp,_nSigma)) {
527 coutE(Plotting) << "RooHist::addAsymmetryBin: unable to calculate binomial error for bin with " << n1 << "," << n2 << " events" << endl;
528 return;
529 }
530
531 Double_t a= (Double_t)(n1-n2)/(n1+n2);
532 SetPoint(index,binCenter,a*scaleFactor);
533 SetPointError(index,dx*xErrorFrac,dx*xErrorFrac,(a-ym)*scaleFactor,(yp-a)*scaleFactor);
534 updateYAxisLimits(scale*yp);
535 updateYAxisLimits(scale*ym);
536}
537
538
539
540////////////////////////////////////////////////////////////////////////////////
541/// Add a bin to this histogram with the value (n1-n2)/(n1+n2)
542/// using an error bar calculated with Binomial statistics.
543
544void 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)
545{
546 Double_t scale= 1;
547 if(binWidth > 0) scale= _nominalBinWidth/binWidth;
548 Int_t index= GetN();
549
550 // calculate Binomial errors for this bin
551 Double_t ym,yp,dx(0.5*binWidth);
552 Double_t a= (Double_t)(n1-n2)/(n1+n2);
553
554 Double_t error = 2*sqrt( pow(en1,2)*pow(n2,2) + pow(en2,2)*pow(n1,2) ) / pow(n1+n2,2) ;
555 ym=a-error ;
556 yp=a+error ;
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/// Add a bin to this histogram with the value n1/(n1+n2)
568/// using an error bar calculated with Binomial statistics.
569
570void RooHist::addEfficiencyBin(Axis_t binCenter, Int_t n1, Int_t n2, Double_t binWidth, Double_t xErrorFrac, Double_t scaleFactor)
571{
572 Double_t scale= 1;
573 if(binWidth > 0) scale= _nominalBinWidth/binWidth;
574 Int_t index= GetN();
575
576 Double_t a= (Double_t)(n1)/(n1+n2);
577
578 // calculate Binomial errors for this bin
579 Double_t ym,yp,dx(0.5*binWidth);
580 if(!RooHistError::instance().getBinomialIntervalEff(n1,n2,ym,yp,_nSigma)) {
581 coutE(Plotting) << "RooHist::addEfficiencyBin: unable to calculate binomial error for bin with " << n1 << "," << n2 << " events" << endl;
582 return;
583 }
584
585 SetPoint(index,binCenter,a*scaleFactor);
586 SetPointError(index,dx*xErrorFrac,dx*xErrorFrac,(a-ym)*scaleFactor,(yp-a)*scaleFactor);
587 updateYAxisLimits(scale*yp);
588 updateYAxisLimits(scale*ym);
589}
590
591
592
593////////////////////////////////////////////////////////////////////////////////
594/// Add a bin to this histogram with the value n1/(n1+n2)
595/// using an error bar calculated with Binomial statistics.
596
597void 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)
598{
599 Double_t scale= 1;
600 if(binWidth > 0) scale= _nominalBinWidth/binWidth;
601 Int_t index= GetN();
602
603 Double_t a= (Double_t)(n1)/(n1+n2);
604
605 Double_t error = sqrt( pow(en1,2)*pow(n2,2) + pow(en2,2)*pow(n1,2) ) / pow(n1+n2,2) ;
606
607 // calculate Binomial errors for this bin
608 Double_t ym,yp,dx(0.5*binWidth);
609 ym=a-error ;
610 yp=a+error ;
611
612
613 SetPoint(index,binCenter,a*scaleFactor);
614 SetPointError(index,dx*xErrorFrac,dx*xErrorFrac,(a-ym)*scaleFactor,(yp-a)*scaleFactor);
615 updateYAxisLimits(scale*yp);
616 updateYAxisLimits(scale*ym);
617}
618
619
620
621////////////////////////////////////////////////////////////////////////////////
622/// Destructor
623
625{
626}
627
628
629
630////////////////////////////////////////////////////////////////////////////////
631/// Return kTRUE if binning of this RooHist is identical to that of 'other'
632
634{
635 // First check if number of bins is the same
636 if (GetN() != other.GetN()) {
637 return kFALSE ;
638 }
639
640 // Next require that all bin centers are the same
641 Int_t i ;
642 for (i=0 ; i<GetN() ; i++) {
643 Double_t x1,x2,y1,y2 ;
644
645 GetPoint(i,x1,y1) ;
646 other.GetPoint(i,x2,y2) ;
647
648 if (fabs(x1-x2)>1e-10) {
649 return kFALSE ;
650 }
651
652 }
653
654 return kTRUE ;
655}
656
657
658
659////////////////////////////////////////////////////////////////////////////////
660/// Return kTRUE if contents of this RooHist is identical within given
661/// relative tolerance to that of 'other'
662
664{
665 // Make temporary TH1s output of RooHists to perform Kolmogorov test
667 TH1F h_self("h_self","h_self",GetN(),0,1) ;
668 TH1F h_other("h_other","h_other",GetN(),0,1) ;
670
671 for (Int_t i=0 ; i<GetN() ; i++) {
672 h_self.SetBinContent(i+1,GetY()[i]) ;
673 h_other.SetBinContent(i+1,other.GetY()[i]) ;
674 }
675
676 Double_t M = h_self.KolmogorovTest(&h_other,"M") ;
677 if (M>tol) {
678 Double_t kprob = h_self.KolmogorovTest(&h_other) ;
679 cout << "RooHist::isIdentical() tolerance exceeded M=" << M << " (tol=" << tol << "), corresponding prob = " << kprob << endl ;
680 return kFALSE ;
681 }
682
683 return kTRUE ;
684}
685
686
687
688////////////////////////////////////////////////////////////////////////////////
689/// Print info about this histogram to the specified output stream.
690///
691/// Standard: number of entries
692/// Shape: error CL and maximum value
693/// Verbose: print our bin contents and errors
694
695void RooHist::printMultiline(ostream& os, Int_t contents, Bool_t verbose, TString indent) const
696{
698 os << indent << "--- RooHist ---" << endl;
699 Int_t n= GetN();
700 os << indent << " Contains " << n << " bins" << endl;
701 if(verbose) {
702 os << indent << " Errors calculated at" << _nSigma << "-sigma CL" << endl;
703 os << indent << " Bin Contents:" << endl;
704 for(Int_t i= 0; i < n; i++) {
705 os << indent << setw(3) << i << ") x= " << fX[i];
706 if(fEXhigh[i] > 0 || fEXlow[i] > 0) {
707 os << " +" << fEXhigh[i] << " -" << fEXlow[i];
708 }
709 os << " , y = " << fY[i] << " +" << fEYhigh[i] << " -" << fEYlow[i] << endl;
710 }
711 }
712}
713
714
715
716////////////////////////////////////////////////////////////////////////////////
717/// Print name of RooHist
718
719void RooHist::printName(ostream& os) const
720{
721 os << GetName() ;
722}
723
724
725
726////////////////////////////////////////////////////////////////////////////////
727/// Print title of RooHist
728
729void RooHist::printTitle(ostream& os) const
730{
731 os << GetTitle() ;
732}
733
734
735
736////////////////////////////////////////////////////////////////////////////////
737/// Print class name of RooHist
738
739void RooHist::printClassName(ostream& os) const
740{
741 os << IsA()->GetName() ;
742}
743
744
745
746////////////////////////////////////////////////////////////////////////////////
747/// Create and return RooHist containing residuals w.r.t to given curve.
748/// If normalize is true, the residuals are normalized by the histogram
749/// errors creating a RooHist with pull values
750
751RooHist* RooHist::makeResidHist(const RooCurve& curve, bool normalize, bool useAverage) const
752{
753
754 // Copy all non-content properties from hist1
755 RooHist* hist = new RooHist(_nominalBinWidth) ;
756 if (normalize) {
757 hist->SetName(Form("pull_%s_%s",GetName(),curve.GetName())) ;
758 hist->SetTitle(Form("Pull of %s and %s",GetTitle(),curve.GetTitle())) ;
759 } else {
760 hist->SetName(Form("resid_%s_%s",GetName(),curve.GetName())) ;
761 hist->SetTitle(Form("Residual of %s and %s",GetTitle(),curve.GetTitle())) ;
762 }
763
764 // Determine range of curve
765 Double_t xstart,xstop,y ;
766 curve.GetPoint(0,xstart,y) ;
767 curve.GetPoint(curve.GetN()-1,xstop,y) ;
768
769 // Add histograms, calculate Poisson confidence interval on sum value
770 for(Int_t i=0 ; i<GetN() ; i++) {
771 Double_t x,point;
772 GetPoint(i,x,point) ;
773
774 // Only calculate pull for bins inside curve range
775 if (x<xstart || x>xstop) continue ;
776
777 Double_t yy ;
778 if (useAverage) {
779 Double_t exl = GetErrorXlow(i);
780 Double_t exh = GetErrorXhigh(i) ;
781 if (exl<=0 ) exl = GetErrorX(i);
782 if (exh<=0 ) exh = GetErrorX(i);
783 if (exl<=0 ) exl = 0.5*getNominalBinWidth();
784 if (exh<=0 ) exh = 0.5*getNominalBinWidth();
785 yy = point - curve.average(x-exl,x+exh) ;
786 } else {
787 yy = point - curve.interpolate(x) ;
788 }
789
790 Double_t dyl = GetErrorYlow(i) ;
791 Double_t dyh = GetErrorYhigh(i) ;
792 if (normalize) {
793 Double_t norm = (yy>0?dyl:dyh);
794 if (norm==0.) {
795 coutW(Plotting) << "RooHist::makeResisHist(" << GetName() << ") WARNING: point " << i << " has zero error, setting residual to zero" << endl ;
796 yy=0 ;
797 dyh=0 ;
798 dyl=0 ;
799 } else {
800 yy /= norm;
801 dyh /= norm;
802 dyl /= norm;
803 }
804 }
805 hist->addBinWithError(x,yy,dyl,dyh);
806 }
807 return hist ;
808}
#define f(i)
Definition: RSha256.hxx:104
#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)
char name[80]
Definition: TGX11.cxx:109
double pow(double, double)
double sqrt(double)
char * Form(const char *fmt,...)
Abstract interface for evaluating a real-valued function of one real variable and performing numerica...
Definition: RooAbsFunc.h:23
RooAbsRealLValue is the common abstract base class for objects that represent a real value that may a...
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:59
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:28
virtual Bool_t add(const RooAbsCollection &col, Bool_t silent=kFALSE)
Add a collection of arguments to this collection by calling add() for each element in the source coll...
Definition: RooArgSet.h:88
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:612
Double_t interpolate(Double_t x, Double_t tolerance=1e-10) const
Return linearly interpolated value of curve at xvalue.
Definition: RooCurve.cxx:698
RooFitResult is a container class to hold the input and output of a PDF fit to a dataset.
Definition: RooFitResult.h:40
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:27
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:544
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:751
Double_t _nominalBinWidth
Definition: RooHist.h:89
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:570
Double_t getFitRangeNEvt() const
Return the number of events of the dataset associated with this RooHist.
Definition: RooHist.cxx:352
Double_t _rawEntries
Definition: RooHist.h:92
virtual void printTitle(std::ostream &os) const
Print title of RooHist.
Definition: RooHist.cxx:729
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:403
void initialize()
Perform common initialization for all constructors.
Definition: RooHist.cxx:340
RooHist()
Default constructor.
Definition: RooHist.cxx:51
virtual void printName(std::ostream &os) const
Print name of RooHist.
Definition: RooHist.cxx:719
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:473
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:695
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:597
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:423
Double_t getNominalBinWidth() const
Definition: RooHist.h:71
virtual void printClassName(std::ostream &os) const
Print class name of RooHist.
Definition: RooHist.cxx:739
Double_t _entries
Definition: RooHist.h:91
Double_t getFitRangeBinW() const
Return (average) bin width of this RooHist.
Definition: RooHist.cxx:392
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:518
Bool_t hasIdenticalBinning(const RooHist &other) const
Return kTRUE if binning of this RooHist is identical to that of 'other'.
Definition: RooHist.cxx:633
virtual ~RooHist()
Destructor.
Definition: RooHist.cxx:624
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:498
Double_t _nSigma
Definition: RooHist.h:90
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:663
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
Lightweight RooAbsFunction implementation that applies a constant scale factor to another RooAbsFunc.
Definition: RooScaledFunc.h:21
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:2257
Double_t * GetY() const
Definition: TGraph.h:131
virtual void SetName(const char *name="")
Set graph name.
Definition: TGraph.cxx:2296
Int_t GetN() const
Definition: TGraph.h:123
virtual void SetTitle(const char *title="")
Change (i.e.
Definition: TGraph.cxx:2312
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:1586
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:8585
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition: TH1.cxx:8507
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition: TH1.cxx:1226
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:8666
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4899
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition: TH1.cxx:8607
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:7672
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
const char * Data() const
Definition: TString.h:364
TString & Append(const char *cs)
Definition: TString.h:559
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:68
auto * a
Definition: textangle.C:12
static long int sum(long int i)
Definition: Factory.cxx:2276