GEMC  2.3
Geant4 Monte-Carlo Framework
ftof_hitprocess.cc
Go to the documentation of this file.
1 // G4 headers
2 #include "G4Poisson.hh"
3 #include "Randomize.hh"
4 
5 #include <CCDB/Calibration.h>
6 #include <CCDB/Model/Assignment.h>
7 #include <CCDB/CalibrationGenerator.h>
8 using namespace ccdb;
9 
10 // gemc headers
11 #include "ftof_hitprocess.h"
12 
13 // CLHEP units
14 #include "CLHEP/Units/PhysicalConstants.h"
15 using namespace CLHEP;
16 
17 static ftofConstants initializeFTOFConstants(int runno)
18 {
19  ftofConstants ftc;
20 
21  // do not initialize at the beginning, only after the end of the first event,
22  // with the proper run number coming from options or run table
23  if(runno == -1) return ftc;
24 
25  ftc.runNo = runno;
26  ftc.date = "2015-11-29";
27  if(getenv ("CCDB_CONNECTION") != NULL)
28  ftc.connection = (string) getenv("CCDB_CONNECTION");
29  else
30  ftc.connection = "mysql://clas12reader@clasdb.jlab.org/clas12";
31  ftc.variation = "default";
32 
33  ftc.npaddles[0] = 23;
34  ftc.npaddles[1] = 62;
35  ftc.npaddles[2] = 5;
36 
37  ftc.thick[0] = 5.0;
38  ftc.thick[1] = 6.0;
39  ftc.thick[2] = 5.0;
40 
41  ftc.dEdxMIP = 1.956; // muons in polyvinyltoluene
42  ftc.pmtPEYld = 500;
43  ftc.tdcLSB = 41.6667; // counts per ns (24 ps LSB)
44 
45  cout<<"FTOF:Setting time resolution"<<endl;
46  for(int p=0; p<3; p++)
47  {
48  for(int c=1; c<ftc.npaddles[p]+1;c++)
49  {
50  if(p==0) ftc.tres[p].push_back(1e-3*(c*5.45+74.55)); //ps to ns
51  if(p==1) ftc.tres[p].push_back(1e-3*(c*0.90+29.10)); //ps to ns
52  if(p==2) ftc.tres[p].push_back(1e-3*(c*5.00+145.0)); //ps to ns
53  }
54  }
55 
56  ftc.dEMIP[0] = ftc.thick[0]*ftc.dEdxMIP;
57  ftc.dEMIP[1] = ftc.thick[1]*ftc.dEdxMIP;
58  ftc.dEMIP[2] = ftc.thick[2]*ftc.dEdxMIP;
59 
60  int isec,ilay,istr;
61 
62  vector<vector<double> > data;
63 
64  auto_ptr<Calibration> calib(CalibrationGenerator::CreateCalibration(ftc.connection));
65  cout<<"Connecting to "<<ftc.connection<<"/calibration/ftof"<<endl;
66 
67  cout<<"FTOF:Getting attenuation"<<endl;
68  sprintf(ftc.database,"/calibration/ftof/attenuation:%d",ftc.runNo);
69  data.clear(); calib->GetCalib(data,ftc.database);
70  for(unsigned row = 0; row < data.size(); row++)
71  {
72  isec = data[row][0]; ilay = data[row][1]; istr = data[row][2];
73  ftc.attlen[isec-1][ilay-1][0].push_back(data[row][3]);
74  ftc.attlen[isec-1][ilay-1][1].push_back(data[row][4]);
75  }
76 
77  cout<<"FTOF:Getting effective_velocity"<<endl;
78  sprintf(ftc.database,"/calibration/ftof/effective_velocity:%d",ftc.runNo);
79  data.clear(); calib->GetCalib(data,ftc.database);
80  for(unsigned row = 0; row < data.size(); row++)
81  {
82  isec = data[row][0]; ilay = data[row][1]; istr = data[row][2];
83  ftc.veff[isec-1][ilay-1][0].push_back(data[row][3]);
84  ftc.veff[isec-1][ilay-1][1].push_back(data[row][4]);
85  }
86 
87  cout<<"FTOF:Getting status"<<endl;
88  sprintf(ftc.database,"/calibration/ftof/status:%d",ftc.runNo);
89  data.clear() ; calib->GetCalib(data,ftc.database);
90  for(unsigned row = 0; row < data.size(); row++)
91  {
92  isec = data[row][0]; ilay = data[row][1]; istr = data[row][2];
93  ftc.status[isec-1][ilay-1][0].push_back(data[row][3]);
94  ftc.status[isec-1][ilay-1][1].push_back(data[row][4]);
95  }
96 
97  cout<<"FTOF:Getting gain_balance"<<endl;
98  sprintf(ftc.database,"/calibration/ftof/gain_balance:%d",ftc.runNo);
99  data.clear() ; calib->GetCalib(data,ftc.database);
100  for(unsigned row = 0; row < data.size(); row++)
101  {
102  isec = data[row][0]; ilay = data[row][1]; istr = data[row][2];
103  ftc.countsForMIP[isec-1][ilay-1][0].push_back(data[row][3]);
104  ftc.countsForMIP[isec-1][ilay-1][1].push_back(data[row][4]);
105  }
106 
107  cout<<"FTOF:Getting time_walk"<<endl;
108  sprintf(ftc.database,"/calibration/ftof/time_walk:%d",ftc.runNo);
109  data.clear() ; calib->GetCalib(data,ftc.database);
110  for(unsigned row = 0; row < data.size(); row++)
111  {
112  isec = data[row][0]; ilay = data[row][1]; istr = data[row][2];
113  ftc.twlk[isec-1][ilay-1][0].push_back(data[row][3]);
114  ftc.twlk[isec-1][ilay-1][1].push_back(data[row][4]);
115  ftc.twlk[isec-1][ilay-1][2].push_back(data[row][5]);
116  ftc.twlk[isec-1][ilay-1][3].push_back(data[row][6]);
117  ftc.twlk[isec-1][ilay-1][4].push_back(data[row][7]);
118  ftc.twlk[isec-1][ilay-1][5].push_back(data[row][8]);
119  }
120 
121  return ftc;
122 }
123 
125 {
126  if(ftc.runNo != runno)
127  {
128  cout << " > Initializing " << HCname << " digitization for run number " << runno << endl;
129  ftc = initializeFTOFConstants(runno);
130  ftc.runNo = runno;
131  }
132 }
133 
134 
135 map<string, double> ftof_HitProcess :: integrateDgt(MHit* aHit, int hitn)
136 {
137  map<string, double> dgtz;
138  vector<identifier> identity = aHit->GetId();
139 
140  int sector = identity[0].id;
141  int panel = identity[1].id;
142  int paddle = identity[2].id;
143  trueInfos tInfos(aHit);
144 
145  // Get the paddle half-length
146  double length = aHit->GetDetector().dimensions[0];
147 
148  // Distances from left, right
149  double dLeft = length + tInfos.lx;
150  double dRight = length - tInfos.lx;
151 
152  // attenuation length
153  double attlenL = ftc.attlen[sector-1][panel-1][0][paddle-1];
154  double attlenR = ftc.attlen[sector-1][panel-1][1][paddle-1];
155 
156  // attenuation factor
157  double attLeft = exp(-dLeft/cm/attlenL);
158  double attRight = exp(-dRight/cm/attlenR);
159 
160  // Gain factors to simulate FTOF PMT gain matching algorithm.
161  // Each L,R PMT pair has HV adjusted so geometeric mean sqrt(L*R)
162  // is independent of counter length, which compensates for
163  // the factor exp(-L/2/attlen) where L=full length of bar.
164  double gainLeft = sqrt(attLeft*attRight);
165  double gainRight = gainLeft;
166 
167  // Attenuated light at PMT
168  double eneL = tInfos.eTot*attLeft;
169  double eneR = tInfos.eTot*attRight;
170 
171  double adcl = 0;
172  double adcr = 0;
173  double adclu = 0;
174  double adcru = 0;
175  double tdcl = 0;
176  double tdcr = 0;
177  double tdclu = 0;
178  double tdcru = 0;
179 
180  // Fluctuate the light measured by the PMT with
181  // Poisson distribution for emitted photoelectrons
182  // Treat L and R separately, in case nphe=0
183 
184  if (eneL>0)
185  adclu = eneL*ftc.countsForMIP[sector-1][panel-1][0][paddle-1]/ftc.dEMIP[panel-1]/gainLeft;
186 
187  if (eneR>0)
188  adcru = eneR*ftc.countsForMIP[sector-1][panel-1][1][paddle-1]/ftc.dEMIP[panel-1]/gainRight;
189 
190 
191  double npheL = G4Poisson(eneL*ftc.pmtPEYld);
192  eneL = npheL/ftc.pmtPEYld;
193 
194  if (eneL>0) {
195  adcl = eneL*ftc.countsForMIP[sector-1][panel-1][0][paddle-1]/ftc.dEMIP[panel-1]/gainLeft;
196  double A = ftc.twlk[sector-1][panel-1][0][paddle-1];
197  double B = ftc.twlk[sector-1][panel-1][1][paddle-1];
198  //double C = ftc.twlk[sector-1][panel-1][2][paddle-1];
199  double timeWalkLeft = A/pow(adcl,B);
200  double tLeftU = tInfos.time + dLeft/ftc.veff[sector-1][panel-1][0][paddle-1]/cm + timeWalkLeft;
201  double tLeft = G4RandGauss::shoot(tLeftU, sqrt(2)*ftc.tres[panel-1][paddle-1]);
202  tdclu = tLeftU*ftc.tdcLSB;
203  tdcl = tLeft*ftc.tdcLSB;
204  }
205 
206  double npheR = G4Poisson(eneR*ftc.pmtPEYld);
207  eneR = npheR/ftc.pmtPEYld;
208 
209  if (eneR>0) {
210  adcr = eneR*ftc.countsForMIP[sector-1][panel-1][1][paddle-1]/ftc.dEMIP[panel-1]/gainRight;
211  double A = ftc.twlk[sector-1][panel-1][3][paddle-1];
212  double B = ftc.twlk[sector-1][panel-1][4][paddle-1];
213  //double C = ftc.twlk[sector-1][panel-1][5][paddle-1];
214  double timeWalkRight = A/pow(adcr,B);
215  double tRightU = tInfos.time + dRight/ftc.veff[sector-1][panel-1][1][paddle-1]/cm + timeWalkRight;
216  double tRight = G4RandGauss::shoot(tRightU, sqrt(2)*ftc.tres[panel-1][paddle-1]);
217  tdcru = tRightU*ftc.tdcLSB;
218  tdcr = tRight*ftc.tdcLSB;
219  }
220 
221  // Status flags
222  switch (ftc.status[sector-1][panel-1][0][paddle-1])
223  {
224  case 0:
225  break;
226  case 1:
227  adcl = 0;
228  break;
229  case 2:
230  tdcl = 0;
231  break;
232  case 3:
233  adcl = tdcl = 0;
234  break;
235 
236  case 5:
237  break;
238 
239  default:
240  cout << " > Unknown FTOF status: " << ftc.status[sector-1][panel-1][0][paddle-1] << " for sector " << sector << ", panel " << panel << ", paddle " << paddle << " left " << endl;
241  }
242 
243  switch (ftc.status[sector-1][panel-1][1][paddle-1])
244  {
245  case 0:
246  break;
247  case 1:
248  adcr = 0;
249  break;
250  case 2:
251  tdcr = 0;
252  break;
253  case 3:
254  adcr = tdcr = 0;
255  break;
256 
257  case 5:
258  break;
259 
260  default:
261  cout << " > Unknown FTOF status: " << ftc.status[sector-1][panel-1][1][paddle-1] << " for sector " << sector << ", panel " << panel << ", paddle " << paddle << " right " << endl;
262  }
263 
264 // cout << " > FTOF status: " << ftc.status[sector-1][panel-1][0][paddle-1] << " for sector " << sector << ", panel " << panel << ", paddle " << paddle << " left: " << adcl << endl;
265 // cout << " > FTOF status: " << ftc.status[sector-1][panel-1][1][paddle-1] << " for sector " << sector << ", panel " << panel << ", paddle " << paddle << " right: " << adcr << endl;
266 
267 
268  dgtz["hitn"] = hitn;
269  dgtz["sector"] = sector;
270  dgtz["paddle"] = paddle;
271  dgtz["ADCL"] = adcl;
272  dgtz["ADCR"] = adcr;
273  dgtz["TDCL"] = tdcl;
274  dgtz["TDCR"] = tdcr;
275  dgtz["ADCLu"] = adclu;
276  dgtz["ADCRu"] = adcru;
277  dgtz["TDCLu"] = tdclu;
278  dgtz["TDCRu"] = tdcru;
279 
280  return dgtz;
281 }
282 
283 vector<identifier> ftof_HitProcess :: processID(vector<identifier> id, G4Step* aStep, detector Detector)
284 {
285  id[id.size()-1].id_sharing = 1;
286  return id;
287 }
288 
289 
290 
291 
292 map< string, vector <int> > ftof_HitProcess :: multiDgt(MHit* aHit, int hitn)
293 {
294  map< string, vector <int> > MH;
295 
296  return MH;
297 }
298 
299 // this static function will be loaded first thing by the executable
300 ftofConstants ftof_HitProcess::ftc = initializeFTOFConstants(-1);
301 
302 
303 
304 
vector< double > attlen[6][3][2]
vector< int > status[6][3][2]
void initWithRunNumber(int runno)
vector< double > twlk[6][3][6]
vector< identifier > GetId()
Definition: Hit.h:103
double time
Definition: HitProcess.h:43
double lx
Definition: HitProcess.h:42
double eTot
Definition: HitProcess.h:40
vector< identifier > processID(vector< identifier >, G4Step *, detector)
map< string, double > integrateDgt(MHit *, int)
vector< double > tres[3]
char database[80]
double dEMIP[3]
map< string, vector< int > > multiDgt(MHit *, int)
Definition: Hit.h:22
vector< double > countsForMIP[6][3][2]
vector< double > dimensions
vector of dimensions. Size, units depends on solid type
Definition: detector.h:77
static ftofConstants ftc
detector GetDetector()
Definition: Hit.h:108
vector< double > veff[6][3][2]