Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

MadChi2Calc.cxx

Go to the documentation of this file.
00001 #ifndef madchi2calc_cxx
00002 #define madchi2calc_cxx
00003 #include "TFile.h"
00004 #include "TROOT.h"
00005 #include "TMath.h"
00006 #include "Mad/MadChi2Calc.h"
00007 
00008 //******************************************
00009 MadChi2Calc::MadChi2Calc(int ct) {
00010   
00011   calcType = ct;
00012 
00013   FluxMapHist = NULL;
00014   BinErr = 0.02;
00015   NormErr = 0.02;
00016   BkdXSecErr = 0.05;
00017   HeightErr = NULL;
00018 
00019 }
00020 
00021 //******************************************
00022 MadChi2Calc::~MadChi2Calc() {
00023   
00024   TFile *fluxfile;
00025   if((fluxfile = (TFile*) gROOT->FindObject("FluxFile"))) {
00026     fluxfile->Close();
00027   }
00028   
00029 }
00030 
00031 //******************************************
00032 void MadChi2Calc::SetFluxMap(TH2F *hist){
00033   
00034   if(hist==0) { //open from default file
00035     TFile *f = new TFile("CCHistos.root","READ");
00036     if(f) {
00037       f->SetName("FluxFile"); //set name so we can close file in destructor
00038       FluxMapHist = (TH2F*) f->Get("FluxMap");
00039     }
00040     else FluxMapHist = NULL;
00041     return;
00042   }
00043   FluxMapHist = hist;
00044   
00045 }
00046 
00047 //******************************************
00048 void MadChi2Calc::SetSysErrors(double err1,double err2,
00049                                double *err3,double err4){
00050   this->SetNormalisationError(err1);
00051   this->SetBinToBinError(err2);
00052   this->SetBinHeightError(err3);
00053   this->SetBkdXSecError(err4);
00054 }
00055 
00056 //******************************************
00057 double MadChi2Calc::GetChi2(TH1F *sighist,TH1F *mchist,
00058                             TH1F *bkdhist,double mcfactor) {
00059 
00060   if(!sighist||!mchist) return 0;
00061   int n = sighist->GetNbinsX();
00062   double Max = sighist->GetBinLowEdge(n+1);
00063   double Min = sighist->GetBinLowEdge(1);
00064   double *sig = new double[n];
00065   double *mc = new double[n];  
00066   double *bkd = new double[n];
00067   for(int i=0;i<n;i++){
00068     sig[i] = sighist->GetBinContent(i+1);
00069     mc[i]  = mchist->GetBinContent(i+1);
00070     if(bkdhist) bkd[i] = bkdhist->GetBinContent(i+1);
00071     else bkd[i] = 0;
00072   }
00073 
00074   double chi2 = SumChi2(n,sig,mc,bkd,mcfactor,Min,Max);
00075 
00076   delete [] sig;
00077   delete [] mc;
00078   delete [] bkd;
00079 
00080   return chi2; 
00081 
00082 }
00083 
00084 //*****************************************
00085 double MadChi2Calc::GetChi2(TH2F *sighist,TH2F *mchist,
00086                             TH2F *bkdhist,double mcfactor) {
00087 
00088   if(!sighist||!mchist) return 0;
00089   int nx = sighist->GetNbinsX();
00090   int ny = sighist->GetNbinsY();
00091   double *sig = new double[nx*ny];
00092   double *mc = new double[nx*ny];  
00093   double *bkd = new double[nx*ny];
00094   for(int i=0;i<nx;i++){
00095     for(int j=0;j<ny;j++){
00096       sig[i*ny+j] = sighist->GetBinContent(i+1,j+1);
00097       mc[i*ny+j]  = mchist->GetBinContent(i+1,j+1);
00098       if(bkdhist) bkd[i*ny+j] = bkdhist->GetBinContent(i+1,j+1);
00099       else bkd[i*ny+j] = 0;
00100     }
00101   }
00102 
00103   double chi2 = SumChi2(nx*ny,sig,mc,bkd,mcfactor,0,1);
00104 
00105   delete [] sig;
00106   delete [] mc;
00107   delete [] bkd;
00108 
00109   return chi2; 
00110 
00111 }
00112 
00113 //******************************************
00114 double MadChi2Calc::GetChi2(int n, double *sig,double *mc,
00115                             double *bkd,double mcfactor,double Min,double Max){
00116 
00117   return SumChi2(n,sig,mc,bkd,mcfactor,Min,Max);
00118 
00119 }
00120 
00121 //******************************************
00122 double MadChi2Calc::SumChi2(int n,double *sig,double *mc,
00123                             double *bkd,double mcfactor,double Min,double Max){
00124   
00125   double chi2 = 0;
00126   switch(calcType) {
00127   case 1: 
00128     for(int i=0;i<n;i++){
00129       chi2 += BasicChi2(sig[i],mc[i]/mcfactor,bkd[i]/mcfactor);
00130     }
00131     break;
00132   case 2: 
00133     chi2 = WithSysErrChi2(n,sig,mc,bkd,mcfactor,Min,Max);
00134     break;
00135   case 3:
00136     chi2 = WithSysErrLoopsChi2(n,sig,mc,bkd,mcfactor);
00137     break;
00138   default: 
00139     for(int i=0;i<n;i++){
00140       chi2 += PoisDistChi2(sig[i],mc[i]/mcfactor,bkd[i]/mcfactor);
00141     }
00142     break;
00143   }
00144 
00145   return chi2;
00146 
00147 }
00148 
00149 //******************************************
00150 double MadChi2Calc::BasicChi2(double sig,double mc,double bkd){
00151   
00152   return (mc+bkd-sig)*(mc+bkd-sig)/sig;
00153 
00154 }
00155 
00156 //******************************************
00157 double MadChi2Calc::PoisDistChi2(double sig,double mc,double bkd){
00158 
00159   if(sig==0||mc+bkd==0) return 2.*(mc+bkd-sig);
00160   return 2.*(mc+bkd-sig)+2.*sig*TMath::Log(sig/(mc+bkd));
00161 
00162 }
00163 
00164 //******************************************
00165 double MadChi2Calc::WithSysErrChi2(int n,double *sig,double *mc,
00166                                    double *bkd,double mcfactor,
00167                                    double Min,double Max){
00168 
00169   float fw = (Max-Min)/float(n);
00170   int nSquare = int(float(n)*float(n));
00171   float *ErrArray = new float[nSquare];
00172   float *InvErrArray = new float[nSquare];
00173 
00174   for(int i=0;i<n;i++){
00175     for(int j=0;j<n;j++){   
00176       
00177       float DLM = 0.;
00178       if(i==j) DLM=1.;
00179       
00180       float FSum=0.;
00181       if(FluxMapHist){
00182         for(int k=0;k<n;k++) {
00183           int binx_k = FluxMapHist->GetXaxis()->FindBin(float(k+0.5)*fw);
00184           int binx_j = FluxMapHist->GetXaxis()->FindBin(float(j+0.5)*fw);
00185           int biny   = FluxMapHist->GetYaxis()->FindBin(float(i+0.5)*fw);
00186           FSum += FluxMapHist->GetBinContent(binx_k,biny)
00187             *FluxMapHist->GetBinContent(binx_j,biny);
00188         }
00189       }
00190       
00191       ErrArray[(j*n)+i] = DLM*(mc[i]+bkd[i])/mcfactor
00192         + NormErr*NormErr*(mc[i]+bkd[i])*(mc[j]+bkd[j])/(mcfactor*mcfactor)
00193         + BinErr*BinErr*FSum*(mc[i]+bkd[i])*(mc[j]+bkd[j])/(mcfactor*mcfactor);
00194       
00195       if(HeightErr) ErrArray[(j*n)+i] += HeightErr[j]*HeightErr[j]
00196                       *(mc[i]+bkd[i])*(mc[j]+bkd[j])/(mcfactor*mcfactor);
00197       else ErrArray[(j*n)+i] += 0.02*0.02
00198              *(mc[i]+bkd[i])*(mc[j]+bkd[j])/(mcfactor*mcfactor);
00199     }
00200   }
00201   
00202   TMatrix matrix(n,n);
00203   matrix.SetMatrixArray(ErrArray);
00204   matrix.Invert(); //Error Matrix inversion
00205   matrix.GetMatrix2Array(InvErrArray);
00206   
00207   double ChiSq = 0;
00208   for(int i=0;i<n;i++){
00209     for(int j=0;j<n;j++) {
00210       ChiSq+=(sig[i]-mc[i])*InvErrArray[(j*n)+i]*(sig[j]-mc[j]);
00211     }
00212   }
00213   return ChiSq;
00214 
00215 }
00216 
00217 //******************************************
00218 double MadChi2Calc::WithSysErrLoopsChi2(int n,double *sig,double *mc,
00219                                         double *bkd,double mcfactor){
00220   
00221   int nNormBins = 40;
00222   double fracNormErr = 0.1; //up to 10% error calculated
00223   double normLoopStep = 2.*fracNormErr/double(nNormBins);
00224   
00225   int nBkdXSecBins = 40;
00226   double fracBkdXSecErr = 0.2; //up to 20% error calculated
00227   double bkdXSecLoopStep = 2.*fracBkdXSecErr/double(nBkdXSecBins);
00228   
00229   double ChiSqMin = 99999;
00230   
00231   //overall normalisation uncertainty:
00232   for(int i=0;i<nNormBins;i++){
00233     double normFactor = 1. - fracNormErr + i*normLoopStep;
00234     //Bkgd cross-section uncertainty
00235     for(int j=0;j<nBkdXSecBins;j++){
00236       double bkdXSecFactor = 1. - fracBkdXSecErr + j*bkdXSecLoopStep;
00237       //calculate sys errors
00238       double ChiSq = 0;
00239       for(int k=0;k<n;k++){
00240         ChiSq += PoisDistChi2(sig[k],normFactor*mc[k]/mcfactor,
00241                               normFactor*bkdXSecFactor*bkd[k]/mcfactor);
00242       }
00243       // Now need to add penalty terms to ChiSq 
00244       // depending on values of systematic shifts
00245       if(NormErr>0) ChiSq += TMath::Power((1.-normFactor)/NormErr,2);
00246       if(BkdXSecErr>0) ChiSq += TMath::Power((1.-bkdXSecFactor)/BkdXSecErr,2);
00247       if(ChiSq<ChiSqMin) ChiSqMin = ChiSq;
00248     }
00249   }
00250   return ChiSqMin;
00251 }
00252 #endif // #ifdef madchi2calc_cxx

Generated on Mon Feb 15 11:06:54 2010 for loon by  doxygen 1.3.9.1