39 ClassImp(RooHistError);
49 const RooHistError &RooHistError::instance()
51 static RooHistError _theInstance;
59 RooHistError::RooHistError()
63 for (i=0 ; i<1000 ; i++) {
64 getPoissonIntervalCalc(i,_poissonLoLUT[i],_poissonHiLUT[i],1.) ;
79 Bool_t RooHistError::getPoissonInterval(Int_t n, Double_t &mu1, Double_t &mu2, Double_t nSigma)
const
82 if (n<1000 && nSigma==1.) {
83 mu1=_poissonLoLUT[n] ;
84 mu2=_poissonHiLUT[n] ;
89 Bool_t ret = getPoissonIntervalCalc(n,mu1,mu2,nSigma) ;
102 Bool_t RooHistError::getPoissonIntervalCalc(Int_t n, Double_t &mu1, Double_t &mu2, Double_t nSigma)
const
106 oocoutE((TObject*)0,Plotting) <<
"RooHistError::getPoissonInterval: cannot calculate interval for n = " << n << endl;
112 mu1= n - sqrt(n+0.25) + 0.5;
113 mu2= n + sqrt(n+0.25) + 0.5;
120 PoissonSum lower(n-1);
121 return getInterval(&upper,&lower,(Double_t)n,1.0,mu1,mu2,nSigma);
125 return getInterval(&upper,0,(Double_t)n,1.0,mu1,mu2,nSigma);
133 Bool_t RooHistError::getBinomialIntervalAsym(Int_t n, Int_t m,
134 Double_t &asym1, Double_t &asym2, Double_t nSigma)
const
138 oocoutE((TObject*)0,Plotting) <<
"RooHistError::getPoissonInterval: cannot calculate interval for n,m = " << n <<
"," << m << endl;
143 if(n == 0 && m == 0) {
150 if ((n>100&&m>100)) {
153 Double_t asym = 1.0*(N-M)/(N+M) ;
154 Double_t approxErr = sqrt(4.0*n/(N+M)*(1-N/(N+M))/(N+M)) ;
156 asym1 = asym-nSigma*approxErr ;
157 asym2 = asym+nSigma*approxErr ;
162 Bool_t swapped(kFALSE);
171 Bool_t status(kFALSE);
172 BinomialSumAsym upper(n,m);
174 BinomialSumAsym lower(n-1,m+1);
175 status= getInterval(&upper,&lower,(Double_t)(n-m)/(n+m),0.1,asym1,asym2,nSigma);
178 status= getInterval(&upper,0,(Double_t)(n-m)/(n+m),0.1,asym1,asym2,nSigma);
196 Bool_t RooHistError::getBinomialIntervalEff(Int_t n, Int_t m,
197 Double_t &asym1, Double_t &asym2, Double_t nSigma)
const
201 oocoutE((TObject*)0,Plotting) <<
"RooHistError::getPoissonInterval: cannot calculate interval for n,m = " << n <<
"," << m << endl;
206 if(n == 0 && m == 0) {
216 Double_t asym = 1.0*(N)/(N+M) ;
217 Double_t approxErr = sqrt(4.0*n/(N+M)*(1-N/(N+M))/(N+M)) ;
219 asym1 = asym-nSigma*0.5*approxErr ;
220 asym2 = asym+nSigma*0.5*approxErr ;
225 Bool_t swapped(kFALSE);
234 Bool_t status(kFALSE);
235 BinomialSumEff upper(n,m);
236 Double_t eff = (Double_t)(n)/(n+m) ;
238 BinomialSumEff lower(n-1,m+1);
239 status= getInterval(&upper,&lower,eff,0.1,asym1,asym2,nSigma*0.5);
242 status= getInterval(&upper,0,eff,0.1,asym1,asym2,nSigma*0.5);
263 Bool_t RooHistError::getInterval(
const RooAbsFunc *Qu,
const RooAbsFunc *Ql, Double_t pointEstimate,
264 Double_t stepSize, Double_t &lo, Double_t &hi, Double_t nSigma)
const
267 assert(0 != Qu || 0 != Ql);
270 Double_t beta= TMath::Erf(nSigma/sqrt(2.));
271 Double_t alpha= 0.5*(1-beta);
275 Double_t loProb(1),hiProb(0);
276 if(0 != Ql) loProb= (*Ql)(&pointEstimate);
277 if(0 != Qu) hiProb= (*Qu)(&pointEstimate);
279 if (Qu && (0 == Ql || loProb > alpha + beta)) {
282 Double_t target= loProb - beta;
283 hi= seek(*Qu,lo,+stepSize,target);
284 RooBrentRootFinder uFinder(*Qu);
285 ok= uFinder.findRoot(hi,hi-stepSize,hi,target);
287 else if(Ql && (0 == Qu || hiProb < alpha)) {
290 Double_t target= hiProb + beta;
291 lo= seek(*Ql,hi,-stepSize,target);
292 RooBrentRootFinder lFinder(*Ql);
293 ok= lFinder.findRoot(lo,lo,lo+stepSize,target);
297 lo= seek(*Ql,pointEstimate,-stepSize,alpha+beta);
298 hi= seek(*Qu,pointEstimate,+stepSize,alpha);
299 RooBrentRootFinder lFinder(*Ql),uFinder(*Qu);
300 ok= lFinder.findRoot(lo,lo,lo+stepSize,alpha+beta);
301 ok|= uFinder.findRoot(hi,hi-stepSize,hi,alpha);
303 if(!ok) oocoutE((TObject*)0,Plotting) <<
"RooHistError::getInterval: failed to find root(s)" << endl;
313 Double_t RooHistError::seek(
const RooAbsFunc &f, Double_t startAt, Double_t step, Double_t value)
const
316 Double_t min(f.getMinLimit(1)),max(f.getMaxLimit(1));
317 Double_t x(startAt), f0= f(&startAt) - value;
321 while(steps-- && (f0*(f(&x)-value) >= 0) && ((x-min)*(max-x) >= 0));
334 RooAbsFunc *RooHistError::createPoissonSum(Int_t n)
336 return new PoissonSum(n);
343 RooAbsFunc *RooHistError::createBinomialSum(Int_t n, Int_t m, Bool_t eff)
346 return new BinomialSumEff(n,m) ;
348 return new BinomialSumAsym(n,m) ;