8 #include "G4Poisson.hh"
9 #include "G4ParticleDefinition.hh"
10 #include "G4NavigationHistory.hh"
13 #include "Randomize.hh"
14 #include "G4SystemOfUnits.hh"
43 double pBeta,
double u,
double v,
double w,
double step_length,
double zFiber,
double dose,
int npe_Dose) {
44 if (pBeta < (1 /
ref_index) || step_length < 0.0001) {
48 double uv =
sqrt(u * u +
v *
v);
51 if (nbOfPhotons < 0) {
53 }
else if (nbOfPhotons > 0) {
55 for (
int i = 0;
i < nbOfPhotons;
i++) {
56 double rand = G4UniformRand();
57 double theta_C = acos(1. / (pBeta *
ref_index));
59 double sinTheta =
sin(theta_C);
60 double cosTheta =
cos(theta_C);
61 double cosPhi =
cos(phi_C);
66 w_ph =
w * cosTheta - sinTheta * cosPhi * uv;
73 int n_photons = npe_Dose;
78 const G4ParticleDefinition* pDef,
91 if (pBeta < (1 /
ref_index) || step_length < 0.0001) {
94 <<
" step_length " << step_length;
99 double uv =
sqrt(u * u +
v *
v);
100 int nbOfPhotons =
computeNbOfPhotons(pBeta, step_length) * aStep->GetTrack()->GetWeight();
102 edm::LogVerbatim(
"HFShower") <<
"HFCherenkov::computeNPE: pBeta " << pBeta <<
" u/v/w " << u <<
"/" <<
v <<
"/" <<
w
103 <<
" step_length " << step_length <<
" zFib " << zFiber <<
" nbOfPhotons "
106 if (nbOfPhotons < 0) {
108 }
else if (nbOfPhotons > 0) {
109 G4StepPoint* preStepPoint = aStep->GetPreStepPoint();
110 const G4TouchableHandle& theTouchable = preStepPoint->GetTouchableHandle();
111 G4ThreeVector localprepos =
112 theTouchable->GetHistory()->GetTopTransform().TransformPoint(aStep->GetPreStepPoint()->GetPosition());
113 G4ThreeVector localpostpos =
114 theTouchable->GetHistory()->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();
141 double lambda = (lambda0 / cm) *
pow(
double(10), 7);
142 wlini.push_back(lambda);
144 edm::LogVerbatim(
"HFShower") <<
"HFCherenkov::computeNPE: " <<
i <<
" lambda " << lambda <<
" w_ph " << w_ph
148 double xemit = length * (G4UniformRand() - 0.5);
149 double gam = atan2(yemit, xemit);
150 double eps = atan2(v_ph, u_ph);
151 double sinBeta =
sin(gam - eps);
152 double rho =
sqrt(xemit * xemit + yemit * yemit);
154 double cosEta =
sqrt(1. - sinEta * sinEta);
155 double sinPsi =
sqrt(1. - w_ph * w_ph);
156 double cosKsi = cosEta * sinPsi;
158 if (cosKsi < aperturetrapped && w_ph > 0.) {
159 edm::LogVerbatim(
"HFShower") <<
"HFCherenkov::Trapped photon : " << u_ph <<
" " << v_ph <<
" " << w_ph <<
" "
160 << xemit <<
" " << gam <<
" " << eps <<
" " << sinBeta <<
" " <<
rho <<
" "
161 << sinEta <<
" " << cosEta <<
" "
162 <<
" " << sinPsi <<
" " << cosKsi;
164 edm::LogVerbatim(
"HFShower") <<
"HFCherenkov::Rejected photon : " << u_ph <<
" " << v_ph <<
" " << w_ph <<
" "
165 << xemit <<
" " << gam <<
" " << eps <<
" " << sinBeta <<
" " <<
rho <<
" "
166 << sinEta <<
" " << cosEta <<
" "
167 <<
" " << sinPsi <<
" " << cosKsi;
174 double prob_HF = 1.0;
175 double a0_inv = 0.1234;
176 double prob_MX =
exp(-0.5 * a0_inv);
178 double a_inv = a0_inv + 0.14 *
pow(dose, 0.30);
179 double z_meters = zFiber;
180 prob_HF =
exp(-z_meters * a_inv);
182 rand = G4UniformRand();
184 edm::LogVerbatim(
"HFShower") <<
"HFCherenkov::computeNPE: probHF " << prob_HF <<
" prob_MX " << prob_MX
185 <<
" Random " <<
rand <<
" Survive? " << (
rand < (prob_HF * prob_MX));
187 if (
rand < (prob_HF * prob_MX)) {
189 rand = G4UniformRand();
192 edm::LogVerbatim(
"HFShower") <<
"HFCherenkov::computeNPE: w_ph " << w_ph <<
" effHEM " << effHEM <<
" Random "
193 <<
rand <<
" Survive? " << (w_ph > 0.997 || (
rand < effHEM));
195 if (w_ph > 0.997 || (
rand < effHEM)) {
196 wlhem.push_back(lambda);
198 rand = G4UniformRand();
200 edm::LogVerbatim(
"HFShower") <<
"HFCherenkov::computeNPE: qEffic " << qEffic <<
" Random " <<
rand
201 <<
" Survive? " << (
rand < qEffic);
205 momZ.push_back(w_ph);
206 wl.push_back(lambda);
222 const G4ParticleDefinition* pDef,
double pBeta,
double u,
double v,
double w,
double step_length) {
228 if (pBeta < (1 /
ref_index) || step_length < 0.0001) {
231 <<
" step_length " << step_length;
236 double uv =
sqrt(u * u +
v *
v);
239 edm::LogVerbatim(
"HFShower") <<
"HFCherenkov::computeNPEinPMT: pBeta " << pBeta <<
" u/v/w " << u <<
"/" <<
v <<
"/"
240 <<
w <<
" step_length " << step_length <<
" nbOfPhotons " << nbOfPhotons;
242 if (nbOfPhotons < 0) {
244 }
else if (nbOfPhotons > 0) {
246 for (
int i = 0;
i < nbOfPhotons;
i++) {
247 double rand = G4UniformRand();
248 double theta_C = acos(1. / (pBeta *
ref_index));
250 double sinTheta =
sin(theta_C);
251 double cosTheta =
cos(theta_C);
252 double cosPhi =
cos(phi_C);
257 w_ph =
w * cosTheta - sinTheta * cosPhi * uv;
259 double r_lambda = G4UniformRand();
261 double lambda = (lambda0 / cm) *
pow(
double(10), 7);
262 wlini.push_back(lambda);
264 edm::LogVerbatim(
"HFShower") <<
"HFCherenkov::computeNPEinPMT: " <<
i <<
" lambda " << lambda <<
" w_ph " << w_ph
269 rand = G4UniformRand();
276 rand = G4UniformRand();
278 edm::LogVerbatim(
"HFShower") <<
"HFCherenkov::computeNPEinPMT: qEffic " << qEffic <<
" Random " <<
rand
279 <<
" Survive? " << (
rand < qEffic);
283 momZ.push_back(w_ph);
284 wl.push_back(lambda);
292 edm::LogVerbatim(
"HFShower") <<
"HFCherenkov::computeNPEinPMT: npe " << npe_;
298 std::vector<double>
v =
wlini;
303 std::vector<double>
v =
wltrap;
313 std::vector<double>
v =
wlhem;
318 std::vector<double>
v =
wlqeff;
323 std::vector<double>
v =
wl;
328 std::vector<double>
v =
momZ;
334 double alpha = 0.0073;
335 double step_length = stepL;
336 double theta_C = acos(1. / (pBeta *
ref_index));
338 double cherenPhPerLength = 2 *
M_PI *
alpha * lambdaDiff * cm;
339 double d_NOfPhotons = cherenPhPerLength *
sin(theta_C) *
sin(theta_C) * (step_length / cm);
340 int nbOfPhotons =
int(d_NOfPhotons);
342 edm::LogVerbatim(
"HFShower") <<
"HFCherenkov::computeNbOfPhotons: StepLength " << step_length <<
" theta_C "
343 << theta_C <<
" lambdaDiff " << lambdaDiff <<
" cherenPhPerLength " << cherenPhPerLength
344 <<
" Photons " << d_NOfPhotons <<
" " << nbOfPhotons;
352 if (wavelength <= 350) {
353 qeff = 2.45867 * (TMath::Landau(wavelength, 353.820, 59.1324));
354 }
else if (wavelength > 350 && wavelength < 500) {
355 qeff = 0.441989 *
exp(-
pow((wavelength - 358.371), 2) / (2 *
pow((138.277), 2)));
356 }
else if (wavelength >= 500 && wavelength < 550) {
357 qeff = 0.271862 *
exp(-
pow((wavelength - 491.505), 2) / (2 *
pow((47.0418), 2)));
358 }
else if (wavelength >= 550) {
359 qeff = 0.137297 *
exp(-
pow((wavelength - 520.260), 2) / (2 *
pow((75.5023), 2)));
362 edm::LogVerbatim(
"HFShower") <<
"HFCherenkov:: for new PMT : wavelength === " << wavelength <<
"\tqeff ===\t"
366 double y = (wavelength - 275.) / 180.;
367 double func = 1. / (1. + 250. *
pow((
y / 5.), 4));
368 double qE_R7525 = 0.77 *
y *
exp(-
y) *
func;
371 edm::LogVerbatim(
"HFShower") <<
"HFCherenkov::computeQEff: wavelength " << wavelength <<
" y/func " <<
y <<
"/"
372 <<
func <<
" qeff " << qeff;
373 edm::LogVerbatim(
"HFShower") <<
"HFCherenkov:: for old PMT : wavelength === " << wavelength <<
"; qeff = " << qeff;
381 if (wavelength < 400.) {
383 }
else if (wavelength >= 400. && wavelength < 410.) {
385 hEMEff = (-1322.453 / wavelength) + 4.2056;
386 }
else if (wavelength >= 410.) {
388 if (wavelength > 415. && wavelength < 445.) {
392 }
else if (wavelength > 550. && wavelength < 600.) {
396 }
else if (wavelength > 565. && wavelength <= 635.) {
398 hEMEff = (701.7268 / wavelength) - 0.186;
402 edm::LogVerbatim(
"HFShower") <<
"HFCherenkov::computeHEMEff: wavelength " << wavelength <<
" hEMEff " << hEMEff;
410 for (
int i = 0;
i < npe; ++
i) {
412 pe += (
val /
gain) + 0.001 * G4UniformRand();
416 edm::LogVerbatim(
"HFShower") <<
"HFCherenkov::smearNPE: npe " << npe <<
" pe " << pe;
432 bool tmp = (aParticleType->GetPDGCharge() != 0);
434 edm::LogVerbatim(
"HFShower") <<
"HFCherenkov::isApplicable: aParticleType " << aParticleType->GetParticleName()
435 <<
" PDGCharge " << aParticleType->GetPDGCharge() <<
" Result " <<
tmp;