StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StPmtSignal.cxx
1 // $Id: StPmtSignal.cxx,v 1.5 2007/09/11 21:49:15 kocolosk Exp $
2 
3 #include "StPmtSignal.h"
4 
5 #include "TMath.h"
6 
7 #include "StMessMgr.h"
8 
9 ClassImp(StPmtSignal)
10 
11 StPmtSignal::StPmtSignal(float pmtGain, float cathodeNoise, float dynodeNoise) :
12  TNamed("HAMAMATSU-R6427", "Bases used in Beam test-98"),
13  mPmtGain(pmtGain), mCathodeNoise(cathodeNoise), mDynodeNoise(dynodeNoise) {
14 
15  float tmpArray[mNumDynodes] = {2.,2.,1.,1.,1.,1.,1.,1., 2., 3., 4.};
16  for(int i=0; i<mNumDynodes; i++) mNodeVoltage[i] = tmpArray[i];
17 
18  //calculate secondary electron conversion coefficients
19  float voltageProduct = 1.0;
20  for(int i=0; i<mNumDynodes; i++) {
21  voltageProduct *= mNodeVoltage[i];
22  }
23  float globalCoeff = TMath::Power( double(mPmtGain/voltageProduct), 1.0/(mNumDynodes) );
24  for(int i=0; i<mNumDynodes; i++) {
25  mSecondaryCoeff[i] = globalCoeff * mNodeVoltage[i];
26  }
27 
28  //calculate inverted partial gains after each dynode
29  mDynodeGain[0] = 1.0;
30  for(int i=0; i<mNumDynodes; i++) {
31  mDynodeGain[i+1] = mDynodeGain[i] / mSecondaryCoeff[i];
32  }
33 
34  //calculate g1=G-1 constants (see SN301)
35  mG1[mNumDynodes] = 0.0;
36  for(int i=mNumDynodes; i>0; i--) {
37  mG1[i-1] = (1.0 + mG1[i]) / mSecondaryCoeff[i-1];
38  }
39 
40  //only for fast simulator
41  mDNW[mNumDynodes] = 0.0;
42  for(int i=mNumDynodes; i>0; i--) {
43  mDNW[i-1] = mDynodeNoise * (1.0+mG1[i]) * mDynodeGain[i] * mDynodeGain[i] + mDNW[i];
44  }
45 
46  LOG_DEBUG << "StPmtSignal properties for " << this->GetName() << " and " << this->GetTitle() << endm;
47  LOG_DEBUG << "nDynodes = " << mNumDynodes << endm;
48  LOG_DEBUG << "cathode noise = " << mCathodeNoise << endm;
49  LOG_DEBUG << "dynode noise = " << mDynodeNoise << endm;
50  LOG_DEBUG << "approximate PMT gain = " << mPmtGain << endm;
51 }
52 
53 int StPmtSignal::getAdc(int nPhotoElectrons, simulatorVersion version) {
54  double nElectrons = nPhotoElectrons + mRandom.PoissonD(mCathodeNoise);
55 
56  double ADC = 0.0;
57 
58  if(version == kFastSimulator) {
59  int i;
60  for(i=0; i<mNumDynodes; i++) {
61  if(nElectrons >= 100) break;
62  nElectrons = mRandom.PoissonD( mSecondaryCoeff[i] * nElectrons + mDynodeNoise );
63  }
64  ADC += mTotalGain * (nElectrons + mDynodeNoise*mG1[i]) * mDynodeGain[i];
65  ADC += mRandom.Gaus(mPedestalMean, TMath::Sqrt(mTotalGain*(ADC*mG1[i]*mDynodeGain[i] + mTotalGain*mDNW[i]) + mPedestalRMS*mPedestalRMS) );
66  }
67  else if(version == kFullSimulator) {
68  for(int i=0; i<mNumDynodes; i++) {
69  nElectrons = mRandom.PoissonD( mSecondaryCoeff[i] * nElectrons + mDynodeNoise );
70  }
71  ADC += mTotalGain * nElectrons * mDynodeGain[mNumDynodes];
72  ADC += mRandom.Gaus(mPedestalMean, mPedestalRMS);
73  }
74  else {
75  LOG_ERROR << version << " is not a valid simulator version " << endm;
76  }
77 
78  int ret = static_cast<int>(TMath::Floor(ADC)); //why does floor() return a double? stupid
79  LOG_DEBUG << Form("hit has photoElectronGain = (%f/%d) = %e", nElectrons, nPhotoElectrons, static_cast<float>(nElectrons/nPhotoElectrons)) << endm;
80 
81  return ret;
82 }
83 
84 /*****************************************************************************
85  * $Log: StPmtSignal.cxx,v $
86  * Revision 1.5 2007/09/11 21:49:15 kocolosk
87  * complete overhaul of the BEMC simulator
88  * http://www.star.bnl.gov/HyperNews-star/get/emc2/2486.html
89  *
90  *****************************************************************************/
int getAdc(int nPhotoElectrons, simulatorVersion version)
return ADC counts for a given # of incident photoelectrons
Definition: StPmtSignal.cxx:53