8 #include "G4Poisson.hh"
9 #include "G4ParticleDefinition.hh"
10 #include "G4NavigationHistory.hh"
13 #include "Randomize.hh"
14 #include "G4SystemOfUnits.hh"
32 edm::LogInfo(
"HFShower") <<
"HFCherenkov:: initialised with ref_index "
34 << lambda1/cm <<
"|" <<
lambda2/cm
35 <<
" aperture(total/trapped) " <<
aperture <<
"|"
37 <<
" Check photon survival in HF " << checkSurvive
38 <<
" Gain " << gain <<
" useNewPMT " << UseNewPMT
47 double u,
double v,
double w,
48 double step_length,
double zFiber,
49 double dose,
int npe_Dose) {
51 if (pBeta < (1/
ref_index) || step_length < 0.0001) {
return 0;}
53 double uv =
sqrt(u*u + v*v);
56 if (nbOfPhotons < 0) {
58 }
else if (nbOfPhotons > 0) {
60 for (
int i = 0;
i < nbOfPhotons;
i++) {
61 double rand = G4UniformRand();
62 double theta_C = acos(1./(pBeta*
ref_index));
64 double sinTheta =
sin(theta_C);
65 double cosTheta =
cos(theta_C);
66 double cosPhi =
cos(phi_C);
71 w_ph = w * cosTheta - sinTheta * cosPhi * uv;
78 int n_photons = npe_Dose;
83 double pBeta,
double u,
double v,
double w,
84 double step_length,
double zFiber,
85 double dose,
int npe_Dose) {
89 if (pBeta < (1/
ref_index) || step_length < 0.0001) {
91 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPE: pBeta " << pBeta
92 <<
" 1/mu " << (1/
ref_index) <<
" step_length "
98 double uv =
sqrt(u*u + v*v);
100 *aStep->GetTrack()->GetWeight();
102 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPE: pBeta " << pBeta
103 <<
" u/v/w " << u <<
"/" << v <<
"/" << w
104 <<
" step_length " << step_length <<
" zFib " << zFiber
105 <<
" nbOfPhotons " << nbOfPhotons;
107 if (nbOfPhotons < 0) {
109 }
else if (nbOfPhotons > 0) {
110 G4StepPoint * preStepPoint = aStep->GetPreStepPoint();
111 G4TouchableHandle theTouchable = preStepPoint->GetTouchableHandle();
112 G4ThreeVector localprepos = theTouchable->GetHistory()->
113 GetTopTransform().TransformPoint(aStep->GetPreStepPoint()->GetPosition());
114 G4ThreeVector localpostpos = theTouchable->GetHistory()->
115 GetTopTransform().TransformPoint(aStep->GetPostStepPoint()->GetPosition());
117 double length=
sqrt((localpostpos.x()-localprepos.x())*(localpostpos.x()-localprepos.x())
118 +(localpostpos.y()-localprepos.y())*(localpostpos.y()-localprepos.y()));
121 double u_ph=0,v_ph=0, w_ph=0;
122 for (
int i = 0;
i < nbOfPhotons;
i++) {
123 double rand = G4UniformRand();
124 double theta_C = acos(1./(pBeta*
ref_index));
126 double sinTheta =
sin(theta_C);
127 double cosTheta =
cos(theta_C);
128 double cosPhi =
cos(phi_C);
129 double sinPhi =
sin(phi_C);
132 u_ph = sinTheta * cosPhi ;
133 v_ph = sinTheta * sinPhi;
136 u_ph = uv * cosTheta + sinTheta * cosPhi *
w;
137 v_ph = sinTheta * sinPhi;
138 w_ph = w * cosTheta - sinTheta * cosPhi * uv;
140 double r_lambda = G4UniformRand();
143 double lambda = (lambda0/cm) *
pow(
double(10),7);
144 wlini.push_back(lambda);
146 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPE: " <<
i <<
" lambda "
147 << lambda <<
" w_ph " << w_ph <<
" aperture "
151 double xemit=length*(G4UniformRand()-0.5);
152 double gam=atan2(yemit,xemit);
153 double eps=atan2(v_ph,u_ph);
154 double sinBeta=
sin(gam-eps);
155 double rho=
sqrt(xemit*xemit+yemit*yemit);
156 double sinEta=rho/
fibreR*sinBeta;
157 double cosEta=
sqrt(1.-sinEta*sinEta);
158 double sinPsi=
sqrt(1.-w_ph*w_ph);
159 double cosKsi=cosEta*sinPsi;
161 if (cosKsi < aperturetrapped && w_ph>0.) {
162 LogDebug(
"HFShower") <<
"HFCherenkov::Trapped photon : " << u_ph <<
" "
163 << v_ph <<
" " << w_ph <<
" " << xemit <<
" "
164 << gam <<
" " << eps <<
" " << sinBeta <<
" "
165 << rho <<
" " << sinEta <<
" " << cosEta <<
" "
166 <<
" " << sinPsi <<
" " << cosKsi;
168 LogDebug(
"HFShower") <<
"HFCherenkov::Rejected photon : " << u_ph <<
" "
169 << v_ph <<
" " << w_ph <<
" " << xemit <<
" "
170 << gam <<
" " << eps <<
" " << sinBeta <<
" "
171 << rho <<
" " << sinEta <<
" " << cosEta <<
" "
172 <<
" " << sinPsi <<
" " << cosKsi;
179 double prob_HF = 1.0;
180 double a0_inv = 0.1234;
181 double prob_MX =
exp( - 0.5 * a0_inv );
183 double a_inv = a0_inv + 0.14 *
pow(dose,0.30);
184 double z_meters = zFiber;
185 prob_HF =
exp(-z_meters * a_inv );
187 rand = G4UniformRand();
189 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPE: probHF " << prob_HF
190 <<
" prob_MX " << prob_MX <<
" Random " << rand
191 <<
" Survive? " << (rand < (prob_HF * prob_MX));
193 if (rand < (prob_HF * prob_MX)) {
195 rand = G4UniformRand();
198 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPE: w_ph " << w_ph
199 <<
" effHEM " << effHEM <<
" Random " << rand
200 <<
" Survive? " << (w_ph>0.997||(rand<effHEM));
202 if (w_ph>0.997 || (rand<effHEM)) {
203 wlhem.push_back(lambda);
205 rand = G4UniformRand();
207 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPE: qEffic "
208 << qEffic <<
" Random " << rand
209 <<
" Survive? " <<(rand < qEffic);
213 momZ.push_back(w_ph);
214 wl.push_back(lambda);
224 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPE: npe " << npe;
230 double u,
double v,
double w,
235 if (pBeta < (1/
ref_index) || step_length < 0.0001) {
237 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPEinPMT: pBeta " << pBeta
238 <<
" 1/mu " << (1/
ref_index) <<
" step_length "
244 double uv =
sqrt(u*u + v*v);
247 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPEinPMT: pBeta " << pBeta
248 <<
" u/v/w " << u <<
"/" << v <<
"/" << w
249 <<
" step_length " << step_length
250 <<
" nbOfPhotons " << nbOfPhotons;
252 if (nbOfPhotons < 0) {
254 }
else if (nbOfPhotons > 0) {
256 for (
int i = 0;
i < nbOfPhotons;
i++) {
257 double rand = G4UniformRand();
258 double theta_C = acos(1./(pBeta*
ref_index));
260 double sinTheta =
sin(theta_C);
261 double cosTheta =
cos(theta_C);
262 double cosPhi =
cos(phi_C);
267 w_ph = w * cosTheta - sinTheta * cosPhi * uv;
269 double r_lambda = G4UniformRand();
272 double lambda = (lambda0/cm) *
pow(
double(10),7);
273 wlini.push_back(lambda);
275 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPEinPMT: " <<
i <<
" lambda "
276 << lambda <<
" w_ph " << w_ph <<
" aperture "
279 if (w_ph > aperture) {
281 rand = G4UniformRand();
283 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPEinPMT: Random " << rand
284 <<
" Survive? " << (rand < 1.);
288 rand = G4UniformRand();
290 rand = G4UniformRand();
292 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPEinPMT: qEffic "
293 << qEffic <<
" Random " << rand
294 <<
" Survive? " <<(rand < qEffic);
298 momZ.push_back(w_ph);
299 wl.push_back(lambda);
307 LogDebug(
"HFShower") <<
"HFCherenkov::computeNPEinPMT: npe " << npe_;
313 std::vector<double>
v =
wlini;
318 std::vector<double>
v =
wltrap;
328 std::vector<double>
v =
wlhem;
333 std::vector<double>
v =
wlqeff;
338 std::vector<double>
v =
wl;
343 std::vector<double>
v =
momZ;
350 double alpha = 0.0073;
351 double step_length = stepL;
352 double theta_C = acos(1./(pBeta*
ref_index));
354 double cherenPhPerLength = 2 *
M_PI * alpha * lambdaDiff*cm;
355 double d_NOfPhotons = cherenPhPerLength *
sin(theta_C)*
sin(theta_C) * (step_length/cm);
356 int nbOfPhotons = int(d_NOfPhotons);
358 LogDebug(
"HFShower") <<
"HFCherenkov::computeNbOfPhotons: StepLength "
359 << step_length <<
" theta_C " << theta_C
360 <<
" lambdaDiff " << lambdaDiff
361 <<
" cherenPhPerLength " << cherenPhPerLength
362 <<
" Photons " << d_NOfPhotons <<
" " << nbOfPhotons;
371 if (wavelength<=350) {
372 qeff=2.45867*(TMath::Landau(wavelength,353.820,59.1324));
373 }
else if (wavelength>350 && wavelength<500) {
374 qeff= 0.441989*
exp(-
pow((wavelength-358.371),2)/(2*
pow((138.277),2)));
375 }
else if (wavelength>=500 && wavelength<550) {
376 qeff= 0.271862*
exp(-
pow((wavelength-491.505),2)/(2*
pow((47.0418),2)));
377 }
else if (wavelength>=550) {
378 qeff= 0.137297*
exp(-
pow((wavelength-520.260),2)/(2*
pow((75.5023),2)));
381 LogDebug(
"HFShower") <<
"HFCherenkov:: for new PMT : wavelength === "
382 << wavelength <<
"\tqeff ===\t" << qeff;
385 double y = (wavelength - 275.) /180.;
386 double func = 1. / (1. + 250.*
pow((y/5.),4));
387 double qE_R7525 = 0.77 * y *
exp(-y) *
func ;
390 LogDebug(
"HFShower") <<
"HFCherenkov:: for old PMT : wavelength === "
391 << wavelength <<
"; qeff = " << qeff;
396 LogDebug(
"HFShower") <<
"HFCherenkov::computeQEff: wavelength " << wavelength
397 <<
" y/func " <<
y <<
"/" <<
func <<
" qeff " << qeff;
405 if (wavelength < 400.) {
407 }
else if (wavelength >= 400. && wavelength < 410.) {
409 hEMEff = (-1322.453 / wavelength) + 4.2056;
410 }
else if (wavelength >= 410.) {
412 if (wavelength > 415. && wavelength < 445.) {
416 }
else if (wavelength > 550. && wavelength < 600.) {
420 }
else if (wavelength > 565. && wavelength <= 635.) {
422 hEMEff = (701.7268 / wavelength) - 0.186;
426 LogDebug(
"HFShower") <<
"HFCherenkov::computeHEMEff: wavelength "
427 << wavelength <<
" hEMEff " << hEMEff;
436 for (
int i = 0;
i < npe; ++
i) {
437 double val = G4Poisson(
gain);
438 pe += (val/
gain) + 0.001*G4UniformRand();
442 LogDebug(
"HFShower") <<
"HFCherenkov::smearNPE: npe " << npe <<
" pe " << pe;
459 bool tmp = (aParticleType->GetPDGCharge() != 0);
461 LogDebug(
"HFShower") <<
"HFCherenkov::isApplicable: aParticleType "
462 << aParticleType->GetParticleName() <<
" PDGCharge "
463 << 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()