GEMC  1.8
Geant4 Monte-Carlo Framework
EC_hitprocess.cc
Go to the documentation of this file.
1 // %%%%%%%%%%
2 // G4 headers
3 // %%%%%%%%%%
4 #include "G4UnitsTable.hh"
5 #include "G4Poisson.hh"
6 #include "Randomize.hh"
7 
8 // %%%%%%%%%%%%%
9 // gemc headers
10 // %%%%%%%%%%%%%
11 #include "EC_hitprocess.h"
12 
13 // Process the ID and hit for the EC using EC scintillator slab geometry instead of individual strips.
14 
16 {
17  PH_output out;
18  out.identity = aHit->GetId();
19 
20  // get sector, stack (inner or outer), view (U, V, W), and strip.
21  int sector = out.identity[0].id;
22  int stack = out.identity[1].id;
23  int view = out.identity[2].id;
24  int strip = out.identity[3].id;
25 
26  HCname = "EC Hit Process";
27 
28  //Attenuation Length (mm)
29  double attlen=3760.;
30 
31  // Get scintillator mother volume dimensions (mm)
32  double pDy1 = aHit->GetDetector().dimensions[3];
33  double pDx2 = aHit->GetDetector().dimensions[5];
34  double BA = sqrt(4*pow(pDy1,2) + pow(pDx2,2)) ;
35 
36  //cout<<"pDx2="<<pDx2<<" pDy1="<<pDy1<<" BA="<<BA<<endl;
37 
38  // %%%%%%%%%%%%%%%%%%%
39  // Raw hit information
40  // %%%%%%%%%%%%%%%%%%%
41  int nsteps = aHit->GetPos().size();
42 
43  // average global, local positions of the hit
44  double x, y, z;
45  double lx, ly, lz;
46  double xlocal,ylocal;
47  x = y = z = lx = ly = lz = 0;
48  vector<G4ThreeVector> pos = aHit->GetPos();
49  vector<G4ThreeVector> Lpos = aHit->GetLPos();
50 
51  // Get Total Energy deposited
52  double Etot = 0;
53  double Etota = 0;
54  double latt = 0;
55  vector<G4double> Edep = aHit->GetEdep();
56 
57  for(int s=0; s<nsteps; s++)
58  {
59  if(attlen>0)
60  {
61  xlocal = Lpos[s].x();
62  ylocal = Lpos[s].y();
63  if(view==1) latt=xlocal+(pDx2/(2.*pDy1))*(ylocal+pDy1);
64  if(view==2) latt=BA*(pDy1-ylocal)/2./pDy1;
65  if(view==3) latt=BA*(ylocal+pDy1-xlocal*2*pDy1/pDx2)/4/pDy1;
66  Etot = Etot + Edep[s];
67  //cout<<"xlocal="<<xlocal<<" ylocal="<<ylocal<<" view="<<view<<" strip="<<strip<<" latt="<<latt<<endl;
68  Etota = Etota + Edep[s]*exp(-latt/attlen);
69  }
70  else
71  {
72  Etot = Etot + Edep[s];
73  Etota = Etota + Edep[s];
74  }
75  }
76 
77  if(Etot>0)
78  for(int s=0; s<nsteps; s++)
79  {
80  x = x + pos[s].x()*Edep[s]/Etot;
81  y = y + pos[s].y()*Edep[s]/Etot;
82  z = z + pos[s].z()*Edep[s]/Etot;
83  lx = lx + Lpos[s].x()*Edep[s]/Etot;
84  ly = ly + Lpos[s].y()*Edep[s]/Etot;
85  lz = lz + Lpos[s].z()*Edep[s]/Etot;
86  }
87  else
88  {
89  x = pos[0].x();
90  y = pos[0].y();
91  z = pos[0].z();
92  lx = Lpos[0].x();
93  ly = Lpos[0].y();
94  lz = Lpos[0].z();
95  }
96 
97  // average time
98  double time = 0;
99  vector<G4double> times = aHit->GetTime();
100  for(int s=0; s<nsteps; s++) time = time + times[s]/nsteps;
101 
102  // Energy of the track
103  double Ene = aHit->GetE();
104 
105  out.raws.push_back(Etot);
106  out.raws.push_back(x);
107  out.raws.push_back(y);
108  out.raws.push_back(z);
109  out.raws.push_back(lx);
110  out.raws.push_back(ly);
111  out.raws.push_back(lz);
112  out.raws.push_back(time);
113  out.raws.push_back((double) aHit->GetPID());
114  out.raws.push_back(aHit->GetVert().getX());
115  out.raws.push_back(aHit->GetVert().getY());
116  out.raws.push_back(aHit->GetVert().getZ());
117  out.raws.push_back(Ene);
118  out.raws.push_back((double) aHit->GetmPID());
119  out.raws.push_back(aHit->GetmVert().getX());
120  out.raws.push_back(aHit->GetmVert().getY());
121  out.raws.push_back(aHit->GetmVert().getZ());
122 
123 
124  // %%%%%%%%%%%%
125  // Digitization
126  // %%%%%%%%%%%%
127 
128  // Jerry Gilfoyle, Feb, 2010
129  // parameters: changed from hardwiring (see below) to gpars array - gilfoyle 8/31/12
130  //int ec_tdc_time_to_channel = (int) gpars["EC/ec_tdc_time_to_channel"]; // conversion from time (ns) to TDC channels.
131  //double ECfactor = (double) gpars["EC/ECfactor"]; // number of photons divided by the energy deposited in MeV; value taken from gsim. see EC NIM paper table 1.
132  //int EC_TDC_MAX = (int) gpars["EC/EC_TDC_MAX"]; // max value for EC tdc.
133  //int ec_charge_to_channel = (int) gpars["EC/ec_charge_to_channel"]; // conversion from charge (pC) to ADC channels; taken from IC code.
134  //double ec_npe_to_charge = (double) gpars["EC/ec_npe_to_charge"]; // unjustified (!!) conversion from number of photoelectrons to charge in pC.
135 
136  // parameters were initially hardwired into the code with the values shown below.
137  // Moved into trunk/database_io/clas/geo/ec/parameters.txt - gilfoyle 8/31/12
138 
139  double ec_tdc_time_to_channel = 20.; // conversion from time (ns) to TDC channels.
140  double ECfactor = 3.5; // number of p.e. divided by the energy deposited in MeV; value taken from gsim. see EC NIM paper table 1.
141  int EC_TDC_MAX = 4095; // max value for EC tdc.
142  double ec_MeV_to_channel = 10.; // conversion from energy (MeV) to ADC channels
143 
144  // initialize ADC and TDC
145  int EC_ADC = 0;
146  int EC_TDC = EC_TDC_MAX;
147 
148  // simulate the adc value.
149  if (Etota > 0) {
150  double EC_npe = G4Poisson(Etota*ECfactor); //number of photoelectrons
151  // Fluctuations in PMT gain distributed using Gaussian with
152  // sigma SNR = sqrt(ngamma)/sqrt(del/del-1) del = dynode gain = 3 (From RCA PMT Handbook) p. 169)
153  // algorithm, values, and comment above taken from gsim.
154  double sigma = sqrt(EC_npe)/1.22;
155  double EC_MeV = G4RandGauss::shoot(EC_npe,sigma)*ec_MeV_to_channel/ECfactor;
156  if (EC_MeV <= 0) EC_MeV=0.0; // guard against weird, rare events.
157  EC_ADC = (int) EC_MeV;
158  }
159 
160  // simulate the tdc.
161  EC_TDC = (int) (time*ec_tdc_time_to_channel);
162  if (EC_TDC > EC_TDC_MAX) EC_TDC = EC_TDC_MAX;
163 
164  out.dgtz.push_back(sector);
165  out.dgtz.push_back(stack);
166  out.dgtz.push_back(view);
167  out.dgtz.push_back(strip);
168  out.dgtz.push_back(EC_ADC);
169  out.dgtz.push_back(EC_TDC);
170 
171  //cout << "sector = " << sector << " stack = " << stack << " view = " << view << " strip = " << strip << " EC_ADC = " << EC_ADC << " EC_TDC = " << EC_TDC << " Edep = " << Etot << endl;
172 
173  return out;
174 }
175 
176 vector<identifier> EC_HitProcess :: ProcessID(vector<identifier> id, G4Step* aStep, detector Detector, gemc_opts Opt)
177 {
178  vector<identifier> yid = id;
179 
180  double NSTRIPS = 36;
181  //int sector = yid[0].id;
182  //int stack = yid[1].id;
183  int view = yid[2].id; // get the view: U->1, V->2, W->3
184 
185  G4StepPoint *prestep = aStep->GetPreStepPoint();
186  G4StepPoint *poststep = aStep->GetPostStepPoint();
187  G4VTouchable* TH = (G4VTouchable*) aStep->GetPreStepPoint()->GetTouchable();
188 
189  string name = TH->GetVolume(0)->GetName();
190  G4ThreeVector xyz = poststep->GetPosition();
191  G4ThreeVector Lxyz = prestep->GetTouchableHandle()->GetHistory()
192  ->GetTopTransform().TransformPoint(xyz);
193 
194  double xlocal = Lxyz.x();
195  double ylocal = Lxyz.y();
196 
197  double pDy1 = Detector.dimensions[3];
198  double pDx2 = Detector.dimensions[5];
199 
200  string detName = Detector.name;
201 
202  //
203  // Some EC geometry:
204  //
205  // B ---------------------- C
206  // \ /
207  // \ /
208  // \ /
209  // \ / face of EC sector looking from the target; z-axis is out
210  // \ x /
211  // \ / | y
212  // \ / | coordinates: origin is at the
213  // \ / _______| geometric center of the triangle.
214  // \ / x
215  // \/
216  // A
217  //
218  // U - strips parallel to BC, start numbering at A
219  // V - strips parallel to AB, start numbering at C
220  // W - strips parallel tp CA, start numbering at B
221  //
222  // other points: D - point where line from C crosses AB at right angle.
223  // F - CF is the component of the hit along CD.
224  // G - point where line from B crosses AC at right angle.
225  // H - BH is the component of the hit position along BG.
226  //
227 
228  // get the strip.
229 
230  double BA = sqrt(4*pow(pDy1,2) + pow(pDx2,2)) ;
231  //double lu=xlocal+(pDx2/(2.*pDy1))*(ylocal+pDy1);
232  //double lv=BA*(pDy1-ylocal)/2./pDy1;
233  //double lw=BA*(ylocal+pDy1-xlocal*2*pDy1/pDx2)/4/pDy1;
234  //cout<<"pDx2="<<pDx2<<" pDy1="<<pDy1<<endl;
235 
236  int strip = 0;
237  if (view == 1) {
238  strip = (int) floor((ylocal + pDy1)*NSTRIPS/(2*pDy1)) + 1; // U view strip.
239  //cout<<"view="<<view<<" strip="<<strip<<" xloc="<<xlocal<<" yloc="<<ylocal<<" lu="<<lu<<endl;
240  }
241  else if (view == 3) {
242  double CFtop = (xlocal - pDx2)*2*pDy1 + (ylocal - pDy1)*pDx2;
243  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.
244 
245  double CDtop = -4*pDx2*pDy1;
246  double CD = abs(CDtop/BA); // maximum length of V view along a line perpendicular to the strips (height of the V view triangle).
247 
248  strip = (int) floor(CF*NSTRIPS/CD)+1 ; // V view strip.
249  //cout<<"view="<<view<<" strip="<<strip<<" xloc="<<xlocal<<" yloc="<<ylocal<<" lv="<<lv<<endl;
250  }
251  else if (view == 2) {
252  double BHtop = (xlocal + pDx2)*(-2*pDy1) + (ylocal - pDy1)*(pDx2);
253  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.
254 
255  double BGtop = 4*pDx2*pDy1;
256  double BG = abs(BGtop/BA); // maximum length of W view along a line perpendicular to the strips (height of the W view triangle).
257 
258  strip = (int) floor(BH*NSTRIPS/BG)+1 ; // W view strip.
259  //cout<<"view="<<view<<" strip="<<strip<<" xloc="<<xlocal<<" yloc="<<ylocal<<" lw="<<lw<<endl;
260  } else {
261  cout << "WARNING: No view found." << endl;
262  }
263 
264 
265  if (strip <=0 ) strip=1;
266  if (strip >=36) strip=36;
267 
268  yid[3].id = strip;
269  yid[3].id_sharing = 1;
270 
271  return yid;
272 }
273 
274 
275 
276 
277 
278 
279 
280 
281 
282 
283 
G4ThreeVector GetVert()
Definition: MHit.h:72
vector< double > raws
Raw information.
Definition: MPHBaseClass.h:26
int GetPID()
Definition: MHit.h:107
int GetmPID()
Definition: MHit.h:122
vector< identifier > GetId()
Definition: MHit.h:96
string HCname
Hit Collection name.
Definition: MPHBaseClass.h:41
G4ThreeVector GetmVert()
Definition: MHit.h:127
vector< identifier > identity
Identifier.
Definition: MPHBaseClass.h:28
vector< G4ThreeVector > GetLPos()
Definition: MHit.h:69
double GetE()
Definition: MHit.h:89
vector< G4ThreeVector > GetPos()
Definition: MHit.h:65
string name
Name of the volume. Since this is the key of the STL map, it has to be unique.
Definition: detector.h:53
Definition: MHit.h:29
vector< double > GetTime()
Definition: MHit.h:82
vector< identifier > ProcessID(vector< identifier >, G4Step *, detector, gemc_opts)
Method to calculate new identifier.
vector< double > dimensions
vector of dimensions. Size, units depends on solid type
Definition: detector.h:63
vector< double > GetEdep()
Definition: MHit.h:76
PH_output ProcessHit(MHit *, gemc_opts)
Method to process the hit.
detector GetDetector()
Definition: MHit.h:101
vector< int > dgtz
Digitized information.
Definition: MPHBaseClass.h:27