Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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 "RooHist.h"
29
30#include "RooAbsRealLValue.h"
31#include "RooHistError.h"
32#include "RooCurve.h"
33#include "RooMsgService.h"
34#include "RooProduct.h"
35#include "RooConstVar.h"
36
37#include "TH1.h"
38#include "Riostream.h"
39#include <iomanip>
40
42
43
44////////////////////////////////////////////////////////////////////////////////
45/// Create an empty histogram that can be filled with the addBin()
46/// and addAsymmetryBin() methods. Use the optional parameter to
47/// specify the confidence level in units of sigma to use for
48/// calculating error bars. The nominal bin width specifies the
49/// default used by addBin(), and is used to set the relative
50/// normalization of bins with different widths.
51
52 RooHist::RooHist(double nominalBinWidth, double nSigma, double /*xErrorFrac*/, double /*scaleFactor*/) :
53 TGraphAsymmErrors(), _nominalBinWidth(nominalBinWidth), _nSigma(nSigma), _rawEntries(-1)
54{
55 initialize();
56}
57
58
59////////////////////////////////////////////////////////////////////////////////
60/// Create a histogram from the contents of the specified TH1 object
61/// which may have fixed or variable bin widths. Error bars are
62/// calculated using Poisson statistics. Prints a warning and rounds
63/// any bins with non-integer contents. 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. If not set, the
68/// nominal bin width is calculated as range/nbins.
69
70RooHist::RooHist(const TH1 &data, double nominalBinWidth, double nSigma, RooAbsData::ErrorType etype, double xErrorFrac,
71 bool correctForBinWidth, double scaleFactor) :
72 TGraphAsymmErrors(), _nominalBinWidth(nominalBinWidth), _nSigma(nSigma), _rawEntries(-1)
73{
74 if(etype == RooAbsData::Poisson && correctForBinWidth == false) {
75 throw std::invalid_argument(
76 "To ensure consistent behavior prior releases, it's not possible to create a RooHist from a TH1 with no bin width correction when using Poisson errors.");
77 }
78
79 initialize();
80 // copy the input histogram's name and title
81 SetName(data.GetName());
82 SetTitle(data.GetTitle());
83 // calculate our nominal bin width if necessary
84 if(_nominalBinWidth == 0) {
85 const TAxis *axis= ((TH1&)data).GetXaxis();
86 if(axis->GetNbins() > 0) _nominalBinWidth= (axis->GetXmax() - axis->GetXmin())/axis->GetNbins();
87 }
88 setYAxisLabel(data.GetYaxis()->GetTitle());
89
90 // initialize our contents from the input histogram's contents
91 Int_t nbin= data.GetNbinsX();
92 for(Int_t bin= 1; bin <= nbin; bin++) {
93 Axis_t x= data.GetBinCenter(bin);
94 Stat_t y= data.GetBinContent(bin);
95 Stat_t dy = data.GetBinError(bin) ;
96 if (etype==RooAbsData::Poisson) {
97 addBin(x,y,data.GetBinWidth(bin),xErrorFrac,scaleFactor);
98 } else if (etype==RooAbsData::SumW2) {
99 addBinWithError(x,y,dy,dy,data.GetBinWidth(bin),xErrorFrac,correctForBinWidth,scaleFactor);
100 } else {
101 addBinWithError(x,y,0,0,data.GetBinWidth(bin),xErrorFrac,correctForBinWidth,scaleFactor);
102 }
103 }
104 // add over/underflow bins to our event count
105 _entries+= data.GetBinContent(0) + data.GetBinContent(nbin+1);
106}
107
108
109
110////////////////////////////////////////////////////////////////////////////////
111/// Create a histogram from the asymmetry between the specified TH1 objects
112/// which may have fixed or variable bin widths, but which must both have
113/// the same binning. The asymmetry is calculated as (1-2)/(1+2). Error bars are
114/// calculated using Binomial statistics. Prints a warning and rounds
115/// any bins with non-integer contents. Use the optional parameter to
116/// specify the confidence level in units of sigma to use for
117/// calculating error bars. The nominal bin width specifies the
118/// default used by addAsymmetryBin(), and is used to set the relative
119/// normalization of bins with different widths. If not set, the
120/// nominal bin width is calculated as range/nbins.
121
122RooHist::RooHist(const TH1 &data1, const TH1 &data2, double nominalBinWidth, double nSigma,
123 RooAbsData::ErrorType etype, double xErrorFrac, bool efficiency, double scaleFactor) :
124 TGraphAsymmErrors(), _nominalBinWidth(nominalBinWidth), _nSigma(nSigma), _rawEntries(-1)
125{
126 initialize();
127 // copy the first input histogram's name and title
128 SetName(data1.GetName());
129 SetTitle(data1.GetTitle());
130 // calculate our nominal bin width if necessary
131 if(_nominalBinWidth == 0) {
132 const TAxis *axis= data1.GetXaxis();
133 if(axis->GetNbins() > 0) _nominalBinWidth= (axis->GetXmax() - axis->GetXmin())/axis->GetNbins();
134 }
135
136 if (!efficiency) {
137 setYAxisLabel(Form("Asymmetry (%s - %s)/(%s + %s)",
138 data1.GetName(),data2.GetName(),data1.GetName(),data2.GetName()));
139 } else {
140 setYAxisLabel(Form("Efficiency (%s)/(%s + %s)",
141 data1.GetName(),data1.GetName(),data2.GetName()));
142 }
143 // initialize our contents from the input histogram contents
144 Int_t nbin= data1.GetNbinsX();
145 if(data2.GetNbinsX() != nbin) {
146 coutE(InputArguments) << "RooHist::RooHist: histograms have different number of bins" << std::endl;
147 return;
148 }
149 for(Int_t bin= 1; bin <= nbin; bin++) {
150 Axis_t x= data1.GetBinCenter(bin);
151 if(std::abs(data2.GetBinCenter(bin)-x)>1e-10) {
152 coutW(InputArguments) << "RooHist::RooHist: histograms have different centers for bin " << bin << std::endl;
153 }
154 Stat_t y1= data1.GetBinContent(bin);
155 Stat_t y2= data2.GetBinContent(bin);
156 if (!efficiency) {
157
158 if (etype==RooAbsData::Poisson) {
159 addAsymmetryBin(x,roundBin(y1),roundBin(y2),data1.GetBinWidth(bin),xErrorFrac,scaleFactor);
160 } else if (etype==RooAbsData::SumW2) {
161 Stat_t dy1= data1.GetBinError(bin);
162 Stat_t dy2= data2.GetBinError(bin);
163 addAsymmetryBinWithError(x,y1,y2,dy1,dy2,data1.GetBinWidth(bin),xErrorFrac,scaleFactor);
164 } else {
165 addAsymmetryBinWithError(x,y1,y2,0,0,data1.GetBinWidth(bin),xErrorFrac,scaleFactor);
166 }
167
168 } else {
169
170 if (etype==RooAbsData::Poisson) {
171 addEfficiencyBin(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 addEfficiencyBinWithError(x,y1,y2,dy1,dy2,data1.GetBinWidth(bin),xErrorFrac,scaleFactor);
176 } else {
177 addEfficiencyBinWithError(x,y1,y2,0,0,data1.GetBinWidth(bin),xErrorFrac,scaleFactor);
178 }
179
180 }
181
182 }
183 // we do not have a meaningful number of entries
184 _entries= -1;
185}
186
187
188
189////////////////////////////////////////////////////////////////////////////////
190/// Create histogram as sum of two existing histograms. If Poisson errors are selected the histograms are
191/// added and Poisson confidence intervals are calculated for the summed content. If wgt1 and wgt2 are not
192/// 1 in this mode, a warning message is printed. If SumW2 errors are selected the histograms are added
193/// and the histograms errors are added in quadrature, taking the weights into account.
194
195RooHist::RooHist(const RooHist& hist1, const RooHist& hist2, double wgt1, double wgt2,
196 RooAbsData::ErrorType etype, double xErrorFrac) : _rawEntries(-1)
197{
198 // Initialize the histogram
199 initialize() ;
200
201 // Copy all non-content properties from hist1
202 SetName(hist1.GetName()) ;
203 SetTitle(hist1.GetTitle()) ;
205 _nSigma=hist1._nSigma ;
207
208 if (!hist1.hasIdenticalBinning(hist2)) {
209 coutE(InputArguments) << "RooHist::RooHist input histograms have incompatible binning, combined histogram will remain empty" << std::endl ;
210 return ;
211 }
212
213 if (etype==RooAbsData::Poisson) {
214 // Add histograms with Poisson errors
215
216 // Issue warning if weights are not 1
217 if (wgt1!=1.0 || wgt2 != 1.0) {
218 coutW(InputArguments) << "RooHist::RooHist: WARNING: Poisson errors of weighted sum of two histograms is not well defined! " << std::endl
219 << " Summed histogram bins will rounded to nearest integer for Poisson confidence interval calculation" << std::endl ;
220 }
221
222 // Add histograms, calculate Poisson confidence interval on sum value
223 Int_t i,n=hist1.GetN() ;
224 for(i=0 ; i<n ; i++) {
225 double x1,y1,x2,y2,dx1 ;
226 hist1.GetPoint(i,x1,y1) ;
227 dx1 = hist1.GetErrorX(i) ;
228 hist2.GetPoint(i,x2,y2) ;
229 addBin(x1,roundBin(wgt1*y1+wgt2*y2),2*dx1/xErrorFrac,xErrorFrac) ;
230 }
231
232 } else {
233 // Add histograms with SumW2 errors
234
235 // Add histograms, calculate combined sum-of-weights error
236 Int_t i,n=hist1.GetN() ;
237 for(i=0 ; i<n ; i++) {
238 double x1,y1,x2,y2,dx1,dy1,dy2 ;
239 hist1.GetPoint(i,x1,y1) ;
240 dx1 = hist1.GetErrorX(i) ;
241 dy1 = hist1.GetErrorY(i) ;
242 dy2 = hist2.GetErrorY(i) ;
243 hist2.GetPoint(i,x2,y2) ;
244 double dy = sqrt(wgt1*wgt1*dy1*dy1+wgt2*wgt2*dy2*dy2) ;
245 addBinWithError(x1,wgt1*y1+wgt2*y2,dy,dy,2*dx1/xErrorFrac,xErrorFrac) ;
246 }
247 }
248
249}
250
251
252////////////////////////////////////////////////////////////////////////////////
253/// Create histogram from a pdf or function. Errors are computed based on the fit result provided.
254///
255/// This signature is intended for unfolding/deconvolution scenarios,
256/// where a pdf is constructed as "data minus background" and is thus
257/// intended to be displayed as "data" (or at least data-like).
258/// Usage of this signature is triggered by the draw style "P" in RooAbsReal::plotOn.
259///
260/// More details.
261/// \param[in] f The function to be plotted.
262/// \param[in] x The variable on the x-axis
263/// \param[in] xErrorFrac Size of the error in x as a fraction of the bin width
264/// \param[in] scaleFactor arbitrary scaling of the y-values
265/// \param[in] normVars variables over which to normalize
266/// \param[in] fr fit result
267RooHist::RooHist(const RooAbsReal &f, RooAbsRealLValue &x, double xErrorFrac, double scaleFactor, const RooArgSet *normVars, const RooFitResult* fr) :
268 TGraphAsymmErrors(), _nSigma(1), _rawEntries(-1)
269{
270 // grab the function's name and title
271 SetName(f.GetName());
272 std::string title{f.GetTitle()};
273 SetTitle(title.c_str());
274 // append " ( [<funit> ][/ <xunit> ])" to our y-axis label if necessary
275 if(0 != strlen(f.getUnit()) || 0 != strlen(x.getUnit())) {
276 title += " ( ";
277 if(0 != strlen(f.getUnit())) {
278 title += f.getUnit();
279 title += " ";
280 }
281 if(0 != strlen(x.getUnit())) {
282 title += "/ ";
283 title += x.getUnit();
284 title += " ";
285 }
286 title += ")";
287 }
288 setYAxisLabel(title.c_str());
289
290 RooProduct scaledFunc{"scaled_func", "scaled_func", {f, RooFit::RooConst(scaleFactor)}};
291 std::unique_ptr<RooAbsFunc> funcPtr{scaledFunc.bindVars(x, normVars, true)};
292
293 // calculate the points to add to our curve
294 int xbins = x.numBins();
295 RooArgSet nset;
296 if(normVars) nset.add(*normVars);
297 for(int i=0; i<xbins; ++i){
298 double xval = x.getBinning().binCenter(i);
299 double xwidth = x.getBinning().binWidth(i);
300 Axis_t xval_ax = xval;
301 double yval = (*funcPtr)(&xval);
302 double yerr = std::sqrt(yval);
303 if(fr) yerr = f.getPropagatedError(*fr,nset);
304 addBinWithError(xval_ax,yval,yerr,yerr,xwidth,xErrorFrac,false,scaleFactor) ;
305 _entries += yval;
306 }
307 _nominalBinWidth = 1.;
308}
309
310
311////////////////////////////////////////////////////////////////////////////////
312/// Perform common initialization for all constructors.
313
315{
317}
318
319
320////////////////////////////////////////////////////////////////////////////////
321/// Return the number of events of the dataset associated with this RooHist.
322/// This is the number of events in the RooHist itself, unless a different
323/// value was specified through setRawEntries()
324
326{
327 return (_rawEntries==-1 ? _entries : _rawEntries) ;
328}
329
330
331////////////////////////////////////////////////////////////////////////////////
332/// Calculate integral of histogram in given range
333
334double RooHist::getFitRangeNEvt(double xlo, double xhi) const
335{
336 double sum(0) ;
337 for (int i=0 ; i<GetN() ; i++) {
338 double x,y ;
339
340 GetPoint(i,x,y) ;
341
342 if (x>=xlo && x<=xhi) {
343 // We have to use the original weights of the histogram, because the
344 // scaled points have nothing to do anymore with event weights in the
345 // case of non-uniform binning. For backwards compatibility with the
346 // RooHist version 1, we first need to check if the `_originalWeights`
347 // member is filled.
348 sum += _originalWeights.empty() ? y : _originalWeights[i];
349 }
350 }
351
352 if (_rawEntries!=-1) {
353 coutW(Plotting) << "RooHist::getFitRangeNEvt() WARNING: The number of normalisation events associated to histogram " << GetName() << " is not equal to number of events in this histogram."
354 << "\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"
355 << "\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:"
356 << "\n\t\t\t data->plotOn(frame01,CutRange(\"SB1\"));"
357 << "\n\t\t\t const double nData = data->sumEntries(\"\", \"SB1\"); //or the cut string such as sumEntries(\"x > 0.\");"
358 << "\n\t\t\t model.plotOn(frame01, RooFit::Normalization(nData, RooAbsReal::NumEvent), ProjectionRange(\"SB1\"));" << std::endl ;
360 }
361
362 return sum ;
363}
364
365
366////////////////////////////////////////////////////////////////////////////////
367/// Return the nearest positive integer to the input value
368/// and print a warning if an adjustment is required.
369
371{
372 if(y < 0) {
373 coutW(Plotting) << fName << "::roundBin: rounding negative bin contents to zero: " << y << std::endl;
374 return 0;
375 }
376 Int_t n= (Int_t)(y+0.5);
377 if(std::abs(y-n)>1e-6) {
378 coutW(Plotting) << fName << "::roundBin: rounding non-integer bin contents: " << y << std::endl;
379 }
380 return n;
381}
382
383
384void RooHist::addPoint(Axis_t binCenter, double y, double yscale, double exlow, double exhigh, double eylow, double eyhigh)
385{
386 const int index = GetN();
387 SetPoint(index, binCenter, y*yscale);
388
389 // If the scale is negative, the low and high errors must be swapped
390 if(std::abs(yscale) < 0) {
391 std::swap(eylow, eyhigh);
392 }
393
394 SetPointError(index, exlow, exhigh, std::abs(yscale) * eylow, std::abs(yscale) * eyhigh);
395
396 updateYAxisLimits(yscale * (y - eylow));
397 updateYAxisLimits(yscale * (y + eyhigh));
398
399 // We also track the original weights of the histogram, because if we only
400 // have info on the scaled points it's not possible anymore to compute the
401 // number of events in a subrange of the RooHist.
402 _originalWeights.resize(index + 1);
404}
405
406
407////////////////////////////////////////////////////////////////////////////////
408/// Add a bin to this histogram with the specified integer bin contents
409/// and using an error bar calculated with Poisson statistics. The bin width
410/// is used to set the relative scale of bins with different widths.
411
412void RooHist::addBin(Axis_t binCenter, double n, double binWidth, double xErrorFrac, double scaleFactor)
413{
414 if (n<0) {
415 coutW(Plotting) << "RooHist::addBin(" << GetName() << ") WARNING: negative entry set to zero when Poisson error bars are requested" << std::endl ;
416 }
417
418 double scale= 1;
419 if(binWidth > 0) {
420 scale= _nominalBinWidth/binWidth;
421 }
422 _entries+= n;
423
424 // calculate Poisson errors for this bin
425 double ym,yp,dx(0.5*binWidth);
426
427 if (std::abs((double)((n-Int_t(n))>1e-5))) {
428 // need interpolation
429 double ym1(0),yp1(0),ym2(0),yp2(0) ;
430 Int_t n1 = Int_t(n) ;
431 Int_t n2 = n1+1 ;
432 if(!RooHistError::instance().getPoissonInterval(n1,ym1,yp1,_nSigma) ||
433 !RooHistError::instance().getPoissonInterval(n2,ym2,yp2,_nSigma)) {
434 coutE(Plotting) << "RooHist::addBin: unable to add bin with " << n << " events" << std::endl;
435 }
436 ym = ym1 + (n-n1)*(ym2-ym1) ;
437 yp = yp1 + (n-n1)*(yp2-yp1) ;
438 coutW(Plotting) << "RooHist::addBin(" << GetName()
439 << ") WARNING: non-integer bin entry " << n << " with Poisson errors, interpolating between Poisson errors of adjacent integer" << std::endl ;
440 } else {
441 // integer case
442 if(!RooHistError::instance().getPoissonInterval(Int_t(n),ym,yp,_nSigma)) {
443 coutE(Plotting) << "RooHist::addBin: unable to add bin with " << n << " events" << std::endl;
444 return;
445 }
446 }
447
448 addPoint(binCenter,n, scale*scaleFactor,dx*xErrorFrac,dx*xErrorFrac, n-ym, yp-n);
449}
450
451
452
453////////////////////////////////////////////////////////////////////////////////
454/// Add a bin to this histogram with the specified bin contents
455/// and error. The bin width is used to set the relative scale of
456/// bins with different widths.
457
458void RooHist::addBinWithError(Axis_t binCenter, double n, double elow, double ehigh, double binWidth,
459 double xErrorFrac, bool correctForBinWidth, double scaleFactor)
460{
461 double scale= 1;
462 if(binWidth > 0 && correctForBinWidth) {
463 scale= _nominalBinWidth/binWidth;
464 }
465 _entries+= n;
466
467 double dx(0.5*binWidth) ;
468 addPoint(binCenter,n, scale*scaleFactor,dx*xErrorFrac,dx*xErrorFrac, elow, ehigh);
469}
470
471
472
473
474////////////////////////////////////////////////////////////////////////////////
475/// Add a bin to this histogram with the specified bin contents
476/// and error. The bin width is used to set the relative scale of
477/// bins with different widths.
478
479void RooHist::addBinWithXYError(Axis_t binCenter, double n, double exlow, double exhigh, double eylow, double eyhigh,
480 double scaleFactor)
481{
482 _entries+= n;
483
484 addPoint(binCenter, n, scaleFactor,exlow,exhigh, eylow, eyhigh);
485}
486
487
488
489
490
491////////////////////////////////////////////////////////////////////////////////
492/// Add a bin to this histogram with the value (n1-n2)/(n1+n2)
493/// using an error bar calculated with Binomial statistics.
494
495void RooHist::addAsymmetryBin(Axis_t binCenter, Int_t n1, Int_t n2, double binWidth, double xErrorFrac, double scaleFactor)
496{
497 // calculate Binomial errors for this bin
498 double ym,yp,dx(0.5*binWidth);
499 if(!RooHistError::instance().getBinomialIntervalAsym(n1,n2,ym,yp,_nSigma)) {
500 coutE(Plotting) << "RooHist::addAsymmetryBin: unable to calculate binomial error for bin with " << n1 << "," << n2 << " events" << std::endl;
501 return;
502 }
503
504 double a= (double)(n1-n2)/(n1+n2);
505 addPoint(binCenter, a, scaleFactor,dx*xErrorFrac,dx*xErrorFrac, a-ym, yp-a);
506}
507
508
509
510////////////////////////////////////////////////////////////////////////////////
511/// Add a bin to this histogram with the value (n1-n2)/(n1+n2)
512/// using an error bar calculated with Binomial statistics.
513
514void RooHist::addAsymmetryBinWithError(Axis_t binCenter, double n1, double n2, double en1, double en2, double binWidth, double xErrorFrac, double scaleFactor)
515{
516 // calculate Binomial errors for this bin
517 double ym,yp,dx(0.5*binWidth);
518 double a= (double)(n1-n2)/(n1+n2);
519
520 double error = 2*sqrt( pow(en1,2)*pow(n2,2) + pow(en2,2)*pow(n1,2) ) / pow(n1+n2,2) ;
521 ym=a-error ;
522 yp=a+error ;
523
524 addPoint(binCenter,a, scaleFactor, dx*xErrorFrac,dx*xErrorFrac, a-ym, yp-a);
525}
526
527
528
529////////////////////////////////////////////////////////////////////////////////
530/// Add a bin to this histogram with the value n1/(n1+n2)
531/// using an error bar calculated with Binomial statistics.
532
533void RooHist::addEfficiencyBin(Axis_t binCenter, Int_t n1, Int_t n2, double binWidth, double xErrorFrac, double scaleFactor)
534{
535 double a= (double)(n1)/(n1+n2);
536
537 // calculate Binomial errors for this bin
538 double ym,yp,dx(0.5*binWidth);
539 if(!RooHistError::instance().getBinomialIntervalEff(n1,n2,ym,yp,_nSigma)) {
540 coutE(Plotting) << "RooHist::addEfficiencyBin: unable to calculate binomial error for bin with " << n1 << "," << n2 << " events" << std::endl;
541 return;
542 }
543
544 addPoint(binCenter,a, scaleFactor,dx*xErrorFrac,dx*xErrorFrac, a-ym, yp-a);
545}
546
547
548
549////////////////////////////////////////////////////////////////////////////////
550/// Add a bin to this histogram with the value n1/(n1+n2)
551/// using an error bar calculated with Binomial statistics.
552
553void RooHist::addEfficiencyBinWithError(Axis_t binCenter, double n1, double n2, double en1, double en2, double binWidth, double xErrorFrac, double scaleFactor)
554{
555 double a= (double)(n1)/(n1+n2);
556
557 double error = sqrt( pow(en1,2)*pow(n2,2) + pow(en2,2)*pow(n1,2) ) / pow(n1+n2,2) ;
558
559 // calculate Binomial errors for this bin
560 double ym,yp,dx(0.5*binWidth);
561 ym=a-error ;
562 yp=a+error ;
563
564
565 addPoint(binCenter,a, scaleFactor,dx*xErrorFrac,dx*xErrorFrac, a-ym, yp-a);
566}
567
568
569////////////////////////////////////////////////////////////////////////////////
570/// Return true if binning of this RooHist is identical to that of 'other'
571
572bool RooHist::hasIdenticalBinning(const RooHist& other) const
573{
574 // First check if number of bins is the same
575 if (GetN() != other.GetN()) {
576 return false ;
577 }
578
579 // Next require that all bin centers are the same
580 Int_t i ;
581 for (i=0 ; i<GetN() ; i++) {
582 double x1,x2,y1,y2 ;
583
584 GetPoint(i,x1,y1) ;
585 other.GetPoint(i,x2,y2) ;
586
587 if (std::abs(x1-x2) > 1e-10 * _nominalBinWidth) {
588 return false ;
589 }
590
591 }
592
593 return true ;
594}
595
596
597
598////////////////////////////////////////////////////////////////////////////////
599/// Return true if contents of this RooHist is identical within given
600/// relative tolerance to that of 'other'
601
602bool RooHist::isIdentical(const RooHist& other, double tol, bool verbose) const
603{
604 // Make temporary TH1s output of RooHists to perform Kolmogorov test
605 TH1::AddDirectory(false) ;
606 TH1F h_self("h_self","h_self",GetN(),0,1) ;
607 TH1F h_other("h_other","h_other",GetN(),0,1) ;
608 TH1::AddDirectory(true) ;
609
610 for (Int_t i=0 ; i<GetN() ; i++) {
611 h_self.SetBinContent(i+1,GetY()[i]) ;
612 h_other.SetBinContent(i+1,other.GetY()[i]) ;
613 }
614
615 double M = h_self.KolmogorovTest(&h_other,"M") ;
616 if (M>tol) {
617 double kprob = h_self.KolmogorovTest(&h_other) ;
618 if(verbose) std::cout << "RooHist::isIdentical() tolerance exceeded M=" << M << " (tol=" << tol << "), corresponding prob = " << kprob << std::endl ;
619 return false ;
620 }
621
622 return true ;
623}
624
625
626
627////////////////////////////////////////////////////////////////////////////////
628/// Print info about this histogram to the specified output stream.
629///
630/// Standard: number of entries
631/// Shape: error CL and maximum value
632/// Verbose: print our bin contents and errors
633
634void RooHist::printMultiline(std::ostream& os, Int_t contents, bool verbose, TString indent) const
635{
636 RooPlotable::printMultiline(os,contents,verbose,indent);
637 os << indent << "--- RooHist ---" << std::endl;
638 Int_t n= GetN();
639 os << indent << " Contains " << n << " bins" << std::endl;
640 if(verbose) {
641 os << indent << " Errors calculated at" << _nSigma << "-sigma CL" << std::endl;
642 os << indent << " Bin Contents:" << std::endl;
643 for(Int_t i= 0; i < n; i++) {
644 os << indent << std::setw(3) << i << ") x= " << fX[i];
645 if(fEXhigh[i] > 0 || fEXlow[i] > 0) {
646 os << " +" << fEXhigh[i] << " -" << fEXlow[i];
647 }
648 os << " , y = " << fY[i] << " +" << fEYhigh[i] << " -" << fEYlow[i] << std::endl;
649 }
650 }
651}
652
653
654
655////////////////////////////////////////////////////////////////////////////////
656/// Print name of RooHist
657
658void RooHist::printName(std::ostream& os) const
659{
660 os << GetName() ;
661}
662
663
664
665////////////////////////////////////////////////////////////////////////////////
666/// Print title of RooHist
667
668void RooHist::printTitle(std::ostream& os) const
669{
670 os << GetTitle() ;
671}
672
673
674
675////////////////////////////////////////////////////////////////////////////////
676/// Print class name of RooHist
677
678void RooHist::printClassName(std::ostream& os) const
679{
680 os << ClassName() ;
681}
682
683
684std::unique_ptr<RooHist> RooHist::createEmptyResidHist(const RooCurve& curve, bool normalize) const
685{
686 // Copy all non-content properties from hist1
687 auto hist = std::make_unique<RooHist>(_nominalBinWidth) ;
688 const std::string name = GetName() + std::string("_") + curve.GetName();
689 const std::string title = GetTitle() + std::string(" and ") + curve.GetTitle();
690 hist->SetName(((normalize ? "pull_" : "resid_") + name).c_str()) ;
691 hist->SetTitle(((normalize ? "Pull of " : "Residual of ") + title).c_str()) ;
692
693 return hist;
694}
695
696
697void RooHist::fillResidHist(RooHist & residHist, const RooCurve& curve,bool normalize, bool useAverage) const
698{
699 // Determine range of curve
700 double xstart,xstop,y ;
701 curve.GetPoint(0,xstart,y) ;
702 curve.GetPoint(curve.GetN()-1,xstop,y) ;
703
704 // Add histograms, calculate Poisson confidence interval on sum value
705 for(Int_t i=0 ; i<GetN() ; i++) {
706 double x,point;
707 GetPoint(i,x,point) ;
708
709 // Only calculate pull for bins inside curve range
710 if (x<xstart || x>xstop) continue ;
711
712 double yy ;
713 if (useAverage) {
714 double exl = GetErrorXlow(i);
715 double exh = GetErrorXhigh(i) ;
716 if (exl<=0 ) exl = GetErrorX(i);
717 if (exh<=0 ) exh = GetErrorX(i);
718 if (exl<=0 ) exl = 0.5*getNominalBinWidth();
719 if (exh<=0 ) exh = 0.5*getNominalBinWidth();
720 yy = point - curve.average(x-exl,x+exh) ;
721 } else {
722 yy = point - curve.interpolate(x) ;
723 }
724
725 double dyl = GetErrorYlow(i) ;
726 double dyh = GetErrorYhigh(i) ;
727 if (normalize) {
728 double norm = (yy>0?dyl:dyh);
729 if (norm==0.) {
730 coutW(Plotting) << "RooHist::makeResisHist(" << GetName() << ") WARNING: point " << i << " has zero error, setting residual to zero" << std::endl;
731 yy=0 ;
732 dyh=0 ;
733 dyl=0 ;
734 } else {
735 yy /= norm;
736 dyh /= norm;
737 dyl /= norm;
738 }
739 }
740 residHist.addBinWithError(x,yy,dyl,dyh);
741 }
742}
743
744
745////////////////////////////////////////////////////////////////////////////////
746/// Create and return RooHist containing residuals w.r.t to given curve.
747/// If normalize is true, the residuals are normalized by the histogram
748/// errors creating a RooHist with pull values
749
750RooHist* RooHist::makeResidHist(const RooCurve& curve, bool normalize, bool useAverage) const
751{
752 RooHist* hist = createEmptyResidHist(curve, normalize).release();
753 fillResidHist(*hist, curve, normalize, useAverage);
754 return hist ;
755}
#define f(i)
Definition RSha256.hxx:104
#define a(i)
Definition RSha256.hxx:99
#define e(i)
Definition RSha256.hxx:103
#define coutW(a)
#define coutE(a)
int Int_t
Definition RtypesCore.h:45
#define ClassImp(name)
Definition Rtypes.h:377
static void indent(ostringstream &buf, int indent_level)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t SetMarkerStyle
Option_t Option_t TPoint TPoint const char y1
char name[80]
Definition TGX11.cxx:110
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2467
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
RooAbsRealLValue is the common abstract base class for objects that represent a real value that may a...
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:59
RooFit::OwningPtr< RooAbsFunc > bindVars(const RooArgSet &vars, const RooArgSet *nset=nullptr, bool clipInvalid=false) const
Create an interface adaptor f(vars) that binds us to the specified variables (in arbitrary order).
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:55
A RooCurve is a one-dimensional graphical representation of a real-valued function.
Definition RooCurve.h:36
double interpolate(double x, double tolerance=1e-10) const
Return linearly interpolated value of curve at xvalue.
Definition RooCurve.cxx:663
double average(double lo, double hi) const
Return average curve value in [xFirst,xLast] by integrating curve between points and dividing by xLas...
Definition RooCurve.cxx:577
RooFitResult is a container class to hold the input and output of a PDF fit to a dataset.
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:29
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:750
double _nominalBinWidth
Average bin width.
Definition RooHist.h:98
double _rawEntries
Number of entries in source dataset.
Definition RooHist.h:101
void printClassName(std::ostream &os) const override
Print class name of RooHist.
Definition RooHist.cxx:678
void addEfficiencyBin(Axis_t binCenter, Int_t n1, Int_t n2, double binWidth=0, double xErrorFrac=1.0, double 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:533
void fillResidHist(RooHist &residHist, const RooCurve &curve, bool normalize=false, bool useAverage=false) const
Definition RooHist.cxx:697
void initialize()
Perform common initialization for all constructors.
Definition RooHist.cxx:314
void addBinWithError(Axis_t binCenter, double n, double elow, double ehigh, double binWidth=0, double xErrorFrac=1.0, bool correctForBinWidth=true, double scaleFactor=1.0)
Add a bin to this histogram with the specified bin contents and error.
Definition RooHist.cxx:458
void addEfficiencyBinWithError(Axis_t binCenter, double n1, double n2, double en1, double en2, double binWidth=0, double xErrorFrac=1.0, double 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:553
RooHist()
Definition RooHist.h:31
void printName(std::ostream &os) const override
Print name of RooHist.
Definition RooHist.cxx:658
void printMultiline(std::ostream &os, Int_t content, bool verbose=false, TString indent="") const override
Print info about this histogram to the specified output stream.
Definition RooHist.cxx:634
std::unique_ptr< RooHist > createEmptyResidHist(const RooCurve &curve, bool normalize=false) const
Definition RooHist.cxx:684
void printTitle(std::ostream &os) const override
Print title of RooHist.
Definition RooHist.cxx:668
std::vector< double > _originalWeights
The original bin weights that were passed to the RooHist::addBin functions before scaling and bin wid...
Definition RooHist.h:103
double getNominalBinWidth() const
Definition RooHist.h:73
void addAsymmetryBinWithError(Axis_t binCenter, double n1, double n2, double en1, double en2, double binWidth=0, double xErrorFrac=1.0, double 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:514
double _entries
Number of entries in histogram.
Definition RooHist.h:100
Int_t roundBin(double y)
Return the nearest positive integer to the input value and print a warning if an adjustment is requir...
Definition RooHist.cxx:370
bool isIdentical(const RooHist &other, double tol=1e-6, bool verbose=true) const
Return true if contents of this RooHist is identical within given relative tolerance to that of 'othe...
Definition RooHist.cxx:602
void addAsymmetryBin(Axis_t binCenter, Int_t n1, Int_t n2, double binWidth=0, double xErrorFrac=1.0, double 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:495
double _nSigma
Number of 'sigmas' error bars represent.
Definition RooHist.h:99
void addBin(Axis_t binCenter, double n, double binWidth=0, double xErrorFrac=1.0, double scaleFactor=1.0)
Add a bin to this histogram with the specified integer bin contents and using an error bar calculated...
Definition RooHist.cxx:412
void addPoint(Axis_t binCenter, double y, double yscale, double exlow, double exhigh, double eylow, double eyhigh)
Definition RooHist.cxx:384
bool hasIdenticalBinning(const RooHist &other) const
Return true if binning of this RooHist is identical to that of 'other'.
Definition RooHist.cxx:572
double getFitRangeNEvt() const override
Return the number of events of the dataset associated with this RooHist.
Definition RooHist.cxx:325
void addBinWithXYError(Axis_t binCenter, double n, double exlow, double exhigh, double eylow, double eyhigh, double scaleFactor=1.0)
Add a bin to this histogram with the specified bin contents and error.
Definition RooHist.cxx:479
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Print detailed information.
void updateYAxisLimits(double y)
Definition RooPlotable.h:30
void setYAxisLabel(const char *label)
Definition RooPlotable.h:29
const char * getYAxisLabel() const
Definition RooPlotable.h:28
A RooProduct represents the product of a given set of RooAbsReal objects.
Definition RooProduct.h:29
Class to manage histogram axis.
Definition TAxis.h:31
Double_t GetXmax() const
Definition TAxis.h:140
Double_t GetXmin() const
Definition TAxis.h:139
Int_t GetNbins() const
Definition TAxis.h:125
TGraph with asymmetric error bars.
Double_t * fEXhigh
[fNpoints] array of X high errors
Double_t GetErrorY(Int_t bin) const override
Returns the combined error along Y at point i by computing the average of the lower and upper varianc...
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 GetErrorXhigh(Int_t i) const override
Get high error on X.
Double_t * fEYhigh
[fNpoints] array of Y high errors
Double_t GetErrorYhigh(Int_t i) const override
Get high error on Y.
Double_t GetErrorXlow(Int_t i) const override
Get low error on X.
Double_t * fEYlow
[fNpoints] array of Y low errors
Double_t * fEXlow
[fNpoints] array of X low errors
Double_t GetErrorYlow(Int_t i) const override
Get low error on Y.
Double_t GetErrorX(Int_t bin) const override
Returns the combined error along X at point i by computing the average of the lower and upper varianc...
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Set x and y values for point number i.
Definition TGraph.cxx:2315
Double_t * GetY() const
Definition TGraph.h:138
Int_t GetN() const
Definition TGraph.h:130
Double_t * fY
[fNpoints] array of Y points
Definition TGraph.h:48
void SetName(const char *name="") override
Set graph name.
Definition TGraph.cxx:2354
Double_t * fX
[fNpoints] array of X points
Definition TGraph.h:47
void SetTitle(const char *title="") override
Change (i.e.
Definition TGraph.cxx:2370
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:1507
1-D histogram with a float per channel (see TH1 documentation)}
Definition TH1.h:577
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:58
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition TH1.cxx:9058
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition TH1.cxx:8980
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition TH1.cxx:1267
TAxis * GetXaxis()
Definition TH1.h:322
virtual Int_t GetNbinsX() const
Definition TH1.h:295
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:9139
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:5032
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition TH1.cxx:9080
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:8095
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:48
TString fName
Definition TNamed.h:32
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:207
Basic string class.
Definition TString.h:139
RooConstVar & RooConst(double val)
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2345