GEMC  2.3
Geant4 Monte-Carlo Framework
bmt_strip.cc
Go to the documentation of this file.
1 // gemc headers
2 #include "bmt_strip.h"
3 #include "Randomize.hh"
4 
5 // c++ headers
6 #include <iostream>
7 #include <cmath>
8 #include <cstdlib>
9 
10 
11 // Veronique Ziegler (Dec. 3 2015)
12 // Note: this method only contains the constants for the third micromegas region,
13 // the constants for the other 2 are missing...
14 // M. Ungaro (Jan 26 2016)
15 // Updated to read constants at the beginning of each run
16 
17 // the routine to find the strip
18 vector<double> bmt_strip::FindStrip(int layer, int sector, G4ThreeVector xyz, double Edep, bmtConstants bmtc)
19 {
20  double x = xyz.x()/mm;
21  double y = xyz.y()/mm;
22  double z = xyz.z()/mm;
23 
24  double w_i = 25; //ionization potential assumed to be 25 eV
25  int Nel = (int) (1e6*Edep/w_i); // the number of electrons produced
26 
27  // the return vector is always in pairs the first index is the strip number, the second is the Edep on the strip
28  vector<double> strip_id;
29 
30  int strip = -1;
31  if(Nel>0) // if the track deposited energy is greater than the assumed ionization potential digitize
32  {
33  for(int iel=0;iel<Nel;iel++) // at this stage the same algorithm requiring looping over all e-'s is kept (slow...)
34  {
35  int num_region = (int) (layer+1)/2 - 1; // region index (0...2) 0=layers 1&2, 1=layers 3&4, 2=layers 5&6;
36  // start the loop and get the strip number from the layer, z and phi hit information
37  double sigma =0;
38  if(layer%2==0)
39  {// C layer
40  double z_i = bmtc.CRZZMIN[num_region] + bmtc.CRZOFFSET[num_region]; // fiducial z-profile lower limit
41  double z_f = bmtc.CRZZMIN[num_region] + bmtc.CRZOFFSET[num_region] + bmtc.CRZLENGTH[num_region]; // fiducial z-profile upper limit
42 
43  if(z>=z_i && z<=z_f)
44  {
45  sigma = getSigmaLongit(layer, x, y, bmtc); // longitudinal diffusion
46 
47  double z_d = (double) (G4RandGauss::shoot(z,sigma)); // shower profile in z generated using a gaussian distribution with width=sigma
48 
49  strip = getCStrip(layer, z_d, bmtc);
50  }
51  }
52 
53  if(layer%2==1)
54  {// Z layer
55  sigma = getSigmaAzimuth(layer, x, y, bmtc); // diffusion taking into account the Lorentz angle
56 
57  double Delta_rad = sqrt(x*x+y*y) - bmtc.CRZRADIUS[num_region] + bmtc.hStrip2Det;
58 
59  double phi = atan2(y,x);
60 
61  //shower profile in phi generated
62  double phi_d = phi + ((G4RandGauss::shoot(0,sigma))/cos(bmtc.ThetaL) - Delta_rad*tan(bmtc.ThetaL))/bmtc.CRZRADIUS[num_region];
63 
64  strip = getZStrip(layer, phi_d, bmtc);
65  }
66  // if the strip is found (i.e. the hit is within acceptance
67  if(strip != -1)
68  { // search the existing strip array to see if this strip is already stored, if yes, add contributing energy
69  for(int istrip=0;istrip< (int) (strip_id.size()/2);istrip++)
70  {
71  if(strip_id[2*istrip]==strip)
72  {// already hit strip - add Edep
73  strip_id[2*istrip+1] = strip_id[2*istrip+1]+1./((double) Nel); // no gain fluctuation ;
74  strip = -1; // not to use it anymore
75  }
76  }
77  if(strip > -1) { // new strip, add it
78  strip_id.push_back(strip);
79  strip_id.push_back(1./((double) Nel)); // no gain fluctuation yet
80  }
81  }
82  else
83  {// not in the acceptance
84  strip_id.push_back(-1);
85  strip_id.push_back(1);
86  }
87  }
88  }
89  else
90  { // Nel=0, consider the Edep is 0
91  strip_id.push_back(-1);
92  strip_id.push_back(1);
93  }
94 
95  return strip_id;
96 }
97 
98 
99 //
100 // param layer
101 // param x x-coordinate of the hit in the lab frame
102 // param y y-coordinate of the hit in the lab frame
103 // return the sigma along the beam direction (longitudinal)
104 //
105 double bmt_strip::getSigmaLongit(int layer, double x, double y, bmtConstants bmtc)
106 {
107 
108  // sigma for C-detector
109  int num_region = (int) (layer+1)/2 - 1; // region index (0...2) 0=layers 1&2, 1=layers 3&4, 2=layers 5&6
110 
111  return bmtc.SigmaDrift*sqrt((sqrt(x*x+y*y) - bmtc.CRCRADIUS[num_region] + bmtc.hStrip2Det)/bmtc.hDrift);
112 }
113 
114 //
115 // param layer
116 // param x x-coordinate of the hit in the lab frame
117 // param y y-coordinate of the hit in the lab frame
118 // return the sigma along in the azimuth direction taking the Lorentz angle into account
119 //
120 double bmt_strip::getSigmaAzimuth(int layer, double x, double y, bmtConstants bmtc)
121 { // sigma for Z-detectors
122 
123  int num_region = (int) (layer+1)/2 - 1;
124  double sigma = bmtc.SigmaDrift*sqrt((sqrt(x*x+y*y) - bmtc.CRZRADIUS[num_region] + bmtc.hStrip2Det)/bmtc.hDrift/cos(bmtc.ThetaL));
125 
126  return sigma;
127 
128 }
129 
130 //
131 // param layer the layer 1...6
132 // param angle the position angle of the hit in the Z detector
133 // return the Z strip as a function of azimuthal angle
134 //
135 int bmt_strip::getZStrip(int layer, double angle, bmtConstants bmtc)
136 {
137  int num_region = (int) (layer+1)/2 - 1; // region index (0...2) 0=layers 1&2, 1=layers 3&4, 2=layers 5&6
138  int num_detector =isInSector( layer, angle, bmtc) - 1;
139  if(num_detector==-1)
140  return -1;
141 
142  if(angle<0)
143  angle+=2*pi; // from 0 to 2Pi
144 
145  if(num_detector==1)
146  {
147  double angle_f=bmtc.CRCEDGE1[num_region][1] + (bmtc.CRCXPOS[num_region] + bmtc.CRCLENGTH[num_region])/bmtc.CRCRADIUS[num_region] - 2*pi;
148  if(angle>=0 && angle<=angle_f)
149  angle+=2*pi;
150  }
151  double strip_calc = ( (angle - bmtc.CRZEDGE1[num_region][num_detector])*bmtc.CRZRADIUS[num_region]-bmtc.CRZXPOS[num_region] - bmtc.CRZWIDTH[num_region]/2.)/(bmtc.CRZWIDTH[num_region]
152  + bmtc.CRZSPACING[num_region]);
153 
154  strip_calc = (int)(round(strip_calc) );
155  int strip_num = (int) floor(strip_calc);
156 
157  int value = strip_num + 1;
158 
159  if(value < 1 || value > bmtc.CRZNSTRIPS[num_region])
160  value = -1;
161 
162  return value;
163 }
164 //
165 // param sector
166 // param layer
167 // param trk_z the track z position of intersection with the C-detector
168 // return the C-strip
169 //
170 int bmt_strip::getCStrip(int layer, double trk_z, bmtConstants bmtc)
171 {
172 
173  int num_region = (int) (layer+1)/2 - 1; // region index (0...2) 0=layers 1&2, 1=layers 3&4, 2=layers 5&6
174  int strip_group = 0;
175  int ClosestStrip =-1;
176  // get group
177  int len = bmtc.CRCGROUP[num_region].size();
178  double Z_lowBound[len];
179  double Z_uppBound[len];
180  int NStrips[len];
181 
182  double zi= bmtc.CRCZMIN[num_region] + bmtc.CRCOFFSET[num_region];
183  double z = trk_z - zi;
184 
185  Z_lowBound[0] = bmtc.CRCWIDTH[num_region][0]/2.; // the lower bound is the zMin+theOffset with half the width
186  Z_uppBound[0] = Z_lowBound[0]
187  + (bmtc.CRCGROUP[num_region][0]-1)*(bmtc.CRCWIDTH[num_region][0]+ bmtc.CRCSPACING[num_region]);
188  NStrips[0] = bmtc.CRCGROUP[num_region][0];
189  for(int i =1; i< len; i++)
190  {
191  Z_lowBound[i] = Z_uppBound[i-1] + bmtc.CRCWIDTH[num_region][i-1]/2. + bmtc.CRCSPACING[num_region] + bmtc.CRCWIDTH[num_region][i]/2.;
192  Z_uppBound[i] = Z_lowBound[i] + (bmtc.CRCGROUP[num_region][i]-1)*(bmtc.CRCWIDTH[num_region][i] + bmtc.CRCSPACING[num_region]);
193 
194  NStrips[i] = NStrips[i-1] + bmtc.CRCGROUP[num_region][i];
195 
196  if(z>=Z_lowBound[i] && z<=Z_uppBound[i]) {
197  strip_group = i;
198  ClosestStrip = 1 + (int) (round(((z-Z_lowBound[strip_group])/(bmtc.CRCWIDTH[num_region][strip_group] + bmtc.CRCSPACING[num_region]))))+NStrips[i-1];
199 
200  len =i;
201  }
202  }
203  return ClosestStrip;
204 }
205 
206 
207 
208 // param layer the hit layer
209 // param strip the hit strip
210 // return the z position in mm for the C-detectors
211 //
212 // WARNING: This routine is not used?
213 //
214 double bmt_strip::CRCStrip_GetZ(int layer, int strip, bmtConstants bmtc)
215 {
216  int num_strip = strip - 1; // index of the strip (starts at 0)
217  int num_region = (int) (layer+1)/2 - 1; // region index (0...2) 0=layers 1&2, 1=layers 3&4, 2=layers 5&6
218 
219  //For CR6C, this function returns the Z position of the strip center
220  int group=0;
221  int limit = bmtc.CRCGROUP[num_region][group];
222  double zc = bmtc.CRCZMIN[num_region] + bmtc.CRCOFFSET[num_region] + bmtc.CRCWIDTH[num_region][group]/2.;
223 
224  if (num_strip>0){
225  for (int j=1;j<num_strip+1;j++)
226  {
227  zc += bmtc.CRCWIDTH[num_region][group]/2.;
228  if (j>=limit)
229  { //test if we change the width
230  group++;
231  limit += bmtc.CRCGROUP[num_region][group];
232  }
233  zc += bmtc.CRCWIDTH[num_region][group]/2. + bmtc.CRCSPACING[num_region];
234  }
235  }
236 
237  return zc; //in mm
238 }
239 
240 // param sector the sector in CLAS12 1...3
241 // param layer the layer 1...6
242 // param strip the strip number (starts at 1)
243 // return the angle to localize the center of strip
244 //
245 double bmt_strip::CRZStrip_GetPhi(int sector, int layer, int strip, bmtConstants bmtc)
246 {
247  // Sector = num_detector + 1;
248  // num_detector = 0 (region A), 1 (region B), 2, (region C)
249  //For CRZ, this function returns the angle to localize the center of strip "num_strip" for the "num_detector"
250  int num_detector = getDetectorIndex(sector); // index of the detector (0...2): sector 1 corresponds to detector B, 2 to A, 3 to C in the geometry created by GEMC
251  int num_strip = strip - 1; // index of the strip (starts at 0)
252  int num_region = (int) (layer+1)/2 - 1; // region index (0...2) 0=layers 1&2, 1=layers 3&4, 2=layers 5&6
253 
254  double angle = bmtc.CRZEDGE1[num_region][num_detector] + (bmtc.CRZXPOS[num_region]+(bmtc.CRZWIDTH[num_region]/2.
255  + num_strip*(bmtc.CRZWIDTH[num_region]+bmtc.CRZSPACING[num_region])))/bmtc.CRZRADIUS[num_region];
256  if (angle>2*pi) angle-=2*pi;
257  return angle; //in rad
258 }
259 
260 // not used (implemented for alternate algorithm not yet fully developed)
261 double bmt_strip::getEnergyFraction(double z0, double z, double sigma)
262 {
263  double pdf_gaussian = (1./(sigma*sqrt(2*pi)))* exp( -0.5*((z-z0)/sigma)*((z-z0)/sigma) );
264  return pdf_gaussian;
265 }
266 
268 {
269  //sector 1 corresponds to detector B, 2 to A, 3 to C
270  // A is detIdx 0, B 1, C 2.
271  int DetIdx = -1;
272  if(sector == 1)
273  DetIdx = 1;
274  if(sector == 2)
275  DetIdx = 0;
276  if(sector == 3)
277  DetIdx = 2;
278 
279  return DetIdx;
280 }
281 
282 
283 // not used yet (implemented for alternate algorithm not yet fully developed)
284 int bmt_strip::isInSector(int layer, double angle, bmtConstants bmtc)
285 {
286 
287  int num_region = (int) (layer+1)/2 - 1; // region index (0...2) 0=layers 1&2, 1=layers 3&4, 2=layers 5&6
288 
289  if(angle<0)
290  angle+=2*pi; // from 0 to 2Pi
291  double angle_pr = angle + 2*pi;
292 
293  double angle_i = 0; // first angular boundary init
294  double angle_f = 0; // second angular boundary for detector A, B, or C init
295  int num_detector = -1;
296 
297  for(int i = 0; i<3; i++) {
298 
299  angle_i = bmtc.CRCEDGE1[num_region][i] + bmtc.CRCXPOS[num_region] /bmtc.CRCRADIUS[num_region];
300  angle_f = bmtc.CRCEDGE1[num_region][i] + (bmtc.CRCXPOS[num_region] + bmtc.CRCLENGTH[num_region])/bmtc.CRCRADIUS[num_region];
301 
302  if( (angle>=angle_i && angle<=angle_f) || (angle_pr>=angle_i && angle_pr<=angle_f) )
303  num_detector=i;
304  }
305  return num_detector + 1;
306 }
307 
308 
309 
310 
311 
double CRCRADIUS[NREGIONS]
Definition: bmt_strip.h:56
double CRCSPACING[NREGIONS]
Definition: bmt_strip.h:58
double CRCLENGTH[NREGIONS]
Definition: bmt_strip.h:59
vector< vector< int > > CRCGROUP
Definition: bmt_strip.h:66
double CRCEDGE1[NREGIONS][NREGIONS]
Definition: bmt_strip.h:64
double CRZWIDTH[NREGIONS]
Definition: bmt_strip.h:46
double getEnergyFraction(double z0, double z, double sigma)
Definition: bmt_strip.cc:261
double CRZRADIUS[NREGIONS]
Definition: bmt_strip.h:43
double CRZEDGE1[NREGIONS][NREGIONS]
Definition: bmt_strip.h:52
vector< double > FindStrip(int layer, int sector, G4ThreeVector xyz, double Edep, bmtConstants bmtc)
Definition: bmt_strip.cc:18
int getCStrip(int layer, double trk_z, bmtConstants bmtc)
Definition: bmt_strip.cc:170
int getZStrip(int layer, double angle, bmtConstants bmtc)
Definition: bmt_strip.cc:135
double getSigmaAzimuth(int layer, double x, double y, bmtConstants bmtc)
Definition: bmt_strip.cc:120
double CRCStrip_GetZ(int layer, int strip, bmtConstants bmtc)
Definition: bmt_strip.cc:214
double SigmaDrift
Definition: bmt_strip.h:33
int getDetectorIndex(int sector)
Definition: bmt_strip.cc:267
int isInSector(int layer, double angle, bmtConstants bmtc)
Definition: bmt_strip.cc:284
vector< vector< double > > CRCWIDTH
Definition: bmt_strip.h:67
double CRCXPOS[NREGIONS]
Definition: bmt_strip.h:63
double CRZXPOS[NREGIONS]
Definition: bmt_strip.h:51
double getSigmaLongit(int layer, double x, double y, bmtConstants bmtc)
Definition: bmt_strip.cc:105
double CRCOFFSET[NREGIONS]
Definition: bmt_strip.h:62
double CRZZMIN[NREGIONS]
Definition: bmt_strip.h:48
double ThetaL
Definition: bmt_strip.h:36
double CRZLENGTH[NREGIONS]
Definition: bmt_strip.h:47
int CRZNSTRIPS[NREGIONS]
Definition: bmt_strip.h:44
double hStrip2Det
Definition: bmt_strip.h:35
double CRCZMIN[NREGIONS]
Definition: bmt_strip.h:60
double CRZStrip_GetPhi(int sector, int layer, int strip, bmtConstants bmtc)
Definition: bmt_strip.cc:245
double hDrift
Definition: bmt_strip.h:34
double CRZSPACING[NREGIONS]
Definition: bmt_strip.h:45
double CRZOFFSET[NREGIONS]
Definition: bmt_strip.h:50