TFeldmanCousins.cxx

Go to the documentation of this file.
00001 // @(#)root/physics:$Id: TFeldmanCousins.cxx 30837 2009-10-23 07:02:49Z moneta $
00002 // Author: Adrian Bevan  2001
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
00006  * Copyright (C) 2001, Liverpool University.                             *
00007  * All rights reserved.                                                  *
00008  *                                                                       *
00009  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00010  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00011  *************************************************************************/
00012 
00013 ////////////////////////////////////////////////////////////////////////////
00014 // TFeldmanCousins
00015 //
00016 // class to calculate the CL upper limit using
00017 // the Feldman-Cousins method as described in PRD V57 #7, p3873-3889
00018 //
00019 // The default confidence interval calvculated using this method is 90%
00020 // This is set either by having a default the constructor, or using the
00021 // appropriate fraction when instantiating an object of this class (e.g. 0.9)
00022 //
00023 // The simple extension to a gaussian resolution function bounded at zero
00024 // has not been addressed as yet -> `time is of the essence' as they write
00025 // on the wall of the maze in that classic game ...
00026 //
00027 //    VARIABLES THAT CAN BE ALTERED
00028 //    -----------------------------
00029 // => depending on your desired precision: The intial values of fMuMin,
00030 // fMuMax, fMuStep and fNMax are those used in the PRD:
00031 //   fMuMin = 0.0
00032 //   fMuMax = 50.0
00033 //   fMuStep= 0.005
00034 // but there is total flexibility in changing this should you desire.
00035 //
00036 //
00037 // see example of use in $ROOTSYS/tutorials/math/FeldmanCousins.C
00038 //
00039 // see note about: "Should I use TRolke, TFeldmanCousins, TLimit?"
00040 //  in the TRolke class description.
00041 //
00042 // Author: Adrian Bevan, Liverpool University
00043 //
00044 // Copyright Liverpool University 2001       bevan@slac.stanford.edu
00045 ///////////////////////////////////////////////////////////////////////////
00046 
00047 #include "Riostream.h"
00048 #include "TMath.h"
00049 #include "TFeldmanCousins.h"
00050 
00051 ClassImp(TFeldmanCousins)
00052 
00053 //______________________________________________________________________________
00054 TFeldmanCousins::TFeldmanCousins(Double_t newFC, TString options)
00055 {
00056    //constructor
00057    fCL          = newFC;
00058    fUpperLimit  = 0.0;
00059    fLowerLimit  = 0.0;
00060    fNobserved   = 0.0;
00061    fNbackground = 0.0;
00062    options.ToLower();
00063    if (options.Contains("q")) fQUICK = 1;
00064    else                       fQUICK = 0;
00065 
00066    fNMax   = 50;
00067    fMuStep = 0.005;
00068    SetMuMin();
00069    SetMuMax();
00070    SetMuStep();
00071 }
00072 
00073 
00074 //______________________________________________________________________________
00075 TFeldmanCousins::~TFeldmanCousins()
00076 {
00077 }
00078 
00079 
00080 //______________________________________________________________________________
00081 Double_t TFeldmanCousins::CalculateLowerLimit(Double_t Nobserved, Double_t Nbackground)
00082 {
00083 ////////////////////////////////////////////////////////////////////////////////////////////
00084 // given Nobserved and Nbackground, try different values of mu that give lower limits that//
00085 // are consistent with Nobserved.  The closed interval (plus any stragglers) corresponds  //
00086 // to the F&C interval                                                                    //
00087 ////////////////////////////////////////////////////////////////////////////////////////////
00088 
00089    CalculateUpperLimit(Nobserved, Nbackground);
00090    return fLowerLimit;
00091 }
00092 
00093 
00094 //______________________________________________________________________________
00095 Double_t TFeldmanCousins::CalculateUpperLimit(Double_t Nobserved, Double_t Nbackground)
00096 {
00097 ////////////////////////////////////////////////////////////////////////////////////////////
00098 // given Nobserved and Nbackground, try different values of mu that give upper limits that//
00099 // are consistent with Nobserved.  The closed interval (plus any stragglers) corresponds  //
00100 // to the F&C interval                                                                    //
00101 ////////////////////////////////////////////////////////////////////////////////////////////
00102 
00103    fNobserved   = Nobserved;
00104    fNbackground = Nbackground;
00105 
00106    Double_t mu = 0.0;
00107 
00108    // for each mu construct the ranked table of probabilities and test the
00109    // observed number of events with the upper limit
00110    Double_t min = -999.0;
00111    Double_t max = 0;
00112    Int_t iLower = 0;
00113 
00114    Int_t i;
00115    for(i = 0; i <= fNMuStep; i++) {
00116       mu = fMuMin + (Double_t)i*fMuStep;
00117       Int_t goodChoice = FindLimitsFromTable( mu );
00118       if( goodChoice ) {
00119          min = mu;
00120          iLower = i;
00121          break;
00122       }
00123    }
00124 
00125    //==================================================================
00126    // For quicker evaluation, assume that you get the same results when
00127    // you expect the uppper limit to be > Nobserved-Nbackground.
00128    // This is certainly true for all of the published tables in the PRD
00129    // and is a reasonable assumption in any case.
00130    //==================================================================
00131 
00132    Double_t quickJump = 0.0;
00133    if (fQUICK)          quickJump = Nobserved-Nbackground-fMuMin;
00134    if (quickJump < 0.0) quickJump = 0.0;
00135 
00136    for(i = iLower+1; i <= fNMuStep; i++) {
00137       mu = fMuMin + (Double_t)i*fMuStep + quickJump;
00138       Int_t goodChoice = FindLimitsFromTable( mu );
00139       if( !goodChoice ) {
00140          max = mu;
00141          break;
00142       }
00143    }
00144 
00145    fUpperLimit = max;
00146    fLowerLimit = min;
00147 
00148    return max;
00149 }
00150 
00151 
00152 //______________________________________________________________________________
00153 Int_t TFeldmanCousins::FindLimitsFromTable( Double_t mu )
00154 {
00155 ///////////////////////////////////////////////////////////////////
00156 // calculate the probability table for a given mu for n = 0, NMAX//
00157 // and return 1 if the number of observed events is consistent   //
00158 // with the CL bad                                               //
00159 ///////////////////////////////////////////////////////////////////
00160 
00161    Double_t *p          = new Double_t[fNMax];   //the array of probabilities in the interval MUMIN-MUMAX
00162    Double_t *r          = new Double_t[fNMax];   //the ratio of likliehoods = P(Mu|Nobserved)/P(MuBest|Nobserved)
00163    Int_t    *rank       = new Int_t[fNMax];      //the ranked array corresponding to R (largest first)
00164    Double_t *muBest     = new Double_t[fNMax];
00165    Double_t *probMuBest = new Double_t[fNMax];
00166 
00167    //calculate P(i | mu) and P(i | mu)/P(i | mubest)
00168    Int_t i;
00169    for(i = 0; i < fNMax; i++) {
00170       muBest[i] = (Double_t)(i - fNbackground);
00171       if(muBest[i]<0.0) muBest[i] = 0.0;
00172       probMuBest[i] = Prob(i, muBest[i],  fNbackground);
00173       p[i]          = Prob(i, mu,  fNbackground);
00174       if(probMuBest[i] == 0.0) r[i] = 0.0;
00175       else                     r[i] = p[i]/probMuBest[i];
00176    }
00177 
00178    //rank the likelihood ratio
00179    TMath::Sort(fNMax, r, rank);
00180 
00181    //search through the probability table and get the i for the CL
00182    Double_t sum = 0.0;
00183    Int_t iMax = rank[0];
00184    Int_t iMin = rank[0];
00185    for(i = 0; i < fNMax; i++) {
00186       sum += p[rank[i]];
00187       if(iMax < rank[i]) iMax = rank[i];
00188       if(iMin > rank[i]) iMin = rank[i];
00189       if(sum >= fCL) break;
00190    }
00191 
00192    delete [] p;
00193    delete [] r;
00194    delete [] rank;
00195    delete [] muBest;
00196    delete [] probMuBest;
00197 
00198    if((fNobserved <= iMax) && (fNobserved >= iMin)) return 1;
00199    else return 0;
00200 }
00201 
00202 
00203 //______________________________________________________________________________
00204 Double_t TFeldmanCousins::Prob(Int_t N, Double_t mu, Double_t B)
00205 {
00206 ////////////////////////////////////////////////
00207 // calculate the poissonian probability for   //
00208 // a mean of mu+B events with a variance of N //
00209 ////////////////////////////////////////////////
00210 
00211    return TMath::Poisson( N, mu+B);
00212 }
00213 
00214 //______________________________________________________________________________
00215 void TFeldmanCousins::SetMuMax(Double_t newMax)
00216 {
00217    //set maximum value of signal to use in calculating the tables
00218    fMuMax   = newMax;
00219    fNMax    = (Int_t)newMax;
00220    SetMuStep(fMuStep);
00221 }
00222 
00223 //______________________________________________________________________________
00224 void TFeldmanCousins::SetMuStep(Double_t newMuStep)
00225 {
00226    //set the step in signal to use when generating tables
00227    if(newMuStep == 0.0) {
00228       cout << "TFeldmanCousins::SetMuStep ERROR New step size is zero - unable to change value"<< endl;
00229       return;
00230    } else {
00231       fMuStep = newMuStep;
00232       fNMuStep = (Int_t)((fMuMax - fMuMin)/fMuStep);
00233    }
00234 }

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