GEMC  2.3
Geant4 Monte-Carlo Framework
pcal_hitprocess.cc
Go to the documentation of this file.
1 // G4 headers
2 #include "G4Poisson.hh"
3 #include "Randomize.hh"
4 #include <math.h>
5 
6 #include <CCDB/Calibration.h>
7 #include <CCDB/Model/Assignment.h>
8 #include <CCDB/CalibrationGenerator.h>
9 using namespace ccdb;
10 
11 // gemc headers
12 #include "pcal_hitprocess.h"
13 
14 static pcConstants initializePCConstants(int runno)
15 {
16  pcConstants pcc;
17 
18  // do not initialize at the beginning, only after the end of the first event,
19  // with the proper run number coming from options or run table
20  if(runno == -1) return pcc;
21 
22  int isec,ilay,istr;
23 
24  // database
25  pcc.runNo = runno;
26  pcc.date = "2015-11-29";
27  if(getenv ("CCDB_CONNECTION") != NULL)
28  pcc.connection = (string) getenv("CCDB_CONNECTION");
29  else
30  pcc.connection = "mysql://clas12reader@clasdb.jlab.org/clas12";
31  pcc.variation = "default";
32 
33  pcc.TDC_time_to_evio = 1000.; // Currently EVIO banks receive time from rol2.c in ps (raw counts x 24 ps/chan. for both V1190/1290), so convert ns to ps.
34  pcc.ADC_MeV_to_evio = 10. ; // MIP based calibration is nominally 10 channels/MeV
35  pcc.veff = 160. ; // Effective velocity of scintillator light (mm/ns)
36  pcc.pmtPEYld = 11.5 ; // Number of p.e. divided by the energy deposited in MeV. See EC NIM paper table 1.
37  pcc.pmtQE = 0.27 ;
38  pcc.pmtDynodeGain = 4.0 ;
39  pcc.pmtDynodeK = 0.5 ; // K=0 (Poisson) K=1(exponential) vector<vector<double> > data;
40  // Fluctuations in PMT gain distributed using Gaussian with
41  // sigma=1/SNR where SNR = sqrt[(1-QE+(k*del+1)/(del-1))/npe] del = dynode gain k=0-1
42  // Adapted from G-75 (pg. 169) and and G-111 (pg. 174) from RCA PMT Handbook.
43  // Factor k for dynode statistics can range from k=0 (Poisson) to k=1 (exponential).
44  // Note: GSIM sigma was incorrect (used 1/sigma for sigma).
45  pcc.pmtFactor = sqrt(1-pcc.pmtQE+(pcc.pmtDynodeK*pcc.pmtDynodeGain+1)/(pcc.pmtDynodeGain-1));
46 
47  vector<vector<double> > data;
48  auto_ptr<Calibration> calib(CalibrationGenerator::CreateCalibration(pcc.connection));
49 
50  sprintf(pcc.database,"/calibration/ec/attenuation:%d",pcc.runNo);
51  data.clear(); calib->GetCalib(data,pcc.database);
52 
53  for(unsigned row = 0; row < data.size(); row++)
54  {
55  isec = data[row][0]; ilay = data[row][1]; istr = data[row][2];
56  pcc.attlen[isec-1][ilay-1][0].push_back(data[row][3]);
57  pcc.attlen[isec-1][ilay-1][1].push_back(data[row][4]);
58  pcc.attlen[isec-1][ilay-1][2].push_back(data[row][5]);
59  }
60 
61  return pcc;
62 }
63 
64 
66 {
67  if(pcc.runNo != runno)
68  {
69  cout << " > Initializing " << HCname << " digitization for run number " << runno << endl;
70  pcc = initializePCConstants(runno);
71  pcc.runNo = runno;
72  }
73 }
74 map<string, double> pcal_HitProcess :: integrateDgt(MHit* aHit, int hitn)
75 {
76  map<string, double> dgtz;
77  vector<identifier> identity = aHit->GetId();
78 
79  // get sector, view (U, V, W), and strip.
80  int sector = identity[0].id;
81  int module = identity[1].id;
82  int view = identity[2].id;
83  int strip = identity[3].id;
84  trueInfos tInfos(aHit);
85 
86  HCname = "PCAL Hit Process";
87 
88  // Get scintillator volume x dimension (mm)
89  double pDx2 = aHit->GetDetector().dimensions[5];
90 
91  //cout<<"pDx2="<<pDx2<<" pDy1="<<pDy1<<endl;
92 
93 
94  // Get Total Energy deposited
95  double Etota = 0;
96  double Ttota = 0;
97  double latt = 0;
98 
99  vector<G4double> Edep = aHit->GetEdep();
100  vector<G4ThreeVector> Lpos = aHit->GetLPos();
101 
102  double att;
103 
104  double A = pcc.attlen[sector-1][view-1][0][strip-1];
105  double B = pcc.attlen[sector-1][view-1][1][strip-1]*10.;
106  double C = pcc.attlen[sector-1][view-1][2][strip-1];
107 
108  //cout<<"sector "<<sector<<"view "<<view<<"strip "<<strip<<"B "<<B<<endl;
109 
110  for(unsigned int s=0; s<tInfos.nsteps; s++)
111  {
112  if(B>0)
113  {
114  double xlocal = Lpos[s].x();
115  if(view==1) latt=pDx2+xlocal;
116  if(view==2) latt=pDx2+xlocal;
117  if(view==3) latt=pDx2+xlocal;
118  att = A*exp(-latt/B)+C;
119  Etota = Etota + Edep[s]*att;
120  Ttota = Ttota + latt/pcc.veff;
121  }
122  else
123  {
124  Etota = Etota + Edep[s];
125  }
126  }
127 
128  // initialize ADC and TDC
129  int ADC = 0;
130  int TDC = 0;
131 
132  // simulate the adc value.
133  if (Etota > 0) {
134  double PC_npe = G4Poisson(Etota*pcc.pmtPEYld); //number of photoelectrons
135  if (PC_npe>0) {
136  double sigma = pcc.pmtFactor/sqrt(PC_npe);
137  double PC_MeV = G4RandGauss::shoot(PC_npe,sigma)*pcc.ADC_MeV_to_evio/pcc.pmtPEYld;
138  if (PC_MeV>0) {
139  ADC = (int) PC_MeV;
140  TDC = (int) ((tInfos.time+Ttota/tInfos.nsteps)*pcc.TDC_time_to_evio);
141  }
142  }
143  }
144 
145  // EVIO banks record time with offset determined by position of data in capture window. On forward carriage this is currently
146  // around 1.4 us. This offset is omitted in the simulation.
147 
148  dgtz["hitn"] = hitn;
149  dgtz["sector"] = sector;
150  dgtz["module"] = module;
151  dgtz["view"] = view;
152  dgtz["strip"] = strip;
153  dgtz["ADC"] = ADC;
154  dgtz["TDC"] = TDC;
155 
156  //cout << "sector = " << sector << " layer = " << module << " view = " << view << " strip = " << strip << " PL_ADC = " << ADC << " TDC = " << TDC << " Edep = " << Etot << endl;
157 
158  return dgtz;
159 }
160 
161 
162 vector<identifier> pcal_HitProcess :: processID(vector<identifier> id, G4Step* aStep, detector Detector)
163 {
164  //int sector = yid[0].id;
165  //int layer = yid[1].id;
166  //int view = yid[2].id; // get the view: U->1, V->2, W->3
167  //int strip = yid[3].id;
168  //return yid;
169  id[id.size()-1].id_sharing = 1;
170  return id;
171 }
172 
173 
174 
175 map< string, vector <int> > pcal_HitProcess :: multiDgt(MHit* aHit, int hitn)
176 {
177  map< string, vector <int> > MH;
178 
179  return MH;
180 }
181 
182 // this static function will be loaded first thing by the executable
183 pcConstants pcal_HitProcess::pcc = initializePCConstants(-1);
184 
185 
186 
187 
188 
189 
190 
map< string, vector< int > > multiDgt(MHit *, int)
double pmtDynodeGain
map< string, double > integrateDgt(MHit *, int)
char database[80]
string variation
vector< identifier > GetId()
Definition: Hit.h:103
static pcConstants pcc
vector< double > attlen[6][9][3]
double time
Definition: HitProcess.h:43
double ADC_MeV_to_evio
vector< G4ThreeVector > GetLPos()
Definition: Hit.h:76
double TDC_time_to_evio
Definition: Hit.h:22
string connection
unsigned int nsteps
Definition: HitProcess.h:39
vector< double > dimensions
vector of dimensions. Size, units depends on solid type
Definition: detector.h:77
double pmtDynodeK
void initWithRunNumber(int runno)
vector< double > GetEdep()
Definition: Hit.h:83
vector< identifier > processID(vector< identifier >, G4Step *, detector)
detector GetDetector()
Definition: Hit.h:108
double pmtFactor