00001
00002
00003
00005
00006 #include "SimG4CMS/Calo/interface/HFShowerParam.h"
00007 #include "SimG4CMS/Calo/interface/HFFibreFiducial.h"
00008 #include "DetectorDescription/Core/interface/DDFilter.h"
00009 #include "DetectorDescription/Core/interface/DDFilteredView.h"
00010
00011 #include "FWCore/Utilities/interface/Exception.h"
00012 #include "FWCore/ServiceRegistry/interface/Service.h"
00013 #include "CommonTools/UtilAlgos/interface/TFileService.h"
00014
00015 #include "G4VPhysicalVolume.hh"
00016 #include "G4Step.hh"
00017 #include "G4Track.hh"
00018 #include "G4NavigationHistory.hh"
00019 #include "Randomize.hh"
00020
00021 #include "CLHEP/Units/GlobalPhysicalConstants.h"
00022 #include "CLHEP/Units/GlobalSystemOfUnits.h"
00023 #include<iostream>
00024
00025
00026
00027
00028
00029 HFShowerParam::HFShowerParam(std::string & name, const DDCompactView & cpv,
00030 edm::ParameterSet const & p) : showerLibrary(0),
00031 fibre(0), gflash(0),
00032 fillHisto(false) {
00033 edm::ParameterSet m_HF = p.getParameter<edm::ParameterSet>("HFShower");
00034 pePerGeV = m_HF.getParameter<double>("PEPerGeV");
00035 trackEM = m_HF.getParameter<bool>("TrackEM");
00036 bool useShowerLibrary = m_HF.getParameter<bool>("UseShowerLibrary");
00037 bool useGflash = m_HF.getParameter<bool>("UseHFGflash");
00038 edMin = m_HF.getParameter<double>("EminLibrary");
00039 onlyLong = m_HF.getParameter<bool>("OnlyLong");
00040 ref_index = m_HF.getParameter<double>("RefIndex");
00041 double lambdaMean = m_HF.getParameter<double>("LambdaMean");
00042 aperture = cos(asin(m_HF.getParameter<double>("Aperture")));
00043 applyFidCut = m_HF.getParameter<bool>("ApplyFiducialCut");
00044 parametrizeLast = m_HF.getUntrackedParameter<bool>("ParametrizeLast",false);
00045 edm::LogInfo("HFShower") << "HFShowerParam::Use of shower library is set to "
00046 << useShowerLibrary << " Use of Gflash is set to "
00047 << useGflash << " P.E. per GeV " << pePerGeV
00048 << ", ref. index of fibre " << ref_index
00049 << ", Track EM Flag " << trackEM << ", edMin "
00050 << edMin << " GeV, use of Short fibre info in"
00051 << " shower library set to " << !(onlyLong)
00052 << ", use of parametrization for last part set to "
00053 << parametrizeLast << ", Mean lambda " << lambdaMean
00054 << ", aperture (cutoff) " << aperture
00055 << ", Application of Fiducial Cut " << applyFidCut;
00056
00057 #ifdef plotDebug
00058 edm::Service<TFileService> tfile;
00059 if (tfile.isAvailable()) {
00060 fillHisto = true;
00061 LogDebug("HFShower") << "HFShowerParam::Save histos in directory "
00062 << "ProfileFromParam";
00063 TFileDirectory showerDir = tfile->mkdir("ProfileFromParam");
00064 hzvem = showerDir.make<TH1F>("hzvem", "Longitudinal Profile (EM Part);Number of PE",330,0.0,1650.0);
00065 hzvhad = showerDir.make<TH1F>("hzvhad","Longitudinal Profile (Had Part);Number of PE",330,0.0,1650.0);
00066 em_2d_1 = showerDir.make<TH2F>("em_2d_1","Lateral Profile vs. Shower Depth;cm;Events",800,800.0,1600.0,100,50.0,150.0);
00067 em_long_1 = showerDir.make<TH1F>("em_long_1","Longitudinal Profile;Radiation Length;Number of Spots",800,800.0,1600.0);
00068 em_long_1_tuned = showerDir.make<TH1F>("em_long_1_tuned","Longitudinal Profile;Radiation Length;Number of Spots",800,800.0,1600.0);
00069 em_lateral_1 = showerDir.make<TH1F>("em_lateral_1","Lateral Profile;cm;Events",100,50.0,150.0);
00070 em_2d_2 = showerDir.make<TH2F>("em_2d_2","Lateral Profile vs. Shower Depth;cm;Events",800,800.0,1600.0,100,50.0,150.0);
00071 em_long_2 = showerDir.make<TH1F>("em_long_2","Longitudinal Profile;Radiation Length;Number of Spots",800,800.0,1600.0);
00072 em_lateral_2 = showerDir.make<TH1F>("em_lateral_2","Lateral Profile;cm;Events",100,50.0,150.0);
00073 em_long_gflash = showerDir.make<TH1F>("em_long_gflash","Longitudinal Profile From GFlash;cm;Number of Spots",800,800.0,1600.0);
00074 em_long_sl = showerDir.make<TH1F>("em_long_sl","Longitudinal Profile From Shower Library;cm;Number of Spots",800,800.0,1600.0);
00075 } else {
00076 fillHisto = false;
00077 edm::LogInfo("HFShower") << "HFShowerParam::No file is available for "
00078 << "saving histos so the flag is set to false";
00079 }
00080 #endif
00081
00082 G4String attribute = "ReadOutName";
00083 G4String value = name;
00084 DDSpecificsFilter filter;
00085 DDValue ddv(attribute,value,0);
00086 filter.setCriteria(ddv,DDSpecificsFilter::equals);
00087 DDFilteredView fv(cpv);
00088 fv.addFilter(filter);
00089 bool dodet = fv.firstChild();
00090 if (dodet) {
00091 DDsvalues_type sv(fv.mergedSpecifics());
00092
00093 gpar = getDDDArray("gparHF",sv);
00094 edm::LogInfo("HFShower") << "HFShowerParam: " <<gpar.size() <<" gpar (cm)";
00095 for (unsigned int ig=0; ig<gpar.size(); ig++)
00096 edm::LogInfo("HFShower") << "HFShowerParam: gpar[" << ig << "] = "
00097 << gpar[ig]/cm << " cm";
00098 } else {
00099 edm::LogError("HFShower") << "HFShowerParam: cannot get filtered "
00100 << " view for " << attribute << " matching " << name;
00101 throw cms::Exception("Unknown", "HFShowerParam") << "cannot match " << attribute
00102 << " to " << name <<"\n";
00103 }
00104
00105 if (useShowerLibrary) showerLibrary = new HFShowerLibrary(name, cpv, p);
00106 if (useGflash) gflash = new HFGflash(p);
00107 fibre = new HFFibre(name, cpv, p);
00108 attLMeanInv = fibre->attLength(lambdaMean);
00109 edm::LogInfo("HFShower") << "att. length used for (lambda=" << lambdaMean
00110 << ") = " << 1/(attLMeanInv*cm) << " cm";
00111 }
00112
00113 HFShowerParam::~HFShowerParam() {
00114 if (fibre) delete fibre;
00115 if (gflash) delete gflash;
00116 if (showerLibrary) delete showerLibrary;
00117 }
00118
00119 void HFShowerParam::initRun(G4ParticleTable * theParticleTable) {
00120 emPDG = theParticleTable->FindParticle("e-")->GetPDGEncoding();
00121 epPDG = theParticleTable->FindParticle("e+")->GetPDGEncoding();
00122 gammaPDG = theParticleTable->FindParticle("gamma")->GetPDGEncoding();
00123 #ifdef DebugLog
00124 edm::LogInfo("HFShower") << "HFShowerParam: Particle code for e- = " << emPDG
00125 << " for e+ = " << epPDG << " for gamma = " << gammaPDG;
00126 #endif
00127 if (showerLibrary) showerLibrary->initRun(theParticleTable);
00128 }
00129
00130 std::vector<HFShowerParam::Hit> HFShowerParam::getHits(G4Step * aStep,
00131 double weight) {
00132 G4StepPoint * preStepPoint = aStep->GetPreStepPoint();
00133 G4Track * track = aStep->GetTrack();
00134 G4ThreeVector hitPoint = preStepPoint->GetPosition();
00135 G4int particleCode = track->GetDefinition()->GetPDGEncoding();
00136 double zv = std::abs(hitPoint.z()) - gpar[4] - 0.5*gpar[1];
00137 G4ThreeVector localPoint = G4ThreeVector(hitPoint.x(),hitPoint.y(),zv);
00138
00139 double pin = (preStepPoint->GetTotalEnergy())/GeV;
00140 double zint = hitPoint.z();
00141 double zz = std::abs(zint) - gpar[4];
00142
00143 #ifdef DebugLog
00144 edm::LogInfo("HFShower") << "HFShowerParam: getHits "
00145 << track->GetDefinition()->GetParticleName()
00146 << " of energy " << pin << " GeV"
00147 << " Pos x,y,z = " << hitPoint.x() << ","
00148 << hitPoint.y() << "," << zint << " (" << zz << ","
00149 << localPoint.z() << ", "
00150 << (localPoint.z()+0.5*gpar[1]) << ") Local "
00151 << localPoint;
00152 #endif
00153 std::vector<HFShowerParam::Hit> hits;
00154 HFShowerParam::Hit hit;
00155 hit.position = hitPoint;
00156
00157
00158 bool other = false;
00159 double pBeta = track->GetDynamicParticle()->GetTotalMomentum() / track->GetDynamicParticle()->GetTotalEnergy();
00160 double dirz = (track->GetDynamicParticle()->GetMomentumDirection()).z();
00161 if (hitPoint.z() < 0) dirz *= -1.;
00162 #ifdef DebugLog
00163 edm::LogInfo("HFShower") << "HFShowerParam: getHits Momentum "
00164 <<track->GetDynamicParticle()->GetMomentumDirection()
00165 << " HitPoint " << hitPoint << " dirz " << dirz;
00166 #endif
00167 if (particleCode != emPDG && particleCode != epPDG && particleCode != gammaPDG ) {
00168 if (track->GetDefinition()->GetPDGCharge() != 0 && pBeta > (1/ref_index) &&
00169 aStep->GetTotalEnergyDeposit() > 0) other = true;
00170 }
00171
00172
00173 if (particleCode == emPDG || particleCode == epPDG ||
00174 particleCode == gammaPDG || other) {
00175
00176 double edep = 0.;
00177 bool kill = false;
00178 if ((!trackEM) && ((zz<(gpar[1]-gpar[2])) || parametrizeLast) && (!other)){
00179 edep = pin;
00180 kill = true;
00181 } else if ((track->GetDefinition()->GetPDGCharge() != 0) &&
00182 (pBeta > (1/ref_index)) && (dirz > aperture)) {
00183 edep = (aStep->GetTotalEnergyDeposit())/GeV;
00184 }
00185 std::string path = "ShowerLibrary";
00186 #ifdef DebugLog
00187 edm::LogInfo("HFShower") << "HFShowerParam: getHits edep = " << edep
00188 << " weight " << weight << " final " <<edep*weight
00189 << ", Kill = " << kill << ", pin = " << pin
00190 << ", edMin = " << edMin << " Other " << other;
00191 #endif
00192 edep *= weight;
00193 if (edep > 0) {
00194 if ((showerLibrary || gflash) && kill && pin > edMin && (!other)) {
00195 if (showerLibrary) {
00196 std::vector<HFShowerLibrary::Hit> hitSL = showerLibrary->getHits(aStep,kill,weight,onlyLong);
00197 for (unsigned int i=0; i<hitSL.size(); i++) {
00198 bool ok = true;
00199 #ifdef DebugLog
00200 edm::LogInfo("HFShower") << "HFShowerParam: getHits applyFidCut = " << applyFidCut;
00201 #endif
00202 if (applyFidCut) {
00203 int npmt = HFFibreFiducial:: PMTNumber(hitSL[i].position);
00204 if (npmt <= 0) ok = false;
00205 }
00206 if (ok) {
00207 hit.position = hitSL[i].position;
00208 hit.depth = hitSL[i].depth;
00209 hit.time = hitSL[i].time;
00210 hit.edep = 1;
00211 hits.push_back(hit);
00212 #ifdef plotDebug
00213 if (fillHisto) {
00214 double zv = std::abs(hit.position.z()) - gpar[4];
00215 hzvem->Fill(zv);
00216 em_long_sl->Fill(hit.position.z()/cm);
00217 double sq = sqrt(pow(hit.position.x()/cm,2)+pow(hit.position.y()/cm,2));
00218 double zp = hit.position.z()/cm;
00219 if (hit.depth == 1) {
00220 em_2d_1->Fill(zp, sq);
00221 em_lateral_1->Fill(sq);
00222 em_long_1->Fill(zp);
00223 } else if (hit.depth == 2) {
00224 em_2d_2->Fill(zp, sq);
00225 em_lateral_2->Fill(sq);
00226 em_long_2->Fill(zp);
00227 }
00228 }
00229 #endif
00230 #ifdef DebugLog
00231 edm::LogInfo("HFShower") << "HFShowerParam: Hit at depth "
00232 << hit.depth << " with edep " << hit.edep
00233 << " Time " << hit.time;
00234 #endif
00235 }
00236 }
00237 } else {
00238 std::vector<HFGflash::Hit>hitSL=gflash->gfParameterization(aStep,kill, onlyLong);
00239 for (unsigned int i=0; i<hitSL.size(); ++i) {
00240 bool ok = true;
00241 G4ThreeVector pe_effect(hitSL[i].position.x(), hitSL[i].position.y(),
00242 hitSL[i].position.z());
00243 double zv = std::abs(pe_effect.z()) - gpar[4];
00244
00245 int depth = 1;
00246 int npmt = 0;
00247 if (zv < 0. || zv > gpar[1]) {
00248 #ifdef mkdebug
00249 std::cout<<"-#Zcut-HFShowerParam::getHits:z="<<zv<<",m="<<gpar[1]<<std::endl;
00250 #endif
00251 ok = false;
00252 }
00253 if (ok && applyFidCut) {
00254 npmt = HFFibreFiducial:: PMTNumber(pe_effect);
00255 #ifdef DebugLog
00256 edm::LogInfo("HFShower") << "HFShowerParam::getHits:#PMT= "
00257 << npmt << ",z = " << zv;
00258 #endif
00259 if (npmt <= 0) {
00260 #ifdef DebugLog
00261 edm::LogInfo("HFShower") << "-#PMT=0 cut-HFShowerParam::"
00262 << "getHits: npmt = " << npmt;
00263 #endif
00264 ok = false;
00265 } else if (npmt > 24) {
00266 if (zv > gpar[0]) {
00267 depth = 2;
00268 } else {
00269 #ifdef DebugLog
00270 edm::LogInfo("HFShower") << "-SHORT cut-HFShowerParam::"
00271 << "getHits:zMin=" << gpar[0];
00272 #endif
00273 ok = false;
00274 }
00275 }
00276 #ifdef DebugLog
00277 edm::LogInfo("HFShower") << "HFShowerParam: npmt " << npmt
00278 << " zv " << std::abs(pe_effect.z())
00279 << ":" << gpar[4] << ":" << zv << ":"
00280 << gpar[0] << " ok " << ok << " depth "
00281 << depth;
00282 #endif
00283 } else {
00284 if (G4UniformRand() > 0.5) depth = 2;
00285 if (depth == 2 && zv < gpar[0]) ok = false;
00286 }
00287
00288 double dist = fibre->zShift(localPoint,depth,0);
00289 double r1 = G4UniformRand();
00290 #ifdef DebugLog
00291 edm::LogInfo("HFShower") << "HFShowerParam:Distance to PMT (" <<npmt
00292 << ") " << dist << ", exclusion flag "
00293 << (r1 > exp(-attLMeanInv*zv));
00294 #endif
00295 if (r1 > exp(-attLMeanInv*dist)) ok = false;
00296 if (ok) {
00297 double r2 = G4UniformRand();
00298 #ifdef DebugLog
00299 edm::LogInfo("HFShower") << "HFShowerParam:Extra exclusion "
00300 << r2 << ">" << weight << " "
00301 << (r2 > weight);
00302 #endif
00303 if (r2 < weight) {
00304 double time = fibre->tShift(localPoint,depth,0);
00305
00306 hit.position = hitSL[i].position;
00307 hit.depth = depth;
00308 hit.time = time + hitSL[i].time;
00309 hit.edep = 1;
00310 hits.push_back(hit);
00311 #ifdef plotDebug
00312 if (fillHisto) {
00313 em_long_gflash->Fill(pe_effect.z()/cm, hitSL[i].edep);
00314 hzvem->Fill(zv);
00315 double sq = sqrt(pow(hit.position.x()/cm,2)+pow(hit.position.y()/cm,2));
00316 double zp = hit.position.z()/cm;
00317 if (hit.depth == 1) {
00318 em_2d_1->Fill(zp, sq);
00319 em_lateral_1->Fill(s);
00320 em_long_1->Fill(zp);
00321 } else if (hit.depth == 2) {
00322 em_2d_2->Fill(zp, sq);
00323 em_lateral_2->Fill(sq);
00324 em_long_2->Fill(zp);
00325 }
00326 }
00327 #endif
00328 #ifdef DebugLog
00329 edm::LogInfo("HFShower") << "HFShowerParam: Hit at depth "
00330 << hit.depth << " with edep "
00331 << hit.edep << " Time " << hit.time;
00332 #endif
00333 }
00334 }
00335 }
00336 }
00337 } else {
00338 path = "Rest";
00339 edep *= pePerGeV;
00340 double tSlice = (aStep->GetPostStepPoint()->GetGlobalTime());
00341 double time = fibre->tShift(localPoint,1,0);
00342 bool ok = true;
00343 if (applyFidCut) {
00344 int npmt = HFFibreFiducial:: PMTNumber(hitPoint);
00345 if (npmt <= 0) ok = false;
00346 }
00347 #ifdef DebugLog
00348 edm::LogInfo("HFShower") << "HFShowerParam: getHits hitPoint " << hitPoint << " flag " << ok;
00349 #endif
00350 if (ok) {
00351 hit.depth = 1;
00352 hit.time = tSlice+time;
00353 hit.edep = edep;
00354 hits.push_back(hit);
00355 #ifdef DebugLog
00356 edm::LogInfo("HFShower") << "HFShowerParam: Hit at depth 1 with edep "
00357 << edep << " Time " << tSlice << ":" << time
00358 << ":" << hit.time;
00359 #endif
00360 #ifdef plotDebug
00361 double zv = std::abs(hitPoint.z()) - gpar[4];
00362 if (fillHisto) {
00363 hzvhad->Fill(zv);
00364 }
00365 #endif
00366 if (zz >= gpar[0]) {
00367 time = fibre->tShift(localPoint,2,0);
00368 hit.depth = 2;
00369 hit.time = tSlice+time;
00370 hits.push_back(hit);
00371 #ifdef DebugLog
00372 edm::LogInfo("HFShower") <<"HFShowerParam: Hit at depth 2 with edep "
00373 << edep << " Time " << tSlice << ":" << time
00374 << hit.time;
00375 #endif
00376 #ifdef plotDebug
00377 if (fillHisto) {
00378 hzvhad->Fill(zv);
00379 }
00380 #endif
00381 }
00382 }
00383 }
00384 #ifdef DebugLog
00385 for (unsigned int ii=0; ii<hits.size(); ++ii) {
00386 double zv = std::abs(hits[ii].position.z());
00387 if (zv > 12790) edm::LogInfo("HFShower")<< "HFShowerParam: Abnormal hit along "
00388 << path << " in "
00389 << preStepPoint->GetPhysicalVolume()->GetLogicalVolume()->GetName()
00390 << " at " << hits[ii].position << " zz "
00391 << zv << " Edep " << edep << " due to "
00392 <<track->GetDefinition()->GetParticleName()
00393 << " time " << hit.time;
00394 }
00395 #endif
00396 if (kill) {
00397 track->SetTrackStatus(fStopAndKill);
00398 G4TrackVector tv = *(aStep->GetSecondary());
00399 for (unsigned int kk=0; kk<tv.size(); ++kk) {
00400 if (tv[kk]->GetVolume() == preStepPoint->GetPhysicalVolume())
00401 tv[kk]->SetTrackStatus(fStopAndKill);
00402 }
00403 }
00404 #ifdef DebugLog
00405 edm::LogInfo("HFShower") << "HFShowerParam: getHits kill (" << kill
00406 << ") track " << track->GetTrackID()
00407 << " at " << hitPoint
00408 << " and deposit " << edep << " " << hits.size()
00409 << " times" << " ZZ " << zz << " " << gpar[0];
00410 #endif
00411 }
00412 }
00413 return hits;
00414 }
00415
00416 std::vector<double> HFShowerParam::getDDDArray(const std::string & str,
00417 const DDsvalues_type & sv)
00418 {
00419 #ifdef DebugLog
00420 LogDebug("HFShower") << "HFShowerParam:getDDDArray called for " << str;
00421 #endif
00422 DDValue value(str);
00423 if (DDfetch(&sv,value))
00424 {
00425 #ifdef DebugLog
00426 LogDebug("HFShower") << value;
00427 #endif
00428 const std::vector<double> & fvec = value.doubles();
00429 int nval = fvec.size();
00430 if (nval < 2) {
00431 edm::LogError("HFShower") << "HFShowerParam : # of " << str
00432 << " bins " << nval << " < 2 ==> illegal";
00433 throw cms::Exception("Unknown", "HFShowerParam") << "nval < 2 for array "
00434 << str << "\n";
00435 }
00436 return fvec;
00437 } else {
00438 edm::LogError("HFShower") << "HFShowerParam : cannot get array " << str;
00439 throw cms::Exception("Unknown", "HFShowerParam") << "cannot get array "
00440 << str << "\n";
00441 }
00442 }