RooHist.cxx

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Project: RooFit                                                           *
00003  * Package: RooFitCore                                                       *
00004  * @(#)root/roofitcore:$Id: RooHist.cxx 36207 2010-10-08 19:00:29Z wouter $
00005  * Authors:                                                                  *
00006  *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
00007  *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
00008  *                                                                           *
00009  * Copyright (c) 2000-2005, Regents of the University of California          *
00010  *                          and Stanford University. All rights reserved.    *
00011  *                                                                           *
00012  * Redistribution and use in source and binary forms,                        *
00013  * with or without modification, are permitted according to the terms        *
00014  * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
00015  *****************************************************************************/
00016 
00017 //////////////////////////////////////////////////////////////////////////////
00018 //
00019 // BEGIN_HTML
00020 // A RooHist is a graphical representation of binned data based on the
00021 // TGraphAsymmErrors class. Error bars are calculated using either Poisson
00022 // or Binomial statistics. A RooHist is used to represent histograms in
00023 // a RooPlot.
00024 // END_HTML
00025 //
00026 
00027 #include "RooFit.h"
00028 
00029 #include "RooHist.h"
00030 #include "RooHist.h"
00031 #include "RooHistError.h"
00032 #include "RooCurve.h"
00033 #include "RooMsgService.h"
00034 
00035 #include "TH1.h"
00036 #include "TClass.h"
00037 #include "Riostream.h"
00038 #include <iomanip>
00039 #include <math.h>
00040 
00041 ClassImp(RooHist)
00042   ;
00043 
00044 
00045 //_____________________________________________________________________________
00046 RooHist::RooHist() :
00047   _nominalBinWidth(1),
00048   _nSigma(1),
00049   _entries(0),
00050   _rawEntries(0)
00051 {
00052   // Default constructor
00053 }
00054 
00055 
00056 
00057 //_____________________________________________________________________________
00058   RooHist::RooHist(Double_t nominalBinWidth, Double_t nSigma, Double_t /*xErrorFrac*/, Double_t /*scaleFactor*/) :
00059     TGraphAsymmErrors(), _nominalBinWidth(nominalBinWidth), _nSigma(nSigma), _rawEntries(-1)
00060 {
00061   // Create an empty histogram that can be filled with the addBin()
00062   // and addAsymmetryBin() methods. Use the optional parameter to
00063   // specify the confidence level in units of sigma to use for
00064   // calculating error bars. The nominal bin width specifies the
00065   // default used by addBin(), and is used to set the relative
00066   // normalization of bins with different widths.
00067 
00068   initialize();
00069 }
00070 
00071 
00072 //_____________________________________________________________________________
00073 RooHist::RooHist(const TH1 &data, Double_t nominalBinWidth, Double_t nSigma, RooAbsData::ErrorType etype, Double_t xErrorFrac, 
00074                  Bool_t correctForBinWidth, Double_t scaleFactor) :
00075   TGraphAsymmErrors(), _nominalBinWidth(nominalBinWidth), _nSigma(nSigma), _rawEntries(-1)
00076 {
00077   // Create a histogram from the contents of the specified TH1 object
00078   // which may have fixed or variable bin widths. Error bars are
00079   // calculated using Poisson statistics. Prints a warning and rounds
00080   // any bins with non-integer contents. Use the optional parameter to
00081   // specify the confidence level in units of sigma to use for
00082   // calculating error bars. The nominal bin width specifies the
00083   // default used by addBin(), and is used to set the relative
00084   // normalization of bins with different widths. If not set, the
00085   // nominal bin width is calculated as range/nbins.
00086 
00087   initialize();
00088   // copy the input histogram's name and title
00089   SetName(data.GetName());
00090   SetTitle(data.GetTitle());
00091   // calculate our nominal bin width if necessary
00092   if(_nominalBinWidth == 0) {
00093     const TAxis *axis= ((TH1&)data).GetXaxis();
00094     if(axis->GetNbins() > 0) _nominalBinWidth= (axis->GetXmax() - axis->GetXmin())/axis->GetNbins();
00095   }
00096   // TH1::GetYaxis() is not const (why!?)
00097   setYAxisLabel(const_cast<TH1&>(data).GetYaxis()->GetTitle());
00098   
00099   // initialize our contents from the input histogram's contents
00100   Int_t nbin= data.GetNbinsX();
00101   for(Int_t bin= 1; bin <= nbin; bin++) {
00102     Axis_t x= data.GetBinCenter(bin);
00103     Stat_t y= data.GetBinContent(bin);
00104     Stat_t dy = data.GetBinError(bin) ;
00105     if (etype==RooAbsData::Poisson) {
00106       addBin(x,y,data.GetBinWidth(bin),xErrorFrac,scaleFactor);
00107     } else if (etype==RooAbsData::SumW2) {
00108       addBinWithError(x,y,dy,dy,data.GetBinWidth(bin),xErrorFrac,correctForBinWidth,scaleFactor);
00109     } else {
00110       addBinWithError(x,y,0,0,data.GetBinWidth(bin),xErrorFrac,correctForBinWidth,scaleFactor);
00111     }
00112   }
00113   // add over/underflow bins to our event count
00114   _entries+= data.GetBinContent(0) + data.GetBinContent(nbin+1);
00115 }
00116 
00117 
00118 
00119 //_____________________________________________________________________________
00120 RooHist::RooHist(const TH1 &data1, const TH1 &data2, Double_t nominalBinWidth, Double_t nSigma, 
00121                  RooAbsData::ErrorType etype, Double_t xErrorFrac, Bool_t efficiency, Double_t scaleFactor) :
00122   TGraphAsymmErrors(), _nominalBinWidth(nominalBinWidth), _nSigma(nSigma), _rawEntries(-1)
00123 {
00124   // Create a histogram from the asymmetry between the specified TH1 objects
00125   // which may have fixed or variable bin widths, but which must both have
00126   // the same binning. The asymmetry is calculated as (1-2)/(1+2). Error bars are
00127   // calculated using Binomial statistics. Prints a warning and rounds
00128   // any bins with non-integer contents. Use the optional parameter to
00129   // specify the confidence level in units of sigma to use for
00130   // calculating error bars. The nominal bin width specifies the
00131   // default used by addAsymmetryBin(), and is used to set the relative
00132   // normalization of bins with different widths. If not set, the
00133   // nominal bin width is calculated as range/nbins.
00134 
00135   initialize();
00136   // copy the first input histogram's name and title
00137   SetName(data1.GetName());
00138   SetTitle(data1.GetTitle());
00139   // calculate our nominal bin width if necessary
00140   if(_nominalBinWidth == 0) {
00141     const TAxis *axis= ((TH1&)data1).GetXaxis();
00142     if(axis->GetNbins() > 0) _nominalBinWidth= (axis->GetXmax() - axis->GetXmin())/axis->GetNbins();
00143   }
00144 
00145   if (!efficiency) {
00146     setYAxisLabel(Form("Asymmetry (%s - %s)/(%s + %s)",
00147                      data1.GetName(),data2.GetName(),data1.GetName(),data2.GetName()));
00148   } else {
00149     setYAxisLabel(Form("Efficiency (%s)/(%s + %s)",
00150                      data1.GetName(),data1.GetName(),data2.GetName()));
00151   }
00152   // initialize our contents from the input histogram contents
00153   Int_t nbin= data1.GetNbinsX();
00154   if(data2.GetNbinsX() != nbin) {
00155     coutE(InputArguments) << "RooHist::RooHist: histograms have different number of bins" << endl;
00156     return;
00157   }
00158   for(Int_t bin= 1; bin <= nbin; bin++) {
00159     Axis_t x= data1.GetBinCenter(bin);
00160     if(fabs(data2.GetBinCenter(bin)-x)>1e-10) {
00161       coutW(InputArguments) << "RooHist::RooHist: histograms have different centers for bin " << bin << endl;
00162     }
00163     Stat_t y1= data1.GetBinContent(bin);
00164     Stat_t y2= data2.GetBinContent(bin);
00165     if (!efficiency) {
00166 
00167       if (etype==RooAbsData::Poisson) {
00168         addAsymmetryBin(x,roundBin(y1),roundBin(y2),data1.GetBinWidth(bin),xErrorFrac,scaleFactor);
00169       } else if (etype==RooAbsData::SumW2) {    
00170         Stat_t dy1= data1.GetBinError(bin);
00171         Stat_t dy2= data2.GetBinError(bin);
00172         addAsymmetryBinWithError(x,y1,y2,dy1,dy2,data1.GetBinWidth(bin),xErrorFrac,scaleFactor);
00173       } else {
00174         addAsymmetryBinWithError(x,y1,y2,0,0,data1.GetBinWidth(bin),xErrorFrac,scaleFactor);
00175       }
00176 
00177     } else {
00178 
00179       if (etype==RooAbsData::Poisson) {
00180         addEfficiencyBin(x,roundBin(y1),roundBin(y2),data1.GetBinWidth(bin),xErrorFrac,scaleFactor);
00181       } else if (etype==RooAbsData::SumW2) {
00182         Stat_t dy1= data1.GetBinError(bin);
00183         Stat_t dy2= data2.GetBinError(bin);
00184         addEfficiencyBinWithError(x,y1,y2,dy1,dy2,data1.GetBinWidth(bin),xErrorFrac,scaleFactor);
00185       } else {
00186         addEfficiencyBinWithError(x,y1,y2,0,0,data1.GetBinWidth(bin),xErrorFrac,scaleFactor);
00187       }
00188 
00189     }
00190 
00191   }
00192   // we do not have a meaningful number of entries
00193   _entries= -1;
00194 }
00195 
00196 
00197 
00198 //_____________________________________________________________________________
00199 RooHist::RooHist(const RooHist& hist1, const RooHist& hist2, Double_t wgt1, Double_t wgt2, 
00200                  RooAbsData::ErrorType etype, Double_t xErrorFrac) : _rawEntries(-1)
00201 {
00202   // Create histogram as sum of two existing histograms. If Poisson errors are selected the histograms are
00203   // added and Poisson confidence intervals are calculated for the summed content. If wgt1 and wgt2 are not
00204   // 1 in this mode, a warning message is printed. If SumW2 errors are selectd the histograms are added
00205   // and the histograms errors are added in quadrature, taking the weights into account.
00206 
00207   // Initialize the histogram
00208   initialize() ;
00209      
00210   // Copy all non-content properties from hist1
00211   SetName(hist1.GetName()) ;
00212   SetTitle(hist1.GetTitle()) ;  
00213   _nominalBinWidth=hist1._nominalBinWidth ;
00214   _nSigma=hist1._nSigma ;
00215   setYAxisLabel(hist1.getYAxisLabel()) ;
00216 
00217   if (!hist1.hasIdenticalBinning(hist2)) {
00218     coutE(InputArguments) << "RooHist::RooHist input histograms have incompatible binning, combined histogram will remain empty" << endl ;
00219     return ;
00220   }
00221 
00222   if (etype==RooAbsData::Poisson) {
00223     // Add histograms with Poisson errors
00224 
00225     // Issue warning if weights are not 1
00226     if (wgt1!=1.0 || wgt2 != 1.0) {
00227       coutW(InputArguments) << "RooHist::RooHist: WARNING: Poisson errors of weighted sum of two histograms is not well defined! " << endl
00228                             << "                  Summed histogram bins will rounded to nearest integer for Poisson confidence interval calculation" << endl ;
00229     }
00230 
00231     // Add histograms, calculate Poisson confidence interval on sum value
00232     Int_t i,n=hist1.GetN() ;
00233     for(i=0 ; i<n ; i++) {
00234       Double_t x1,y1,x2,y2,dx1 ;
00235 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
00236       hist1.GetPoint(i,x1,y1) ;
00237 #else
00238       const_cast<RooHist&>(hist1).GetPoint(i,x1,y1) ;
00239 #endif
00240       dx1 = hist1.GetErrorX(i) ;
00241 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
00242       hist2.GetPoint(i,x2,y2) ;
00243 #else
00244       const_cast<RooHist&>(hist2).GetPoint(i,x2,y2) ;
00245 #endif
00246       addBin(x1,roundBin(wgt1*y1+wgt2*y2),2*dx1/xErrorFrac,xErrorFrac) ;
00247     }    
00248 
00249   } else {
00250     // Add histograms with SumW2 errors
00251 
00252     // Add histograms, calculate combined sum-of-weights error
00253     Int_t i,n=hist1.GetN() ;
00254     for(i=0 ; i<n ; i++) {
00255       Double_t x1,y1,x2,y2,dx1,dy1,dy2 ;
00256 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
00257       hist1.GetPoint(i,x1,y1) ;
00258 #else
00259       const_cast<RooHist&>(hist1).GetPoint(i,x1,y1) ;
00260 #endif
00261       dx1 = hist1.GetErrorX(i) ;
00262       dy1 = hist1.GetErrorY(i) ;
00263       dy2 = hist2.GetErrorY(i) ;
00264 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
00265       hist2.GetPoint(i,x2,y2) ;
00266 #else
00267       const_cast<RooHist&>(hist2).GetPoint(i,x2,y2) ;
00268 #endif
00269       Double_t dy = sqrt(wgt1*wgt1*dy1*dy1+wgt2*wgt2*dy2*dy2) ;
00270       addBinWithError(x1,wgt1*y1+wgt2*y2,dy,dy,2*dx1/xErrorFrac,xErrorFrac) ;
00271     }       
00272   }
00273 
00274 }
00275 
00276 
00277 //_____________________________________________________________________________
00278 void RooHist::initialize() 
00279 {
00280   // Perform common initialization for all constructors.
00281 
00282   SetMarkerStyle(8);
00283   _entries= 0;
00284 }
00285 
00286 
00287 //_____________________________________________________________________________
00288 Double_t RooHist::getFitRangeNEvt() const 
00289 {
00290   // Return the number of events of the dataset associated with this RooHist.
00291   // This is the number of events in the RooHist itself, unless a different
00292   // value was specified through setRawEntries()
00293 
00294   return (_rawEntries==-1 ? _entries : _rawEntries) ;
00295 }
00296 
00297 
00298 //_____________________________________________________________________________
00299 Double_t RooHist::getFitRangeNEvt(Double_t xlo, Double_t xhi) const 
00300 {
00301   // Calculate integral of histogram in given range 
00302 
00303   Double_t sum(0) ;
00304   for (int i=0 ; i<GetN() ; i++) {
00305     Double_t x,y ;
00306 
00307 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
00308     GetPoint(i,x,y) ;
00309 #else
00310     const_cast<RooHist*>(this)->GetPoint(i,x,y) ;
00311 #endif
00312 
00313     if (x>=xlo && x<=xhi) {
00314       sum += y ;
00315     }
00316   }
00317   
00318   if (_rawEntries!=-1) {
00319     coutW(Plotting) << "RooHist::getFitRangeNEvt() WARNING: Number of normalization events associated to histogram is not equal to number of events in histogram" << endl
00320                     << "                           due cut made in RooAbsData::plotOn() call. Automatic normalization over sub-range of plot variable assumes"    << endl
00321                     << "                           that the effect of that cut is uniform across the plot, which may be an incorrect assumption. To be sure of"   << endl 
00322                     << "                           correct normalization explicit pass normalization information to RooAbsPdf::plotOn() call using Normalization()" << endl ;
00323     sum *= _rawEntries / _entries ;
00324   }
00325 
00326   return sum ;
00327 }
00328 
00329 
00330 
00331 //_____________________________________________________________________________
00332 Double_t RooHist::getFitRangeBinW() const 
00333 {
00334   // Return (average) bin width of this RooHist
00335   return _nominalBinWidth ;
00336 }
00337 
00338 
00339 
00340 //_____________________________________________________________________________
00341 Int_t RooHist::roundBin(Double_t y) 
00342 {
00343   // Return the nearest positive integer to the input value
00344   // and print a warning if an adjustment is required.
00345 
00346   if(y < 0) {
00347     coutW(Plotting) << fName << "::roundBin: rounding negative bin contents to zero: " << y << endl;
00348     return 0;
00349   }
00350   Int_t n= (Int_t)(y+0.5);
00351   if(fabs(y-n)>1e-6) {
00352     coutW(Plotting) << fName << "::roundBin: rounding non-integer bin contents: " << y << endl;
00353   }
00354   return n;
00355 }
00356 
00357 
00358 
00359 //_____________________________________________________________________________
00360 void RooHist::addBin(Axis_t binCenter, Double_t n, Double_t binWidth, Double_t xErrorFrac, Double_t scaleFactor) 
00361 {
00362   // Add a bin to this histogram with the specified integer bin contents
00363   // and using an error bar calculated with Poisson statistics. The bin width
00364   // is used to set the relative scale of bins with different widths.
00365 
00366   if (n<0) {
00367     coutW(Plotting) << "RooHist::addBin(" << GetName() << ") WARNING: negative entry set to zero when Poisson error bars are requested" << endl ;
00368   }
00369   
00370   Double_t scale= 1;
00371   if(binWidth > 0) {
00372     scale= _nominalBinWidth/binWidth;
00373   }  
00374   _entries+= n;
00375   Int_t index= GetN();
00376   
00377   // calculate Poisson errors for this bin
00378   Double_t ym,yp,dx(0.5*binWidth);
00379 
00380   if (fabs((double)((n-Int_t(n))>1e-5))) {
00381     // need interpolation
00382     Double_t ym1(0),yp1(0),ym2(0),yp2(0) ;
00383     Int_t n1 = Int_t(n) ;
00384     Int_t n2 = n1+1 ;
00385     if(!RooHistError::instance().getPoissonInterval(n1,ym1,yp1,_nSigma) ||
00386        !RooHistError::instance().getPoissonInterval(n2,ym2,yp2,_nSigma)) {
00387       coutE(Plotting) << "RooHist::addBin: unable to add bin with " << n << " events" << endl;
00388     }
00389     ym = ym1 + (n-n1)*(ym2-ym1) ;
00390     yp = yp1 + (n-n1)*(yp2-yp1) ;
00391     coutW(Plotting) << "RooHist::addBin(" << GetName() 
00392                     << ") WARNING: non-integer bin entry " << n << " with Poisson errors, interpolating between Poisson errors of adjacent integer" << endl ;
00393   } else {
00394   // integer case
00395   if(!RooHistError::instance().getPoissonInterval(Int_t(n),ym,yp,_nSigma)) {
00396       coutE(Plotting) << "RooHist::addBin: unable to add bin with " << n << " events" << endl;
00397       return;
00398     }
00399   }
00400 
00401   SetPoint(index,binCenter,n*scale*scaleFactor);
00402   SetPointError(index,dx*xErrorFrac,dx*xErrorFrac,scale*(n-ym)*scaleFactor,scale*(yp-n)*scaleFactor);
00403   updateYAxisLimits(scale*yp);
00404   updateYAxisLimits(scale*ym);
00405 }
00406 
00407 
00408 
00409 //_____________________________________________________________________________
00410 void RooHist::addBinWithError(Axis_t binCenter, Double_t n, Double_t elow, Double_t ehigh, Double_t binWidth, 
00411                               Double_t xErrorFrac, Bool_t correctForBinWidth, Double_t scaleFactor) 
00412 {
00413   // Add a bin to this histogram with the specified bin contents
00414   // and error. The bin width is used to set the relative scale of 
00415   // bins with different widths.
00416 
00417   Double_t scale= 1;
00418   if(binWidth > 0 && correctForBinWidth) {
00419     scale= _nominalBinWidth/binWidth;
00420   }  
00421   _entries+= n;
00422   Int_t index= GetN();
00423 
00424   Double_t dx(0.5*binWidth) ;
00425   SetPoint(index,binCenter,n*scale*scaleFactor);
00426   SetPointError(index,dx*xErrorFrac,dx*xErrorFrac,elow*scale*scaleFactor,ehigh*scale*scaleFactor);
00427   updateYAxisLimits(scale*(n-elow));
00428   updateYAxisLimits(scale*(n+ehigh));
00429 }
00430 
00431 
00432 
00433 
00434 //_____________________________________________________________________________
00435 void RooHist::addBinWithXYError(Axis_t binCenter, Double_t n, Double_t exlow, Double_t exhigh, Double_t eylow, Double_t eyhigh, 
00436                                 Double_t scaleFactor)
00437 {
00438   // Add a bin to this histogram with the specified bin contents
00439   // and error. The bin width is used to set the relative scale of 
00440   // bins with different widths.
00441 
00442   _entries+= n;
00443   Int_t index= GetN();
00444 
00445   SetPoint(index,binCenter,n*scaleFactor);
00446   SetPointError(index,exlow,exhigh,eylow*scaleFactor,eyhigh*scaleFactor);
00447   updateYAxisLimits(scaleFactor*(n-eylow));
00448   updateYAxisLimits(scaleFactor*(n+eyhigh));
00449 }
00450 
00451 
00452 
00453 
00454 
00455 //_____________________________________________________________________________
00456 void RooHist::addAsymmetryBin(Axis_t binCenter, Int_t n1, Int_t n2, Double_t binWidth, Double_t xErrorFrac, Double_t scaleFactor) 
00457 {
00458   // Add a bin to this histogram with the value (n1-n2)/(n1+n2)
00459   // using an error bar calculated with Binomial statistics.
00460   
00461   Double_t scale= 1;
00462   if(binWidth > 0) scale= _nominalBinWidth/binWidth;
00463   Int_t index= GetN();
00464 
00465   // calculate Binomial errors for this bin
00466   Double_t ym,yp,dx(0.5*binWidth);
00467   if(!RooHistError::instance().getBinomialIntervalAsym(n1,n2,ym,yp,_nSigma)) {
00468     coutE(Plotting) << "RooHist::addAsymmetryBin: unable to calculate binomial error for bin with " << n1 << "," << n2 << " events" << endl;
00469     return;
00470   }
00471 
00472   Double_t a= (Double_t)(n1-n2)/(n1+n2);
00473   SetPoint(index,binCenter,a*scaleFactor);
00474   SetPointError(index,dx*xErrorFrac,dx*xErrorFrac,(a-ym)*scaleFactor,(yp-a)*scaleFactor);
00475   updateYAxisLimits(scale*yp);
00476   updateYAxisLimits(scale*ym);
00477 }
00478 
00479 
00480 
00481 //_____________________________________________________________________________
00482 void RooHist::addAsymmetryBinWithError(Axis_t binCenter, Double_t n1, Double_t n2, Double_t en1, Double_t en2, Double_t binWidth, Double_t xErrorFrac, Double_t scaleFactor) 
00483 {
00484   // Add a bin to this histogram with the value (n1-n2)/(n1+n2)
00485   // using an error bar calculated with Binomial statistics.
00486   
00487   Double_t scale= 1;
00488   if(binWidth > 0) scale= _nominalBinWidth/binWidth;
00489   Int_t index= GetN();
00490 
00491   // calculate Binomial errors for this bin
00492   Double_t ym,yp,dx(0.5*binWidth);
00493   Double_t a= (Double_t)(n1-n2)/(n1+n2);
00494 
00495   Double_t error = 2*sqrt( pow(en1,2)*pow(n2,2) + pow(en2,2)*pow(n1,2) ) / pow(n1+n2,2) ;
00496   ym=a-error ;
00497   yp=a+error ;
00498 
00499   SetPoint(index,binCenter,a*scaleFactor);
00500   SetPointError(index,dx*xErrorFrac,dx*xErrorFrac,(a-ym)*scaleFactor,(yp-a)*scaleFactor);
00501   updateYAxisLimits(scale*yp);
00502   updateYAxisLimits(scale*ym);
00503 }
00504 
00505 
00506 
00507 //_____________________________________________________________________________
00508 void RooHist::addEfficiencyBin(Axis_t binCenter, Int_t n1, Int_t n2, Double_t binWidth, Double_t xErrorFrac, Double_t scaleFactor) 
00509 {
00510   // Add a bin to this histogram with the value n1/(n1+n2)
00511   // using an error bar calculated with Binomial statistics.
00512   
00513   Double_t scale= 1;
00514   if(binWidth > 0) scale= _nominalBinWidth/binWidth;
00515   Int_t index= GetN();
00516 
00517   Double_t a= (Double_t)(n1)/(n1+n2);
00518 
00519   // calculate Binomial errors for this bin
00520   Double_t ym,yp,dx(0.5*binWidth);
00521   if(!RooHistError::instance().getBinomialIntervalEff(n1,n2,ym,yp,_nSigma)) {
00522     coutE(Plotting) << "RooHist::addEfficiencyBin: unable to calculate binomial error for bin with " << n1 << "," << n2 << " events" << endl;
00523     return;
00524   }  
00525 
00526   SetPoint(index,binCenter,a*scaleFactor);
00527   SetPointError(index,dx*xErrorFrac,dx*xErrorFrac,(a-ym)*scaleFactor,(yp-a)*scaleFactor);
00528   updateYAxisLimits(scale*yp);
00529   updateYAxisLimits(scale*ym);
00530 }
00531 
00532 
00533 
00534 //_____________________________________________________________________________
00535 void RooHist::addEfficiencyBinWithError(Axis_t binCenter, Double_t n1, Double_t n2, Double_t en1, Double_t en2, Double_t binWidth, Double_t xErrorFrac, Double_t scaleFactor) 
00536 {
00537   // Add a bin to this histogram with the value n1/(n1+n2)
00538   // using an error bar calculated with Binomial statistics.
00539   
00540   Double_t scale= 1;
00541   if(binWidth > 0) scale= _nominalBinWidth/binWidth;
00542   Int_t index= GetN();
00543 
00544   Double_t a= (Double_t)(n1)/(n1+n2);
00545 
00546   Double_t error = sqrt( pow(en1,2)*pow(n2,2) + pow(en2,2)*pow(n1,2) ) / pow(n1+n2,2) ;
00547 
00548   // calculate Binomial errors for this bin
00549   Double_t ym,yp,dx(0.5*binWidth);
00550   ym=a-error ;
00551   yp=a+error ;
00552  
00553   
00554   SetPoint(index,binCenter,a*scaleFactor);
00555   SetPointError(index,dx*xErrorFrac,dx*xErrorFrac,(a-ym)*scaleFactor,(yp-a)*scaleFactor);
00556   updateYAxisLimits(scale*yp);
00557   updateYAxisLimits(scale*ym);
00558 }
00559 
00560 
00561 
00562 //_____________________________________________________________________________
00563 RooHist::~RooHist() 
00564 { 
00565   // Destructor
00566 }
00567 
00568 
00569 
00570 //_____________________________________________________________________________
00571 Bool_t RooHist::hasIdenticalBinning(const RooHist& other) const 
00572 {
00573   // Return kTRUE if binning of this RooHist is identical to that of 'other'
00574 
00575   // First check if number of bins is the same
00576   if (GetN() != other.GetN()) {
00577     return kFALSE ;
00578   }
00579 
00580   // Next require that all bin centers are the same
00581   Int_t i ;
00582   for (i=0 ; i<GetN() ; i++) {
00583     Double_t x1,x2,y1,y2 ;
00584     
00585 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
00586     GetPoint(i,x1,y1) ;
00587     other.GetPoint(i,x2,y2) ;
00588 #else
00589     const_cast<RooHist&>(*this).GetPoint(i,x1,y1) ;
00590     const_cast<RooHist&>(other).GetPoint(i,x2,y2) ;
00591 #endif
00592 
00593     if (fabs(x1-x2)>1e-10) {
00594       return kFALSE ;
00595     }
00596 
00597   }
00598 
00599   return kTRUE ;
00600 }
00601 
00602 
00603 
00604 //_____________________________________________________________________________
00605 Bool_t RooHist::isIdentical(const RooHist& other, Double_t tol) const 
00606 {
00607   // Return kTRUE if contents of this RooHIst is identical within given
00608   // relative tolerance to that of 'other'
00609 
00610   // Make temporary TH1s output of RooHists to perform kolmogorov test
00611   TH1::AddDirectory(kFALSE) ;
00612   TH1F h_self("h_self","h_self",GetN(),0,1) ;
00613   TH1F h_other("h_other","h_other",GetN(),0,1) ;
00614   TH1::AddDirectory(kTRUE) ;
00615 
00616   for (Int_t i=0 ; i<GetN() ; i++) {
00617     h_self.SetBinContent(i+1,GetY()[i]) ;
00618     h_other.SetBinContent(i+1,other.GetY()[i]) ;
00619   }  
00620 
00621   Double_t M = h_self.KolmogorovTest(&h_other,"M") ;
00622   if (M>tol) {
00623     Double_t kprob = h_self.KolmogorovTest(&h_other) ;
00624     cout << "RooHist::isIdentical() tolerance exceeded M=" << M << " (tol=" << tol << "), corresponding prob = " << kprob << endl ;
00625     return kFALSE ;
00626   }
00627 
00628   return kTRUE ;
00629 }
00630 
00631 
00632 
00633 //_____________________________________________________________________________
00634 void RooHist::printMultiline(ostream& os, Int_t contents, Bool_t verbose, TString indent) const 
00635 {
00636   // Print info about this histogram to the specified output stream.
00637   //
00638   //   Standard: number of entries
00639   //      Shape: error CL and maximum value
00640   //    Verbose: print our bin contents and errors
00641   
00642   RooPlotable::printMultiline(os,contents,verbose,indent);
00643   os << indent << "--- RooHist ---" << endl;
00644   Int_t n= GetN();
00645   os << indent << "  Contains " << n << " bins" << endl;
00646   if(verbose) {
00647     os << indent << "  Errors calculated at" << _nSigma << "-sigma CL" << endl;
00648     os << indent << "  Bin Contents:" << endl;
00649     for(Int_t i= 0; i < n; i++) {
00650       os << indent << setw(3) << i << ") x= " <<  fX[i];
00651       if(fEXhigh[i] > 0 || fEXlow[i] > 0) {
00652         os << " +" << fEXhigh[i] << " -" << fEXlow[i];
00653       }
00654       os << " , y = " << fY[i] << " +" << fEYhigh[i] << " -" << fEYlow[i] << endl;
00655     }
00656   }
00657 }
00658 
00659 
00660 
00661 //_____________________________________________________________________________
00662 void RooHist::printName(ostream& os) const 
00663 {
00664   // Print name of RooHist
00665 
00666   os << GetName() ;
00667 }
00668 
00669 
00670 
00671 //_____________________________________________________________________________
00672 void RooHist::printTitle(ostream& os) const 
00673 {
00674   // Print title of RooHist
00675 
00676   os << GetTitle() ;
00677 }
00678 
00679 
00680 
00681 //_____________________________________________________________________________
00682 void RooHist::printClassName(ostream& os) const 
00683 {
00684   // Print class name of RooHist
00685 
00686   os << IsA()->GetName() ;
00687 }
00688 
00689 
00690 
00691 //_____________________________________________________________________________
00692 RooHist* RooHist::makeResidHist(const RooCurve& curve,bool normalize) const 
00693 {
00694   // Create and return RooHist containing  residuals w.r.t to given curve.
00695   // If normalize is true, the residuals are normalized by the histogram
00696   // errors creating a RooHist with pull values
00697 
00698 
00699   // Copy all non-content properties from hist1
00700   RooHist* hist = new RooHist(_nominalBinWidth) ;
00701   if (normalize) {
00702     hist->SetName(Form("pull_%s_%s",GetName(),curve.GetName())) ;
00703     hist->SetTitle(Form("Pull of %s and %s",GetTitle(),curve.GetTitle())) ;  
00704   } else {
00705     hist->SetName(Form("resid_%s_%s",GetName(),curve.GetName())) ;
00706     hist->SetTitle(Form("Residual of %s and %s",GetTitle(),curve.GetTitle())) ;  
00707   }
00708 
00709   // Determine range of curve 
00710   Double_t xstart,xstop,y ;
00711 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
00712   curve.GetPoint(0,xstart,y) ;
00713   curve.GetPoint(curve.GetN()-1,xstop,y) ;
00714 #else
00715   const_cast<RooCurve&>(curve).GetPoint(0,xstart,y) ;
00716   const_cast<RooCurve&>(curve).GetPoint(curve.GetN()-1,xstop,y) ;
00717 #endif
00718   
00719   // Add histograms, calculate Poisson confidence interval on sum value
00720   for(Int_t i=0 ; i<GetN() ; i++) {    
00721     Double_t x,point;
00722 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
00723     GetPoint(i,x,point) ;
00724 #else
00725     const_cast<RooHist&>(*this).GetPoint(i,x,point) ;
00726 #endif
00727 
00728     // Only calculate pull for bins inside curve range
00729     if (x<xstart || x>xstop) continue ;
00730 
00731     Double_t yy = point - curve.interpolate(x) ;
00732     Double_t dyl = GetErrorYlow(i) ;
00733     Double_t dyh = GetErrorYhigh(i) ;
00734     if (normalize) {
00735         Double_t norm = (yy>0?dyl:dyh);
00736         if (norm==0.) {
00737           coutW(Plotting) << "RooHist::makeResisHist(" << GetName() << ") WARNING: point " << i << " has zero error, setting residual to zero" << endl ;
00738           yy=0 ;
00739           dyh=0 ;
00740           dyl=0 ;
00741         } else {
00742           yy   /= norm;
00743           dyh /= norm;
00744           dyl /= norm;
00745         }
00746     }
00747     hist->addBinWithError(x,yy,dyl,dyh);
00748   }
00749   return hist ;
00750 }

Generated on Tue Jul 5 15:06:42 2011 for ROOT_528-00b_version by  doxygen 1.5.1