TRolke.cxx

Go to the documentation of this file.
00001 
00002 //////////////////////////////////////////////////////////////////////////////
00003 //
00004 //  TRolke 
00005 //
00006 //  This class computes confidence intervals for the rate of a Poisson
00007 //  process in the presence of uncertain background and/or efficiency. 
00008 //
00009 //  The treatment and the resulting limits are fully frequentist. The
00010 //  limit calculations make use of the profile likelihood method.
00011 //
00012 //      Author: Jan Conrad (CERN) 2004
00013 //      Updated: Johan Lundberg (CERN) 2009
00014 //
00015 //      Copyright CERN 2004,2009           Jan.Conrad@cern.ch,
00016 //                                     Johan.Lundberg@cern.ch
00017 //
00018 //  For a full list of methods and their syntax, and build instructions,
00019 //  consult the header file TRolke.h.
00020 //  -------------------------------- 
00021 //
00022 //  Examples/tutorials are found in the separate file Rolke.C 
00023 //  ---------------------------------------------------------
00024 //
00025 //////////////////////////////////////////////////////////////////////////////
00026 //
00027 //
00028 //  TRolke implements the following Models
00029 //  =======================================
00030 //
00031 //  The signal is always assumed to be Poisson, with the following
00032 //  combinations of models of background and detection efficiency:
00033 //
00034 //  If unsure, first consider model 3, 4 or 5.
00035 //
00036 //       1: SetPoissonBkgBinomEff(x,y,z,tau,m)
00037 //
00038 //          Background: Poisson
00039 //          Efficiency: Binomial    
00040 //
00041 //          when the background is simultaneously measured 
00042 //          from sidebands (or MC), and
00043 //          the signal efficiency was determined from Monte Carlo 
00044 //
00045 //       2: SetPoissonBkgGaussEff(x,y,em,sde,tau)
00046 //
00047 //          Background: Poisson
00048 //          Efficiency: Gaussian    
00049 //
00050 //          when the background is simultaneously measured 
00051 //          from sidebands (or MC), and
00052 //          the efficiency is modeled as Gaussian
00053 //
00054 //       3: SetGaussBkgGaussEff(x,bm,em,sde,sdb)
00055 //
00056 //          Background: Gaussian
00057 //          Efficiency: Gaussian    
00058 //
00059 //          when background and efficiency can both be
00060 //          modeled as Gaussian.
00061 //
00062 //       4: SetPoissonBkgKnownEff(x,y,tau,e)
00063 //
00064 //          Background: Poisson
00065 //          Efficiency: Known     
00066 //
00067 //          when the background is simultaneously measured 
00068 //          from sidebands (or MC).
00069 //
00070 //       5: SetGaussBkgKnownEff(x,bm,sdb,e)
00071 //
00072 //          Background: Gaussian
00073 //          Efficiency: Known       
00074 //
00075 //          when background is Gaussian
00076 //
00077 //       6: SetKnownBkgBinomEff(x,z,b,m)
00078 //
00079 //          Background: Known    
00080 //          Efficiency: Binomial    
00081 //
00082 //          when signal efficiency was determined from Monte Carlo 
00083 //
00084 //       7: SetKnownBkgGaussEff(x,em,sde,b)
00085 //
00086 //          Background: Known    
00087 //          Efficiency: Gaussian     
00088 //
00089 //          when background is known and efficiency Gaussian
00090 //
00091 //  Parameters and further explanation
00092 //  ==================================
00093 //
00094 //  For all models:
00095 //  ---------------
00096 //    
00097 //    x = number of observed events in the experiment
00098 //    
00099 //    Efficiency (e or em) is the detection probability for signal. 
00100 //    A low efficiency hence generally means weaker limits.
00101 //    If the efficiency of an experiment (with analysis cuts) is 
00102 //    dealt with elsewhere, em or e can be set to one.
00103 //
00104 //  For Poisson background measurements (sideband or MC):
00105 //  -----------------------------------------------------
00106 //
00107 //    y = number of observed events in background region
00108 //    tau = 
00109 //        Either: the ratio between signal and background region
00110 //        in case background is observed. 
00111 //        Or: the ratio between observed and simulated live-time
00112 //        in case background is determined from MC.
00113 //
00114 //  For Gaussian efficiency or background:
00115 //  --------------------------------------
00116 //
00117 //    bm  = estimate of the background
00118 //    sdb = corresponding standard deviation 
00119 //
00120 //    em  = estimate of the efficiency
00121 //    sde = corresponding standard deviation 
00122 //
00123 //        If the efficiency scale of dealt with elsewhere,
00124 //        set em to 1 and sde to the relative uncertainty.
00125 //
00126 //  For Binomial signal efficiency:
00127 //  -------------------------------
00128 //
00129 //     m = number of MC events generated
00130 //     z = number of MC events observed
00131 //
00132 //  For the case of known background expectation or known efficiency:
00133 //  -----------------------------------------------------------------
00134 //
00135 //     e = true efficiency (considered known)
00136 //     b = background expectation value (considered known)
00137 //
00138 //
00139 ////////////////////////////////////////////////////////////////////  
00140 //
00141 //
00142 //  The confidence level (CL) is set either at construction
00143 //  time or with either of SetCL or SetCLSigmas
00144 //
00145 //  The TRolke method is very similar to the one used in MINUIT (MINOS).
00146 //
00147 //  Two options are offered to deal with cases where the maximum likelihood
00148 //  estimate (MLE) is not in the physical region. Version "bounded likelihood"
00149 //  is the one used by MINOS if bounds for the physical region are chosen. 
00150 //  Unbounded likelihood (the default) allows the MLE to be in the
00151 //  unphysical region. It has however better coverage.
00152 //  For more details consult the reference (see below).
00153 //
00154 //  For a description of the method and its properties:
00155 //
00156 //  W.Rolke, A. Lopez, J. Conrad and Fred James
00157 //  "Limits and Confidence Intervals in presence of nuisance parameters"
00158 //   http://lanl.arxiv.org/abs/physics/0403059
00159 //   Nucl.Instrum.Meth.A551:493-503,2005
00160 //
00161 //  Should I use TRolke, TFeldmanCousins, TLimit?
00162 //  ----------------------------------------------
00163 //
00164 //  1. Does TRolke make TFeldmanCousins obsolete?
00165 //
00166 //  Certainly not. TFeldmanCousins is the fully frequentist construction and
00167 //  should be used in case of no (or negligible) uncertainties. It is however
00168 //  not capable of treating uncertainties in nuisance parameters. In other
00169 //  words, it does not handle background expectations or signal efficiencies
00170 //  which are known only with some limited accuracy.
00171 //
00172 //  TRolke is designed for this case and it is shown in the reference above
00173 //  that it has good coverage properties for most cases, and can be used
00174 //  where FeldmannCousins can't.
00175 //
00176 //  2. What are the advantages of TRolke over TLimit?
00177 //
00178 //  TRolke is fully frequentist. TLimit treats nuisance parameters Bayesian.
00179 //
00180 //  For a coverage study of a Bayesian method refer to
00181 //  physics/0408039 (Tegenfeldt & J.C). However, this note studies
00182 //  the coverage of Feldman&Cousins with Bayesian treatment of nuisance
00183 //  parameters. To make a long story short: using the Bayesian method you
00184 //  might introduce a small amount of over-coverage (though I haven't shown it
00185 //  for TLimit). On the other hand, coverage of course is a not so interesting
00186 //  when you consider yourself a Bayesian.
00187 //
00188 ///////////////////////////////////////////////////////////////////////////
00189 
00190 #include "TRolke.h"
00191 #include "TMath.h"
00192 #include "Riostream.h"
00193 
00194 ClassImp(TRolke)
00195 
00196 //__________________________________________________________________________
00197 TRolke::TRolke(Double_t CL, Option_t * /*option*/) 
00198 :  fCL(CL),
00199    fUpperLimit(0.0), 
00200    fLowerLimit(0.0), 
00201    fBounding(false),  // true gives bounded likelihood   
00202    fNumWarningsDeprecated1(0),
00203    fNumWarningsDeprecated2(0)
00204 {
00205 //constructor with optional Confidence Level argument.
00206 //'option' is not used.
00207 
00208    SetModelParameters();
00209 }
00210 
00211 //___________________________________________________________________________
00212 TRolke::~TRolke()
00213 {
00214 }
00215 
00216 /* ______________________ new interface _____________________ */
00217 void TRolke::SetPoissonBkgBinomEff(Int_t x, Int_t y, Int_t z, Double_t tau, Int_t m)
00218 {
00219 // Model 1: Background - Poisson, Efficiency - Binomial
00220 //    x   : number of observed events in the experiment
00221 //    y   : number of observed events in background region
00222 //    z   : number of MC events observed
00223 //    tau : ratio parameter (read TRolke.cxx for details)
00224 //    m   : number of MC events generated
00225    SetModelParameters(
00226          x  ,       //   Int_t x,
00227          y  ,       //   Int_t y,
00228          z  ,       //   Int_t z,
00229          0  ,       //   Double_t bm,
00230          0  ,       //   Double_t em,
00231          0  ,       //   Double_t e,
00232          1  ,       //   Int_t mid,
00233          0  ,       //   Double_t sde,
00234          0  ,       //   Double_t sdb,
00235          tau,       //   Double_t tau,
00236          0  ,       //   Double_t b,
00237          m);        //   Int_t m          
00238 }
00239 
00240 void TRolke::SetPoissonBkgGaussEff(Int_t x, Int_t y, Double_t em, Double_t tau, Double_t sde)
00241 {
00242 // Model 2: Background - Poisson, Efficiency - Gaussian
00243 //    x   : number of observed events in the experiment
00244 //    y   : number of observed events in background region
00245 //    em  : estimate of the efficiency
00246 //    tau : ratio parameter (read TRolke.cxx for details)
00247 //    sde : efficiency estimate's standard deviation 
00248    SetModelParameters(
00249          x  ,       //   Int_t x,
00250          y  ,       //   Int_t y,
00251          0  ,       //   Int_t z,
00252          0  ,       //   Double_t bm,
00253          em ,       //   Double_t em,
00254          0  ,       //   Double_t e,
00255          2  ,       //   Int_t mid,
00256          sde,       //   Double_t sde,
00257          0  ,       //   Double_t sdb,
00258          tau,       //   Double_t tau,
00259          0  ,       //   Double_t b,
00260          0);        //   Int_t m
00261 
00262 }
00263 
00264 void TRolke::SetGaussBkgGaussEff(Int_t x, Double_t bm, Double_t em, Double_t sde, Double_t sdb)
00265 {
00266 // Model 3: Background - Gaussian, Efficiency - Gaussian (x,bm,em,sde,sdb)
00267 //    x   : number of observed events in the experiment
00268 //    bm  : estimate of the background
00269 //    em  : estimate of the efficiency
00270 //    sde : efficiency estimate's standard deviation 
00271 //    sdb : background estimate's standard deviation 
00272    SetModelParameters(
00273          x  ,       //   Int_t x,
00274          0  ,       //   Int_t y,
00275          0  ,       //   Int_t z,
00276          bm ,       //   Double_t bm,
00277          em ,       //   Double_t em,
00278          0  ,       //   Double_t e,
00279          3  ,       //   Int_t mid,
00280          sde,       //   Double_t sde,
00281          sdb,       //   Double_t sdb,
00282          0  ,       //   Double_t tau,
00283          0  ,       //   Double_t b,
00284          0);        //   Int_t m
00285 
00286 }
00287 
00288 void TRolke::SetPoissonBkgKnownEff(Int_t x, Int_t y, Double_t tau, Double_t e)
00289 {
00290 // Model 4: Background - Poisson, Efficiency - known     (x,y,tau,e)
00291 //    x   : number of observed events in the experiment
00292 //    y   : number of observed events in background region
00293 //    tau : ratio parameter (read TRolke.cxx for details)
00294 //    e   : true efficiency (considered known)
00295    SetModelParameters(
00296          x  ,       //   Int_t x,
00297          y  ,       //   Int_t y,
00298          0  ,       //   Int_t z,
00299          0  ,       //   Double_t bm,
00300          0  ,       //   Double_t em,
00301          e  ,       //   Double_t e,
00302          4  ,       //   Int_t mid,
00303          0  ,       //   Double_t sde,
00304          0  ,       //   Double_t sdb,
00305          tau,       //   Double_t tau,
00306          0  ,       //   Double_t b,
00307          0);        //   Int_t m
00308 
00309 }
00310 
00311 void TRolke::SetGaussBkgKnownEff(Int_t x, Double_t bm, Double_t sdb, Double_t e)
00312 {
00313 // Model 5: Background - Gaussian, Efficiency - known    (x,bm,sdb,e
00314 //    x   : number of observed events in the experiment
00315 //    bm  : estimate of the background
00316 //    sdb : background estimate's standard deviation 
00317 //    e   : true efficiency (considered known)
00318    SetModelParameters(
00319          x  ,       //   Int_t x,
00320          0  ,       //   Int_t y,
00321          0  ,       //   Int_t z,
00322          bm ,       //   Double_t bm,
00323          0  ,       //   Double_t em,
00324          e  ,       //   Double_t e,
00325          5  ,       //   Int_t mid,
00326          0  ,       //   Double_t sde,
00327          sdb,       //   Double_t sdb,
00328          0  ,       //   Double_t tau,
00329          0  ,       //   Double_t b,
00330          0);        //   Int_t m
00331 
00332 }
00333 
00334 void TRolke::SetKnownBkgBinomEff(Int_t x, Int_t z, Int_t m, Double_t b)
00335 {
00336 // Model 6: Background - known, Efficiency - Binomial    (x,z,m,b)
00337 //    x   : number of observed events in the experiment
00338 //    z   : number of MC events observed
00339 //    m   : number of MC events generated
00340 //    b   : background expectation value (considered known)
00341    SetModelParameters(
00342          x  ,       //   Int_t x,
00343          0  ,       //   Int_t y
00344          z  ,       //   Int_t z,
00345          0  ,       //   Double_t bm,
00346          0  ,       //   Double_t em,
00347          0  ,       //   Double_t e,
00348          6  ,       //   Int_t mid,
00349          0  ,       //   Double_t sde,
00350          0  ,       //   Double_t sdb,
00351          0  ,       //   Double_t tau,
00352          b  ,       //   Double_t b,
00353          m);        //   Int_t m
00354 
00355 }
00356 
00357 void TRolke::SetKnownBkgGaussEff(Int_t x, Double_t em, Double_t sde, Double_t b)
00358 {
00359 // Model 7: Background - known, Efficiency - Gaussian    (x,em,sde,b)
00360 //    x   : number of observed events in the experiment
00361 //    em  : estimate of the efficiency
00362 //    sde : efficiency estimate's standard deviation 
00363 //    b   : background expectation value (considered known)
00364    SetModelParameters(
00365          x  ,       //   Int_t x,
00366          0  ,       //   Int_t y
00367          0  ,       //   Int_t z,
00368          0  ,       //   Double_t bm,
00369          em ,       //   Double_t em,
00370          0  ,       //   Double_t e,
00371          7  ,       //   Int_t mid,
00372          sde,       //   Double_t sde,
00373          0  ,       //   Double_t sdb,
00374          0  ,       //   Double_t tau,
00375          b  ,       //   Double_t b,
00376          0);        //   Int_t m
00377 
00378 }
00379 
00380 bool TRolke::GetLimits(Double_t& low, Double_t& high)
00381 {
00382 /* Calculate and get the upper and lower limits for the pre-specified model */ 
00383    if ((f_mid<1)||(f_mid>7)) {
00384       std::cerr << "TRolke - Error: Model id "<< f_mid<<std::endl;
00385       if (f_mid<1) {
00386          std::cerr << "TRolke - Please specify a model with e.g. 'SetGaussBkgGaussEff' (read the docs in Rolke.cxx )"<<std::endl; 
00387       }
00388       return false;
00389    }
00390 
00391    ComputeInterval(f_x, f_y, f_z, f_bm, f_em, f_e, f_mid, f_sde, f_sdb, f_tau, f_b, f_m);
00392    low = fLowerLimit;
00393    high = fUpperLimit;
00394    if (low < high) {     
00395       return true;
00396    }else{ 
00397       std::cerr << "TRolke - Warning: no limits found" <<std::endl;
00398       return false;
00399    }
00400 }
00401 
00402 Double_t TRolke::GetUpperLimit()
00403 {
00404 /* Calculate and get upper limit for the pre-specified model */ 
00405    Double_t low(0), high(0);
00406    GetLimits(low,high);
00407    return fUpperLimit;
00408 }
00409 
00410 Double_t TRolke::GetLowerLimit()
00411 {
00412 /* Calculate and get lower limit for the pre-specified model */ 
00413    Double_t low(0), high(0);
00414    GetLimits(low,high);
00415    return fLowerLimit;
00416 }
00417 
00418 Double_t TRolke::GetBackground()
00419 {
00420 /* Return a simple background value (estimate/truth) given the pre-specified model */ 
00421    Double_t background = 0;
00422    switch (f_mid) {
00423       case 1:
00424       case 2:
00425       case 4:
00426          background = f_y / f_tau;
00427          break;
00428       case 3:
00429       case 5:
00430          background = f_bm;
00431          break;
00432       case 6:
00433       case 7:
00434          background = f_b;
00435          break;
00436       default:
00437          std::cerr << "TRolke::GetBackground(): Model NR: " <<
00438             f_mid << " unknown"<<std::endl;
00439          return 0;
00440    }
00441    return background;
00442 }
00443 
00444 bool TRolke::GetSensitivity(Double_t& low, Double_t& high, Double_t pPrecision)
00445 {
00446 // get the upper and lower average limits based on the specified model.
00447 // No uncertainties are considered for the Poisson weights in the averaging sum
00448    Double_t background = GetBackground();
00449 
00450    Double_t weight = 0;
00451    Double_t weightSum = 0;
00452 
00453    int loop_x = 0;
00454 
00455    while (1) {
00456       ComputeInterval(loop_x, f_y, f_z, f_bm, f_em, f_e, f_mid, f_sde, f_sdb, f_tau, f_b, f_m);
00457       weight = TMath::PoissonI(loop_x, background);
00458       low += fLowerLimit * weight;
00459       high += fUpperLimit * weight;
00460       weightSum += weight;
00461       if (loop_x > (background + 1)) { // don't stop too early
00462          if ((weightSum > (1 - pPrecision)) || (weight < 1e-12)) break;
00463       }
00464       loop_x++;
00465    }
00466    low /= weightSum;
00467    high /= weightSum;
00468 
00469    return (low < high); // could also add more detailed test
00470 }
00471 
00472 
00473 bool TRolke::GetLimitsQuantile(Double_t& low, Double_t& high, Int_t& out_x, Double_t integral)
00474 {
00475 /* get the upper and lower limits for the outcome corresponding to
00476    a given quantile.
00477    For integral=0.5 this gives the median limits
00478    in repeated experiments. The returned out_x is the corresponding
00479    (e.g. median) value of x.
00480    No uncertainties are considered for the Poisson weights when calculating 
00481    the Poisson integral */
00482    Double_t background = GetBackground();
00483    Double_t weight = 0;
00484    Double_t weightSum = 0;
00485    Int_t loop_x = 0;
00486 
00487    while (1) {
00488       weight = TMath::PoissonI(loop_x, background);
00489       weightSum += weight;
00490       if (weightSum >= integral) {
00491          break;
00492       }
00493       loop_x++;
00494    }
00495 
00496    out_x = loop_x;
00497 
00498    ComputeInterval(loop_x, f_y, f_z, f_bm, f_em, f_e, f_mid, f_sde, f_sdb, f_tau, f_b, f_m);
00499    low = fLowerLimit;
00500    high = fUpperLimit;
00501    return (low < high); // could also add more detailed test
00502 
00503 }
00504 
00505 bool TRolke::GetLimitsML(Double_t& low, Double_t& high, Int_t& out_x)
00506 {
00507 /* get the upper and lower limits for the most likely outcome.
00508    The returned out_x is the corresponding value of x 
00509    No uncertainties are considered for the Poisson weights when finding ML */
00510    Double_t background = GetBackground();
00511 
00512    Int_t loop_x = 0; // this can be optimized if needed. 
00513    Int_t loop_max = 1000 + (Int_t)background; //     --||--
00514 
00515    Double_t max = TMath::PoissonI(loop_x, background);
00516    while (loop_x <= loop_max) {
00517       if (TMath::PoissonI(loop_x + 1, background) < max) {
00518          break;
00519       }
00520       loop_x++;
00521       max = TMath::PoissonI(loop_x, background);
00522    }
00523    if (loop_x >= loop_max) {
00524       std::cout << "internal error finding maximum of distribution" << endl;
00525       return false;
00526    }
00527 
00528    out_x = loop_x;
00529 
00530    ComputeInterval(loop_x, f_y, f_z, f_bm, f_em, f_e, f_mid, f_sde, f_sdb, f_tau, f_b, f_m);
00531    low = fLowerLimit;
00532    high = fUpperLimit;
00533    return (low < high); // could also add more detailed test
00534 
00535 }
00536 
00537 bool TRolke::GetCriticalNumber(Int_t& ncrit, Int_t maxtry)
00538 {
00539 // get the value of x corresponding to rejection of the null hypothesis.
00540 // This means a lower limit >0 with the pre-specified Confidence Level. 
00541 // Optionally give maxtry; the maximum value of x to try. Of not, or if
00542 // maxtry<0 an automatic mode is used.
00543    Double_t background = GetBackground();
00544 
00545    int j = 0;
00546    int rolke_ncrit = -1;
00547    int maxj =maxtry ;
00548    if(maxtry<1){
00549      maxj = 1000 + (Int_t)background; // max value to try
00550    }
00551    for (j = 0;j < maxj;j++) {
00552       Int_t rolke_x = j;
00553       ComputeInterval(rolke_x, f_y, f_z, f_bm, f_em, f_e, f_mid, f_sde, f_sdb, f_tau, f_b, f_m);
00554       double rolke_ll = fLowerLimit;
00555       if (rolke_ll > 0) {
00556          rolke_ncrit = j;
00557          break;
00558       }
00559    }
00560 
00561    if (rolke_ncrit == -1) {
00562      std::cerr << "TRolke GetCriticalNumber : Error: problem finding rolke inverse. Specify a larger maxtry value. maxtry was: " << maxj << ". highest x considered was j "<< j<< endl;
00563       ncrit = -1;
00564       return false;
00565    } else {
00566       ncrit = rolke_ncrit;
00567       return true;
00568    }
00569 }
00570 
00571 void TRolke::SetSwitch(bool bnd) {
00572 /* Deprecated name for SetBounding. */
00573    if(fNumWarningsDeprecated1<2){
00574       std::cerr << "*******************************************" <<std::endl;
00575       std::cerr << "TRolke - Warning: 'SetSwitch' is depricated and may be removed from future releases:" <<std::endl;
00576       std::cerr << " - Use 'SetBounding' instead "<<std::endl;
00577       std::cerr << "*******************************************" <<std::endl;
00578       fNumWarningsDeprecated1++;
00579    }
00580    SetBounding(bnd);
00581 }
00582 
00583 void TRolke::Print(Option_t*) const {
00584 /* Dump internals. Print members. */
00585    std::cout << "*******************************************" <<std::endl;
00586    std::cout << "* TRolke::Print() - dump of internals:                " <<std::endl;
00587    std::cout << "*"<<std::endl;
00588    std::cout << "* model id, mid = "<<f_mid <<endl;
00589    std::cout << "*"<<std::endl;
00590    std::cout << "*             x = "<<f_x   <<std::endl;
00591    std::cout << "*            bm = "<<f_bm  <<endl;
00592    std::cout << "*            em = "<<f_em  <<endl;
00593    std::cout << "*           sde = "<<f_sde <<endl;
00594    std::cout << "*           sdb = "<<f_sdb <<endl;
00595    std::cout << "*             y = "<<f_y   <<endl;      
00596    std::cout << "*           tau = "<<f_tau <<endl;
00597    std::cout << "*             e = "<<f_e   <<endl;
00598    std::cout << "*             b = "<<f_b   <<endl;
00599    std::cout << "*             m = "<<f_m   <<endl;
00600    std::cout << "*             z = "<<f_z   <<endl;
00601    std::cout << "*"<<std::endl;
00602    std::cout << "*            CL = "<<fCL <<endl;
00603    std::cout << "*      Bounding = "<<fBounding <<endl;      
00604    std::cout << "*"<<std::endl;
00605    std::cout << "* calculated on demand only:"<<std::endl;
00606    std::cout << "*   fUpperLimit = "<<fUpperLimit<<endl; 
00607    std::cout << "*   fLowerLimit = "<<fLowerLimit<<endl;      
00608    std::cout << "*******************************************" <<std::endl;
00609 }
00610 
00611 
00612 Double_t TRolke::CalculateInterval(Int_t x, Int_t y, Int_t z, Double_t bm, Double_t em, Double_t e, Int_t mid, Double_t sde, Double_t sdb, Double_t tau, Double_t b, Int_t m){
00613 /* Deprecated and error prone model selection interface. 
00614    It's use is trongly discouraged. 'mid' is the model ID (1 to 7).
00615    This method is provided for backwards compatibility/developer use only. */
00616 //    x   : number of observed events in the experiment
00617 //    y   : number of observed events in background region
00618 //    z   : number of MC events observed
00619 //    bm  : estimate of the background
00620 //    em  : estimate of the efficiency
00621 //    e   : true efficiency (considered known)
00622 //    mid : internal model id (really, you should not use this method at all)
00623 //    sde : efficiency estimate's standard deviation 
00624 //    sdb : background estimate's standard deviation 
00625 //    tau : ratio parameter (read TRolke.cxx for details)
00626 //    b   : background expectation value (considered known)
00627 //    m   : number of MC events generated
00628    if (fNumWarningsDeprecated2<2 ) {
00629       std::cerr << "*******************************************" <<std::endl;
00630       std::cerr << "TRolke - Warning: 'CalculateInterval' is depricated and may be removed from future releases:" <<std::endl;
00631       std::cerr << " - Use e.g. 'SetGaussBkgGaussEff' and 'GetLimits' instead (read the docs in Rolke.cxx )"<<std::endl;
00632       std::cerr << "*******************************************" <<std::endl;
00633       fNumWarningsDeprecated2++;
00634    }
00635    SetModelParameters(
00636          x,
00637          y,
00638          z,
00639          bm,
00640          em,
00641          e,
00642          mid,
00643          sde,
00644          sdb,
00645          tau,
00646          b,
00647          m);
00648    return ComputeInterval(f_x, f_y, f_z, f_bm, f_em, f_e, f_mid, f_sde, f_sdb, f_tau, f_b, f_m);
00649 }
00650 
00651 
00652 // --------------- Private methods ----------------
00653 void TRolke::SetModelParameters(Int_t x, Int_t y, Int_t z, Double_t bm, Double_t em, Double_t e, Int_t mid, Double_t sde, Double_t sdb, Double_t tau, Double_t b, Int_t m)
00654 {
00655 //___________________________________________________________________________
00656 //    x   : number of observed events in the experiment
00657 //    y   : number of observed events in background region
00658 //    z   : number of MC events observed
00659 //    bm  : estimate of the background
00660 //    em  : estimate of the efficiency
00661 //    e   : true efficiency (considered known)
00662 //    mid : internal model id
00663 //    sde : efficiency estimate's standard deviation 
00664 //    sdb : background estimate's standard deviation 
00665 //    tau : ratio parameter (read TRolke.cxx for details)
00666 //    b   : background expectation value (considered known)
00667 //    m   : number of MC events generated
00668    f_x   = x   ;
00669    f_y   = y   ;
00670    f_z   = z   ;
00671    f_bm  = bm  ;
00672    f_em  = em  ;
00673    f_e   = e   ;
00674    f_mid = mid ;
00675    f_sde = sde ;
00676    f_sdb = sdb ;
00677    f_tau = tau ;
00678    f_b   = b   ;
00679    f_m   = m   ;
00680 }
00681 
00682 void TRolke::SetModelParameters()
00683 {
00684 /* Clear internal model */
00685    SetModelParameters(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
00686    f_mid=0;
00687 }
00688 
00689 
00690 Double_t TRolke::ComputeInterval(Int_t x, Int_t y, Int_t z, Double_t bm, Double_t em, Double_t e, Int_t mid, Double_t sde, Double_t sdb, Double_t tau, Double_t b, Int_t m)
00691 {
00692 //___________________________________________________________________________
00693 // ComputeInterval, the internals.
00694 //    x   : number of observed events in the experiment
00695 //    y   : number of observed events in background region
00696 //    z   : number of MC events observed
00697 //    bm  : estimate of the background
00698 //    em  : estimate of the efficiency
00699 //    e   : true efficiency (considered known)
00700 //    mid : internal model id (really, you should not use this method at all)
00701 //    sde : efficiency estimate's standard deviation 
00702 //    sdb : background estimate's standard deviation 
00703 //    tau : ratio parameter (read TRolke.cxx for details)
00704 //    b   : background expectation value (considered known)
00705 //    m   : number of MC events generated
00706 
00707    //calculate interval
00708    Int_t done = 0;
00709    Double_t limit[2];
00710 
00711    limit[1] = Interval(x, y, z, bm, em, e, mid, sde, sdb, tau, b, m);
00712 
00713    if (limit[1] > 0) {
00714       done = 1;
00715    }
00716 
00717    if (! fBounding) {
00718 
00719       Int_t trial_x = x;
00720 
00721       while (done == 0) {
00722          trial_x++;
00723          limit[1] = Interval(trial_x, y, z, bm, em, e, mid, sde, sdb, tau, b, m);
00724          if (limit[1] > 0) done = 1;
00725       }
00726    }
00727 
00728    return limit[1];
00729 }
00730 
00731 Double_t TRolke::Interval(Int_t x, Int_t y, Int_t z, Double_t bm, Double_t em, Double_t e, Int_t mid, Double_t sde, Double_t sdb, Double_t tau, Double_t b, Int_t m)
00732 {
00733 //_____________________________________________________________________
00734 // Internal helper function 'Interval'
00735 //
00736 //    x   : number of observed events in the experiment
00737 //    y   : number of observed events in background region
00738 //    z   : number of MC events observed
00739 //    bm  : estimate of the background
00740 //    em  : estimate of the efficiency
00741 //    e   : true efficiency (considered known)
00742 //    mid : internal model id (really, you should not use this method at all)
00743 //    sde : efficiency estimate's standard deviation 
00744 //    sdb : background estimate's standard deviation 
00745 //    tau : ratio parameter (read TRolke.cxx for details)
00746 //    b   : background expectation value (considered known)
00747 //    m   : number of MC events generated
00748 
00749    Double_t dchi2 = TMath::ChisquareQuantile(fCL, 1);
00750    Double_t tempxy[2], limits[2] = {0, 0};
00751    Double_t slope, fmid, low, flow, high, fhigh, test, ftest, mu0, maximum, target, l, f0;
00752    Double_t med = 0;
00753    Double_t maxiter = 1000, acc = 0.00001;
00754    Int_t i;
00755    Int_t bp = 0;
00756 
00757    if ((mid != 3) && (mid != 5)) bm = y;
00758    if ((mid == 3) || (mid == 5)) {
00759       if (bm == 0) bm = 0.00001;
00760    }
00761 
00762    if ((mid == 6) || (mid == 7)) {
00763       if (bm == 0) bm = 0.00001;
00764    }
00765 
00766    if ((mid <= 2) || (mid == 4)) bp = 1;
00767 
00768 
00769    if (bp == 1 && x == 0 && bm > 0) {
00770       for (i = 0; i < 2; i++) {
00771          x++;
00772          tempxy[i] = Interval(x, y, z, bm, em, e, mid, sde, sdb, tau, b, m);
00773       }
00774 
00775       slope = tempxy[1] - tempxy[0];
00776       limits[1] = tempxy[0] - slope;
00777       limits[0] = 0.0;
00778       if (limits[1] < 0) limits[1] = 0.0;
00779       goto done;
00780    }
00781 
00782    if (bp != 1 && x == 0) {
00783 
00784       for (i = 0; i < 2; i++) {
00785          x++;
00786          tempxy[i] = Interval(x, y, z, bm, em, e, mid, sde, sdb, tau, b, m);
00787       }
00788       slope = tempxy[1] - tempxy[0];
00789       limits[1] = tempxy[0] - slope;
00790       limits[0] = 0.0;
00791       if (limits[1] < 0) limits[1] = 0.0;
00792       goto done;
00793    }
00794 
00795    if (bp != 1  && bm == 0) {
00796       for (i = 0; i < 2; i++) {
00797          bm++;
00798          limits[1] = Interval(x, y, z, bm, em, e, mid, sde, sdb, tau, b, m);
00799          tempxy[i] = limits[1];
00800       }
00801       slope = tempxy[1] - tempxy[0];
00802       limits[1] = tempxy[0] - slope;
00803       if (limits[1] < 0) limits[1] = 0;
00804       goto done;
00805    }
00806 
00807    if (x == 0 && bm == 0) {
00808       x++;
00809       bm++;
00810       limits[1] = Interval(x, y, z, bm, em, e, mid, sde, sdb, tau, b, m);
00811       tempxy[0] = limits[1];
00812       x  = 1;
00813       bm = 2;
00814       limits[1] = Interval(x, y, z, bm, em, e, mid, sde, sdb, tau, b, m);
00815       tempxy[1] = limits[1];
00816       x  = 2;
00817       bm = 1;
00818       limits[1] = Interval(x, y, z, bm, em, e, mid, sde, sdb, tau, b, m);
00819       limits[1] = 3 * tempxy[0] - tempxy[1] - limits[1];
00820       if (limits[1] < 0) limits[1] = 0;
00821       goto done;
00822    }
00823 
00824    mu0 = Likelihood(0, x, y, z, bm, em, mid, sde, sdb, tau, b, m, 1);
00825    maximum = Likelihood(0, x, y, z, bm, em, mid, sde, sdb, tau, b, m, 2);
00826    test = 0;
00827    f0 = Likelihood(test, x, y, z, bm, em, mid, sde, sdb, tau, b, m, 3);
00828    if (fBounding) {
00829       if (mu0 < 0) maximum = f0;
00830    }
00831 
00832    target = maximum - dchi2;
00833    if (f0 > target) {
00834       limits[0] = 0;
00835    } else {
00836       if (mu0 < 0) {
00837          limits[0] = 0;
00838          limits[1] = 0;
00839       }
00840 
00841       low   = 0;
00842       flow  = f0;
00843       high  = mu0;
00844       fhigh = maximum;
00845       for (i = 0; i < maxiter; i++) {
00846          l = (target - fhigh) / (flow - fhigh);
00847          if (l < 0.2) l = 0.2;
00848          if (l > 0.8) l = 0.8;
00849          med = l * low + (1 - l) * high;
00850          if (med < 0.01) {
00851             limits[1] = 0.0;
00852             goto done;
00853          }
00854          fmid = Likelihood(med, x, y, z, bm, em, mid, sde, sdb, tau, b, m, 3);
00855          if (fmid > target) {
00856             high  = med;
00857             fhigh = fmid;
00858          } else {
00859             low  = med;
00860             flow = fmid;
00861          }
00862          if ((high - low) < acc*high) break;
00863       }
00864       limits[0] = med;
00865    }
00866 
00867    if (mu0 > 0) {
00868       low  = mu0;
00869       flow = maximum;
00870    } else {
00871       low  = 0;
00872       flow = f0;
00873    }
00874 
00875    test = low + 1 ;
00876    ftest = Likelihood(test, x, y, z, bm, em, mid, sde, sdb, tau, b, m, 3);
00877    if (ftest < target) {
00878       high  = test;
00879       fhigh = ftest;
00880    } else {
00881       slope = (ftest - flow) / (test - low);
00882       high  = test + (target - ftest) / slope;
00883       fhigh = Likelihood(high, x, y, z, bm, em, mid, sde, sdb, tau, b, m, 3);
00884    }
00885 
00886    for (i = 0; i < maxiter; i++) {
00887       l = (target - fhigh) / (flow - fhigh);
00888       if (l < 0.2) l = 0.2;
00889       if (l > 0.8) l = 0.8;
00890       med  = l * low + (1. - l) * high;
00891       fmid = Likelihood(med, x, y, z, bm, em, mid, sde, sdb, tau, b, m, 3);
00892 
00893       if (fmid < target) {
00894          high  = med;
00895          fhigh = fmid;
00896       } else {
00897          low  = med;
00898          flow = fmid;
00899       }
00900 
00901       if (high - low < acc*high) break;
00902    }
00903 
00904    limits[1] = med;
00905 
00906 done:
00907 
00908    // apply known efficiency
00909    if ((mid == 4) || (mid == 5)) {
00910       limits[0] /= e;
00911       limits[1] /= e;
00912    }
00913 
00914    fUpperLimit = limits[1];
00915    fLowerLimit = TMath::Max(limits[0], 0.0);
00916 
00917    return limits[1];
00918 }
00919 
00920 
00921 Double_t TRolke::Likelihood(Double_t mu, Int_t x, Int_t y, Int_t z, Double_t bm, Double_t em, Int_t mid, Double_t sde, Double_t sdb, Double_t tau, Double_t b, Int_t m, Int_t what)
00922 {
00923 //___________________________________________________________________________
00924 //Internal helper function
00925 // Chooses between the different profile likelihood functions to use for the
00926 // different models.
00927 // Returns evaluation of the profile likelihood functions.
00928 
00929    switch (mid) {
00930       case 1:
00931          return EvalLikeMod1(mu, x, y, z, tau, m, what);
00932       case 2:
00933          return EvalLikeMod2(mu, x, y, em, sde, tau, what);
00934       case 3:
00935          return EvalLikeMod3(mu, x, bm, em, sde, sdb, what);
00936       case 4:
00937          return EvalLikeMod4(mu, x, y, tau, what);
00938       case 5:
00939          return EvalLikeMod5(mu, x, bm, sdb, what);
00940       case 6:
00941          return EvalLikeMod6(mu, x, z, b, m, what);
00942       case 7:
00943          return EvalLikeMod7(mu, x, em, sde, b, what);
00944       default:
00945          std::cerr << "TRolke::Likelihood(...): Model NR: " <<
00946             f_mid << " unknown"<<std::endl;
00947          return 0;
00948    }
00949 
00950    return 0;
00951 }
00952 
00953 Double_t TRolke::EvalLikeMod1(Double_t mu, Int_t x, Int_t y, Int_t z, Double_t tau, Int_t m, Int_t what)
00954 {
00955 //_________________________________________________________________________
00956 //
00957 // Calculates the Profile Likelihood for MODEL 1:
00958 //  Poisson background/ Binomial Efficiency
00959 // what = 1: Maximum likelihood estimate is returned
00960 // what = 2: Profile Likelihood of Maximum Likelihood estimate is returned.
00961 // what = 3: Profile Likelihood of Test hypothesis is returned
00962 // otherwise parameters as described in the beginning of the class)
00963    Double_t f  = 0;
00964    Double_t zm = Double_t(z) / m;
00965 
00966    if (what == 1) {
00967       f = (x - y / tau) / zm;
00968    }
00969 
00970    if (what == 2) {
00971       mu = (x - y / tau) / zm;
00972       Double_t b  = y / tau;
00973       Double_t e = zm;
00974       f = LikeMod1(mu, b, e, x, y, z, tau, m);
00975    }
00976 
00977    if (what == 3) {
00978       if (mu == 0) {
00979          Double_t b = (x + y) / (1.0 + tau);
00980          Double_t e = zm;
00981          f = LikeMod1(mu, b, e, x, y, z, tau, m);
00982       } else {
00983          Double_t e = 0;
00984          Double_t b = 0;
00985          ProfLikeMod1(mu, b, e, x, y, z, tau, m);
00986          f = LikeMod1(mu, b, e, x, y, z, tau, m);
00987       }
00988    }
00989 
00990    return f;
00991 }
00992 
00993 
00994 Double_t TRolke::LikeMod1(Double_t mu, Double_t b, Double_t e, Int_t x, Int_t y, Int_t z, Double_t tau, Int_t m)
00995 {
00996 //________________________________________________________________________
00997 // Profile Likelihood function for MODEL 1:
00998 // Poisson background/ Binomial Efficiency
00999 
01000    double s = e*mu+b;
01001    double lls = - s;
01002    if (x > 0) lls = x*TMath::Log(s) - s - LogFactorial(x); 
01003    double bg = tau*b;
01004    double llb =  -bg;
01005    if ( y > 0) llb =  y*TMath::Log( bg) - bg - LogFactorial(y);
01006 
01007    double lle = 0;  // binomial log-like
01008    if (z == 0)         lle = m * TMath::Log(1-e); 
01009    else if ( z == m)   lle = m * TMath::Log(e); 
01010    else                lle =   z * TMath::Log(e) + (m - z)*TMath::Log(1 - e) + LogFactorial(m) - LogFactorial(m-z) - LogFactorial(z); 
01011 
01012    double f = 2*( lls + llb + lle); 
01013    return f;
01014 }
01015 
01016 
01017 // this code is non-sense - // need to solve using Minuit
01018 struct LikeFunction1 { 
01019 };
01020 
01021 void TRolke::ProfLikeMod1(Double_t mu, Double_t &b, Double_t &e, Int_t x, Int_t y, Int_t z, Double_t tau, Int_t m)
01022 {
01023 //________________________________________________________________________
01024 // Helper for calculation of estimates of efficiency and background for model 1
01025 //
01026 
01027    Double_t med = 0.0, fmid;
01028    Int_t maxiter = 1000;
01029    Double_t acc = 0.00001;
01030    Double_t emin = ((m + mu * tau) - TMath::Sqrt((m + mu * tau) * (m + mu * tau) - 4 * mu * tau * z)) / 2 / mu / tau;
01031 
01032    Double_t low  = TMath::Max(1e-10, emin + 1e-10);
01033    Double_t high = 1 - 1e-10;
01034 
01035    for (Int_t i = 0; i < maxiter; i++) {
01036       med = (low + high) / 2.;
01037 
01038       fmid = LikeGradMod1(med, mu, x, y, z, tau, m);
01039 
01040       if (high < 0.5) acc = 0.00001 * high;
01041       else           acc = 0.00001 * (1 - high);
01042 
01043       if ((high - low) < acc*high) break;
01044 
01045       if (fmid > 0) low  = med;
01046       else         high = med;
01047    }
01048 
01049    e = med;
01050    Double_t eta = Double_t(z) / e - Double_t(m - z) / (1 - e);
01051 
01052    b = Double_t(y) / (tau - eta / mu);
01053 }
01054 
01055 //___________________________________________________________________________
01056 Double_t TRolke::LikeGradMod1(Double_t e, Double_t mu, Int_t x, Int_t y, Int_t z, Double_t tau, Int_t m)
01057 {
01058 //gradient model likelihood
01059    Double_t eta, etaprime, bprime, f;
01060    eta = static_cast<double>(z) / e - static_cast<double>(m - z) / (1.0 - e);
01061    etaprime = (-1) * (static_cast<double>(m - z) / ((1.0 - e) * (1.0 - e)) + static_cast<double>(z) / (e * e));
01062    Double_t b = y / (tau - eta / mu);
01063    bprime = (b * b * etaprime) / mu / y;
01064    f = (mu + bprime) * (x / (e * mu + b) - 1) + (y / b - tau) * bprime + eta;
01065    return f;
01066 }
01067 
01068 //___________________________________________________________________________
01069 Double_t TRolke::EvalLikeMod2(Double_t mu, Int_t x, Int_t y, Double_t em, Double_t sde, Double_t tau, Int_t what)
01070 {
01071 // Calculates the Profile Likelihood for MODEL 2:
01072 //  Poisson background/ Gauss Efficiency
01073 // what = 1: Maximum likelihood estimate is returned
01074 // what = 2: Profile Likelihood of Maximum Likelihood estimate is returned.
01075 // what = 3: Profile Likelihood of Test hypothesis is returned
01076 // otherwise parameters as described in the beginning of the class)
01077    Double_t v =  sde * sde;
01078    Double_t coef[4], roots[3];
01079    Double_t f = 0;
01080 
01081    if (what == 1) {
01082       f = (x - y / tau) / em;
01083    }
01084 
01085    if (what == 2) {
01086       mu = (x - y / tau) / em;
01087       Double_t b = y / tau;
01088       Double_t e = em;
01089       f = LikeMod2(mu, b, e, x, y, em, tau, v);
01090    }
01091 
01092    if (what == 3) {
01093       if (mu == 0) {
01094          Double_t b = (x + y) / (1 + tau);
01095          Double_t e = em ; 
01096          f = LikeMod2(mu, b, e, x, y, em, tau, v);
01097       } else {
01098          coef[3] = mu;
01099          coef[2] = mu * mu * v - 2 * em * mu - mu * mu * v * tau;
01100          coef[1] = (- x) * mu * v - mu * mu * mu * v * v * tau - mu * mu * v * em + em * mu * mu * v * tau + em * em * mu - y * mu * v;
01101          coef[0] = x * mu * mu * v * v * tau + x * em * mu * v - y * mu * mu * v * v + y * em * mu * v;
01102 
01103          TMath::RootsCubic(coef, roots[0], roots[1], roots[2]);
01104 
01105          Double_t e = roots[1];
01106          Double_t b; 
01107          if ( v > 0) b = y / (tau + (em - e) / mu / v);
01108          else b = y/tau; 
01109          f = LikeMod2(mu, b, e, x, y, em, tau, v);
01110       }
01111    }
01112 
01113    return f;
01114 }
01115 
01116 //_________________________________________________________________________
01117 Double_t TRolke::LikeMod2(Double_t mu, Double_t b, Double_t e, Int_t x, Int_t y, Double_t em, Double_t tau, Double_t v)
01118 {
01119 // Profile Likelihood function for MODEL 2:
01120 // Poisson background/Gauss Efficiency
01121 
01122    double s = e*mu+b;
01123    double lls = - s;
01124    if (x > 0) lls = x*TMath::Log(s) - s - LogFactorial(x); 
01125    double bg = tau*b;
01126    double llb =  -bg;
01127    if ( y > 0) llb =  y*TMath::Log( bg) - bg - LogFactorial(y);
01128    double lle = 0; 
01129    if ( v > 0) lle = - 0.9189385 - TMath::Log(v) / 2 - (em - e)*(em - e) / v / 2;
01130 
01131    return 2*( lls + llb + lle);
01132 }
01133 
01134 //_____________________________________________________________________
01135 Double_t TRolke::EvalLikeMod3(Double_t mu, Int_t x, Double_t bm, Double_t em, Double_t sde, Double_t sdb, Int_t what)
01136 {
01137 // Calculates the Profile Likelihood for MODEL 3:
01138 // Gauss  background/ Gauss Efficiency
01139 // what = 1: Maximum likelihood estimate is returned
01140 // what = 2: Profile Likelihood of Maximum Likelihood estimate is returned.
01141 // what = 3: Profile Likelihood of Test hypothesis is returned
01142 // otherwise parameters as described in the beginning of the class)
01143 
01144    Double_t f = 0.;
01145    Double_t  v = sde * sde;
01146    Double_t  u = sdb * sdb;
01147 
01148    if (what == 1) {
01149       f = (x - bm) / em;
01150    }
01151 
01152 
01153    if (what == 2) {
01154       mu = (x - bm) / em;
01155       Double_t b  = bm;
01156       Double_t e  = em;
01157       f  = LikeMod3(mu, b, e, x, bm, em, u, v);
01158    }
01159 
01160 
01161    if (what == 3) {
01162       if (mu == 0.0) {
01163          Double_t b = ((bm - u) + TMath::Sqrt((bm - u) * (bm - u) + 4 * x * u)) / 2.;
01164          Double_t e = em;
01165          f = LikeMod3(mu, b, e, x, bm, em, u, v);
01166       } else {
01167          Double_t e = em; 
01168          Double_t b = bm; 
01169          if ( v > 0) { 
01170             Double_t temp[3];
01171             temp[0] = mu * mu * v + u;
01172             temp[1] = mu * mu * mu * v * v + mu * v * u - mu * mu * v * em + mu * v * bm - 2 * u * em;
01173             temp[2] = mu * mu * v * v * bm - mu * v * u * em - mu * v * bm * em + u * em * em - mu * mu * v * v * x;
01174             e = (-temp[1] + TMath::Sqrt(temp[1] * temp[1] - 4 * temp[0] * temp[2])) / 2 / temp[0];
01175             b = bm - (u * (em - e)) / v / mu;
01176          }
01177          f = LikeMod3(mu, b, e, x, bm, em, u, v);
01178       }
01179    }
01180 
01181    return f;
01182 }
01183 
01184 //____________________________________________________________________
01185 Double_t TRolke::LikeMod3(Double_t mu, Double_t b, Double_t e, Int_t x, Double_t bm, Double_t em, Double_t u, Double_t v)
01186 {
01187 // Profile Likelihood function for MODEL 3:
01188 // Gauss background/Gauss Efficiency
01189 
01190    double s = e*mu+b;
01191    double lls = - s;
01192    if (x > 0) lls = x*TMath::Log(s) - s - LogFactorial(x); 
01193    double llb =  0;
01194    if ( u > 0) llb = - 0.9189385 - TMath::Log(u) / 2 - (bm - b)*(bm - b) / u / 2;
01195    double lle = 0; 
01196    if ( v > 0) lle = - 0.9189385 - TMath::Log(v) / 2 - (em - e)*(em - e) / v / 2;
01197 
01198    return 2*( lls + llb + lle);
01199 
01200 }
01201 
01202 //____________________________________________________________________
01203 Double_t TRolke::EvalLikeMod4(Double_t mu, Int_t x, Int_t y, Double_t tau, Int_t what)
01204 {
01205 // Calculates the Profile Likelihood for MODEL 4:
01206 // Poiss  background/Efficiency known
01207 // what = 1: Maximum likelihood estimate is returned
01208 // what = 2: Profile Likelihood of Maximum Likelihood estimate is returned.
01209 // what = 3: Profile Likelihood of Test hypothesis is returned
01210 // otherwise parameters as described in the beginning of the class)
01211    Double_t f = 0.0;
01212 
01213    if (what == 1) f = x - y / tau;
01214    if (what == 2) {
01215       mu = x - y / tau;
01216       Double_t b  = y / tau;
01217       f  = LikeMod4(mu, b, x, y, tau);
01218    }
01219    if (what == 3) {
01220       if (mu == 0.0) {
01221          Double_t b = Double_t(x + y) / (1 + tau);
01222          f = LikeMod4(mu, b, x, y, tau);
01223       } else {
01224          Double_t b = (x + y - (1 + tau) * mu + sqrt((x + y - (1 + tau) * mu) * (x + y - (1 + tau) * mu) + 4 * (1 + tau) * y * mu)) / 2 / (1 + tau);
01225          f = LikeMod4(mu, b, x, y, tau);
01226       }
01227    }
01228    return f;
01229 }
01230 
01231 //___________________________________________________________________
01232 Double_t TRolke::LikeMod4(Double_t mu, Double_t b, Int_t x, Int_t y, Double_t tau)
01233 {
01234 // Profile Likelihood function for MODEL 4:
01235 // Poiss background/Efficiency known
01236 
01237    double s = mu+b;
01238    double lls = - s;
01239    if (x > 0) lls = x*TMath::Log(s) - s - LogFactorial(x); 
01240    double bg = tau*b;
01241    double llb =  -bg;
01242    if ( y > 0) llb =  y*TMath::Log( bg) - bg - LogFactorial(y);
01243 
01244    return 2*( lls + llb);
01245 }
01246 
01247 //___________________________________________________________________
01248 Double_t TRolke::EvalLikeMod5(Double_t mu, Int_t x, Double_t bm, Double_t sdb, Int_t what)
01249 {
01250 // Calculates the Profile Likelihood for MODEL 5:
01251 // Gauss  background/Efficiency known
01252 // what = 1: Maximum likelihood estimate is returned
01253 // what = 2: Profile Likelihood of Maximum Likelihood estimate is returned.
01254 // what = 3: Profile Likelihood of Test hypothesis is returned
01255 // otherwise parameters as described in the beginning of the class)
01256 
01257    Double_t u = sdb * sdb;
01258    Double_t f = 0;
01259 
01260    if (what == 1) {
01261       f = x - bm;
01262    }
01263    if (what == 2) {
01264       mu = x - bm;
01265       Double_t b  = bm;
01266       f  = LikeMod5(mu, b, x, bm, u);
01267    }
01268 
01269    if (what == 3) {
01270       Double_t b = ((bm - u - mu) + TMath::Sqrt((bm - u - mu) * (bm - u - mu) - 4 * (mu * u - mu * bm - u * x))) / 2;
01271       f = LikeMod5(mu, b, x, bm, u);
01272    }
01273    return f;
01274 }
01275 
01276 //_______________________________________________________________________
01277 Double_t TRolke::LikeMod5(Double_t mu, Double_t b, Int_t x, Double_t bm, Double_t u)
01278 {
01279 // Profile Likelihood function for MODEL 5:
01280 // Gauss background/Efficiency known
01281 
01282    double s = mu+b;
01283    double lls = - s;
01284    if (x > 0) lls = x*TMath::Log(s) - s - LogFactorial(x); 
01285    double llb =  0;
01286    if ( u > 0) llb = - 0.9189385 - TMath::Log(u) / 2 - (bm - b)*(bm - b) / u / 2;
01287 
01288    return 2*( lls + llb);
01289 }
01290 
01291 //_______________________________________________________________________
01292 Double_t TRolke::EvalLikeMod6(Double_t mu, Int_t x, Int_t z, Double_t b, Int_t m, Int_t what)
01293 {
01294 // Calculates the Profile Likelihood for MODEL 6:
01295 // Background known/Efficiency binomial
01296 // what = 1: Maximum likelihood estimate is returned
01297 // what = 2: Profile Likelihood of Maximum Likelihood estimate is returned.
01298 // what = 3: Profile Likelihood of Test hypothesis is returned
01299 // otherwise parameters as described in the beginning of the class)
01300 
01301    Double_t coef[4], roots[3];
01302    Double_t f = 0.;
01303    Double_t zm = Double_t(z) / m;
01304 
01305    if (what == 1) {
01306       f = (x - b) / zm;
01307    }
01308 
01309    if (what == 2) {
01310       mu = (x - b) / zm;
01311       Double_t e  = zm;
01312       f  = LikeMod6(mu, b, e, x, z, m);
01313    }
01314    if (what == 3) {
01315       Double_t e;
01316       if (mu == 0) {
01317          e = zm;
01318       } else {
01319          coef[3] = mu * mu;
01320          coef[2] = mu * b - mu * x - mu * mu - mu * m;
01321          coef[1] = mu * x - mu * b + mu * z - m * b;
01322          coef[0] = b * z;
01323          TMath::RootsCubic(coef, roots[0], roots[1], roots[2]);
01324          e = roots[1];
01325       }
01326       f = LikeMod6(mu, b, e, x, z, m);
01327    }
01328    return f;
01329 }
01330 
01331 //_______________________________________________________________________
01332 Double_t TRolke::LikeMod6(Double_t mu, Double_t b, Double_t e, Int_t x, Int_t z, Int_t m)
01333 {
01334 // Profile Likelihood function for MODEL 6:
01335 // background known/ Efficiency binomial
01336 
01337    double s = e*mu+b;
01338    double lls = - s;
01339    if (x > 0) lls = x*TMath::Log(s) - s - LogFactorial(x); 
01340 
01341    double lle = 0; 
01342    if (z == 0)        lle = m * TMath::Log(1-e); 
01343    else if ( z == m)  lle = m * TMath::Log(e); 
01344    else               lle =   z * TMath::Log(e) + (m - z)*TMath::Log(1 - e) + LogFactorial(m) - LogFactorial(m-z) - LogFactorial(z); 
01345 
01346    return 2* (lls + lle); 
01347 }
01348 
01349 
01350 //___________________________________________________________________________
01351 Double_t TRolke::EvalLikeMod7(Double_t mu, Int_t x, Double_t em, Double_t sde, Double_t b, Int_t what)
01352 {
01353 // Calculates the Profile Likelihood for MODEL 7:
01354 // background known/Efficiency Gauss
01355 // what = 1: Maximum likelihood estimate is returned
01356 // what = 2: Profile Likelihood of Maximum Likelihood estimate is returned.
01357 // what = 3: Profile Likelihood of Test hypothesis is returned
01358 // otherwise parameters as described in the beginning of the class)
01359 
01360    Double_t v = sde * sde;
01361    Double_t f = 0.;
01362 
01363    if (what ==  1) {
01364       f = (x - b) / em;
01365    }
01366 
01367    if (what == 2) {
01368       mu = (x - b) / em;
01369       Double_t e  = em;
01370       f  = LikeMod7(mu, b, e, x, em, v);
01371    }
01372 
01373    if (what == 3) {
01374       Double_t e;
01375       if (mu == 0) {
01376          e = em;
01377       } else {
01378          e = (-(mu * em - b - mu * mu * v) - TMath::Sqrt((mu * em - b - mu * mu * v) * (mu * em - b - mu * mu * v) + 4 * mu * (x * mu * v - mu * b * v + b * em))) / (- mu) / 2;
01379       }
01380       f = LikeMod7(mu, b, e, x, em, v);
01381    }
01382 
01383    return f;
01384 }
01385 
01386 //___________________________________________________________________________
01387 Double_t TRolke::LikeMod7(Double_t mu, Double_t b, Double_t e, Int_t x, Double_t em, Double_t v)
01388 {
01389 // Profile Likelihood function for MODEL 6:
01390 // background known/ Efficiency gaussian
01391 
01392    double s = e*mu+b;
01393    double lls = - s;
01394    if (x > 0) lls = x*TMath::Log(s) - s - LogFactorial(x); 
01395 
01396    double lle = 0; 
01397    if ( v > 0) lle = - 0.9189385 - TMath::Log(v) / 2 - (em - e)*(em - e) / v / 2;
01398 
01399    return 2*( lls + lle);
01400 }
01401 
01402 //______________________________________________________________________
01403 Double_t TRolke::EvalPolynomial(Double_t x, const Int_t  coef[], Int_t N)
01404 {
01405 // evaluate polynomial
01406    const Int_t   *p;
01407    p = coef;
01408    Double_t ans = *p++;
01409    Int_t i = N;
01410 
01411    do
01412       ans = ans * x  +  *p++;
01413    while (--i);
01414 
01415    return ans;
01416 }
01417 
01418 //______________________________________________________________________
01419 Double_t TRolke::EvalMonomial(Double_t x, const Int_t coef[], Int_t N)
01420 {   
01421 // evaluate mononomial
01422    Double_t ans;
01423    const Int_t   *p;
01424 
01425    p   = coef;
01426    ans = x + *p++;
01427    Int_t i = N - 1;
01428 
01429    do
01430       ans = ans * x  + *p++;
01431    while (--i);
01432 
01433    return ans;
01434 }
01435 
01436 //______________________________________________________________________
01437 Double_t TRolke::LogFactorial(Int_t n)
01438 {
01439 // LogFactorial function (use the logGamma function via the relation Gamma(n+1) = n!
01440 
01441    return TMath::LnGamma(n+1);
01442 }
01443 
01444 

Generated on Tue Jul 5 14:37:48 2011 for ROOT_528-00b_version by  doxygen 1.5.1