void THSEventsPDF::adjustBinning(Int_t* offset1) const { RooRealVar* xvar = fx_off ; if (!dynamic_cast<RooRealVar*>(xvar)) { coutE(InputArguments) << "RooDataHist::adjustBinning(" << GetName() << ") ERROR: dimension " << xvar->GetName() << " must be real" << endl ; assert(0) ; } Double_t xlo = xvar->getMin() ; Double_t xhi = xvar->getMax() ; //adjust bin range limits with new scale parameter //cout<<scale<<" "<<fMean<<" "<<xlo<<" "<<xhi<<endl; xlo=(xlo-fMean)/scale+fMean; xhi=(xhi-fMean)/scale+fMean; if(xvar->getBinning().lowBound()==xlo&&xvar->getBinning().highBound()==xhi) return; xvar->setRange(xlo,xhi) ; // Int_t xmin(0) ; // cout<<"THSEventsPDF::adjustBinning( "<<xlo <<" "<<xhi<<endl; //now adjust fitting range to bin limits??Possibly not if (fRHist->GetXaxis()->GetXbins()->GetArray()) { RooBinning xbins(fRHist->GetNbinsX(),fRHist->GetXaxis()->GetXbins()->GetArray()) ; Double_t tolerance = 1e-6*xbins.averageBinWidth() ; // Adjust xlo/xhi to nearest boundary Double_t xloAdj = xbins.binLow(xbins.binNumber(xlo+tolerance)) ; Double_t xhiAdj = xbins.binHigh(xbins.binNumber(xhi-tolerance)) ; xbins.setRange(xloAdj,xhiAdj) ; xvar->setBinning(xbins) ; if (fabs(xloAdj-xlo)>tolerance||fabs(xhiAdj-xhi)<tolerance) { coutI(DataHandling) << "RooDataHist::adjustBinning(" << GetName() << "): fit range of variable " << xvar->GetName() << " expanded to nearest bin boundaries: [" << xlo << "," << xhi << "] --> [" << xloAdj << "," << xhiAdj << "]" << endl ; } } else { RooBinning xbins(fRHist->GetXaxis()->GetXmin(),fRHist->GetXaxis()->GetXmax()) ; xbins.addUniform(fRHist->GetNbinsX(),fRHist->GetXaxis()->GetXmin(),fRHist->GetXaxis()->GetXmax()) ; Double_t tolerance = 1e-6*xbins.averageBinWidth() ; // Adjust xlo/xhi to nearest boundary Double_t xloAdj = xbins.binLow(xbins.binNumber(xlo+tolerance)) ; Double_t xhiAdj = xbins.binHigh(xbins.binNumber(xhi-tolerance)) ; xbins.setRange(xloAdj,xhiAdj) ; xvar->setRange(xloAdj,xhiAdj) ; //xvar->setRange(xlo,xhi) ; } return; }
RooHistN::RooHistN(const TH1 &data1, const TH1 &data2, Double_t nominalBinWidth, Double_t nSigma, Double_t xErrorFrac) : TGraphAsymmErrors(), _nominalBinWidth(nominalBinWidth), _nSigma(nSigma), _rawEntries(-1) { // Create a histogram from the asymmetry between the specified TH1 objects // which may have fixed or variable bin widths, but which must both have // the same binning. The asymmetry is calculated as (1-2)/(1+2). Error bars are // calculated using Binomial statistics. Prints a warning and rounds // any bins with non-integer contents. Use the optional parameter to // specify the confidence level in units of sigma to use for // calculating error bars. The nominal bin width specifies the // default used by addAsymmetryBin(), and is used to set the relative // normalization of bins with different widths. If not set, the // nominal bin width is calculated as range/nbins. initialize(); // copy the first input histogram's name and title SetName(data1.GetName()); SetTitle(data1.GetTitle()); // calculate our nominal bin width if necessary if(_nominalBinWidth == 0) { const TAxis *axis= ((TH1&)data1).GetXaxis(); if(axis->GetNbins() > 0) _nominalBinWidth= (axis->GetXmax() - axis->GetXmin())/axis->GetNbins(); } setYAxisLabel(Form("Asymmetry (%s - %s)/(%s + %s)", data1.GetName(),data2.GetName(),data1.GetName(),data2.GetName())); // initialize our contents from the input histogram contents Int_t nbin= data1.GetNbinsX(); if(data2.GetNbinsX() != nbin) { coutE(InputArguments) << "RooHistN::RooHistN: histograms have different number of bins" << endl; return; } for(Int_t bin= 1; bin <= nbin; bin++) { Axis_t x= data1.GetBinCenter(bin); if(fabs(data2.GetBinCenter(bin)-x)>1e-10) { coutW(InputArguments) << "RooHistN::RooHistN: histograms have different centers for bin " << bin << endl; } Stat_t y1= data1.GetBinContent(bin); Stat_t y2= data2.GetBinContent(bin); addAsymmetryBin(x,roundBin(y1),roundBin(y2),data1.GetBinWidth(bin),xErrorFrac); } // we do not have a meaningful number of entries _entries= -1; }
void RooHistN::addAsymmetryBin(Axis_t binCenter, Int_t n1, Int_t n2, Double_t binWidth, Double_t xErrorFrac) { // Add a bin to this histogram with the value (n1-n2)/(n1+n2) // using an error bar calculated with Binomial statistics. Double_t scale= 1; if(binWidth > 0) scale= _nominalBinWidth/binWidth; Int_t index= GetN(); // calculate Binomial errors for this bin Double_t ym,yp,dx(0.5*binWidth); if(!RooHistError::instance().getBinomialInterval(n1,n2,ym,yp,_nSigma)) { coutE(Plotting) << "RooHistN::addAsymmetryBin: unable to calculate binomial error for bin with " << n1 << "," << n2 << " events" << endl; return; } Double_t a= (Double_t)(n1-n2)/(n1+n2); SetPoint(index,binCenter,a); SetPointError(index,dx*xErrorFrac,dx*xErrorFrac,(a-ym),(yp-a)); updateYAxisLimits(scale*yp); updateYAxisLimits(scale*ym); }
void RooHistN::addBin(Axis_t binCenter, Int_t n, Double_t binWidth, Double_t xErrorFrac) { // Add a bin to this histogram with the specified integer bin contents // and using an error bar calculated with Poisson statistics. The bin width // is used to set the relative scale of bins with different widths. Double_t scale= 1; if(binWidth > 0) { scale= _nominalBinWidth/binWidth; } _entries+= n; Int_t index= GetN(); // calculate Poisson errors for this bin Double_t ym,yp,dx(0.5*binWidth); if(!RooHistError::instance().getPoissonInterval(n,ym,yp,_nSigma)) { coutE(Plotting) << "RooHistN::addBin: unable to add bin with " << n << " events" << endl; return; } SetPoint(index,binCenter,n*scale); SetPointError(index,dx*xErrorFrac,dx*xErrorFrac,scale*(n-ym),scale*(yp-n)); updateYAxisLimits(scale*yp); updateYAxisLimits(scale*ym); }
RooHistN::RooHistN(const RooHistN& hist1, const RooHistN& hist2, Double_t wgt1, Double_t wgt2, RooAbsData::ErrorType etype, Double_t xErrorFrac) : _rawEntries(-1){ // Create histogram as sum of two existing histograms. If Poisson errors are selected the histograms are // added and Poisson confidence intervals are calculated for the summed content. If wgt1 and wgt2 are not // 1 in this mode, a warning message is printed. If SumW2 errors are selectd the histograms are added // and the histograms errors are added in quadrature, taking the weights into account. // Initialize the histogram initialize() ; // Copy all non-content properties from hist1 SetName(hist1.GetName()) ; SetTitle(hist1.GetTitle()) ; _nominalBinWidth=hist1._nominalBinWidth ; _nSigma=hist1._nSigma ; setYAxisLabel(hist1.getYAxisLabel()) ; if (!hist1.hasIdenticalBinning(hist2)) { coutE(InputArguments) << "RooHistN::RooHistN input histograms have incompatible binning, combined histogram will remain empty" << endl ; return ; } if (etype==RooAbsData::Poisson) { // Add histograms with Poisson errors // Issue warning if weights are not 1 if (wgt1!=1.0 || wgt2 != 1.0) { coutW(InputArguments) << "RooHistN::RooHistN: WARNING: Poisson errors of weighted sum of two histograms is not well defined! " << endl << " Summed histogram bins will rounded to nearest integer for Poisson confidence interval calculation" << endl ; } // Add histograms, calculate Poisson confidence interval on sum value Int_t i,n=hist1.GetN() ; for(i=0 ; i<n ; i++) { Double_t x1,y1,x2,y2,dx1 ; #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1) hist1.GetPoint(i,x1,y1) ; #else const_cast<RooHistN&>(hist1).GetPoint(i,x1,y1) ; #endif dx1 = hist1.GetErrorX(i) ; #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1) hist2.GetPoint(i,x2,y2) ; #else const_cast<RooHistN&>(hist2).GetPoint(i,x2,y2) ; #endif addBin(x1,roundBin(wgt1*y1+wgt2*y2),2*dx1/xErrorFrac,xErrorFrac) ; } } else { // Add histograms with SumW2 errors // Add histograms, calculate combined sum-of-weights error Int_t i,n=hist1.GetN() ; for(i=0 ; i<n ; i++) { Double_t x1,y1,x2,y2,dx1,dy1,dy2 ; #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1) hist1.GetPoint(i,x1,y1) ; #else const_cast<RooHistN&>(hist1).GetPoint(i,x1,y1) ; #endif dx1 = hist1.GetErrorX(i) ; dy1 = hist1.GetErrorY(i) ; dy2 = hist2.GetErrorY(i) ; #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1) hist2.GetPoint(i,x2,y2) ; #else const_cast<RooHistN&>(hist2).GetPoint(i,x2,y2) ; #endif Double_t dy = sqrt(wgt1*wgt1*dy1*dy1+wgt2*wgt2*dy2*dy2) ; addBinWithError(x1,wgt1*y1+wgt2*y2,dy,dy,2*dx1/xErrorFrac,xErrorFrac) ; } } }