CMS 3D CMS Logo

HitDigitizerFP420.cc
Go to the documentation of this file.
1 // File: HitDigitizerFP420.cc
3 // Date: 08.2008
4 // Description: HitDigitizerFP420 for FP420
5 // Modifications:
8 //#include "SimG4CMS/FP420/interface/FP420G4HitCollection.h"
9 //#include "SimG4CMS/FP420/interface/FP420G4Hit.h"
10 
15 
19 
20 using namespace std;
21 #include <vector>
22 
23 #define CBOLTZ (1.38E-23)
24 #define e_SI (1.6E-19)
25 
26 // HitDigitizerFP420::HitDigitizerFP420(float in,float inp,float inpx,float
27 // inpy){ HitDigitizerFP420::HitDigitizerFP420(float in,float inp,float
28 // inpx,float inpy,float ild,float ildx,float ildy){
30  float in, float ild, float ildx, float ildy, float in0, float in2, float in3, int verbosity) {
31  moduleThickness = in;
32  double bz420 = in0;
33  double bzD2 = in2;
34  double bzD3 = in3;
35  // double pitch =inp;
36  // double pitchX =inpx;
37  // double pitchY =inpy;
38  double ldrift = ild;
39  double ldriftX = ildx;
40  double ldriftY = ildy;
41  //
42  // Construct default classes
43  //
44 
45  // theCDividerFP420 = new ChargeDividerFP420(pitch);
46  theCDividerFP420 = new ChargeDividerFP420(moduleThickness, bz420, bzD2, bzD3, verbosity);
47 
48  depletionVoltage = 20.0; //
49  appliedVoltage = 25.0; // a bit bigger than depletionVoltage to have positive
50  // value A for logA, A=1-2*Tfract.*Vd/(Vd+Vb)
51 
52  // chargeMobility=480.0;// = 480.0 !holes mobility [cm**2/V/sec] p-side;
53  // = 1350.0 !electron mobility - n-side
54  chargeMobility = 1350.0; // = 480.0 !holes mobility [cm**2/V/sec] p-side;
55  // = 1350.0 !electron mobility - n-side
56  // temperature=297.; // 24 C degree +273 = 297 ---->diffusion const for
57  // electrons= (1.38E-23/1.6E-19)*1350.0*297=34.6
58  // diffusion const for holes = 12.3 [cm**2/sec]
59  temperature = 263.; // -10 C degree +273 = 263 ---->diffusion const for
60  // electrons= (1.38E-23/1.6E-19)*1350.0*263=30.6
61  double diffusionConstant = CBOLTZ / e_SI * chargeMobility * temperature;
62  // noDiffusion=true; // true if no Diffusion
63  noDiffusion = false; // false if Diffusion
64  if (noDiffusion)
65  diffusionConstant *= 1.0e-3;
66 
67  chargeDistributionRMS = 6.5e-10;
68 
69  // arbitrary:
70  tanLorentzAnglePerTesla = 0.; // try =0.106 if B field exist
71 
72  // double timeNormalisation =
73  // pow(moduleThickness,2)/(2.*depletionVoltage*chargeMobility); double
74  // timeNormalisation = pow(pitch,2)/(2.*depletionVoltage*chargeMobility);
75 
76  double timeNormalisation = pow(ldrift, 2) / (2. * depletionVoltage * chargeMobility); //
77  // double timeNormalisation =
78  // pow(ldrift,2)/(2.*depletionVoltage*chargeMobility);//
79  timeNormalisation = timeNormalisation * 0.01; // because ldrift in [mm] but mu_e in [cm2/V/sec
80 
81  // double timeNormalisation =
82  // pow(pitch/2.,2)/(2.*depletionVoltage*chargeMobility);// i entered
83  // pitch as a distance between 2 read-out strips, not real distance
84  // between any (p or n) electrods which will be in 2 times less. But in
85  // expression for timeNormalisation the real distance of charge
86  // collection must be, so use pitch/2. !
87 
88  double clusterWidth = 5.; // was = 3
89  gevperelectron = 3.61e-09; // double GevPerElectron = 3.61e-09
90 
91  // GevPerElectron AZ:average deposited energy per e-h pair [keV]??? =0.0036
92  if (verbosity > 0) {
93  std::cout << "HitDigitizerFP420: constructor ldrift= " << ldrift << std::endl;
94  std::cout << "ldriftY= " << ldriftY << "ldriftX= " << ldriftX << std::endl;
95  std::cout << "depletionVoltage" << depletionVoltage << "appliedVoltage" << appliedVoltage << "chargeMobility"
96  << chargeMobility << "temperature" << temperature << "diffusionConstant" << diffusionConstant
97  << "chargeDistributionRMS" << chargeDistributionRMS << "moduleThickness" << moduleThickness
98  << "timeNormalisation" << timeNormalisation << "gevperelectron" << gevperelectron << std::endl;
99  }
100  // ndif
101 
102  theCDrifterFP420 = new ChargeDrifterFP420(moduleThickness,
103  timeNormalisation,
104  diffusionConstant,
105  temperature,
106  chargeDistributionRMS,
107  depletionVoltage,
108  appliedVoltage,
109  ldriftX,
110  ldriftY,
111  verbosity);
112  // pitchX,
113  // pitchY);
114 
115  theIChargeFP420 = new InduceChargeFP420(clusterWidth, gevperelectron);
116 }
117 
119  delete theCDividerFP420;
120  delete theCDrifterFP420;
121  delete theIChargeFP420;
122 }
123 
124 // HitDigitizerFP420::hit_map_type HitDigitizerFP420::processHit(const PSimHit&
125 // hit, G4ThreeVector bfield, int xytype,int numStrips, double pitch){
127  const G4ThreeVector &bfield,
128  int xytype,
129  int numStrips,
130  double pitch,
131  int numStripsW,
132  double pitchW,
133  double moduleThickness,
134  int verbosity) {
135  // use chargePosition just for cross-check in "induce" method
136  // hit center in 3D-detector r.f.
137 
138  float middlex = (hit.exitPoint().x() + hit.entryPoint().x()) / 2.;
139  float middley = (hit.exitPoint().y() + hit.entryPoint().y()) / 2.;
140 
141  float chargePosition = -100.;
142  // Y:
143  if (xytype == 1) {
144  // chargePosition = fabs(-numStrips/2. - ( int(middle.x()/pitch) +1.)
145  // );
146  // chargePosition = fabs(int(middle.x()/pitch+0.5*(numStrips+1)) + 1.);
147  // chargePosition = fabs(int(middle.y()/pitch+0.5*(numStrips+1))
148  // + 1.);
149  // local and global reference frames are rotated in 90 degree, so global X
150  // and local Y are collinear
151  // chargePosition = int(fabs(middle.x()/pitch + 0.5*numStrips + 1.));//
152  // charge in strip coord
153  chargePosition = 0.5 * (numStrips) + middlex / pitch; // charge in strip coord 0 - numStrips-1
154 
155  }
156  // X:
157  else if (xytype == 2) {
158  // chargePosition = fabs(-numStrips/2. - ( int(middle.y()/pitch) +1.)
159  // );
160  // chargePosition = fabs(int(middle.y()/pitch+0.5*(numStrips+1)) + 1.);
161  // chargePosition = fabs(int(middle.x()/pitch+0.5*(numStrips+1))
162  // + 1.);
163  // local and global reference frames are rotated in 90 degree, so global X
164  // and local Y are collinear
165  // chargePosition = int(fabs(middle.y()/pitch + 0.5*numStrips + 1.));
166  chargePosition = 0.5 * (numStrips) + middley / pitch; // charge in strip coord 0 - numStrips-1
167 
168  // std::cout << " chargePosition SiHitDi... = " << chargePosition <<
169  // std::endl;
170  } else {
171  std::cout << "================================================================" << std::endl;
172  std::cout << "**** HitDigitizerFP420: !!! ERROR: you have not to be "
173  "here !!! xytype="
174  << xytype << std::endl;
175  // std::cout << "**** HitDigitizerFP420: !!! ERROR: you have not to be
176  // here !!! xytype=" << xytype << std::endl;
177 
178  // break;
179  }
180  // if(chargePosition > numStrips || chargePosition<1) {
181  if (chargePosition > numStrips || chargePosition < 0) {
182  std::cout << "**** HitDigitizerFP420: !!! ERROR: check correspondence of XY "
183  "detector dimensions in XML and here !!! chargePosition = "
184  << chargePosition << std::endl;
185  // break;
186  }
187 
188  if (verbosity > 0) {
189  std::cout << " ====== **** HitDigitizerFP420: !!! processHit !!! : "
190  "input: xytype="
191  << xytype << " numStrips= " << numStrips << " pitch= " << pitch
192  << " Calculated chargePosition= " << chargePosition << std::endl;
193  std::cout << "The middle of hit point on input was: middlex = " << middlex << std::endl;
194  std::cout << "The middle of hit point on input was: middley = " << middley << std::endl;
195  // std::cout << "For checks: hit point Entry = " << hit.getEntry() <<
196  // std::endl;
197  std::cout << " ====== **** HitDigitizerFP420:processHit: start "
198  "CDrifterFP420 divide"
199  << std::endl;
200  }
201  //
202  // Fully process one SimHit
203  //
204 
205  // CDrifterFP420::ionization_type ion = theCDividerFP420->divide(hit,pitch);
206  CDrifterFP420::ionization_type ion = theCDividerFP420->divide(hit, moduleThickness);
207  //
208  // Compute the drift direction for this det
209  //
210 
211  // G4ThreeVector driftDir = DriftDirection(&det,bfield);
212  G4ThreeVector driftDir = DriftDirection(bfield, xytype, verbosity);
213  if (verbosity > 0) {
214  std::cout << " ====== **** HitDigitizerFP420:processHit: driftDir= " << driftDir << std::endl;
215  std::cout << " ====== **** HitDigitizerFP420:processHit: start "
216  "induce , CDrifterFP420 drift "
217  << std::endl;
218  }
219 
220  // if(driftDir.z() ==0.) {
221  // std::cout << " pxlx: drift in z is zero " << std::endl;
222  // } else
223  //
224 
225  return theIChargeFP420->induce(
226  theCDrifterFP420->drift(ion, driftDir, xytype), numStrips, pitch, numStripsW, pitchW, xytype, verbosity);
227 
228  //
229 }
230 
231 G4ThreeVector HitDigitizerFP420::DriftDirection(const G4ThreeVector &_bfield, int xytype, int verbosity) {
232  // LOCAL hit: exchange xytype: 1 <-> 2
233 
234  // Frame detFrame(_detp->surface().position(),_detp->surface().rotation());
235  // G4ThreeVector Bfield=detFrame.toLocal(_bfield);
236  const G4ThreeVector &Bfield = _bfield;
237  float dir_x, dir_y, dir_z;
238  // this lines with dir_... have to be specified(sign?) in dependence of field
239  // direction:
240  /*
241  float dir_x = tanLorentzAnglePerTesla * Bfield.y();
242  float dir_y = -tanLorentzAnglePerTesla * Bfield.x();
243  float dir_z = 1.; // if E field is in z direction
244  */
245  // for electrons:
246  // E field is either in X or Y direction with change vector to opposite
247 
248  // global Y or localX
249  // E field is in Xlocal direction with change vector to opposite
250  if (xytype == 2) {
251  dir_x = 1.; // E field in Xlocal direction
252  dir_y = +tanLorentzAnglePerTesla * Bfield.z();
253  dir_z = -tanLorentzAnglePerTesla * Bfield.y();
254  }
255  // global X
256  // E field is in Ylocal direction with change vector to opposite
257  else if (xytype == 1) {
258  dir_x = +tanLorentzAnglePerTesla * Bfield.z();
259  dir_y = 1.; // E field in Ylocal direction
260  dir_z = -tanLorentzAnglePerTesla * Bfield.x();
261  } else {
262  dir_x = 0.;
263  dir_y = 0.;
264  dir_z = 0.;
265  std::cout << "HitDigitizerFP420: ERROR - wrong xytype=" << xytype << std::endl;
266  }
267 
268  // G4ThreeVector theDriftDirection = LocalVector(dir_x,dir_y,dir_z);
269  G4ThreeVector theDriftDirection(dir_x, dir_y, dir_z);
270  // Local3DPoint
271  // EntryPo(aHit->getEntry().x(),aHit->getEntry().y(),aHit->getEntry().z());
272  if (verbosity > 0) {
273  std::cout << "HitDigitizerFP420:DriftDirection tanLorentzAnglePerTesla= " << tanLorentzAnglePerTesla << std::endl;
274  std::cout << "HitDigitizerFP420:DriftDirection The drift direction in "
275  "local coordinate is "
276  << theDriftDirection << std::endl;
277  }
278 
279  return theDriftDirection;
280 }
#define CBOLTZ
std::map< int, float, std::less< int > > hit_map_type
G4ThreeVector DriftDirection(const G4ThreeVector &, int, int)
#define e_SI
HitDigitizerFP420(float in, float ild, float ildx, float ildy, float in0, float in2, float in3, int verbosity)
constexpr float Bfield
Definition: Config.h:88
std::vector< EnergySegmentFP420 > ionization_type
Definition: CDrifterFP420.h:14
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
hit_map_type processHit(const PSimHit &, const G4ThreeVector &, int, int, double, int, double, double, int)