Go to the documentation of this file.00001
00002
00003
00005
00006 #include "SimG4CMS/Calo/interface/HFCherenkov.h"
00007
00008 #include "G4Poisson.hh"
00009 #include "G4ParticleDefinition.hh"
00010
00011
00012
00013 HFCherenkov::HFCherenkov(edm::ParameterSet const & m_HF) {
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 ref_index = m_HF.getParameter<double>("RefIndex");
00025 lambda1 = ((m_HF.getParameter<double>("Lambda1"))/pow(double(10),7))*cm;
00026 lambda2 = ((m_HF.getParameter<double>("Lambda2"))/pow(double(10),7))*cm;
00027 aperture = cos(asin(m_HF.getParameter<double>("Aperture")));
00028 apertureTrap = cos(asin(m_HF.getParameter<double>("ApertureTrapped")));
00029 gain = m_HF.getParameter<double>("Gain");
00030 checkSurvive = m_HF.getParameter<bool>("CheckSurvive");
00031
00032 edm::LogInfo("HFShower") << "HFCherenkov:: initialised with ref_index "
00033 << ref_index << " lambda1/lambda2 (cm) "
00034 << lambda1/cm << "/" << lambda2/cm
00035 << " aperture(total/trapped) " << aperture << "/"
00036 << apertureTrap << " Check photon survival in HF "
00037 << checkSurvive << " Gain " << gain;
00038
00039 clearVectors();
00040 }
00041
00042 HFCherenkov::~HFCherenkov() {}
00043
00044 int HFCherenkov::computeNPhTrapped(double pBeta,
00045 double u, double v, double w,
00046 double step_length, double zFiber,
00047 double dose, int npe_Dose) {
00048
00049 if (pBeta < (1/ref_index) || step_length < 0.0001) {return 0;}
00050
00051 double uv = sqrt(u*u + v*v);
00052 int nbOfPhotons = computeNbOfPhotons(pBeta, step_length);
00053
00054 if (nbOfPhotons < 0) {
00055 return 0;
00056 } else if (nbOfPhotons > 0) {
00057 double u_ph, v_ph, w_ph=0;
00058 for (int i = 0; i < nbOfPhotons; i++) {
00059 double rand = G4UniformRand();
00060 double theta_C = acos(1./(pBeta*ref_index));
00061 double phi_C = 2*M_PI*rand;
00062 double sinTheta = sin(theta_C);
00063 double cosTheta = cos(theta_C);
00064 double sinPhi = sin(phi_C);
00065 double cosPhi = cos(phi_C);
00066
00067 if (uv < 0.001) {
00068 u_ph = sinTheta * cosPhi;
00069 v_ph = sinTheta * sinPhi;
00070 w_ph = cosTheta;
00071 } else {
00072 u_ph = u * cosTheta + sinTheta * (v*sinPhi + u*w*cosPhi)/ uv;
00073 v_ph = v * cosTheta + sinTheta * (-u*sinPhi + v*w*cosPhi)/ uv;
00074 w_ph = w * cosTheta - sinTheta * cosPhi * uv;
00075 }
00076 if (w_ph > apertureTrap) {
00077 npe_Dose += 1;
00078 }
00079 }
00080 }
00081 int n_photons = npe_Dose;
00082 return n_photons;
00083 }
00084
00085 int HFCherenkov::computeNPE(G4ParticleDefinition* pDef, double pBeta,
00086 double u, double v, double w,
00087 double step_length, double zFiber,
00088 double dose, int npe_Dose) {
00089
00090 clearVectors();
00091 if (!isApplicable(pDef)) {return 0;}
00092 if (pBeta < (1/ref_index) || step_length < 0.0001) {
00093 #ifdef DebugLog
00094 LogDebug("HFShower") << "HFCherenkov::computeNPE: pBeta " << pBeta
00095 << " 1/mu " << (1/ref_index) << " step_length "
00096 << step_length;
00097 #endif
00098 return 0;
00099 }
00100
00101 double uv = sqrt(u*u + v*v);
00102 int nbOfPhotons = computeNbOfPhotons(pBeta, step_length);
00103 #ifdef DebugLog
00104 LogDebug("HFShower") << "HFCherenkov::computeNPE: pBeta " << pBeta
00105 << " u/v/w " << u << "/" << v << "/" << w
00106 << " step_length " << step_length << " zFib " << zFiber
00107 << " nbOfPhotons " << nbOfPhotons;
00108 #endif
00109 if (nbOfPhotons < 0) {
00110 return 0;
00111 } else if (nbOfPhotons > 0) {
00112 double u_ph, v_ph, w_ph=0;
00113 for (int i = 0; i < nbOfPhotons; i++) {
00114 double rand = G4UniformRand();
00115 double theta_C = acos(1./(pBeta*ref_index));
00116 double phi_C = 2*M_PI*rand;
00117 double sinTheta = sin(theta_C);
00118 double cosTheta = cos(theta_C);
00119 double sinPhi = sin(phi_C);
00120 double cosPhi = cos(phi_C);
00121
00122 if (uv < 0.001) {
00123 u_ph = sinTheta * cosPhi;
00124 v_ph = sinTheta * sinPhi;
00125 w_ph = cosTheta;
00126 } else {
00127 u_ph = u * cosTheta + sinTheta * (v*sinPhi + u*w*cosPhi)/ uv;
00128 v_ph = v * cosTheta + sinTheta * (-u*sinPhi + v*w*cosPhi)/ uv;
00129 w_ph = w * cosTheta - sinTheta * cosPhi * uv;
00130 }
00131 double r_lambda = G4UniformRand();
00132 double lambda0 = (lambda1 * lambda2) / (lambda2 - r_lambda *
00133 (lambda2 - lambda1));
00134 double lambda = (lambda0/cm) * pow(double(10),7);
00135 wlini.push_back(lambda);
00136 #ifdef DebugLog
00137 LogDebug("HFShower") << "HFCherenkov::computeNPE: " << i << " lambda "
00138 << lambda << " w_ph " << w_ph << " aperture "
00139 << aperture;
00140 #endif
00141 if (w_ph > aperture) {
00142 wltrap.push_back(lambda);
00143 double prob_HF = 1.0;
00144 double a0_inv = 0.1234;
00145 double prob_MX = exp( - 0.5 * a0_inv );
00146 if (checkSurvive) {
00147 double a_inv = a0_inv + 0.14 * pow(dose,0.30);
00148 double z_meters = zFiber;
00149 prob_HF = exp(-z_meters * a_inv );
00150 }
00151 rand = G4UniformRand();
00152 #ifdef DebugLog
00153 LogDebug("HFShower") << "HFCherenkov::computeNPE: probHF " << prob_HF
00154 << " prob_MX " << prob_MX << " Random " << rand
00155 << " Survive? " << (rand < (prob_HF * prob_MX));
00156 #endif
00157 if (rand < (prob_HF * prob_MX)) {
00158 wlatten.push_back(lambda);
00159 rand = G4UniformRand();
00160 double effHEM = computeHEMEff(lambda);
00161 #ifdef DebugLog
00162 LogDebug("HFShower") << "HFCherenkov::computeNPE: w_ph " << w_ph
00163 << " effHEM " << effHEM << " Random " << rand
00164 << " Survive? " << (w_ph>0.997||(rand<effHEM));
00165 #endif
00166 if (w_ph>0.997 || (rand<effHEM)) {
00167 wlhem.push_back(lambda);
00168 double qEffic = computeQEff(lambda);
00169 rand = G4UniformRand();
00170 #ifdef DebugLog
00171 LogDebug("HFShower") << "HFCherenkov::computeNPE: qEffic "
00172 << qEffic << " Random " << rand
00173 << " Survive? " <<(rand < qEffic);
00174 #endif
00175 if (rand < qEffic) {
00176 npe_Dose += 1;
00177 momZ.push_back(w_ph);
00178 wl.push_back(lambda);
00179 wlqeff.push_back(lambda);
00180 }
00181 }
00182 }
00183 }
00184 }
00185 }
00186 int npe = npe_Dose;
00187 #ifdef DebugLog
00188 LogDebug("HFShower") << "HFCherenkov::computeNPE: npe " << npe;
00189 #endif
00190 return npe;
00191 }
00192
00193 int HFCherenkov::computeNPEinPMT(G4ParticleDefinition* pDef, double pBeta,
00194 double u, double v, double w,
00195 double step_length){
00196 clearVectors();
00197 int npe_ = 0;
00198 if (!isApplicable(pDef)) {return 0;}
00199 if (pBeta < (1/ref_index) || step_length < 0.0001) {
00200 #ifdef DebugLog
00201 LogDebug("HFShower") << "HFCherenkov::computeNPEinPMT: pBeta " << pBeta
00202 << " 1/mu " << (1/ref_index) << " step_length "
00203 << step_length;
00204 #endif
00205 return 0;
00206 }
00207
00208 double uv = sqrt(u*u + v*v);
00209 int nbOfPhotons = computeNbOfPhotons(pBeta, step_length);
00210 #ifdef DebugLog
00211 LogDebug("HFShower") << "HFCherenkov::computeNPEinPMT: pBeta " << pBeta
00212 << " u/v/w " << u << "/" << v << "/" << w
00213 << " step_length " << step_length
00214 << " nbOfPhotons " << nbOfPhotons;
00215 #endif
00216 if (nbOfPhotons < 0) {
00217 return 0;
00218 } else if (nbOfPhotons > 0) {
00219 double u_ph, v_ph, w_ph=0;
00220 for (int i = 0; i < nbOfPhotons; i++) {
00221 double rand = G4UniformRand();
00222 double theta_C = acos(1./(pBeta*ref_index));
00223 double phi_C = 2*M_PI*rand;
00224 double sinTheta = sin(theta_C);
00225 double cosTheta = cos(theta_C);
00226 double sinPhi = sin(phi_C);
00227 double cosPhi = cos(phi_C);
00228
00229 if (uv < 0.001) {
00230 u_ph = sinTheta * cosPhi;
00231 v_ph = sinTheta * sinPhi;
00232 w_ph = cosTheta;
00233 } else {
00234 u_ph = u * cosTheta + sinTheta * (v*sinPhi + u*w*cosPhi)/ uv;
00235 v_ph = v * cosTheta + sinTheta * (-u*sinPhi + v*w*cosPhi)/ uv;
00236 w_ph = w * cosTheta - sinTheta * cosPhi * uv;
00237 }
00238 double r_lambda = G4UniformRand();
00239 double lambda0 = (lambda1 * lambda2) / (lambda2 - r_lambda *
00240 (lambda2 - lambda1));
00241 double lambda = (lambda0/cm) * pow(double(10),7);
00242 wlini.push_back(lambda);
00243 #ifdef DebugLog
00244 LogDebug("HFShower") << "HFCherenkov::computeNPEinPMT: " <<i <<" lambda "
00245 << lambda << " w_ph " << w_ph << " aperture "
00246 << aperture;
00247 #endif
00248 if (w_ph > aperture) {
00249 wltrap.push_back(lambda);
00250 rand = G4UniformRand();
00251 #ifdef DebugLog
00252 LogDebug("HFShower") << "HFCherenkov::computeNPEinPMT: Random " << rand
00253 << " Survive? " << (rand < 1.);
00254 #endif
00255 if (rand < 1.0) {
00256 wlatten.push_back(lambda);
00257 rand = G4UniformRand();
00258 double qEffic = computeQEff(lambda);
00259 rand = G4UniformRand();
00260 #ifdef DebugLog
00261 LogDebug("HFShower") << "HFCherenkov::computeNPEinPMT: qEffic "
00262 << qEffic << " Random " << rand
00263 << " Survive? " <<(rand < qEffic);
00264 #endif
00265 if (rand < qEffic) {
00266 npe_ += 1;
00267 momZ.push_back(w_ph);
00268 wl.push_back(lambda);
00269 wlqeff.push_back(lambda);
00270 }
00271 }
00272 }
00273 }
00274 }
00275 #ifdef DebugLog
00276 LogDebug("HFShower") << "HFCherenkov::computeNPEinPMT: npe " << npe_;
00277 #endif
00278 return npe_;
00279 }
00280
00281 std::vector<double> HFCherenkov::getWLIni() {
00282 std::vector<double> v = wlini;
00283 return v;
00284 }
00285
00286 std::vector<double> HFCherenkov::getWLTrap() {
00287 std::vector<double> v = wltrap;
00288 return v;
00289 }
00290
00291 std::vector<double> HFCherenkov::getWLAtten() {
00292 std::vector<double> v = wlatten;
00293 return v;
00294 }
00295
00296 std::vector<double> HFCherenkov::getWLHEM() {
00297 std::vector<double> v = wlhem;
00298 return v;
00299 }
00300
00301 std::vector<double> HFCherenkov::getWLQEff() {
00302 std::vector<double> v = wlqeff;
00303 return v;
00304 }
00305
00306 std::vector<double> HFCherenkov::getWL() {
00307 std::vector<double> v = wl;
00308 return v;
00309 }
00310
00311 std::vector<double> HFCherenkov::getMom() {
00312 std::vector<double> v = momZ;
00313 return v;
00314 }
00315
00316 int HFCherenkov::computeNbOfPhotons(double beta, G4double stepL) {
00317
00318 double pBeta = beta;
00319 double alpha = 0.0073;
00320 double step_length = stepL;
00321 double theta_C = acos(1./(pBeta*ref_index));
00322 double lambdaDiff = (1./lambda1 - 1./lambda2);
00323 double cherenPhPerLength = 2 * M_PI * alpha * lambdaDiff*cm;
00324 double d_NOfPhotons = cherenPhPerLength * sin(theta_C)*sin(theta_C) * (step_length/cm);
00325 int nbOfPhotons = int(d_NOfPhotons);
00326 #ifdef DebugLog
00327 LogDebug("HFShower") << "HFCherenkov::computeNbOfPhotons: StepLength "
00328 << step_length << " theta_C " << theta_C
00329 << " lambdaDiff " << lambdaDiff
00330 << " cherenPhPerLength " << cherenPhPerLength
00331 << " Photons " << d_NOfPhotons << " " << nbOfPhotons;
00332 #endif
00333 return nbOfPhotons;
00334 }
00335
00336 double HFCherenkov::computeQEff(double wavelength) {
00337
00338 double y = (wavelength - 275.) /180.;
00339 double func = 1. / (1. + 250.*pow((y/5.),4));
00340 double qE_R7525 = 0.77 * y * exp(-y) * func ;
00341 double qeff = qE_R7525;
00342 #ifdef DebugLog
00343 LogDebug("HFShower") << "HFCherenkov::computeQEff: wavelength " << wavelength
00344 << " y/func " << y << "/" << func << " qeff " << qeff;
00345 #endif
00346 return qeff;
00347 }
00348
00349 double HFCherenkov::computeHEMEff(double wavelength) {
00350
00351 double hEMEff = 0;
00352 if (wavelength < 400.) {
00353 hEMEff = 0.;
00354 } else if (wavelength >= 400. && wavelength < 410.) {
00355
00356 hEMEff = (-1322.453 / wavelength) + 4.2056;
00357 } else if (wavelength >= 410.) {
00358 hEMEff = 0.99;
00359 if (wavelength > 415. && wavelength < 445.) {
00360
00361
00362 hEMEff = 0.97;
00363 } else if (wavelength > 550. && wavelength < 600.) {
00364
00365
00366 hEMEff = 0.98;
00367 } else if (wavelength > 565. && wavelength <= 635.) {
00368
00369 hEMEff = (701.7268 / wavelength) - 0.186;
00370 }
00371 }
00372 #ifdef DebugLog
00373 LogDebug("HFShower") << "HFCherenkov::computeHEMEff: wavelength "
00374 << wavelength << " hEMEff " << hEMEff;
00375 #endif
00376 return hEMEff;
00377 }
00378
00379 double HFCherenkov::smearNPE(int npe) {
00380
00381 double pe = 0.;
00382 if (npe > 0) {
00383 for (int i = 0; i < npe; ++i) {
00384 double val = G4Poisson(gain);
00385 pe += (val/gain) + 0.001*G4UniformRand();
00386 }
00387 }
00388 #ifdef DebugLog
00389 LogDebug("HFShower") << "HFCherenkov::smearNPE: npe " << npe << " pe " << pe;
00390 #endif
00391 return pe;
00392 }
00393
00394 void HFCherenkov::clearVectors() {
00395
00396 wl.clear();
00397 wlini.clear();
00398 wltrap.clear();
00399 wlatten.clear();
00400 wlhem.clear();
00401 wlqeff.clear();
00402 momZ.clear();
00403 }
00404
00405 bool HFCherenkov::isApplicable(const G4ParticleDefinition* aParticleType) {
00406 bool tmp = (aParticleType->GetPDGCharge() != 0);
00407 #ifdef DebugLog
00408 LogDebug("HFShower") << "HFCherenkov::isApplicable: aParticleType "
00409 << aParticleType->GetParticleName() << " PDGCharge "
00410 << aParticleType->GetPDGCharge() << " Result " << tmp;
00411 #endif
00412 return tmp;
00413 }