CMS 3D CMS Logo

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