GEMC  2.3
Geant4 Monte-Carlo Framework
ec_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 "ec_hitprocess.h"
12 
13 static ecConstants initializeECConstants(int runno)
14 {
15  ecConstants ecc;
16 
17  // do not initialize at the beginning, only after the end of the first event,
18  // with the proper run number coming from options or run table
19  if(runno == -1) return ecc;
20 
21  int isec,ilay,istr;
22 
23  // database
24  ecc.runNo = runno;
25  ecc.date = "2015-11-29";
26  if(getenv ("CCDB_CONNECTION") != NULL)
27  ecc.connection = (string) getenv("CCDB_CONNECTION");
28  else
29  ecc.connection = "mysql://clas12reader@clasdb.jlab.org/clas12";
30  ecc.variation = "default";
31 
32  ecc.NSTRIPS = 36;
33  ecc.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  ecc.ADC_MeV_to_evio = 10. ; // MIP based calibration is nominally 10 channels/MeV
35  ecc.veff = 160. ; // Effective velocity of scintillator light (mm/ns)
36  ecc.pmtPEYld = 3.5 ; // Number of p.e. divided by the energy deposited in MeV. See EC NIM paper table 1.
37  ecc.pmtQE = 0.27 ;
38  ecc.pmtDynodeGain = 4.0 ;
39  ecc.pmtDynodeK = 0.5 ; // K=0 (Poisson) K=1(exponential)
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  ecc.pmtFactor = sqrt(1-ecc.pmtQE+(ecc.pmtDynodeK*ecc.pmtDynodeGain+1)/(ecc.pmtDynodeGain-1));
46 
47  vector<vector<double> > data;
48  auto_ptr<Calibration> calib(CalibrationGenerator::CreateCalibration(ecc.connection));
49 
50  sprintf(ecc.database,"/calibration/ec/attenuation:%d",ecc.runNo);
51  data.clear(); calib->GetCalib(data,ecc.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  ecc.attlen[isec-1][ilay-1][0].push_back(data[row][3]);
57  ecc.attlen[isec-1][ilay-1][1].push_back(data[row][4]);
58  ecc.attlen[isec-1][ilay-1][2].push_back(data[row][5]);
59  }
60 
61  return ecc;
62 }
63 
65 {
66  if(ecc.runNo != runno)
67  {
68  cout << " > Initializing " << HCname << " digitization for run number " << runno << endl;
69  ecc = initializeECConstants(runno);
70  ecc.runNo = runno;
71  }
72 }
73 
74 
75 // Process the ID and hit for the EC using EC scintillator slab geometry instead of individual strips.
76 map<string, double> ec_HitProcess :: integrateDgt(MHit* aHit, int hitn)
77 {
78  map<string, double> dgtz;
79  vector<identifier> identity = aHit->GetId();
80 
81  // get sector, stack (inner or outer), view (U, V, W), and strip.
82  int sector = identity[0].id;
83  int stack = identity[1].id;
84  int view = identity[2].id;
85  int strip = identity[3].id;
86  int layer = (stack-1)*3+view+3; // layer=1-3 (PCAL) 4-9 (ECAL)
87 
88  trueInfos tInfos(aHit);
89 
90  // Get scintillator mother volume dimensions (mm)
91  double pDy1 = aHit->GetDetector().dimensions[3];
92  double pDx2 = aHit->GetDetector().dimensions[5];
93  double BA = sqrt(4*pow(pDy1,2) + pow(pDx2,2)) ;
94 
95  vector<G4ThreeVector> pos = aHit->GetPos();
96  vector<G4ThreeVector> Lpos = aHit->GetLPos();
97 
98  // Get Total Energy deposited
99  double Etota = 0;
100  double Ttota = 0;
101  double latt = 0;
102 
103  vector<G4double> Edep = aHit->GetEdep();
104 
105  double att;
106 
107  double A = ecc.attlen[sector-1][layer-1][0][strip-1];
108  double B = ecc.attlen[sector-1][layer-1][1][strip-1]*10.;
109  double C = ecc.attlen[sector-1][layer-1][2][strip-1];
110 
111  for(unsigned int s=0; s<tInfos.nsteps; s++)
112  {
113  if(B>0)
114  {
115  double xlocal = Lpos[s].x();
116  double ylocal = Lpos[s].y();
117  if(view==1) latt = xlocal+(pDx2/(2.*pDy1))*(ylocal+pDy1);
118  if(view==2) latt = BA*(pDy1-ylocal)/2./pDy1;
119  if(view==3) latt = BA*(ylocal+pDy1-xlocal*2*pDy1/pDx2)/4/pDy1;
120  att = A*exp(-latt/B)+C;
121  Etota = Etota + Edep[s]*att;
122  Ttota = Ttota + latt/ecc.veff;
123 
124  }
125  else
126  {
127  Etota = Etota + Edep[s];
128  }
129  }
130 
131 
132  // initialize ADC and TDC
133  int ADC = 0;
134  int TDC = 0;
135 
136  // simulate the adc value.
137  if (Etota > 0) {
138  double EC_npe = G4Poisson(Etota*ecc.pmtPEYld); //number of photoelectrons
139  if (EC_npe>0) {
140  double sigma = ecc.pmtFactor/sqrt(EC_npe);
141  double EC_MeV = G4RandGauss::shoot(EC_npe,sigma)*ecc.ADC_MeV_to_evio/ecc.pmtPEYld;
142  if (EC_MeV>0) {
143  ADC = (int) EC_MeV;
144  TDC = (int) ((tInfos.time+Ttota/tInfos.nsteps)*ecc.TDC_time_to_evio);
145  }
146  }
147  }
148 
149  // EVIO banks record time with offset determined by position of data in capture window. On forward carriage this is currently
150  // around 1.4 us. This offset is omitted in the simulation.
151 
152  dgtz["hitn"] = hitn;
153  dgtz["sector"] = sector;
154  dgtz["stack"] = stack;
155  dgtz["view"] = view;
156  dgtz["strip"] = strip;
157  dgtz["ADC"] = ADC;
158  dgtz["TDC"] = TDC;
159 
160  return dgtz;
161 }
162 
163 vector<identifier> ec_HitProcess :: processID(vector<identifier> id, G4Step* aStep, detector Detector)
164 {
165  vector<identifier> yid = id;
166 
167  int view = yid[2].id; // get the view: U->1, V->2, W->3
168 
169  G4StepPoint *prestep = aStep->GetPreStepPoint();
170  G4StepPoint *poststep = aStep->GetPostStepPoint();
171 
172  G4ThreeVector xyz = poststep->GetPosition();
173  G4ThreeVector Lxyz = prestep->GetTouchableHandle()->GetHistory()
174  ->GetTopTransform().TransformPoint(xyz);
175 
176  double xlocal = Lxyz.x();
177  double ylocal = Lxyz.y();
178 
179  double pDy1 = Detector.dimensions[3];
180  double pDx2 = Detector.dimensions[5];
181 
182  // Some EC geometry:
183  //
184  // B ---------------------- C
185  // \ /
186  // \ /
187  // \ /
188  // \ / face of EC sector looking from the target; z-axis is out
189  // \ x /
190  // \ / | y
191  // \ / | coordinates: origin is at the
192  // \ / _______| geometric center of the triangle.
193  // \ / x
194  // \/
195  // A
196  //
197  // U - strips parallel to BC, start numbering at A
198  // V - strips parallel to AB, start numbering at C
199  // W - strips parallel tp CA, start numbering at B
200  //
201  // other points: D - point where line from C crosses AB at right angle.
202  // F - CF is the component of the hit along CD.
203  // G - point where line from B crosses AC at right angle.
204  // H - BH is the component of the hit position along BG.
205  //
206 
207  // get the strip.
208  double BA = sqrt(4*pow(pDy1,2) + pow(pDx2,2)) ;
209  //double lu=xlocal+(pDx2/(2.*pDy1))*(ylocal+pDy1);
210  //double lv=BA*(pDy1-ylocal)/2./pDy1;
211  //double lw=BA*(ylocal+pDy1-xlocal*2*pDy1/pDx2)/4/pDy1;
212  //cout<<"pDx2="<<pDx2<<" pDy1="<<pDy1<<endl;
213 
214  int strip = 0;
215  if (view == 1)
216  {
217  strip = (int) floor((ylocal + pDy1)*ecc.NSTRIPS/(2*pDy1)) + 1; // U view strip.
218  //cout << "view=" << view << " strip=" << strip << " xloc=" << xlocal << " yloc=" << ylocal << " pDy1: " << pDy1 << " floor:" << (ylocal + pDy1)*ecc.NSTRIPS/(2*pDy1) << " NS: " << ecc.NSTRIPS << endl;
219  }
220  else if (view == 2)
221  {
222  double BHtop = (xlocal + pDx2)*(-2*pDy1) + (ylocal - pDy1)*(pDx2);
223  double BH = abs(BHtop/BA); // component of vector from the apex of the W view to the hit along a line perpendicular to the strips.
224 
225  double BGtop = 4*pDx2*pDy1;
226  double BG = abs(BGtop/BA); // maximum length of W view along a line perpendicular to the strips (height of the W view triangle).
227 
228  strip = (int) floor(BH*ecc.NSTRIPS/BG)+1 ; // W view strip.
229  //cout<<"view="<<view<<" strip="<<strip<<" xloc="<<xlocal<<" yloc="<<ylocal<<endl;
230  }
231  else if (view == 3)
232  {
233  double CFtop = (xlocal - pDx2)*2*pDy1 + (ylocal - pDy1)*pDx2;
234  double CF = abs(CFtop/BA); // component of vector from the apex of the V view to the hit along a line perpendicular to the strips.
235 
236  double CDtop = -4*pDx2*pDy1;
237  double CD = abs(CDtop/BA); // maximum length of V view along a line perpendicular to the strips (height of the V view triangle).
238 
239  strip = (int) floor(CF*ecc.NSTRIPS/CD)+1 ; // V view strip.
240  //cout<<"view="<<view<<" strip="<<strip<<" xloc="<<xlocal<<" yloc="<<ylocal<<endl;
241  }
242  else
243  {
244  cout << " EC Hit Process WARNING: No view found." << endl;
245  }
246 
247 
248  if (strip <=0 ) strip = 1;
249  if (strip >=36) strip = 36;
250 
251  yid[3].id = strip;
252  yid[3].id_sharing = 1;
253 
254  return yid;
255 }
256 
257 
258 
259 map< string, vector <int> > ec_HitProcess :: multiDgt(MHit* aHit, int hitn)
260 {
261  map< string, vector <int> > MH;
262 
263  return MH;
264 }
265 
266 
267 
268 // this static function will be loaded first thing by the executable
269 ecConstants ec_HitProcess::ecc = initializeECConstants(-1);
270 
271 
272 
273 
274 
275 
276 
277 
278 
279 
280 
double pmtPEYld
Definition: ec_hitprocess.h:29
double ADC_MeV_to_evio
Definition: ec_hitprocess.h:27
map< string, double > integrateDgt(MHit *, int)
void initWithRunNumber(int runno)
double pmtQE
Definition: ec_hitprocess.h:30
vector< identifier > GetId()
Definition: Hit.h:103
string variation
Definition: ec_hitprocess.h:14
string connection
Definition: ec_hitprocess.h:16
double NSTRIPS
Definition: ec_hitprocess.h:25
double time
Definition: HitProcess.h:43
vector< G4ThreeVector > GetLPos()
Definition: Hit.h:76
double TDC_time_to_evio
Definition: ec_hitprocess.h:26
vector< double > attlen[6][9][3]
Definition: ec_hitprocess.h:23
char database[80]
Definition: ec_hitprocess.h:17
vector< G4ThreeVector > GetPos()
Definition: Hit.h:72
Definition: Hit.h:22
static ecConstants ecc
Definition: ec_hitprocess.h:45
double pmtDynodeK
Definition: ec_hitprocess.h:32
vector< identifier > processID(vector< identifier >, G4Step *, detector)
double pmtFactor
Definition: ec_hitprocess.h:33
unsigned int nsteps
Definition: HitProcess.h:39
vector< double > dimensions
vector of dimensions. Size, units depends on solid type
Definition: detector.h:77
vector< double > GetEdep()
Definition: Hit.h:83
detector GetDetector()
Definition: Hit.h:108
map< string, vector< int > > multiDgt(MHit *, int)
double pmtDynodeGain
Definition: ec_hitprocess.h:31