00001
00002
00003 #include "StPmtSignal.h"
00004
00005 #include "TMath.h"
00006
00007 #include "StMessMgr.h"
00008
00009 ClassImp(StPmtSignal)
00010
00011 StPmtSignal::StPmtSignal(float pmtGain, float cathodeNoise, float dynodeNoise) :
00012 TNamed("HAMAMATSU-R6427", "Bases used in Beam test-98"),
00013 mPmtGain(pmtGain), mCathodeNoise(cathodeNoise), mDynodeNoise(dynodeNoise) {
00014
00015 float tmpArray[mNumDynodes] = {2.,2.,1.,1.,1.,1.,1.,1., 2., 3., 4.};
00016 for(int i=0; i<mNumDynodes; i++) mNodeVoltage[i] = tmpArray[i];
00017
00018
00019 float voltageProduct = 1.0;
00020 for(int i=0; i<mNumDynodes; i++) {
00021 voltageProduct *= mNodeVoltage[i];
00022 }
00023 float globalCoeff = TMath::Power( double(mPmtGain/voltageProduct), 1.0/(mNumDynodes) );
00024 for(int i=0; i<mNumDynodes; i++) {
00025 mSecondaryCoeff[i] = globalCoeff * mNodeVoltage[i];
00026 }
00027
00028
00029 mDynodeGain[0] = 1.0;
00030 for(int i=0; i<mNumDynodes; i++) {
00031 mDynodeGain[i+1] = mDynodeGain[i] / mSecondaryCoeff[i];
00032 }
00033
00034
00035 mG1[mNumDynodes] = 0.0;
00036 for(int i=mNumDynodes; i>0; i--) {
00037 mG1[i-1] = (1.0 + mG1[i]) / mSecondaryCoeff[i-1];
00038 }
00039
00040
00041 mDNW[mNumDynodes] = 0.0;
00042 for(int i=mNumDynodes; i>0; i--) {
00043 mDNW[i-1] = mDynodeNoise * (1.0+mG1[i]) * mDynodeGain[i] * mDynodeGain[i] + mDNW[i];
00044 }
00045
00046 LOG_DEBUG << "StPmtSignal properties for " << this->GetName() << " and " << this->GetTitle() << endm;
00047 LOG_DEBUG << "nDynodes = " << mNumDynodes << endm;
00048 LOG_DEBUG << "cathode noise = " << mCathodeNoise << endm;
00049 LOG_DEBUG << "dynode noise = " << mDynodeNoise << endm;
00050 LOG_DEBUG << "approximate PMT gain = " << mPmtGain << endm;
00051 }
00052
00053 int StPmtSignal::getAdc(int nPhotoElectrons, simulatorVersion version) {
00054 double nElectrons = nPhotoElectrons + mRandom.PoissonD(mCathodeNoise);
00055
00056 double ADC = 0.0;
00057
00058 if(version == kFastSimulator) {
00059 int i;
00060 for(i=0; i<mNumDynodes; i++) {
00061 if(nElectrons >= 100) break;
00062 nElectrons = mRandom.PoissonD( mSecondaryCoeff[i] * nElectrons + mDynodeNoise );
00063 }
00064 ADC += mTotalGain * (nElectrons + mDynodeNoise*mG1[i]) * mDynodeGain[i];
00065 ADC += mRandom.Gaus(mPedestalMean, TMath::Sqrt(mTotalGain*(ADC*mG1[i]*mDynodeGain[i] + mTotalGain*mDNW[i]) + mPedestalRMS*mPedestalRMS) );
00066 }
00067 else if(version == kFullSimulator) {
00068 for(int i=0; i<mNumDynodes; i++) {
00069 nElectrons = mRandom.PoissonD( mSecondaryCoeff[i] * nElectrons + mDynodeNoise );
00070 }
00071 ADC += mTotalGain * nElectrons * mDynodeGain[mNumDynodes];
00072 ADC += mRandom.Gaus(mPedestalMean, mPedestalRMS);
00073 }
00074 else {
00075 LOG_ERROR << version << " is not a valid simulator version " << endm;
00076 }
00077
00078 int ret = static_cast<int>(TMath::Floor(ADC));
00079 LOG_DEBUG << Form("hit has photoElectronGain = (%f/%d) = %e", nElectrons, nPhotoElectrons, static_cast<float>(nElectrons/nPhotoElectrons)) << endm;
00080
00081 return ret;
00082 }
00083
00084
00085
00086
00087
00088
00089
00090