CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_1/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   G4StepPoint * preStepPoint  = aStep->GetPreStepPoint(); 
00132   G4Track *     track    = aStep->GetTrack();   
00133   G4ThreeVector hitPoint = preStepPoint->GetPosition();   
00134   G4int         particleCode = track->GetDefinition()->GetPDGEncoding();
00135   double        zv = std::abs(hitPoint.z()) - gpar[4] - 0.5*gpar[1];
00136   G4ThreeVector localPoint = G4ThreeVector(hitPoint.x(),hitPoint.y(),zv);
00137 
00138   double pin    = (preStepPoint->GetTotalEnergy())/GeV;
00139   double zint   = hitPoint.z(); 
00140   double zz     = std::abs(zint) - gpar[4];
00141 
00142 #ifdef DebugLog
00143   edm::LogInfo("HFShower") << "HFShowerParam: getHits " 
00144                            << track->GetDefinition()->GetParticleName()
00145                            << " of energy " << pin << " GeV" 
00146                            << " Pos x,y,z = " << hitPoint.x() << "," 
00147                            << hitPoint.y() << "," << zint << " (" << zz << ","
00148                            << localPoint.z() << ", " 
00149                            << (localPoint.z()+0.5*gpar[1]) << ") Local " 
00150                            << localPoint;
00151 #endif
00152   std::vector<HFShowerParam::Hit> hits;
00153   HFShowerParam::Hit hit;
00154   hit.position = hitPoint;
00155 
00156   // look for other charged particles
00157   bool   other = false;
00158   double pBeta = track->GetDynamicParticle()->GetTotalMomentum() / track->GetDynamicParticle()->GetTotalEnergy();
00159   double dirz  = (track->GetDynamicParticle()->GetMomentumDirection()).z();
00160   if (hitPoint.z() < 0) dirz *= -1.;
00161 #ifdef DebugLog
00162   edm::LogInfo("HFShower") << "HFShowerParam: getHits Momentum " 
00163                            <<track->GetDynamicParticle()->GetMomentumDirection()
00164                            << " HitPoint " << hitPoint << " dirz " << dirz;
00165 #endif  
00166   if (particleCode != emPDG && particleCode != epPDG && particleCode != gammaPDG ) {
00167     if (track->GetDefinition()->GetPDGCharge() != 0 && pBeta > (1/ref_index) &&
00168         aStep->GetTotalEnergyDeposit() > 0) other = true;
00169   }
00170 
00171   // take only e+-/gamma/or special particles
00172   if (particleCode == emPDG || particleCode == epPDG ||
00173       particleCode == gammaPDG || other) {
00174     // Leave out the last part
00175     double edep = 0.;
00176     bool   kill = false;
00177     if ((!trackEM) && ((zz<(gpar[1]-gpar[2])) || parametrizeLast) && (!other)){
00178       edep = pin;
00179       kill = true;
00180     } else if ((track->GetDefinition()->GetPDGCharge() != 0) && 
00181                (pBeta > (1/ref_index)) && (dirz > aperture)) {
00182       edep = (aStep->GetTotalEnergyDeposit())/GeV;
00183     }
00184     std::string path = "ShowerLibrary";
00185 #ifdef DebugLog
00186     edm::LogInfo("HFShower") << "HFShowerParam: getHits edep = " << edep
00187                              << ", Kill = " << kill << ", pin = " << pin 
00188                              << ", edMin = " << edMin << " Other " << other;
00189 #endif
00190     if (edep > 0) {
00191       if ((showerLibrary || gflash) && kill && pin > edMin && (!other)) {
00192         if (showerLibrary) {
00193           std::vector<HFShowerLibrary::Hit> hitSL = showerLibrary->getHits(aStep,kill,onlyLong);
00194           for (unsigned int i=0; i<hitSL.size(); i++) {
00195             bool ok = true;
00196 #ifdef DebugLog
00197             edm::LogInfo("HFShower") << "HFShowerParam: getHits applyFidCut = " << applyFidCut;
00198 #endif
00199             if (applyFidCut) { // @@ For showerlibrary no z-cut for Short (no z)
00200               int npmt = HFFibreFiducial:: PMTNumber(hitSL[i].position);
00201               if (npmt <= 0) ok = false;
00202             } 
00203             if (ok) {
00204               hit.position = hitSL[i].position;
00205               hit.depth    = hitSL[i].depth;
00206               hit.time     = hitSL[i].time;
00207               hit.edep     = 1;
00208               hits.push_back(hit);
00209 #ifdef plotDebug
00210               if (fillHisto) {
00211                 double zv  = std::abs(hit.position.z()) - gpar[4];
00212                 hzvem->Fill(zv);
00213                 em_long_sl->Fill(hit.position.z()/cm);
00214                 double sq = sqrt(pow(hit.position.x()/cm,2)+pow(hit.position.y()/cm,2));
00215                 double zp = hit.position.z()/cm;
00216                 if (hit.depth == 1) {
00217                   em_2d_1->Fill(zp, sq);  
00218                   em_lateral_1->Fill(sq);
00219                   em_long_1->Fill(zp);
00220                 } else if (hit.depth == 2) {
00221                   em_2d_2->Fill(zp, sq);
00222                   em_lateral_2->Fill(sq);
00223                   em_long_2->Fill(zp);
00224                 }
00225               }
00226 #endif
00227 #ifdef DebugLog
00228               edm::LogInfo("HFShower") << "HFShowerParam: Hit at depth " 
00229                                        << hit.depth << " with edep " << hit.edep
00230                                        << " Time " << hit.time;
00231 #endif
00232             }
00233           }
00234         } else { // GFlash clusters with known z
00235           std::vector<HFGflash::Hit>hitSL=gflash->gfParameterization(aStep,kill, onlyLong);
00236           for (unsigned int i=0; i<hitSL.size(); ++i) {
00237             bool ok = true;
00238             G4ThreeVector pe_effect(hitSL[i].position.x(), hitSL[i].position.y(),
00239                                     hitSL[i].position.z());
00240             double zv  = std::abs(pe_effect.z()) - gpar[4];
00241             //depth
00242             int depth    = 1;
00243             int npmt     = 0;
00244             if (zv < 0. || zv > gpar[1]) {
00245 #ifdef mkdebug
00246               std::cout<<"-#Zcut-HFShowerParam::getHits:z="<<zv<<",m="<<gpar[1]<<std::endl;
00247 #endif
00248               ok = false;
00249             }
00250             if (ok && applyFidCut) {
00251               npmt = HFFibreFiducial:: PMTNumber(pe_effect);
00252 #ifdef DebugLog
00253               edm::LogInfo("HFShower") << "HFShowerParam::getHits:#PMT= "
00254                                        << npmt << ",z = " << zv;
00255 #endif
00256               if (npmt <= 0) {
00257 #ifdef DebugLog
00258                 edm::LogInfo("HFShower") << "-#PMT=0 cut-HFShowerParam::"
00259                                          << "getHits: npmt = " << npmt;
00260 #endif
00261                 ok = false;
00262               } else if (npmt > 24) { // a short fibre
00263                 if    (zv > gpar[0]) {
00264                   depth = 2; 
00265                 } else {
00266 #ifdef DebugLog
00267                   edm::LogInfo("HFShower") << "-SHORT cut-HFShowerParam::"
00268                                            << "getHits:zMin=" << gpar[0];
00269 #endif
00270                   ok = false;
00271                 }
00272               }
00273 #ifdef DebugLog
00274               edm::LogInfo("HFShower") << "HFShowerParam: npmt " << npmt 
00275                                        << " zv " << std::abs(pe_effect.z()) 
00276                                        << ":" << gpar[4] << ":" << zv << ":" 
00277                                        << gpar[0] << " ok " << ok << " depth "
00278                                        << depth;
00279 #endif
00280             } else {
00281               if (G4UniformRand() > 0.5) depth = 2;
00282               if (depth == 2 && zv < gpar[0]) ok = false;
00283             }
00284             //attenuation
00285             double dist = fibre->zShift(localPoint,depth,0); // distance to PMT
00286             double r1   = G4UniformRand();
00287 #ifdef DebugLog
00288             edm::LogInfo("HFShower") << "HFShowerParam:Distance to PMT (" <<npmt
00289                                      << ") " << dist << ", exclusion flag " 
00290                                      << (r1 > exp(-attLMeanInv*zv));
00291 #endif
00292             if (r1 > exp(-attLMeanInv*dist)) ok = false;
00293             if (ok) {
00294               double time = fibre->tShift(localPoint,depth,0); //remaining part
00295 
00296               hit.position = hitSL[i].position;
00297               hit.depth    = depth;
00298               hit.time     = time + hitSL[i].time;
00299               hit.edep     = 1;
00300               hits.push_back(hit);
00301 #ifdef plotDebug
00302               if (fillHisto) {
00303                 em_long_gflash->Fill(pe_effect.z()/cm, hitSL[i].edep);
00304                 hzvem->Fill(zv);
00305                 double sq = sqrt(pow(hit.position.x()/cm,2)+pow(hit.position.y()/cm,2));
00306                 double zp = hit.position.z()/cm;
00307                 if (hit.depth == 1) {
00308                   em_2d_1->Fill(zp, sq);
00309                   em_lateral_1->Fill(s);
00310                   em_long_1->Fill(zp);
00311                 } else if (hit.depth == 2) {
00312                   em_2d_2->Fill(zp, sq);
00313                   em_lateral_2->Fill(sq);
00314                   em_long_2->Fill(zp);
00315                 }
00316               }
00317 #endif
00318 #ifdef DebugLog
00319               edm::LogInfo("HFShower") << "HFShowerParam: Hit at depth " 
00320                                        << hit.depth << " with edep " 
00321                                        << hit.edep << " Time "  << hit.time;
00322 #endif
00323             }
00324           }
00325         }
00326       } else {
00327         path          = "Rest";
00328         edep         *= pePerGeV;
00329         double tSlice = (aStep->GetPostStepPoint()->GetGlobalTime());
00330         double time   = fibre->tShift(localPoint,1,0); // remaining part
00331         bool ok = true;
00332         if (applyFidCut) { // @@ For showerlibrary no z-cut for Short (no z)
00333           int npmt = HFFibreFiducial:: PMTNumber(hitPoint);
00334           if (npmt <= 0) ok = false;
00335         } 
00336 #ifdef DebugLog
00337         edm::LogInfo("HFShower") << "HFShowerParam: getHits hitPoint " << hitPoint << " flag " << ok;
00338 #endif
00339         if (ok) {
00340           hit.depth     = 1;
00341           hit.time      = tSlice+time;
00342           hit.edep      = edep;
00343           hits.push_back(hit);
00344 #ifdef DebugLog
00345           edm::LogInfo("HFShower") << "HFShowerParam: Hit at depth 1 with edep "
00346                                    << edep << " Time " << tSlice << ":" << time
00347                                    << ":" << hit.time;
00348 #endif
00349 #ifdef plotDebug
00350           double zv = std::abs(hitPoint.z()) - gpar[4];
00351           if (fillHisto) {
00352             hzvhad->Fill(zv);
00353           }
00354 #endif
00355           if (zz >= gpar[0]) {
00356             time      = fibre->tShift(localPoint,2,0);
00357             hit.depth = 2;
00358             hit.time  = tSlice+time;
00359             hits.push_back(hit);
00360 #ifdef DebugLog
00361             edm::LogInfo("HFShower") <<"HFShowerParam: Hit at depth 2 with edep "
00362                                      << edep << " Time " << tSlice << ":" << time
00363                                      << hit.time;
00364 #endif
00365 #ifdef plotDebug
00366             if (fillHisto) {
00367               hzvhad->Fill(zv);
00368             }
00369 #endif
00370           }
00371         }
00372       }
00373 #ifdef DebugLog
00374       for (unsigned int ii=0; ii<hits.size(); ++ii) {
00375         double zv = std::abs(hits[ii].position.z());
00376         if (zv > 12790) edm::LogInfo("HFShower")<< "HFShowerParam: Abnormal hit along " 
00377                                                 << path << " in " 
00378                                                 << preStepPoint->GetPhysicalVolume()->GetLogicalVolume()->GetName()
00379                                                 << " at " << hits[ii].position << " zz " 
00380                                                 << zv << " Edep " << edep << " due to " 
00381                                                 <<track->GetDefinition()->GetParticleName()
00382                                                 << " time " << hit.time;
00383       }
00384 #endif
00385       if (kill) {
00386         track->SetTrackStatus(fStopAndKill);
00387         G4TrackVector tv = *(aStep->GetSecondary());
00388         for (unsigned int kk=0; kk<tv.size(); ++kk) {
00389           if (tv[kk]->GetVolume() == preStepPoint->GetPhysicalVolume())
00390             tv[kk]->SetTrackStatus(fStopAndKill);
00391         }
00392       }
00393 #ifdef DebugLog
00394       edm::LogInfo("HFShower") << "HFShowerParam: getHits kill (" << kill
00395                                << ") track " << track->GetTrackID() 
00396                                << " at " << hitPoint
00397                                << " and deposit " << edep << " " << hits.size()
00398                                << " times" << " ZZ " << zz << " " << gpar[0];
00399 #endif
00400     }
00401   }
00402   return hits;
00403 }
00404 
00405 std::vector<double> HFShowerParam::getDDDArray(const std::string & str, 
00406                                                const DDsvalues_type & sv)
00407 {
00408 #ifdef DebugLog
00409   LogDebug("HFShower") << "HFShowerParam:getDDDArray called for " << str;
00410 #endif
00411   DDValue value(str);
00412   if (DDfetch(&sv,value))
00413   {
00414 #ifdef DebugLog
00415     LogDebug("HFShower") << value;
00416 #endif
00417     const std::vector<double> & fvec = value.doubles();
00418     int nval = fvec.size();
00419     if (nval < 2) {
00420       edm::LogError("HFShower") << "HFShowerParam : # of " << str 
00421                                 << " bins " << nval << " < 2 ==> illegal";
00422       throw cms::Exception("Unknown", "HFShowerParam") << "nval < 2 for array "
00423                                                        << str << "\n";
00424     }
00425     return fvec;
00426   } else {
00427     edm::LogError("HFShower") << "HFShowerParam : cannot get array " << str;
00428     throw cms::Exception("Unknown", "HFShowerParam")  << "cannot get array "
00429                                                       << str << "\n";
00430   }
00431 }