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