8 #include "G4Poisson.hh"
9 #include "G4ParticleDefinition.hh"
10 #include "G4NavigationHistory.hh"
12 #include "G4SystemOfUnits.hh"
13 #include "Randomize.hh"
31 edm::LogInfo(
"HFShower") <<
"HFCherenkov:: initialised with ref_index "
33 << lambda1/cm <<
"|" <<
lambda2/cm
34 <<
" aperture(total/trapped) " <<
aperture <<
"|"
36 <<
" Check photon survival in HF " << checkSurvive
37 <<
" Gain " << gain <<
" useNewPMT " << UseNewPMT
46 double u,
double v,
double w,
47 double step_length,
double zFiber,
48 double dose,
int npe_Dose) {
50 if (pBeta < (1/
ref_index) || step_length < 0.0001) {
return 0;}
52 double uv =
sqrt(u*u + v*v);
55 if (nbOfPhotons < 0) {
57 }
else if (nbOfPhotons > 0) {
59 for (
int i = 0;
i < nbOfPhotons;
i++) {
60 double rand = G4UniformRand();
61 double theta_C = acos(1./(pBeta*
ref_index));
63 double sinTheta =
sin(theta_C);
64 double cosTheta =
cos(theta_C);
65 double cosPhi =
cos(phi_C);
70 w_ph = w * cosTheta - sinTheta * cosPhi * uv;
77 int n_photons = npe_Dose;
82 double pBeta,
double u,
double v,
double w,
83 double step_length,
double zFiber,
84 double dose,
int npe_Dose) {
88 if (pBeta < (1/
ref_index) || step_length < 0.0001) {
90 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPE: pBeta " << pBeta
91 <<
" 1/mu " << (1/
ref_index) <<
" step_length "
97 double uv =
sqrt(u*u + v*v);
99 *aStep->GetTrack()->GetWeight();
101 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPE: pBeta " << pBeta
102 <<
" u/v/w " << u <<
"/" << v <<
"/" << w
103 <<
" step_length " << step_length <<
" zFib " << zFiber
104 <<
" nbOfPhotons " << nbOfPhotons;
106 if (nbOfPhotons < 0) {
108 }
else if (nbOfPhotons > 0) {
109 G4StepPoint * preStepPoint = aStep->GetPreStepPoint();
110 G4TouchableHandle theTouchable = preStepPoint->GetTouchableHandle();
111 G4ThreeVector localprepos = theTouchable->GetHistory()->
112 GetTopTransform().TransformPoint(aStep->GetPreStepPoint()->GetPosition());
113 G4ThreeVector localpostpos = theTouchable->GetHistory()->
114 GetTopTransform().TransformPoint(aStep->GetPostStepPoint()->GetPosition());
116 double length=
sqrt((localpostpos.x()-localprepos.x())*(localpostpos.x()-localprepos.x())
117 +(localpostpos.y()-localprepos.y())*(localpostpos.y()-localprepos.y()));
120 double u_ph=0,v_ph=0, w_ph=0;
121 for (
int i = 0;
i < nbOfPhotons;
i++) {
122 double rand = G4UniformRand();
123 double theta_C = acos(1./(pBeta*
ref_index));
125 double sinTheta =
sin(theta_C);
126 double cosTheta =
cos(theta_C);
127 double cosPhi =
cos(phi_C);
128 double sinPhi =
sin(phi_C);
131 u_ph = sinTheta * cosPhi ;
132 v_ph = sinTheta * sinPhi;
135 u_ph = uv * cosTheta + sinTheta * cosPhi *
w;
136 v_ph = sinTheta * sinPhi;
137 w_ph = w * cosTheta - sinTheta * cosPhi * uv;
139 double r_lambda = G4UniformRand();
142 double lambda = (lambda0/cm) *
pow(
double(10),7);
143 wlini.push_back(lambda);
145 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPE: " <<
i <<
" lambda "
146 << lambda <<
" w_ph " << w_ph <<
" aperture "
150 double xemit=length*(G4UniformRand()-0.5);
151 double gam=atan2(yemit,xemit);
152 double eps=atan2(v_ph,u_ph);
153 double sinBeta=
sin(gam-eps);
154 double rho=
sqrt(xemit*xemit+yemit*yemit);
155 double sinEta=rho/
fibreR*sinBeta;
156 double cosEta=
sqrt(1.-sinEta*sinEta);
157 double sinPsi=
sqrt(1.-w_ph*w_ph);
158 double cosKsi=cosEta*sinPsi;
160 if (cosKsi < aperturetrapped && w_ph>0.) {
161 LogDebug(
"HFShower") <<
"HFCherenkov::Trapped photon : " << u_ph <<
" "
162 << v_ph <<
" " << w_ph <<
" " << xemit <<
" "
163 << gam <<
" " << eps <<
" " << sinBeta <<
" "
164 << rho <<
" " << sinEta <<
" " << cosEta <<
" "
165 <<
" " << sinPsi <<
" " << cosKsi;
167 LogDebug(
"HFShower") <<
"HFCherenkov::Rejected photon : " << u_ph <<
" "
168 << v_ph <<
" " << w_ph <<
" " << xemit <<
" "
169 << gam <<
" " << eps <<
" " << sinBeta <<
" "
170 << rho <<
" " << sinEta <<
" " << cosEta <<
" "
171 <<
" " << sinPsi <<
" " << cosKsi;
178 double prob_HF = 1.0;
179 double a0_inv = 0.1234;
180 double prob_MX =
exp( - 0.5 * a0_inv );
182 double a_inv = a0_inv + 0.14 *
pow(dose,0.30);
183 double z_meters = zFiber;
184 prob_HF =
exp(-z_meters * a_inv );
186 rand = G4UniformRand();
188 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPE: probHF " << prob_HF
189 <<
" prob_MX " << prob_MX <<
" Random " << rand
190 <<
" Survive? " << (rand < (prob_HF * prob_MX));
192 if (rand < (prob_HF * prob_MX)) {
194 rand = G4UniformRand();
197 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPE: w_ph " << w_ph
198 <<
" effHEM " << effHEM <<
" Random " << rand
199 <<
" Survive? " << (w_ph>0.997||(rand<effHEM));
201 if (w_ph>0.997 || (rand<effHEM)) {
202 wlhem.push_back(lambda);
204 rand = G4UniformRand();
206 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPE: qEffic "
207 << qEffic <<
" Random " << rand
208 <<
" Survive? " <<(rand < qEffic);
212 momZ.push_back(w_ph);
213 wl.push_back(lambda);
223 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPE: npe " << npe;
229 double u,
double v,
double w,
234 if (pBeta < (1/
ref_index) || step_length < 0.0001) {
236 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPEinPMT: pBeta " << pBeta
237 <<
" 1/mu " << (1/
ref_index) <<
" step_length "
243 double uv =
sqrt(u*u + v*v);
246 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPEinPMT: pBeta " << pBeta
247 <<
" u/v/w " << u <<
"/" << v <<
"/" << w
248 <<
" step_length " << step_length
249 <<
" nbOfPhotons " << nbOfPhotons;
251 if (nbOfPhotons < 0) {
253 }
else if (nbOfPhotons > 0) {
255 for (
int i = 0;
i < nbOfPhotons;
i++) {
256 double rand = G4UniformRand();
257 double theta_C = acos(1./(pBeta*
ref_index));
259 double sinTheta =
sin(theta_C);
260 double cosTheta =
cos(theta_C);
261 double cosPhi =
cos(phi_C);
266 w_ph = w * cosTheta - sinTheta * cosPhi * uv;
268 double r_lambda = G4UniformRand();
271 double lambda = (lambda0/cm) *
pow(
double(10),7);
272 wlini.push_back(lambda);
274 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPEinPMT: " <<
i <<
" lambda "
275 << lambda <<
" w_ph " << w_ph <<
" aperture "
278 if (w_ph > aperture) {
280 rand = G4UniformRand();
282 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPEinPMT: Random " << rand
283 <<
" Survive? " << (rand < 1.);
287 rand = G4UniformRand();
289 rand = G4UniformRand();
291 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPEinPMT: qEffic "
292 << qEffic <<
" Random " << rand
293 <<
" Survive? " <<(rand < qEffic);
297 momZ.push_back(w_ph);
298 wl.push_back(lambda);
306 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPEinPMT: npe " << npe_;
312 std::vector<double>
v =
wlini;
317 std::vector<double>
v =
wltrap;
327 std::vector<double>
v =
wlhem;
332 std::vector<double>
v =
wlqeff;
337 std::vector<double>
v =
wl;
342 std::vector<double>
v =
momZ;
349 double alpha = 0.0073;
350 double step_length = stepL;
351 double theta_C = acos(1./(pBeta*
ref_index));
353 double cherenPhPerLength = 2 *
M_PI * alpha * lambdaDiff*cm;
354 double d_NOfPhotons = cherenPhPerLength *
sin(theta_C)*
sin(theta_C) * (step_length/cm);
355 int nbOfPhotons = int(d_NOfPhotons);
357 LogDebug(
"HFShower") <<
"HFCherenkov::computeNbOfPhotons: StepLength "
358 << step_length <<
" theta_C " << theta_C
359 <<
" lambdaDiff " << lambdaDiff
360 <<
" cherenPhPerLength " << cherenPhPerLength
361 <<
" Photons " << d_NOfPhotons <<
" " << nbOfPhotons;
370 if (wavelength<=350) {
371 qeff=2.45867*(TMath::Landau(wavelength,353.820,59.1324));
372 }
else if (wavelength>350 && wavelength<500) {
373 qeff= 0.441989*
exp(-
pow((wavelength-358.371),2)/(2*
pow((138.277),2)));
374 }
else if (wavelength>=500 && wavelength<550) {
375 qeff= 0.271862*
exp(-
pow((wavelength-491.505),2)/(2*
pow((47.0418),2)));
376 }
else if (wavelength>=550) {
377 qeff= 0.137297*
exp(-
pow((wavelength-520.260),2)/(2*
pow((75.5023),2)));
380 LogDebug(
"HFShower") <<
"HFCherenkov:: for new PMT : wavelength === "
381 << wavelength <<
"\tqeff ===\t" << qeff;
384 double y = (wavelength - 275.) /180.;
385 double func = 1. / (1. + 250.*
pow((y/5.),4));
386 double qE_R7525 = 0.77 * y *
exp(-y) *
func ;
389 LogDebug(
"HFShower") <<
"HFCherenkov:: for old PMT : wavelength === "
390 << wavelength <<
"; qeff = " << qeff;
395 LogDebug(
"HFShower") <<
"HFCherenkov::computeQEff: wavelength " << wavelength
396 <<
" y/func " <<
y <<
"/" <<
func <<
" qeff " << qeff;
404 if (wavelength < 400.) {
406 }
else if (wavelength >= 400. && wavelength < 410.) {
408 hEMEff = (-1322.453 / wavelength) + 4.2056;
409 }
else if (wavelength >= 410.) {
411 if (wavelength > 415. && wavelength < 445.) {
415 }
else if (wavelength > 550. && wavelength < 600.) {
419 }
else if (wavelength > 565. && wavelength <= 635.) {
421 hEMEff = (701.7268 / wavelength) - 0.186;
425 LogDebug(
"HFShower") <<
"HFCherenkov::computeHEMEff: wavelength "
426 << wavelength <<
" hEMEff " << hEMEff;
435 for (
int i = 0;
i < npe; ++
i) {
436 double val = G4Poisson(
gain);
437 pe += (val/
gain) + 0.001*G4UniformRand();
441 LogDebug(
"HFShower") <<
"HFCherenkov::smearNPE: npe " << npe <<
" pe " << pe;
458 bool tmp = (aParticleType->GetPDGCharge() != 0);
460 LogDebug(
"HFShower") <<
"HFCherenkov::isApplicable: aParticleType "
461 << aParticleType->GetParticleName() <<
" PDGCharge "
462 << aParticleType->GetPDGCharge() <<
" Result " <<
tmp;
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
double computeQEff(double wavelength)
Sin< T >::type sin(const T &t)
HFCherenkov(edm::ParameterSet const &p)
std::vector< double > wlqeff
int computeNPEinPMT(G4ParticleDefinition *pDef, double pBeta, double u, double v, double w, double step_length)
std::vector< double > wlini
double computeHEMEff(double wavelength)
double smearNPE(G4int Npe)
std::vector< double > getWL()
std::vector< double > getWLQEff()
std::vector< double > wltrap
Cos< T >::type cos(const T &t)
std::vector< double > wlhem
std::vector< double > getMom()
std::vector< double > getWLIni()
std::vector< std::vector< double > > tmp
int computeNbOfPhotons(double pBeta, double step_length)
std::vector< double > getWLTrap()
std::vector< double > getWLAtten()
bool isApplicable(const G4ParticleDefinition *aParticleType)
std::vector< double > wlatten
std::vector< double > momZ
int computeNPhTrapped(double pBeta, double u, double v, double w, double step_length, double zFiber, double Dose, int Npe_Dose)
Power< A, B >::type pow(const A &a, const B &b)
int computeNPE(G4Step *step, G4ParticleDefinition *pDef, double pBeta, double u, double v, double w, double step_length, double zFiber, double Dose, int Npe_Dose)
std::vector< double > getWLHEM()