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

FitterEM.cxx

Go to the documentation of this file.
00001 #include <map>
00002 #include <vector>
00003 #include "TMatrixD.h"
00004 #include "TF2.h"
00005 #include "Conventions/PlaneView.h"
00006 #include "Conventions/StripEnd.h"
00007 #include "Validity/VldContext.h"
00008 #include "Calibrator/Calibrator.h"
00009 #include "MessageService/MsgService.h"
00010 #include "FitterEM.h"
00011 #include "KeyFunc.cc"
00012 #include "rte.cc"
00013 #include "CalcEM.cc"
00014 #include "TROOT.h"
00015 #include "TMath.h"
00016 
00017 #define DELTA_T 0.145
00018 #define DELTA_R 0.101
00019 #define DELTA_PHI 2*2.*TMath::Pi()/360.
00020 #define EPSILON 1
00021 #define CUTOFF 1e-6 //1e-7
00022 #define MIPCUT 1.0
00023 #define NPAR 6 
00024 
00025 using namespace std;
00026 
00027 CVSID("$Id: FitterEM.cxx,v 1.2 2004/09/29 00:07:29 cbs Exp $");
00028 
00029 FitterEM::FitterEM(){
00030   //this constructor is just for testing function
00031   //do not use
00032   fNStp = 1;
00033 
00034   fNPlanes = 0;
00035   fMinBoxPlane = 999;
00036   fMaxBoxPlane = 0;
00037   fNStrips = 0;
00038   fMinBoxStrip = 999;
00039   fMaxBoxStrip = 0;
00040 
00041   fclosestPlaneToVtx = -1;
00042   fclosestZedDiff = 99999;
00043   fclosestZedView = 0;
00044   fclosestUStripToVtx = -1;
00045   fclosestVStripToVtx = -1;
00046   fclosestTPosUDiff = 99999;
00047   fclosestTPosVDiff = 99999;
00048 
00049   fTotMip = 0;
00050   fPlaneArray = new Int_t[fNStp];
00051   fStripArray = new Int_t[fNStp];
00052   fViewArray  = new Int_t[fNStp];
00053   fMipArray   = new Double_t[fNStp];
00054   fZedArray   = new Double_t[fNStp];
00055   fTPosArray  = new Double_t[fNStp];
00056   fBoxPlaneArray = new Int_t[fNStp];
00057   fBoxStripArray = new Int_t[fNStp];
00058   fMips = NULL;
00059 
00060   fEnergy = 0;
00061   fVtx = NULL;
00062   fdudz = 1;
00063   fdvdz = 1;
00064 
00065   fCache = new CacherEM();
00066   fBinCorrel = NULL;
00067 
00068   fPass = true; //start out optimistic
00069   fFittedPars = NULL; //these always constitute the "Current" fit params
00070   fFittedErr = NULL;
00071   fChi2Min = 99999;
00072   fNDF = 0;
00073   fNiter = 0;
00074   fStepSize = NULL;  
00075   fNSteps = NULL;  
00076 
00077   fSignStat = 0;
00078   fRunStat = 0;
00079   fKSStat = 0;
00080 
00081 }
00082 
00083 //**************************************************
00084 FitterEM::FitterEM(Int_t nstp,CandStripHandleItr itr){
00085 
00086   fNStp = nstp;
00087   fDataStpItr = itr;
00088 
00089   fNPlanes = 0;
00090   fMinBoxPlane = 999;
00091   fMaxBoxPlane = 0;
00092   fNStrips = 0;
00093   fMinBoxStrip = 999;
00094   fMaxBoxStrip = 0;
00095 
00096   fclosestPlaneToVtx = -1;
00097   fclosestZedDiff = 99999;
00098   fclosestZedView = 0;
00099   fclosestUStripToVtx = -1;
00100   fclosestVStripToVtx = -1;
00101   fclosestTPosUDiff = 99999;
00102   fclosestTPosVDiff = 99999;
00103 
00104   fTotMip = 0;
00105   fPlaneArray = new Int_t[fNStp];
00106   fStripArray = new Int_t[fNStp];
00107   fViewArray  = new Int_t[fNStp];
00108   fMipArray   = new Double_t[fNStp];
00109   fZedArray   = new Double_t[fNStp];
00110   fTPosArray  = new Double_t[fNStp];
00111   fBoxPlaneArray = new Int_t[fNStp];
00112   fBoxStripArray = new Int_t[fNStp];
00113   fMips = NULL;
00114 
00115   SetUpStripInfo();
00116 
00117   fEnergy = 0;
00118   fVtx = NULL;
00119   fdudz = 1;
00120   fdvdz = 1;
00121 
00122   fCache = new CacherEM();
00123   fBinCorrel = NULL;
00124 
00125   fPass = true; //start out optimistic
00126   fFittedPars = NULL; //these always constitute the "Current" fit params
00127   fFittedErr = NULL;
00128   fChi2Min = 99999;
00129   fNDF = 0;
00130   fNiter = 0;
00131   fStepSize = NULL;  
00132   fNSteps = NULL;  
00133 
00134   fSignStat = 0;
00135   fRunStat = 0;
00136   fKSStat = 0;
00137 
00138 }
00139 
00140 
00141 //**************************************************
00142 FitterEM::~FitterEM(){
00143   delete [] fVtx;
00144   delete [] fFittedPars;
00145   delete [] fFittedErr;
00146   delete [] fPlaneArray;
00147   delete [] fStripArray;
00148   delete [] fViewArray;
00149   delete [] fMipArray;
00150   delete [] fZedArray;
00151   delete [] fTPosArray;
00152   delete [] fBoxPlaneArray;
00153   delete [] fBoxStripArray;
00154   delete [] fMips;
00155   delete [] fStepSize;
00156   delete [] fNSteps;
00157   delete fCache;
00158   if(fBinCorrel) delete fBinCorrel;
00159   TF2 *prof = NULL; //this should have been created in the course of fitting
00160   if(gROOT->FindObject("FITSHOWEREM_2DPROFILE")) { 
00161     prof = (TF2*) gROOT->FindObject("FITSHOWEREM_2DPROFILE");
00162     delete prof;   //delete it!
00163   }
00164   MSG("FitShowerEM",Msg::kDebug) << "Deleting FitterEM" << endl;
00165 }
00166 
00167 //**************************************************
00168 void FitterEM::SetUpStripInfo(){
00169 
00170   Int_t icnt = 0;
00171   Calibrator& cal=Calibrator::Instance();
00172   
00173   while (CandStripHandle *stp = fDataStpItr()) {
00174     
00175     if(icnt==0) {
00176       const VldContext *vc = stp->GetVldContext();
00177       cal.Reset(*vc);
00178     }
00179 
00180     int plane = stp->GetPlane();
00181     int strip = stp->GetStrip();
00182     fPlaneArray[icnt] = plane;
00183     fStripArray[icnt] = strip;
00184     fViewArray[icnt]  = stp->GetPlaneView(); //U == 2, V == 3;
00185     fMipArray[icnt]   = cal.GetMIP(stp->GetCharge(CalDigitType::kSigCorr,
00186                                                   StripEnd::kWhole));
00187     fTotMip += fMipArray[icnt];
00188     fZedArray[icnt]   = stp->GetZPos();
00189     fTPosArray[icnt]  = stp->GetTPos();
00190     fBoxPlaneArray[icnt] = 0;
00191     fBoxStripArray[icnt] = 0;
00192 
00193     MSG("FitShowerEM", Msg::kVerbose) << "pl="<<fPlaneArray[icnt]
00194                                       <<" st="<<fStripArray[icnt]
00195                                       <<" pv="<<fViewArray[icnt]
00196                                       <<" mips="<<fMipArray[icnt]
00197                                       <<endl;
00198     
00199     icnt++;
00200   }
00201 
00202 }
00203 
00204 //**************************************************
00205 void FitterEM::SetInputParams(Double_t energy,Double_t* vtx,
00206                               Double_t dudz,Double_t dvdz) {
00207   fEnergy = energy;
00208   fVtx = new Double_t[3]; 
00209   fVtx[0] = vtx[0]; 
00210   fVtx[1] = vtx[1]; 
00211   fVtx[2] = vtx[2];
00212   fdudz = dudz; 
00213   fdvdz = dvdz;
00214   SetUpFitBox();
00215 }
00216 
00217 //**************************************************
00218 void FitterEM::QuickInput(Double_t energy,Double_t vtxu,Double_t vtxv,
00219                           Double_t vtxz,Double_t dudz,Double_t dvdz,
00220                           Int_t view) {
00221   
00222   fFittedPars = new Double_t[NPAR];
00223   fFittedPars[0] = energy;
00224   fFittedPars[1] = vtxu/0.041; //vertex
00225   fFittedPars[2] = vtxv/0.041;
00226   fFittedPars[3] = vtxz/0.060;
00227   fFittedPars[4] = TMath::ATan(dudz*6.0/4.1); //angles in rads 
00228   fFittedPars[5] = TMath::ATan(dvdz*6.0/4.1); //in pln-stp coords
00229   
00230   fclosestZedView = view;
00231 
00232   MSG("FitShowerEM", Msg::kDebug) 
00233     << "Fit Parameters to start with:\n" 
00234     << "Energy = "<<fFittedPars[0]<<"\n"
00235     << "UVtx   = "<<fFittedPars[1]<<"\n"
00236     << "VVtx   = "<<fFittedPars[2]<<"\n"
00237     << "ZVtx   = "<<fFittedPars[3]<<"\n"
00238     << "UAng   = "<<fFittedPars[4]<<"\n"
00239     << "VAng   = "<<fFittedPars[5]<<endl;
00240 
00241 }
00242 
00243 //**************************************************
00244 Double_t *FitterEM::GetFittedPars(){
00245   //convert back from internal coords to CandFitShowerEM coords
00246   fFittedPars[0] = fFittedPars[0]; //energy is ok
00247   fFittedPars[1] = fFittedPars[1]*0.041+fVtx[0]-fclosestTPosUDiff;//u vertex
00248   fFittedPars[2] = fFittedPars[2]*0.041+fVtx[1]-fclosestTPosVDiff;//v vertex
00249   fFittedPars[3] = fFittedPars[3]*0.060+fVtx[2]-fclosestZedDiff;//z vertex
00250   fFittedPars[4] = TMath::Tan(fFittedPars[4])*4.1/6.0; //dudz
00251   fFittedPars[5] = TMath::Tan(fFittedPars[5])*4.1/6.0;//dvdz
00252   return fFittedPars; 
00253 }
00254 
00255 //**************************************************
00256 void FitterEM::SetStepSize(Double_t *stepSize) {
00257   
00258   fStepSize = new Double_t[NPAR];
00259   for(int i=0;i<NPAR;i++) fStepSize[i] = stepSize[i];
00260   
00261   fStepSize[0] *= fEnergy;           //assume a %    --> GeV
00262   fStepSize[1] /= 0.041;             //assume in m   --> units of strip
00263   fStepSize[2] /= 0.041;             //assume in m   --> units of strip
00264   fStepSize[3] /= 0.060;             //assume in m   --> units of plane
00265   
00266   //assume in deg in metre-metre --> rads in plane-strip
00267   fStepSize[4]=TMath::ATan(TMath::Tan(fStepSize[4]*TMath::Pi()/180.)*6.0/4.1);
00268   fStepSize[5]=TMath::ATan(TMath::Tan(fStepSize[5]*TMath::Pi()/180.)*6.0/4.1);
00269   
00270   MSG("FitShowerEM",Msg::kDebug) << "Step Sizes: " << fStepSize[0] 
00271                                  << " " << fStepSize[1] << " " << fStepSize[2]
00272                                  << " " << fStepSize[3] << " " << fStepSize[4]
00273                                  << " " << fStepSize[5] << endl;
00274   
00275 }
00276 
00277 //**************************************************
00278 void FitterEM::SetNSteps(Int_t *NSteps) {
00279   
00280   fNSteps = new Int_t[NPAR];
00281   for(int i=0;i<NPAR;i++) fNSteps[i] = NSteps[i];
00282 
00283   MSG("FitShowerEM",Msg::kDebug) << "Number of Steps: " << fNSteps[0] 
00284                                  << " " << fNSteps[1] << " " << fNSteps[2]
00285                                  << " " << fNSteps[3] << " " << fNSteps[4]
00286                                  << " " << fNSteps[5] << endl;
00287 }
00288 
00289 //**************************************************
00290 void FitterEM::SetUpFitBox() {
00291 
00292   //This is the tricky part...
00293   //need to move into (plane,strip) Box with vertex approx at (0,0,0)
00294   //adjust all strip numbers by appropriate transverse vtx
00295    //adjust all plane numbers by z vtx
00296   //adjust angles to be u-z, v-z projection angles in rads 
00297   //calculated in units of plane and strip
00298   //need to set fFittedPars to be the new angles and vtx in the Box coords
00299   
00300   for(int i=0;i<fNStp;i++){
00301     float ZedDiff = fZedArray[i]-fVtx[2];
00302     if(fabs(ZedDiff)<fabs(fclosestZedDiff)){
00303       fclosestZedDiff = ZedDiff;
00304       fclosestPlaneToVtx = fPlaneArray[i];
00305       fclosestZedView = fViewArray[i];
00306     }
00307   }
00308   
00309   Int_t closestOtherViewPlaneToVtxPlane = 99999;
00310   for(int i=0;i<fNStp;i++){
00311     //if this is the vertex plane, use it for finding transverse vertex
00312     if(fPlaneArray[i]==fclosestPlaneToVtx){
00313       if(fViewArray[i]==2){ //U strips
00314         float TPosDiff = fTPosArray[i]-fVtx[0];
00315         if(fabs(TPosDiff)<fabs(fclosestTPosUDiff)){
00316           fclosestTPosUDiff = TPosDiff;
00317           fclosestUStripToVtx = fStripArray[i];
00318         }
00319       }
00320       else if(fViewArray[i]==3){ //V strips
00321         float TPosDiff = fTPosArray[i]-fVtx[1];
00322         if(fabs(TPosDiff)<fabs(fclosestTPosVDiff)){
00323           fclosestTPosVDiff = TPosDiff;
00324           fclosestVStripToVtx = fStripArray[i];
00325         }
00326       }
00327     }
00328     //otherwise, if plane-view is not same as vertex plane-view, 
00329     //then use it to find vertex in other view:
00330     else if(fViewArray[i]!=fclosestZedView){
00331       //look for closest plane in other view:
00332       if(abs(fPlaneArray[i]-fclosestPlaneToVtx)<= 
00333          abs(closestOtherViewPlaneToVtxPlane-fclosestPlaneToVtx)){
00334         closestOtherViewPlaneToVtxPlane=fPlaneArray[i];
00335         if(fViewArray[i]==2){ //U strips
00336           float TPosDiff = fTPosArray[i]-fVtx[0];
00337           if(fabs(TPosDiff)<fabs(fclosestTPosUDiff)){
00338             fclosestTPosUDiff = TPosDiff;
00339             fclosestUStripToVtx = fStripArray[i];
00340           }
00341         }
00342         else if(fViewArray[i]==3){ //V strips
00343           float TPosDiff = fTPosArray[i]-fVtx[1];
00344           if(fabs(TPosDiff)<fabs(fclosestTPosVDiff)){
00345             fclosestTPosVDiff = TPosDiff;
00346             fclosestVStripToVtx = fStripArray[i];
00347           }
00348         }
00349       }
00350     }
00351   }
00352   
00353 
00354   MSG("FitShowerEM", Msg::kDebug) 
00355     << "Box Quantities: Closest Plane To Vtx="<<fclosestPlaneToVtx
00356     << " with ZedDiff="<<fclosestZedDiff
00357     << " and in View="<<fclosestZedView<<"\n"
00358     << "Closest U Strip to Vtx="<<fclosestUStripToVtx
00359     << " with TPosDiff="<<fclosestTPosUDiff<<"\n"
00360     << "Closest V Strip to Vtx="<<fclosestVStripToVtx
00361     << " with TPosDiff="<<fclosestTPosVDiff<<"\n"
00362     << "(Vertex from CandShowerEM=["<<fVtx[0]<<","<<fVtx[1]<<","<<fVtx[2]<<"])"
00363     << endl;
00364   
00365   for(int i=0;i<fNStp;i++){
00366     
00367     fBoxPlaneArray[i] = fPlaneArray[i]-fclosestPlaneToVtx;
00368     if(fViewArray[i]==2) {//U strips  
00369       fBoxStripArray[i] = fStripArray[i]-fclosestUStripToVtx; 
00370     }
00371     if(fViewArray[i]==3) {//V strips
00372       fBoxStripArray[i] = fStripArray[i]-fclosestVStripToVtx; 
00373     }
00374     
00375     if(fBoxPlaneArray[i]<fMinBoxPlane) fMinBoxPlane = fBoxPlaneArray[i];
00376     if(fBoxPlaneArray[i]>fMaxBoxPlane) fMaxBoxPlane = fBoxPlaneArray[i];
00377     if(fBoxStripArray[i]<fMinBoxStrip) fMinBoxStrip = fBoxStripArray[i];
00378     if(fBoxStripArray[i]>fMaxBoxStrip) fMaxBoxStrip = fBoxStripArray[i];
00379   }
00380 
00381 
00382   fNPlanes = fMaxBoxPlane-fMinBoxPlane+1;
00383   fNStrips = fMaxBoxStrip-fMinBoxStrip+1;
00384   
00385   //now make fMips[plane*strip] array to simplify Mip value access in fit
00386   Int_t TotStp = fNPlanes*fNStrips;
00387   fMips = new Double_t[TotStp];
00388   for(int i=0;i<TotStp;i++) fMips[i] = 0;
00389   for(int i=0;i<fNStp;i++){    
00390     int n = ((fBoxPlaneArray[i]-fMinBoxPlane)*fNStrips 
00391              + (fBoxStripArray[i] - fMinBoxStrip));
00392     fMips[n] = 100.*fMipArray[i]/fTotMip; //make everything a percentage
00393   }
00394   
00395   MSG("FitShowerEM", Msg::kDebug) 
00396     << "Box Limits: "<<"\n"
00397     << "NPlanes="<<fNPlanes<<" with Min="<<fMinBoxPlane
00398     << " and Max="<<fMaxBoxPlane<<"\n"
00399     << "NStrips="<<fNStrips<<" with Min="<<fMinBoxStrip
00400     << " and Max="<<fMaxBoxStrip<<endl;
00401 
00402   fFittedPars = new Double_t[NPAR];
00403   fFittedPars[0] = fEnergy;
00404   fFittedPars[1] = fclosestTPosUDiff/0.041; //vertex
00405   fFittedPars[2] = fclosestTPosVDiff/0.041;
00406   fFittedPars[3] = fclosestZedDiff/0.060;  
00407   fFittedPars[4] = TMath::ATan(fdudz*6.0/4.1); //angles in rads 
00408   fFittedPars[5] = TMath::ATan(fdvdz*6.0/4.1); //in pln-stp coords
00409   
00410   MSG("FitShowerEM", Msg::kDebug) 
00411     << "Fit Parameters to start with:\n" 
00412     << "Energy = "<<fFittedPars[0]<<"\n"
00413     << "UVtx   = "<<fFittedPars[1]<<"\n"
00414     << "VVtx   = "<<fFittedPars[2]<<"\n"
00415     << "ZVtx   = "<<fFittedPars[3]<<"\n"
00416     << "UAng   = "<<fFittedPars[4]<<"\n"
00417     << "VAng   = "<<fFittedPars[5]<<endl;
00418 
00419   fBinCorrel = new BinCorrelationEM(fFittedPars);
00420 
00421 }
00422   
00423 
00424 //**************************************************
00425 Double_t FitterEM::PredictEMLoss(Int_t plane,Int_t strip,Double_t &flucVal)
00426 {
00427 
00428   if(!fCache->ValidPS(fFittedPars)){
00429     fCache->ClearPSCache();
00430     double sumE = 0;
00431     vector<rte> rtmap;
00432     
00433     if(!fCache->ValidRT(fFittedPars)){
00434       fCache->ClearCache();
00435       rtmap = RTCalc(fFittedPars[0],DELTA_T,DELTA_R,EPSILON,CUTOFF,sumE);
00436       fCache->StoreRT(NPAR,fFittedPars,rtmap,sumE);
00437       fCache->PrintRTMap();
00438     }
00439     else {
00440       rtmap = fCache->GetRTMap();
00441       sumE = fCache->GetSumE();
00442     }
00443     
00444     map<int,spef> psmap = PSCalc(rtmap,fclosestZedView,
00445                                  fFittedPars[1],fFittedPars[2],
00446                                  fFittedPars[3],fFittedPars[4],
00447                                  fFittedPars[5],DELTA_PHI,sumE);
00448     fCache->StorePS(NPAR,fFittedPars,psmap);
00449     fCache->PrintPSMap();
00450   }
00451  
00452   map<int,spef> spmap = fCache->GetPSMap();
00453   int key = MakeKey(plane,strip);
00454   map<int,spef>::iterator theOne = spmap.find(key);
00455   map<int,spef>::iterator end = spmap.end();
00456   if(theOne==end) {
00457     flucVal = 0.;
00458     return 0;
00459   }
00460   flucVal = theOne->second.fl;
00461   return theOne->second.en;
00462   
00463 }
00464 
00465 //**************************************************
00466 Double_t FitterEM::CalculateChi2(){
00467   
00468   fBinCorrel->ReInit(fFittedPars);
00469   Double_t *ErrArray = fBinCorrel->GetErrArray(fMinBoxPlane,fMaxBoxPlane,
00470                                                fMinBoxStrip,fMaxBoxStrip);
00471   
00472   Int_t TotStp = fNPlanes*fNStrips;
00473 
00474   //for holding all necessary function values during calculation
00475   Double_t *ff = new Double_t[TotStp];  //fit func values
00476   Double_t *fff = new Double_t[TotStp]; //fit func fluctuations
00477   for(Int_t i=0;i<TotStp;i++) { 
00478     ff[i] = -1; 
00479     fff[i] = 0.; 
00480   }
00481   
00482   Double_t lastDiagTerm = 1;
00483   Double_t flucVal = 0;
00484   //normalise covariance matrix using function: (make ff a percentage)
00485   for(Int_t i=0;i<TotStp;i++){
00486     if(ff[i]==-1) {
00487       ff[i] = 100.*PredictEMLoss(fMinBoxPlane+i/fNStrips,
00488                                  fMinBoxStrip+i%fNStrips,flucVal);    
00489       fff[i] = 100.*flucVal;
00490     }
00491     for(Int_t j=0;j<TotStp;j++){
00492       if(ff[j]==-1) {
00493         ff[j] = 100.*PredictEMLoss(fMinBoxPlane+j/fNStrips,
00494                                    fMinBoxStrip+j%fNStrips,flucVal);
00495         fff[j] = 100.*flucVal;
00496       }
00497       ErrArray[i*TotStp+j]*=(fff[i]*fff[j]);
00498       if(i==j) {
00499         if(ErrArray[i*TotStp+j]==0) ErrArray[i*TotStp+j] = lastDiagTerm;
00500         else lastDiagTerm = ErrArray[i*TotStp+j];
00501         MSG("FitShowerEM", Msg::kVerbose) << "ErrArray: " 
00502                                           << ErrArray[i*TotStp+j]
00503                                           << endl;      
00504       }
00505       
00506     }
00507   }
00508   
00509   //invert covariance matrix:
00510   Double_t *InvArray = new Double_t[TotStp*TotStp];
00511   TMatrixD matrix(TotStp,TotStp);
00512   matrix.SetMatrixArray(ErrArray);
00513   matrix.Invert();
00514   if(matrix.IsValid()) matrix.GetMatrix2Array(InvArray);
00515   else return -1.0;
00516 
00517   //loop through again to calculate chi2
00518   Double_t Chi2 = 0;
00519   Double_t signStat = 0;
00520   Double_t nValidPoints = 0;
00521   for(Int_t i=0;i<TotStp;i++){
00522     MSG("FitShowerEM", Msg::kVerbose) << "MIP: " << fMips[i] 
00523                                       << " FF: " << ff[i] << endl;
00524     if(fMips[i]>ff[i]) signStat+=1;
00525     nValidPoints+=1;
00526     for(Int_t j=0;j<TotStp;j++){
00527       Chi2+=(fMips[i]-ff[i])*InvArray[i*TotStp+j]*(fMips[j]-ff[j]);
00528     }
00529   }
00530   
00531   fSignStat = signStat/nValidPoints;
00532   fNDF=TotStp;
00533  
00534   delete [] InvArray;
00535   delete [] ff;
00536 
00537   return Chi2;
00538   
00539 }
00540 
00541 //**************************************************
00542 void FitterEM::DoFit(){
00543 
00544   MSG("FitShowerEM", Msg::kDebug) << "In DoFit()" << endl;
00545 
00546   fFittedErr = new Double_t[NPAR];
00547   
00548   Double_t *BestPars = new Double_t[NPAR];  
00549   Double_t *parlowlim = new Double_t[NPAR];
00550   Double_t *parupplim = new Double_t[NPAR];
00551   Int_t nvarypar = 0;
00552   
00553   for(Int_t i=0;i<NPAR;i++){    
00554     if(fStepSize[i]==0||fNSteps[i]<1) {
00555       parlowlim[i] = fFittedPars[i];
00556       parupplim[i] = fFittedPars[i];
00557     }
00558     else {
00559       parlowlim[i] = fFittedPars[i] - fNSteps[i]*fStepSize[i];
00560       parupplim[i] = fFittedPars[i] + fNSteps[i]*fStepSize[i];      
00561       nvarypar += 1;
00562     }
00563   }
00564 
00565   for(Double_t a=parlowlim[0];a<=parupplim[0];a+=fStepSize[0]){
00566     fFittedPars[0] = a;
00567     for(Double_t b=parlowlim[1];b<=parupplim[1];b+=fStepSize[1]){
00568       fFittedPars[1] = b;
00569       for(Double_t c=parlowlim[2];c<=parupplim[2];c+=fStepSize[2]){
00570         fFittedPars[2] = c;
00571         for(Double_t d=parlowlim[3];d<=parupplim[3];d+=fStepSize[3]){
00572           fFittedPars[3] = d;
00573           for(Double_t e=parlowlim[4];e<=parupplim[4];e+=fStepSize[4]){
00574             fFittedPars[4] = e;
00575             for(Double_t f=parlowlim[5];f<=parupplim[5];f+=fStepSize[5]){
00576               fFittedPars[5] = f;
00577 
00578               MSG("FitShowerEM", Msg::kDebug) 
00579                 <<a<<" "<<b<<" "<<c<<" "<<d<<" "<<e<<" "<<f<<endl;
00580               
00581               if(fFittedPars[0]<0.05) MSG("FitShowerEM", Msg::kWarning) 
00582                 <<"Energy < 50MeV! Not calculating Chi2" << endl;
00583               Double_t Chi2 = CalculateChi2();
00584               fNiter+=1;
00585               if(Chi2==-1) continue; //problem with calculation
00586               if(Chi2<fChi2Min) {
00587                 fChi2Min = Chi2;
00588                 for(Int_t i=0;i<NPAR;i++) BestPars[i] = fFittedPars[i];
00589                 fBestSignStat = fSignStat;
00590                 //DoTests();
00591               }
00592               MSG("FitShowerEM", Msg::kDebug) << "Chi2: "
00593                                               << Chi2 << endl;
00594             }
00595           }
00596         }
00597       }
00598     }
00599   }
00600   
00601   for(Int_t i=0;i<NPAR;i++) fFittedPars[i] = BestPars[i];
00602   fNDF -= nvarypar;
00603 
00604   fPass = true;
00605   if(fChi2Min==99999||fNDF<=0) fPass = false;
00606 
00607 }
00608 
00609 //**************************************************
00610 void FitterEM::DoTests(){
00611 
00612   Int_t nValidData        = 0;
00613   Int_t nValidFunc        = 0;
00614   Double_t *DataVals      = new Double_t[fNPlanes*fNStrips];
00615   Double_t *DataVals_Asc  = new Double_t[fNPlanes*fNStrips];
00616   Double_t *FuncVals      = new Double_t[fNPlanes*fNStrips];
00617   Double_t *FuncVals_Asc  = new Double_t[fNPlanes*fNStrips];
00618   Double_t lowest_DataVal = 99999;
00619   Double_t lowest_FuncVal = 99999;
00620   Double_t flucVal = 0;
00621 
00622   for(Int_t i=0;i<fNPlanes;i++){
00623     for(Int_t j=1;j<=fNStrips;j++){
00624       Float_t bc = fMips[i*fNStrips+j];
00625       Float_t ff = PredictEMLoss(fMinBoxPlane+i,fMinBoxStrip+j,flucVal);
00626 
00627       if(ff>0){
00628         FuncVals[nValidFunc] = ff;
00629         nValidFunc+=1;
00630         if(ff<lowest_FuncVal) lowest_FuncVal = ff;
00631       }
00632       
00633       if(bc>0){
00634         DataVals[nValidData] = bc;
00635         nValidData+=1;
00636         if(bc<lowest_DataVal) lowest_DataVal = bc;
00637       }
00638     }
00639   }
00640   
00641   //put arrays into ascending order:
00642   DataVals_Asc[0] = lowest_DataVal;
00643   for(Int_t i=1;i<nValidData;i++){
00644     Double_t lowest_DataVal = 999999;
00645     for(Int_t j=0;j<nValidData;j++){
00646       if(DataVals[j]<lowest_DataVal&&DataVals[j]>DataVals_Asc[i-1])
00647         lowest_DataVal = DataVals[j];
00648     }
00649     DataVals_Asc[i] = lowest_DataVal;
00650   }
00651   delete [] DataVals;
00652 
00653   FuncVals_Asc[0] = lowest_FuncVal;
00654   for(Int_t i=1;i<nValidFunc;i++){
00655     Double_t lowest_FuncVal = 999999;
00656     for(Int_t j=0;j<nValidFunc;j++){
00657       if(FuncVals[j]<lowest_FuncVal&&FuncVals[j]>FuncVals_Asc[i-1])
00658         lowest_FuncVal = FuncVals[j];
00659     }
00660     FuncVals_Asc[i] = lowest_FuncVal;
00661   }
00662   delete [] FuncVals;
00663 
00664   //calculate number of runs and mean and variance of expected number of runs:
00665   Double_t mean_runs = 1. + 2.*nValidFunc*nValidData/(nValidData+nValidFunc);
00666   Double_t var_runs = (2.*nValidFunc*nValidData
00667                      *(2.*nValidFunc*nValidData - nValidData -nValidFunc))
00668     /((nValidFunc+nValidData)*(nValidFunc+nValidData)
00669       *(nValidFunc+nValidData-1));
00670 
00671   Double_t r = 0;
00672   Int_t nD = 0;
00673   Int_t nF = 0;
00674   Int_t currentBun = 0; // 1 => Data was last lowest; -1 => Func was last lowest
00675   Bool_t change = false;
00676 
00677   for(Int_t i=0;i<nValidData+nValidFunc;i++){
00678     if(DataVals_Asc[nD]<FuncVals_Asc[nF]) {
00679       nD+=1;
00680       if(currentBun!=1) {
00681         change = true;
00682         currentBun = 1;
00683       }
00684     }
00685     else {
00686       nF+=1;
00687       if(currentBun!=-1) {
00688         change = true;
00689         currentBun = -1;
00690       } 
00691     }
00692     if(change) {
00693       r+=1;
00694       change = false;
00695     }
00696     if(nD>=nValidData) break;
00697     if(nF>=nValidFunc) break;
00698   }
00699 
00700   fRunStat = (r - mean_runs)/sqrt(var_runs);
00701   
00702   //Now do K-S test:
00703   for(Int_t i=0;i<nValidData-1;i++){
00704     //between DataVals_Asc[i] and DataVals_Asc[i+1]
00705     //cumulative distribution value is (i+1)/nValidData
00706     //Estimate from Func by interpolating at 
00707     //(DataVals_Asc[i+1]-DataVals_Asc[i])/2.
00708     Double_t S =  Double_t(i+1)/Double_t(nValidData);
00709     Double_t theVal = (DataVals_Asc[i+1]+DataVals_Asc[i])/2.;
00710     Int_t funcIndex = -1;
00711     for(Int_t j=1;j<nValidFunc;j++){
00712       if(FuncVals_Asc[j]>theVal) {
00713         funcIndex = j;
00714         break;
00715       }
00716     }
00717     if(funcIndex==-1) funcIndex = nValidFunc-1;
00718     Double_t estimator = funcIndex-1. + (FuncVals_Asc[funcIndex]-theVal)
00719       /(FuncVals_Asc[funcIndex]-FuncVals_Asc[funcIndex-1]);
00720     estimator/=Double_t(nValidFunc);
00721     
00722     if(fabs(S-estimator)>fKSStat) fKSStat = fabs(S-estimator);
00723     
00724   }
00725 
00726   delete [] DataVals_Asc;
00727   delete [] FuncVals_Asc;
00728   return;
00729 
00730 }
00731 

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