00001 #include "SimPmtM64CrosstalkTable.h" 00002 #include "MessageService/MsgService.h" 00003 #include "Conventions/Munits.h" 00004 00005 CVSID("$Id: SimPmtM64CrosstalkTable.cxx,v 1.9 2008/05/06 12:49:25 tagg Exp $"); 00006 00007 ClassImp(SimPmtM64CrosstalkTable) 00008 00009 SimPmtM64CrosstalkTable::SimPmtM64CrosstalkTable( const VldContext& vc ) 00010 : fContext(vc), 00011 fCache(0), 00012 fResPtr(vc) 00013 { 00014 // Zero arrays. 00015 for(int i=0;i<65;i++) { 00016 fOptTotProb[i]=0; 00017 for(int j=0;j<65;j++) { 00018 fOptDist[i][j] = 0; 00019 fElecFrac[i][j] = 0; 00020 fElecK[i][j] = 0; 00021 } 00022 } 00023 00024 RebuildCache(); 00025 MSG("DetSim",Msg::kDebug) << "Creating SimPmtM64CrosstalkTable.\n"; 00026 } 00027 00028 void SimPmtM64CrosstalkTable::Reset(const VldContext& vc ) 00029 { 00030 if(fContext==vc) return; 00031 fResPtr.NewQuery(vc); 00032 00033 VldRange newrange = fResPtr.GetValidityRec()->GetVldRange(); 00034 00035 if( (newrange.GetTimeStart()!=fLastRange.GetTimeStart()) || 00036 (newrange.GetTimeEnd()!=fLastRange.GetTimeEnd()) || 00037 ( newrange.GetDetectorMask()!=fLastRange.GetDetectorMask()) || 00038 ( newrange.GetSimMask()!=fLastRange.GetSimMask()) ) { 00039 00040 // The vld range has changed, indicating the table has been reloaded. 00041 fLastRange = newrange; 00042 RebuildCache(); 00043 } 00044 00045 fContext=vc; 00046 } 00047 00048 const SimPmtM64Crosstalk* 00049 SimPmtM64CrosstalkTable::GetRow( Int_t injPix, Int_t xPix ) 00050 { 00051 Int_t index = injPix*100 + xPix; 00052 // return fResPtr.GetRowByIndex(index); 00053 00054 if(!fCache) { 00055 MSG("DetSim",Msg::kError) << "Crosstalk cache not yet built!" << endl; 00056 return 0; 00057 } 00058 00059 return fCache[index]; 00060 } 00061 00062 void SimPmtM64CrosstalkTable::RebuildCache() 00063 { 00064 if(fResPtr.GetNumRows()==0) return; // No data to cache. 00065 00066 const int kCacheSize = 6500; 00067 if(fCache) delete [] fCache; 00068 fCache = new const SimPmtM64Crosstalk*[kCacheSize]; 00069 for(int i=0; i<kCacheSize; i++) { 00070 fCache[i] = fResPtr.GetRowByIndex(i); 00071 } 00072 00073 for(int inj=1;inj<=64;inj++) { 00074 fOptTotProb[inj] = 0; 00075 00076 for(int xpix=1; xpix<=64; xpix++) { 00077 fOptDist[inj][xpix] = 0; 00078 fElecFrac[inj][xpix] = 0; 00079 fElecK[inj][xpix] = 0; 00080 00081 const SimPmtM64Crosstalk* row = GetRow(inj,xpix); 00082 if((row)&&(inj!=xpix)) { 00083 float optprob = row->GetOptProb(); 00084 if(optprob < 0) optprob = 0; // No negative optical crosstalk. 00085 fOptTotProb[inj] += optprob; 00086 00087 fElecFrac[inj][xpix] = row->GetElecFrac(); 00088 fElecK[inj][xpix] = row->GetElecK()*Munits::fC; //convert from fC. 00089 } 00090 fOptDist[inj][xpix] = fOptTotProb[inj]; // Cumulative probability. 00091 } 00092 00093 // Normalize the opt distribution. 00094 // .. protect against floating point error. When the FD is simualted, 00095 // the M64 model gets initialized too, even though there's no Xtalk table. 00096 float norm = 1.0; 00097 if(fOptTotProb[inj]<=0) 00098 MSG("DetSim",Msg::kError) << "Got zero total opt xtalk on pixel " << inj << ".. that shouldn't happen."<< endl; 00099 else 00100 norm = 1.0/fOptTotProb[inj]; 00101 00102 for(int xpix=1; xpix<=64; xpix++) { 00103 fOptDist[inj][xpix] *= norm; 00104 } 00105 } 00106 }
1.3.9.1