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