CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/SimG4CMS/Calo/src/HFShowerParam.cc

Go to the documentation of this file.
00001 
00002 // File: HFShowerParam.cc
00003 // Description: Parametrized version of HF hits
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 //#define DebugLog
00026 //#define plotDebug
00027 //#define mkdebug
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     //Special Geometry parameters
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   // look for other charged particles
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   // take only e+-/gamma/or special particles
00173   if (particleCode == emPDG || particleCode == epPDG ||
00174       particleCode == gammaPDG || other) {
00175     // Leave out the last part
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) { // @@ For showerlibrary no z-cut for Short (no z)
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 { // GFlash clusters with known z
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             //depth
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) { // a short fibre
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             //attenuation
00288             double dist = fibre->zShift(localPoint,depth,0); // distance to PMT
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); // remaining part
00342         bool ok = true;
00343         if (applyFidCut) { // @@ For showerlibrary no z-cut for Short (no z)
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 }