CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_1/src/SimG4CMS/Calo/src/HCalSD.cc

Go to the documentation of this file.
00001 
00002 // File: HCalSD.cc
00003 // Description: Sensitive Detector class for calorimeters
00005 
00006 #include "SimG4CMS/Calo/interface/HCalSD.h"
00007 #include "SimG4CMS/Calo/interface/HcalTestNumberingScheme.h"
00008 #include "SimG4CMS/Calo/interface/HFFibreFiducial.h"
00009 #include "SimG4Core/Notification/interface/TrackInformation.h"
00010 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00011 #include "DetectorDescription/Core/interface/DDFilter.h"
00012 #include "DetectorDescription/Core/interface/DDFilteredView.h"
00013 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
00014 #include "DetectorDescription/Core/interface/DDMaterial.h"
00015 #include "DetectorDescription/Core/interface/DDValue.h"
00016 #include "FWCore/Utilities/interface/Exception.h"
00017 
00018 #include "FWCore/ServiceRegistry/interface/Service.h"
00019 #include "CommonTools/UtilAlgos/interface/TFileService.h"
00020 
00021 #include "G4LogicalVolumeStore.hh"
00022 #include "G4LogicalVolume.hh"
00023 #include "G4Step.hh"
00024 #include "G4Track.hh"
00025 #include "G4ParticleTable.hh"
00026 #include "G4VProcess.hh"
00027 
00028 #include <iostream>
00029 #include <fstream>
00030 #include <iomanip>
00031 
00032 //#define DebugLog
00033 //#define plotDebug
00034 
00035 HCalSD::HCalSD(G4String name, const DDCompactView & cpv,
00036                SensitiveDetectorCatalog & clg, 
00037                edm::ParameterSet const & p, const SimTrackManager* manager) : 
00038   CaloSD(name, cpv, clg, p, manager,
00039          p.getParameter<edm::ParameterSet>("HCalSD").getParameter<int>("TimeSliceUnit"),
00040          p.getParameter<edm::ParameterSet>("HCalSD").getParameter<bool>("IgnoreTrackID")), 
00041   numberingFromDDD(0), numberingScheme(0), showerLibrary(0), hfshower(0), 
00042   showerParam(0), showerPMT(0), showerBundle(0), darkening(0) {
00043 
00044   //static SimpleConfigurable<bool>   on1(false, "HCalSD:UseBirkLaw");
00045   //static SimpleConfigurable<double> bk1(0.013, "HCalSD:BirkC1");
00046   //static SimpleConfigurable<double> bk2(0.0568,"HCalSD:BirkC2");
00047   //static SimpleConfigurable<double> bk3(1.75,  "HCalSD:BirkC3");
00048   // Values from NIM 80 (1970) 239-244: as implemented in Geant3
00049   //static SimpleConfigurable<bool> on2(true,"HCalSD:UseShowerLibrary");
00050   edm::ParameterSet m_HC = p.getParameter<edm::ParameterSet>("HCalSD");
00051   useBirk          = m_HC.getParameter<bool>("UseBirkLaw");
00052   birk1            = m_HC.getParameter<double>("BirkC1")*(g/(MeV*cm2));
00053   birk2            = m_HC.getParameter<double>("BirkC2");
00054   birk3            = m_HC.getParameter<double>("BirkC3");
00055   useShowerLibrary = m_HC.getParameter<bool>("UseShowerLibrary");
00056   useParam         = m_HC.getParameter<bool>("UseParametrize");
00057   bool testNumber  = m_HC.getParameter<bool>("TestNumberingScheme");
00058   usePMTHit        = m_HC.getParameter<bool>("UsePMTHits");
00059   betaThr          = m_HC.getParameter<double>("BetaThreshold");
00060   eminHitHB        = m_HC.getParameter<double>("EminHitHB")*MeV;
00061   eminHitHE        = m_HC.getParameter<double>("EminHitHE")*MeV;
00062   eminHitHO        = m_HC.getParameter<double>("EminHitHO")*MeV;
00063   eminHitHF        = m_HC.getParameter<double>("EminHitHF")*MeV;
00064   useFibreBundle   = m_HC.getParameter<bool>("UseFibreBundleHits");
00065   useHF            = m_HC.getUntrackedParameter<bool>("UseHF",true);
00066   bool forTBH2     = m_HC.getUntrackedParameter<bool>("ForTBH2",false);
00067   useLayerWt       = m_HC.getUntrackedParameter<bool>("UseLayerWt",false);
00068   std::string file = m_HC.getUntrackedParameter<std::string>("WtFile","None");
00069   lumiDarkening    = m_HC.getUntrackedParameter<double>("LumiDarkening",0.0);
00070   edm::ParameterSet m_HF  = p.getParameter<edm::ParameterSet>("HFShower");
00071   applyFidCut             = m_HF.getParameter<bool>("ApplyFiducialCut");
00072 
00073 #ifdef DebugLog
00074   LogDebug("HcalSim") << "***************************************************" 
00075                       << "\n"
00076                       << "*                                                 *"
00077                       << "\n"
00078                       << "* Constructing a HCalSD  with name " << name << "\n"
00079                       << "*                                                 *"
00080                       << "\n"
00081                       << "***************************************************";
00082 #endif
00083   edm::LogInfo("HcalSim") << "HCalSD:: Use of HF code is set to " << useHF
00084                           << "\nUse of shower parametrization set to "
00085                           << useParam << "\nUse of shower library is set to " 
00086                           << useShowerLibrary << "\nUse PMT Hit is set to "
00087                           << usePMTHit << " with beta Threshold "<< betaThr
00088                           << "\nUSe of FibreBundle Hit set to "<<useFibreBundle
00089                           << "\n         Use of Birks law is set to      " 
00090                           << useBirk << "  with three constants kB = "
00091                           << birk1 << ", C1 = " << birk2 << ", C2 = " << birk3;
00092   edm::LogInfo("HcalSim") << "HCalSD:: Suppression Flag " << suppressHeavy
00093                           << " protons below " << kmaxProton << " MeV,"
00094                           << " neutrons below " << kmaxNeutron << " MeV and"
00095                           << " ions below " << kmaxIon << " MeV\n"
00096                           << "         Threshold for storing hits in HB: "
00097                           << eminHitHB << " HE: " << eminHitHE << " HO: "
00098                           << eminHitHO << " HF: " << eminHitHF << "\n"
00099                           << "Luminosity for Darkening " << lumiDarkening
00100                           << ", Application of Fiducial Cut " << applyFidCut;
00101 
00102   numberingFromDDD = new HcalNumberingFromDDD(name, cpv);
00103   HcalNumberingScheme* scheme;
00104   if (testNumber || forTBH2) 
00105     scheme = dynamic_cast<HcalNumberingScheme*>(new HcalTestNumberingScheme(forTBH2));
00106   else 
00107     scheme = new HcalNumberingScheme();
00108   setNumberingScheme(scheme);
00109 
00110   const G4LogicalVolumeStore * lvs = G4LogicalVolumeStore::GetInstance();
00111   std::vector<G4LogicalVolume *>::const_iterator lvcite;
00112   G4LogicalVolume* lv;
00113   std::string attribute, value;
00114   if (useHF) {
00115     if (useParam) {
00116       showerParam = new HFShowerParam(name, cpv, p);
00117     }  else {
00118       if (useShowerLibrary) showerLibrary = new HFShowerLibrary(name, cpv, p);
00119       hfshower  = new HFShower(name, cpv, p, 0);
00120     }
00121 
00122     // HF volume names
00123     attribute = "Volume";
00124     value     = "HF";
00125     DDSpecificsFilter filter0;
00126     DDValue           ddv0(attribute, value, 0);
00127     filter0.setCriteria(ddv0, DDSpecificsFilter::equals);
00128     DDFilteredView fv0(cpv);
00129     fv0.addFilter(filter0);
00130     hfNames = getNames(fv0);
00131     fv0.firstChild();
00132     DDsvalues_type sv0(fv0.mergedSpecifics());
00133     std::vector<double> temp =  getDDDArray("Levels",sv0);
00134     edm::LogInfo("HcalSim") << "HCalSD: Names to be tested for " << attribute 
00135                             << " = " << value << " has " << hfNames.size() 
00136                             << " elements";
00137     for (unsigned int i=0; i < hfNames.size(); ++i) {
00138       G4String namv = hfNames[i];
00139       lv            = 0;
00140       for(lvcite=lvs->begin(); lvcite!=lvs->end(); lvcite++) 
00141         if((*lvcite)->GetName()==namv) {
00142           lv = (*lvcite);
00143           break;
00144         }
00145       hfLV.push_back(lv);
00146       int level = static_cast<int>(temp[i]);
00147       hfLevels.push_back(level);
00148       edm::LogInfo("HcalSim") << "HCalSD:  HF[" << i << "] = " << hfNames[i]
00149                               << " LV " << hfLV[i] << " at level " 
00150                               << hfLevels[i];
00151     }
00152   
00153     // HF Fibre volume names
00154     value     = "HFFibre";
00155     DDSpecificsFilter filter1;
00156     DDValue           ddv1(attribute,value,0);
00157     filter1.setCriteria(ddv1, DDSpecificsFilter::equals);
00158     DDFilteredView fv1(cpv);
00159     fv1.addFilter(filter1);
00160     fibreNames = getNames(fv1);
00161     edm::LogInfo("HcalSim") << "HCalSD: Names to be tested for " << attribute 
00162                             << " = " << value << ":";
00163     for (unsigned int i=0; i<fibreNames.size(); ++i) {
00164       G4String namv = fibreNames[i];
00165       lv            = 0;
00166       for (lvcite = lvs->begin(); lvcite != lvs->end(); ++lvcite) {
00167         if ((*lvcite)->GetName() == namv) {
00168           lv = (*lvcite);
00169           break;
00170         }
00171       }
00172       fibreLV.push_back(lv);
00173       edm::LogInfo("HcalSim") << "HCalSD:  (" << i << ") " << fibreNames[i]
00174                               << " LV " << fibreLV[i];
00175     }
00176   
00177     // HF PMT volume names
00178     value     = "HFPMT";
00179     DDSpecificsFilter filter3;
00180     DDValue           ddv3(attribute,value,0);
00181     filter3.setCriteria(ddv3,DDSpecificsFilter::equals);
00182     DDFilteredView fv3(cpv);
00183     fv3.addFilter(filter3);
00184     std::vector<G4String> pmtNames = getNames(fv3);
00185     edm::LogInfo("HcalSim") << "HCalSD: Names to be tested for " << attribute 
00186                             << " = " << value << " have " << pmtNames.size() 
00187                             << " entries";
00188     for (unsigned int i=0; i<pmtNames.size(); ++i)  {
00189       G4String namv = pmtNames[i];
00190       lv            = 0;
00191       for (lvcite = lvs->begin(); lvcite != lvs->end(); ++lvcite) 
00192         if ((*lvcite)->GetName() == namv) {
00193           lv = (*lvcite);
00194           break;
00195         }
00196       pmtLV.push_back(lv);
00197       edm::LogInfo("HcalSim") << "HCalSD:  (" << i << ") " << pmtNames[i]
00198                               << " LV " << pmtLV[i];
00199     }
00200     if (pmtNames.size() > 0) showerPMT = new HFShowerPMT (name, cpv, p);
00201   
00202     // HF Fibre bundles
00203     value     = "HFFibreBundleStraight";
00204     DDSpecificsFilter filter4;
00205     DDValue           ddv4(attribute,value,0);
00206     filter4.setCriteria(ddv4,DDSpecificsFilter::equals);
00207     DDFilteredView fv4(cpv);
00208     fv4.addFilter(filter4);
00209     std::vector<G4String> fibreNames = getNames(fv4);
00210     edm::LogInfo("HcalSim") << "HCalSD: Names to be tested for " << attribute
00211                             << " = " << value << " have " << fibreNames.size()
00212                             << " entries";
00213     for (unsigned int i=0; i<fibreNames.size(); ++i) {
00214       G4String namv = fibreNames[i];
00215       lv            = 0;
00216       for (lvcite = lvs->begin(); lvcite != lvs->end(); lvcite++) 
00217         if ((*lvcite)->GetName() == namv) {
00218           lv = (*lvcite);
00219           break;
00220         }
00221       fibre1LV.push_back(lv);
00222       edm::LogInfo("HcalSim") << "HCalSD:  (" << i << ") " << fibreNames[i]
00223                               << " LV " << fibre1LV[i];
00224     }
00225 
00226     // Geometry parameters for HF
00227     value     = "HFFibreBundleConical";
00228     DDSpecificsFilter filter5;
00229     DDValue           ddv5(attribute,value,0);
00230     filter5.setCriteria(ddv5,DDSpecificsFilter::equals);
00231     DDFilteredView fv5(cpv);
00232     fv5.addFilter(filter5);
00233     fibreNames = getNames(fv5);
00234     edm::LogInfo("HcalSim") << "HCalSD: Names to be tested for " << attribute
00235                             << " = " << value << " have " << fibreNames.size() 
00236                             << " entries";
00237     for (unsigned int i=0; i<fibreNames.size(); ++i) {
00238       G4String namv = fibreNames[i];
00239       lv            = 0;
00240       for (lvcite = lvs->begin(); lvcite != lvs->end(); ++lvcite) 
00241         if ((*lvcite)->GetName() == namv) {
00242           lv = (*lvcite);
00243           break;
00244         }
00245       fibre2LV.push_back(lv);
00246       edm::LogInfo("HcalSim") << "HCalSD:  (" << i << ") " << fibreNames[i]
00247                               << " LV " << fibre2LV[i];
00248     }
00249     if (fibre1LV.size() > 0 || fibre2LV.size() > 0) 
00250       showerBundle = new HFShowerFibreBundle (name, cpv, p);
00251 
00252     attribute = "ReadOutName";
00253     value     = name;
00254     DDSpecificsFilter filter6;
00255     DDValue           ddv6(attribute,value,0);
00256     filter6.setCriteria(ddv6,DDSpecificsFilter::equals);
00257     DDFilteredView fv6(cpv);
00258     fv6.addFilter(filter6);
00259     if (fv6.firstChild()) {
00260       DDsvalues_type sv(fv6.mergedSpecifics());
00261       //Special Geometry parameters
00262       gpar      = getDDDArray("gparHF",sv);
00263       edm::LogInfo("HFShower") << "HFShowerParam: " << gpar.size() 
00264                                << " gpar (cm)";
00265       for (unsigned int ig=0; ig<gpar.size(); ig++)
00266         edm::LogInfo("HFShower") << "HFShowerParam: gpar[" << ig << "] = "
00267                                  << gpar[ig]/cm << " cm";
00268     } else {
00269       edm::LogWarning("HFShower") << "HFShowerParam: cannot get filtered "
00270                                   << " view for " << attribute << " matching " 
00271                                   << name;
00272     }
00273   }
00274 
00275   //Material list for HB/HE/HO sensitive detectors
00276   attribute = "ReadOutName";
00277   DDSpecificsFilter filter2;
00278   DDValue           ddv2(attribute,name,0);
00279   filter2.setCriteria(ddv2,DDSpecificsFilter::equals);
00280   DDFilteredView fv2(cpv);
00281   fv2.addFilter(filter2);
00282   bool dodet = fv2.firstChild();
00283 
00284   DDsvalues_type sv(fv2.mergedSpecifics());
00285   //Layer0 Weight
00286   layer0wt = getDDDArray("Layer0Wt",sv);
00287   edm::LogInfo("HcalSim") << "HCalSD: " << layer0wt.size() << " Layer0Wt";
00288   for (unsigned int it=0; it<layer0wt.size(); ++it)
00289     edm::LogInfo("HcalSim") << "HCalSD: [" << it << "] " << layer0wt[it];
00290 
00291   const G4MaterialTable * matTab = G4Material::GetMaterialTable();
00292   std::vector<G4Material*>::const_iterator matite;
00293   while (dodet) {
00294     const DDLogicalPart & log = fv2.logicalPart();
00295     G4String namx = log.name().name();
00296     if (!isItHF(namx) && !isItFibre(namx)) {
00297       bool notIn = true;
00298       for (unsigned int i=0; i<matNames.size(); ++i) {
00299         if (!strcmp(matNames[i].c_str(),log.material().name().name().c_str())){
00300           notIn = false;
00301           break;
00302         }
00303       }
00304       if (notIn) {
00305         namx = log.material().name().name();
00306         matNames.push_back(namx);
00307         G4Material* mat;
00308         for (matite = matTab->begin(); matite != matTab->end(); ++matite) {
00309           if ((*matite)->GetName() == namx) {
00310             mat = (*matite);
00311             break;
00312           }
00313         }
00314         materials.push_back(mat);
00315       }
00316     }
00317     dodet = fv2.next();
00318   }
00319 
00320   edm::LogInfo("HcalSim") << "HCalSD: Material names for " << attribute 
00321                           << " = " << name << ":";
00322   for (unsigned int i=0; i<matNames.size(); ++i)
00323     edm::LogInfo("HcalSim") << "HCalSD: (" << i << ") " << matNames[i]
00324                             << " pointer " << materials[i];
00325 
00326   mumPDG = mupPDG = 0;
00327   
00328   if (useLayerWt) readWeightFromFile(file);
00329 
00330   for (int i=0;  i<9; ++i) hit_[i] = time_[i]= dist_[i] = 0;
00331   hzvem = hzvhad = 0;
00332 
00333   if (lumiDarkening > 0) darkening = new HEDarkening();
00334 #ifdef plotDebug
00335   edm::Service<TFileService> tfile;
00336 
00337   if ( tfile.isAvailable() ) {
00338     static std::string labels[9] = {"HB", "HE", "HO", "HF Absorber", "HF PMT",
00339                                     "HF Absorber Long", "HF Absorber Short",
00340                                     "HF PMT Long", "HF PMT Short"};
00341     TFileDirectory hcDir = tfile->mkdir("ProfileFromHCalSD");
00342     char name[20], title[60];
00343     for (int i=0; i<9; ++i) {
00344       sprintf (title, "Hit energy in %s", labels[i].c_str());
00345       sprintf (name, "HCalSDHit%d", i);
00346       hit_[i] = hcDir.make<TH1F>(name, title, 2000, 0., 2000.);
00347       sprintf (title, "Energy (MeV)");
00348       hit_[i]->GetXaxis()->SetTitle(title);
00349       hit_[i]->GetYaxis()->SetTitle("Hits");
00350       sprintf (title, "Time of the hit in %s", labels[i].c_str());
00351       sprintf (name, "HCalSDTime%d", i);
00352       time_[i] = hcDir.make<TH1F>(name, title, 2000, 0., 2000.);
00353       sprintf (title, "Time (ns)");
00354       time_[i]->GetXaxis()->SetTitle(title);
00355       time_[i]->GetYaxis()->SetTitle("Hits");
00356       sprintf (title, "Longitudinal profile in %s", labels[i].c_str());
00357       sprintf (name, "HCalSDDist%d", i);
00358       dist_[i] = hcDir.make<TH1F>(name, title, 2000, 0., 2000.);
00359       sprintf (title, "Distance (mm)");
00360       dist_[i]->GetXaxis()->SetTitle(title);
00361       dist_[i]->GetYaxis()->SetTitle("Hits");
00362     }
00363     if (useHF && (!useParam)) {
00364       hzvem  = hcDir.make<TH1F>("hzvem", "Longitudinal Profile (EM Part)",330,0.0,1650.0);
00365       hzvem->GetXaxis()->SetTitle("Longitudinal Profile (EM Part)");
00366       hzvhad = hcDir.make<TH1F>("hzvhad","Longitudinal Profile (Had Part)",330,0.0,1650.0);
00367       hzvhad->GetXaxis()->SetTitle("Longitudinal Profile (Hadronic Part)");
00368     }
00369   }
00370 #endif
00371 }
00372 
00373 HCalSD::~HCalSD() { 
00374 
00375   if (numberingFromDDD) delete numberingFromDDD;
00376   if (numberingScheme)  delete numberingScheme;
00377   if (showerLibrary)    delete showerLibrary;
00378   if (hfshower)         delete hfshower;
00379   if (showerParam)      delete showerParam;
00380   if (showerPMT)        delete showerPMT;
00381   if (showerBundle)     delete showerBundle;
00382   if (darkening)        delete darkening;
00383 }
00384 
00385 bool HCalSD::ProcessHits(G4Step * aStep, G4TouchableHistory * ) {
00386 
00387   NaNTrap( aStep ) ;
00388   
00389   if (aStep == NULL) {
00390     return true;
00391   } else {
00392     G4LogicalVolume* lv =
00393       aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume();
00394     G4String nameVolume = lv->GetName();
00395     if (isItHF(aStep)) {
00396       G4int parCode =aStep->GetTrack()->GetDefinition()->GetPDGEncoding();
00397       if (useParam) {
00398 #ifdef DebugLog
00399         LogDebug("HcalSim") << "HCalSD: " << getNumberOfHits()
00400                             << " hits from parametrization in " << nameVolume 
00401                             << " for Track " << aStep->GetTrack()->GetTrackID()
00402                             <<" (" << aStep->GetTrack()->GetDefinition()->GetParticleName() 
00403                             <<")";
00404 #endif
00405         getFromParam(aStep);
00406 #ifdef DebugLog
00407         LogDebug("HcalSim") << "HCalSD: " << getNumberOfHits() 
00408                             << " hits afterParamS*";
00409 #endif 
00410       } else {
00411         bool notaMuon = true;
00412         if (parCode == mupPDG || parCode == mumPDG ) notaMuon = false;
00413         if (useShowerLibrary && notaMuon) {
00414 #ifdef DebugLog
00415           LogDebug("HcalSim") << "HCalSD: Starts shower library from " 
00416                               << nameVolume << " for Track " 
00417                               << aStep->GetTrack()->GetTrackID() << " ("
00418                               << aStep->GetTrack()->GetDefinition()->GetParticleName() << ")";
00419 #endif
00420           getFromLibrary(aStep);
00421         } else if (isItFibre(lv)) {
00422 #ifdef DebugLog
00423           LogDebug("HcalSim") << "HCalSD: Hit at Fibre in " << nameVolume 
00424                               << " for Track " 
00425                               << aStep->GetTrack()->GetTrackID() <<" ("
00426                               << aStep->GetTrack()->GetDefinition()->GetParticleName() << ")";
00427 #endif
00428           hitForFibre(aStep);
00429         }
00430       }
00431     } else if (isItPMT(lv)) {
00432 #ifdef DebugLog
00433       LogDebug("HcalSim") << "HCalSD: Hit from PMT parametrization from " 
00434                           <<  nameVolume << " for Track " 
00435                           << aStep->GetTrack()->GetTrackID() << " ("
00436                           << aStep->GetTrack()->GetDefinition()->GetParticleName() << ")";
00437 #endif
00438       if (usePMTHit && showerPMT) getHitPMT(aStep);
00439     } else if (isItStraightBundle(lv) || isItConicalBundle(lv)) {
00440 #ifdef DebugLog
00441       LogDebug("HcalSim") << "HCalSD: Hit from FibreBundle from "
00442                           << nameVolume << " for Track " 
00443                           << aStep->GetTrack()->GetTrackID() << " ("
00444                           << aStep->GetTrack()->GetDefinition()->GetParticleName() << ")";
00445 #endif
00446       if (useFibreBundle && showerBundle) 
00447         getHitFibreBundle(aStep, isItConicalBundle(lv));
00448     } else {
00449 #ifdef DebugLog
00450       LogDebug("HcalSim") << "HCalSD: Hit from standard path from " 
00451                           <<  nameVolume << " for Track " 
00452                           << aStep->GetTrack()->GetTrackID() << " ("
00453                           << aStep->GetTrack()->GetDefinition()->GetParticleName() << ")";
00454 #endif
00455       if (getStepInfo(aStep)) {
00456 #ifdef plotDebug
00457         if (edepositEM+edepositHAD > 0)
00458           plotProfile(aStep, aStep->GetPreStepPoint()->GetPosition(),
00459                       edepositEM+edepositHAD,aStep->GetPostStepPoint()->GetGlobalTime(),0);
00460 #endif
00461         if (hitExists() == false && edepositEM+edepositHAD>0.) currentHit = createNewHit();
00462       }
00463     }
00464     return true;
00465   }
00466 } 
00467 
00468 double HCalSD::getEnergyDeposit(G4Step* aStep) {
00469   double destep = aStep->GetTotalEnergyDeposit();
00470   double weight = 1;
00471   G4Track* theTrack = aStep->GetTrack();
00472 
00473   const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
00474   int depth = (touch->GetReplicaNumber(0))%10;
00475   int det   = ((touch->GetReplicaNumber(1))/1000)-3;
00476   if (depth==0 && (det==0 || det==1)) weight = layer0wt[det];
00477   if (useLayerWt) {
00478     int lay   = (touch->GetReplicaNumber(0)/10)%100 + 1;
00479     G4ThreeVector hitPoint = aStep->GetPreStepPoint()->GetPosition();
00480     weight = layerWeight(det+3, hitPoint, depth, lay);
00481   }
00482 
00483   if (darkening !=0 && det == 1) {
00484     int lay = (touch->GetReplicaNumber(0)/10)%100 + 1;
00485     G4ThreeVector hitPoint = aStep->GetPreStepPoint()->GetPosition();
00486     float r = sqrt((hitPoint.x())*(hitPoint.x())+(hitPoint.y())*(hitPoint.y()))/cm;
00487     LogDebug("HcalSim") << "HCalSD:Darkening >>>  position: "<< hitPoint 
00488                         << "    lay: " << lay << "   R: " << r << " cm ";
00489  
00490     float normalized_lumi = darkening->int_lumi(lumiDarkening);
00491     float dose_acquired   = darkening->dose(lay-2,r); // NB: diff. layer count
00492     weight *= darkening->degradation(normalized_lumi * dose_acquired);
00493     LogDebug("HcalSim") << "HCalSD:         >>> norm_Lumi: " << normalized_lumi
00494                         << "  dose: " << dose_acquired
00495                         << "    coefficient = " << weight;
00496   }
00497 
00498   if (suppressHeavy) {
00499     TrackInformation * trkInfo = (TrackInformation *)(theTrack->GetUserInformation());
00500     if (trkInfo) {
00501       int pdg = theTrack->GetDefinition()->GetPDGEncoding();
00502       if (!(trkInfo->isPrimary())) {         // Only secondary particles
00503         double ke = theTrack->GetKineticEnergy()/MeV;
00504         if ( pdg/1000000000 == 1 && (pdg/10000)%100 > 0 &&
00505              (pdg/10)%100 > 0    && ke <kmaxIon   ) weight = 0;
00506         if ((pdg == 2212) && (ke < kmaxProton))     weight = 0;
00507         if ((pdg == 2112) && (ke < kmaxNeutron))    weight = 0;
00508 #ifdef DebugLog
00509         if (weight == 0) 
00510           edm::LogInfo("HcalSim") << "HCalSD:Ignore Track " 
00511                                   << theTrack->GetTrackID() << " Type " 
00512                                   << theTrack->GetDefinition()->GetParticleName()
00513                                   << " Kinetic Energy " << ke << " MeV";
00514 #endif
00515       }
00516     }
00517   }
00518 #ifdef DebugLog
00519   double weight0 = weight;
00520 #endif
00521   if (useBirk) {
00522     G4Material* mat = aStep->GetPreStepPoint()->GetMaterial();
00523     if (isItScintillator(mat)) weight *= getAttenuation(aStep, birk1, birk2, birk3);
00524   }
00525   double wt1 = getResponseWt(theTrack);
00526   double wt2 = theTrack->GetWeight();
00527   /*
00528   if(wt2 != 1.0) { 
00529     std::cout << "HCalSD: Detector " << det+3 << " Depth " << depth
00530               << " weight= " << weight << " wt1= " << wt1 
00531               << " wt2= " << wt2 << std::endl;
00532     std::cout << theTrack->GetDefinition()->GetParticleName()
00533               << " " << theTrack->GetKineticEnergy()
00534               << " Id=" << theTrack->GetTrackID()
00535               << " IdP=" << theTrack->GetParentID();
00536     const G4VProcess* pr = theTrack->GetCreatorProcess();
00537     if(pr) std::cout << " from  " << pr->GetProcessName();
00538     std::cout << std::endl;
00539   }
00540   */
00541 #ifdef DebugLog
00542   edm::LogInfo("HcalSim") << "HCalSD: Detector " << det+3 << " Depth " << depth
00543                           << " weight " << weight0 << " " << weight << " " << wt1 
00544                           << " " << wt2; 
00545 #endif
00546   double edep = weight*wt1*destep;
00547   if(wt2 > 0.0) { edep *= wt2; }
00548   return edep;
00549 }
00550 
00551 uint32_t HCalSD::setDetUnitId(G4Step * aStep) { 
00552 
00553   G4StepPoint* preStepPoint = aStep->GetPreStepPoint(); 
00554   const G4VTouchable* touch = preStepPoint->GetTouchable();
00555   G4ThreeVector hitPoint    = preStepPoint->GetPosition();
00556 
00557   int depth = (touch->GetReplicaNumber(0))%10 + 1;
00558   int lay   = (touch->GetReplicaNumber(0)/10)%100 + 1;
00559   int det   = (touch->GetReplicaNumber(1))/1000;
00560 
00561   return setDetUnitId (det, hitPoint, depth, lay);
00562 }
00563 
00564 void HCalSD::setNumberingScheme(HcalNumberingScheme * scheme) {
00565   if (scheme != 0) {
00566     edm::LogInfo("HcalSim") << "HCalSD: updates numbering scheme for " << GetName() <<"\n";
00567     if (numberingScheme) delete numberingScheme;
00568     numberingScheme = scheme;
00569   }
00570 }
00571 
00572 void HCalSD::initRun() {
00573   G4ParticleTable * theParticleTable = G4ParticleTable::GetParticleTable();
00574   G4String          particleName;
00575   mumPDG = theParticleTable->FindParticle(particleName="mu-")->GetPDGEncoding();
00576   mupPDG = theParticleTable->FindParticle(particleName="mu+")->GetPDGEncoding();
00577 #ifdef DebugLog
00578   edm::LogInfo("HcalSim") << "HCalSD: Particle code for mu- = " << mumPDG
00579                           << " for mu+ = " << mupPDG;
00580 #endif
00581   if (showerLibrary) showerLibrary->initRun(theParticleTable);
00582   if (showerParam)   showerParam->initRun(theParticleTable);
00583   if (hfshower)      hfshower->initRun(theParticleTable);
00584 }
00585 
00586 bool HCalSD::filterHit(CaloG4Hit* aHit, double time) {
00587   double threshold=0;
00588   DetId theId(aHit->getUnitID());
00589   switch (theId.subdetId()) {
00590   case HcalBarrel:
00591     threshold = eminHitHB; break;
00592   case HcalEndcap:
00593     threshold = eminHitHE; break;
00594   case HcalOuter:
00595     threshold = eminHitHO; break;
00596   case HcalForward:
00597     threshold = eminHitHF; break;
00598   default:
00599     break;
00600   }
00601   return ((time <= tmaxHit) && (aHit->getEnergyDeposit() > threshold));
00602 }
00603 
00604 
00605 uint32_t HCalSD::setDetUnitId (int det, G4ThreeVector pos, int depth, int lay=1) { 
00606   uint32_t id = 0;
00607   if (numberingFromDDD) {
00608     //get the ID's as eta, phi, depth, ... indices
00609     HcalNumberingFromDDD::HcalID tmp = numberingFromDDD->unitID(det, pos, depth, lay);
00610     //get the ID
00611     if (numberingScheme) id = numberingScheme->getUnitID(tmp);
00612   }
00613   return id;
00614 }
00615 
00616 std::vector<double> HCalSD::getDDDArray(const std::string & str,
00617                                         const DDsvalues_type & sv) {
00618 #ifdef DebugLog
00619   LogDebug("HcalSim") << "HCalSD:getDDDArray called for " << str;
00620 #endif
00621   DDValue value(str);
00622   if (DDfetch(&sv,value)) {
00623 #ifdef DebugLog
00624     LogDebug("HcalSim") << value;
00625 #endif
00626     const std::vector<double> & fvec = value.doubles();
00627     int nval = fvec.size();
00628     if (nval < 1) {
00629       edm::LogError("HcalSim") << "HCalSD : # of " << str << " bins " << nval
00630           << " < 2 ==> illegal";
00631       throw cms::Exception("Unknown", "HCalSD") << "nval < 2 for array " << str << "\n";
00632     }
00633     
00634     return fvec;
00635   } else {
00636     edm::LogError("HcalSim") << "HCalSD :  cannot get array " << str;
00637     throw cms::Exception("Unknown", "HCalSD") << "cannot get array " << str << "\n";
00638   }
00639 }
00640 
00641 std::vector<G4String> HCalSD::getNames(DDFilteredView& fv) {
00642 
00643   std::vector<G4String> tmp;
00644   bool dodet = fv.firstChild();
00645   while (dodet) {
00646     const DDLogicalPart & log = fv.logicalPart();
00647     bool ok = true;
00648 
00649     for (unsigned int i=0; i<tmp.size(); ++i) {
00650       if (!strcmp(tmp[i].c_str(), log.name().name().c_str())) {
00651         ok = false;
00652         break;
00653       }
00654     }
00655     if (ok) tmp.push_back(log.name().name());
00656     dodet = fv.next();
00657   }
00658   return tmp;
00659 }
00660 
00661 bool HCalSD::isItHF(G4Step * aStep) {
00662   const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
00663   int levels = (touch->GetHistoryDepth()) + 1;
00664   for (unsigned int it=0; it < hfNames.size(); ++it) {
00665     if (levels >= hfLevels[it]) {
00666       G4LogicalVolume* lv = touch->GetVolume(levels-hfLevels[it])->GetLogicalVolume();
00667       if (lv == hfLV[it]) return true;
00668     }
00669   }
00670   return false;
00671 }
00672 
00673 bool HCalSD::isItHF (G4String name) {
00674   std::vector<G4String>::const_iterator it = hfNames.begin();
00675   for (; it != hfNames.end(); ++it) if (name == *it) return true;
00676   return false;
00677 }
00678 
00679 bool HCalSD::isItFibre (G4LogicalVolume* lv) {
00680   std::vector<G4LogicalVolume*>::const_iterator ite = fibreLV.begin();
00681   for (; ite != fibreLV.end(); ++ite) if (lv == *ite) return true;
00682   return false;
00683 }
00684 
00685 bool HCalSD::isItFibre (G4String name) {
00686   std::vector<G4String>::const_iterator it = fibreNames.begin();
00687   for (; it != fibreNames.end(); ++it) if (name == *it) return true;
00688   return false;
00689 }
00690 
00691 bool HCalSD::isItPMT (G4LogicalVolume* lv) {
00692   std::vector<G4LogicalVolume*>::const_iterator ite = pmtLV.begin();
00693   for (; ite != pmtLV.end(); ++ite) if (lv == *ite) return true;
00694   return false;
00695 }
00696 
00697 bool HCalSD::isItStraightBundle (G4LogicalVolume* lv) {
00698   std::vector<G4LogicalVolume*>::const_iterator ite = fibre1LV.begin();
00699   for (; ite != fibre1LV.end(); ++ite) if (lv == *ite) return true;
00700   return false;
00701 }
00702 
00703 bool HCalSD::isItConicalBundle (G4LogicalVolume* lv) {
00704   std::vector<G4LogicalVolume*>::const_iterator ite = fibre2LV.begin();
00705   for (; ite != fibre2LV.end(); ++ite) if (lv == *ite) return true;
00706   return false;
00707 }
00708 
00709 bool HCalSD::isItScintillator (G4Material* mat) {
00710   std::vector<G4Material*>::const_iterator ite = materials.begin();
00711   for (; ite != materials.end(); ++ite) if (mat == *ite) return true;
00712   return false;
00713 }
00714 
00715 bool HCalSD::isItinFidVolume (G4ThreeVector& hitPoint) {
00716   bool flag = true;
00717   if (applyFidCut) {
00718     int npmt = HFFibreFiducial:: PMTNumber(hitPoint);
00719 #ifdef DebugLog
00720     edm::LogInfo("HcalSim") << "HCalSD::isItinFidVolume:#PMT= " << npmt 
00721                             << " for hit point " << hitPoint;
00722 #endif
00723     if (npmt <= 0) flag = false;
00724   }
00725 #ifdef DebugLog
00726     edm::LogInfo("HcalSim") << "HCalSD::isItinFidVolume: point " << hitPoint
00727                             << " return flag " << flag;
00728 #endif
00729   return flag;
00730 }
00731 
00732 void HCalSD::getFromLibrary (G4Step* aStep) {
00733   preStepPoint  = aStep->GetPreStepPoint(); 
00734   theTrack      = aStep->GetTrack();   
00735   int det       = 5;
00736   bool ok;
00737 
00738   std::vector<HFShowerLibrary::Hit> hits = showerLibrary->getHits(aStep, ok);
00739 
00740   double etrack    = preStepPoint->GetKineticEnergy();
00741   int    primaryID = setTrackID(aStep);
00742   /*
00743   int    primaryID = 0;
00744   if (etrack >= energyCut) {
00745     primaryID    = theTrack->GetTrackID();
00746   } else {
00747     primaryID    = theTrack->GetParentID();
00748     if (primaryID == 0) primaryID = theTrack->GetTrackID();
00749   }
00750   */
00751 
00752   // Reset entry point for new primary
00753   posGlobal = preStepPoint->GetPosition();
00754   resetForNewPrimary(posGlobal, etrack);
00755 
00756   G4int particleCode = theTrack->GetDefinition()->GetPDGEncoding();
00757   if (particleCode==emPDG || particleCode==epPDG || particleCode==gammaPDG) {
00758     edepositEM  = 1.*GeV;
00759     edepositHAD = 0.;
00760   } else {
00761     edepositEM  = 0.;
00762     edepositHAD = 1.*GeV;
00763   }
00764 #ifdef DebugLog
00765   edm::LogInfo("HcalSim") << "HCalSD::getFromLibrary " <<hits.size() 
00766                           << " hits for " << GetName() << " of " << primaryID 
00767                           << " with " << theTrack->GetDefinition()->GetParticleName() 
00768                           << " of " << preStepPoint->GetKineticEnergy()/GeV << " GeV";
00769 #endif
00770   for (unsigned int i=0; i<hits.size(); ++i) {
00771     G4ThreeVector hitPoint = hits[i].position;
00772     if (isItinFidVolume (hitPoint)) {
00773       int depth              = hits[i].depth;
00774       double time            = hits[i].time;
00775       unsigned int unitID    = setDetUnitId(det, hitPoint, depth);
00776       currentID.setID(unitID, time, primaryID, 0);
00777 #ifdef plotDebug
00778       plotProfile(aStep, hitPoint, 1.0*GeV, time, depth);
00779       bool emType = false;
00780       if (particleCode==emPDG || particleCode==epPDG || particleCode==gammaPDG)
00781         emType = true;
00782       plotHF(hitPoint,emType);
00783 #endif
00784    
00785       // check if it is in the same unit and timeslice as the previous one
00786       if (currentID == previousID) {
00787         updateHit(currentHit);
00788       } else {
00789         if (!checkHit()) currentHit = createNewHit();
00790       }
00791     }
00792   }
00793 
00794   //Now kill the current track
00795   if (ok) {
00796     theTrack->SetTrackStatus(fStopAndKill);
00797     G4TrackVector tv = *(aStep->GetSecondary());
00798     for (unsigned int kk=0; kk<tv.size(); ++kk)
00799       if (tv[kk]->GetVolume() == preStepPoint->GetPhysicalVolume())
00800         tv[kk]->SetTrackStatus(fStopAndKill);
00801   }
00802 }
00803 
00804 void HCalSD::hitForFibre (G4Step* aStep) { // if not ParamShower
00805 
00806   preStepPoint  = aStep->GetPreStepPoint();
00807   theTrack      = aStep->GetTrack();
00808   int primaryID = setTrackID(aStep);
00809 
00810   int det   = 5;
00811   std::vector<HFShower::Hit> hits = hfshower->getHits(aStep);
00812 
00813   G4int particleCode = theTrack->GetDefinition()->GetPDGEncoding();
00814   if (particleCode==emPDG || particleCode==epPDG || particleCode==gammaPDG) {
00815     edepositEM  = 1.*GeV;
00816     edepositHAD = 0.;
00817   } else {
00818     edepositEM  = 0.;
00819     edepositHAD = 1.*GeV;
00820   }
00821  
00822 #ifdef DebugLog
00823   edm::LogInfo("HcalSim") << "HCalSD::hitForFibre " << hits.size() 
00824      << " hits for " << GetName() << " of " << primaryID 
00825      << " with " << theTrack->GetDefinition()->GetParticleName() 
00826      << " of " << preStepPoint->GetKineticEnergy()/GeV 
00827      << " GeV in detector type " << det;
00828 #endif
00829   if (hits.size() > 0) {
00830     for (unsigned int i=0; i<hits.size(); ++i) {
00831       G4ThreeVector hitPoint = hits[i].position;
00832       if (isItinFidVolume (hitPoint)) {
00833         int depth              = hits[i].depth;
00834         double time            = hits[i].time;
00835         unsigned int unitID = setDetUnitId(det, hitPoint, depth);
00836         currentID.setID(unitID, time, primaryID, 0);
00837 #ifdef plotDebug
00838         plotProfile(aStep, hitPoint, edepositEM, time, depth);
00839         bool emType = false;
00840         if (particleCode==emPDG || particleCode==epPDG || particleCode==gammaPDG)
00841           emType = true;
00842         plotHF(hitPoint,emType);
00843 #endif
00844         // check if it is in the same unit and timeslice as the previous one
00845         if (currentID == previousID) {
00846           updateHit(currentHit);
00847         } else {
00848           posGlobal = preStepPoint->GetPosition();
00849           if (!checkHit()) currentHit = createNewHit();
00850         }
00851       }
00852     }
00853   }
00854 }
00855 
00856 void HCalSD::getFromParam (G4Step* aStep) {
00857   std::vector<HFShowerParam::Hit> hits = showerParam->getHits(aStep);
00858   int nHit = static_cast<int>(hits.size());
00859 
00860   if (nHit > 0) {
00861     preStepPoint  = aStep->GetPreStepPoint();
00862     int primaryID = setTrackID(aStep);
00863    
00864     int det   = 5;
00865 #ifdef DebugLog
00866     edm::LogInfo("HcalSim") << "HCalSD::getFromParam " << nHit << " hits for " 
00867                             << GetName() << " of " << primaryID << " with " 
00868                             <<  aStep->GetTrack()->GetDefinition()->GetParticleName()
00869                             << " of " << preStepPoint->GetKineticEnergy()/GeV 
00870                             << " GeV in detector type " << det;
00871 #endif
00872     for (int i = 0; i<nHit; ++i) {
00873       G4ThreeVector hitPoint = hits[i].position;
00874       int depth              = hits[i].depth;
00875       double time            = hits[i].time;
00876       unsigned int unitID    = setDetUnitId(det, hitPoint, depth);
00877       currentID.setID(unitID, time, primaryID, 0);
00878       edepositEM             = hits[i].edep*GeV; 
00879       edepositHAD            = 0.;
00880 #ifdef plotDebug
00881       plotProfile(aStep, hitPoint, edepositEM, time, depth);
00882 #endif
00883 
00884       // check if it is in the same unit and timeslice as the previous one
00885       if (currentID == previousID) {
00886         updateHit(currentHit);
00887       } else {
00888         posGlobal = preStepPoint->GetPosition();
00889         if (!checkHit()) currentHit = createNewHit();
00890       }
00891     }
00892   }
00893 }
00894 
00895 void HCalSD::getHitPMT (G4Step * aStep) {
00896 
00897   preStepPoint = aStep->GetPreStepPoint();
00898   theTrack     = aStep->GetTrack();
00899   double edep  = showerPMT->getHits(aStep);
00900 
00901   if (edep >= 0) {
00902     double etrack    = preStepPoint->GetKineticEnergy();
00903     int    primaryID = 0;
00904     if (etrack >= energyCut) {
00905       primaryID    = theTrack->GetTrackID();
00906     } else {
00907       primaryID    = theTrack->GetParentID();
00908       if (primaryID == 0) primaryID = theTrack->GetTrackID();
00909     }
00910     // Reset entry point for new primary
00911     posGlobal = preStepPoint->GetPosition();
00912     resetForNewPrimary(posGlobal, etrack);
00913 
00914     //
00915     int    det      = static_cast<int>(HcalForward);
00916     G4ThreeVector hitPoint = preStepPoint->GetPosition();   
00917     double rr       = (hitPoint.x()*hitPoint.x() + hitPoint.y()*hitPoint.y());
00918     double phi      = (rr == 0. ? 0. :atan2(hitPoint.y(),hitPoint.x()));
00919     double etaR     = showerPMT->getRadius();
00920     int depth       = 1;
00921     if (etaR < 0) {
00922       depth         = 2;
00923       etaR          =-etaR;
00924     }
00925     if (hitPoint.z() < 0) etaR =-etaR;
00926 #ifdef DebugLog
00927     edm::LogInfo("HcalSim") << "HCalSD::Hit for Detector " << det << " etaR "
00928                             << etaR << " phi " << phi/deg << " depth " <<depth;
00929 #endif
00930     double time = (aStep->GetPostStepPoint()->GetGlobalTime());
00931     uint32_t unitID = 0;
00932     if (numberingFromDDD) {
00933       HcalNumberingFromDDD::HcalID tmp = numberingFromDDD->unitID(det,etaR,phi,
00934                                                                   depth,1);
00935       if (numberingScheme) unitID = numberingScheme->getUnitID(tmp);
00936     }
00937     currentID.setID(unitID, time, primaryID, 1);
00938 
00939     edepositHAD = aStep->GetTotalEnergyDeposit();
00940     edepositEM  =-edepositHAD + (edep*GeV);
00941 #ifdef plotDebug
00942     plotProfile(aStep, hitPoint, edep*GeV, time, depth);
00943 #endif
00944 #ifdef DebugLog
00945     double beta = preStepPoint->GetBeta();
00946     LogDebug("HcalSim") << "HCalSD::getHitPMT 1 hit for " << GetName() 
00947                         << " of " << primaryID << " with " 
00948                         << theTrack->GetDefinition()->GetParticleName()
00949                         << " of " << preStepPoint->GetKineticEnergy()/GeV 
00950                         << " GeV with velocity " << beta << " UnitID "
00951                         << std::hex << unitID << std::dec;
00952 #endif
00953     // check if it is in the same unit and timeslice as the previous one
00954     if      (currentID == previousID) {
00955       updateHit(currentHit);
00956     } else {
00957       if (!checkHit()) currentHit = createNewHit();
00958     }
00959   }
00960 }
00961 
00962 void HCalSD::getHitFibreBundle (G4Step* aStep, bool type) {
00963   preStepPoint = aStep->GetPreStepPoint();
00964   theTrack     = aStep->GetTrack();
00965   double edep  = showerBundle->getHits(aStep, type);
00966 
00967   if (edep >= 0) {
00968     double etrack    = preStepPoint->GetKineticEnergy();
00969     int    primaryID = 0;
00970     if (etrack >= energyCut) {
00971       primaryID    = theTrack->GetTrackID();
00972     } else {
00973       primaryID    = theTrack->GetParentID();
00974       if (primaryID == 0) primaryID = theTrack->GetTrackID();
00975     }
00976     // Reset entry point for new primary
00977     posGlobal = preStepPoint->GetPosition();
00978     resetForNewPrimary(posGlobal, etrack);
00979 
00980     //
00981     int    det      = static_cast<int>(HcalForward);
00982     G4ThreeVector hitPoint = preStepPoint->GetPosition();   
00983     double rr       = (hitPoint.x()*hitPoint.x() + hitPoint.y()*hitPoint.y());
00984     double phi      = (rr == 0. ? 0. :atan2(hitPoint.y(),hitPoint.x()));
00985     double etaR     = showerBundle->getRadius();
00986     int depth       = 1;
00987     if (etaR < 0) {
00988       depth         = 2;
00989       etaR          =-etaR;
00990     }
00991     if (hitPoint.z() < 0) etaR =-etaR;
00992 #ifdef DebugLog
00993     edm::LogInfo("HcalSim") << "HCalSD::Hit for Detector " << det << " etaR "
00994                             << etaR << " phi " << phi/deg << " depth " <<depth;
00995 #endif
00996     double time = (aStep->GetPostStepPoint()->GetGlobalTime());
00997     uint32_t unitID = 0;
00998     if (numberingFromDDD) {
00999       HcalNumberingFromDDD::HcalID tmp = numberingFromDDD->unitID(det,etaR,phi,depth,1);
01000       if (numberingScheme) unitID = numberingScheme->getUnitID(tmp);
01001     }
01002     if (type) currentID.setID(unitID, time, primaryID, 3);
01003     else      currentID.setID(unitID, time, primaryID, 2);
01004 
01005     edepositHAD = aStep->GetTotalEnergyDeposit();
01006     edepositEM  =-edepositHAD + (edep*GeV);
01007 #ifdef plotDebug
01008     plotProfile(aStep, hitPoint, edep*GeV, time, depth);
01009 #endif
01010 #ifdef DebugLog
01011     double beta = preStepPoint->GetBeta();
01012     LogDebug("HcalSim") << "HCalSD::getHitFibreBundle 1 hit for " << GetName() 
01013                         << " of " << primaryID << " with " 
01014                         << theTrack->GetDefinition()->GetParticleName()
01015                         << " of " << preStepPoint->GetKineticEnergy()/GeV 
01016                         << " GeV with velocity " << beta << " UnitID "
01017                         << std::hex << unitID << std::dec;
01018 #endif
01019     // check if it is in the same unit and timeslice as the previous one
01020     if (currentID == previousID) updateHit(currentHit);
01021     else if (!checkHit()) currentHit = createNewHit();
01022   } // non-zero energy deposit
01023 }
01024 
01025 int HCalSD::setTrackID (G4Step* aStep) {
01026   theTrack     = aStep->GetTrack();
01027 
01028   double etrack = preStepPoint->GetKineticEnergy();
01029   TrackInformation * trkInfo = (TrackInformation *)(theTrack->GetUserInformation());
01030   int      primaryID = trkInfo->getIDonCaloSurface();
01031   if (primaryID == 0) {
01032 #ifdef DebugLog
01033     edm::LogInfo("HcalSim") << "HCalSD: Problem with primaryID **** set by "
01034        << "force to TkID **** " <<theTrack->GetTrackID();
01035 #endif
01036     primaryID = theTrack->GetTrackID();
01037   }
01038 
01039   if (primaryID != previousID.trackID())
01040     resetForNewPrimary(preStepPoint->GetPosition(), etrack);
01041 
01042   return primaryID;
01043 }
01044 
01045 void HCalSD::readWeightFromFile(std::string fName) {
01046 
01047   std::ifstream infile;
01048   int entry=0;
01049   infile.open(fName.c_str(), std::ios::in);
01050   if (infile) {
01051     int    det, zside, etaR, phi, lay;
01052     double wt;
01053     while (infile >> det >> zside >> etaR >> phi >> lay >> wt) {
01054       uint32_t id = HcalTestNumbering::packHcalIndex(det,zside,1,etaR,phi,lay);
01055       layerWeights.insert(std::pair<uint32_t,double>(id,wt));
01056       ++entry;
01057 #ifdef DebugLog
01058       edm::LogInfo("HcalSim") << "HCalSD::readWeightFromFile:Entry " << entry
01059                               << " ID " << std::hex << id << std::dec << " ("
01060                               << det << "/" << zside << "/1/" << etaR << "/"
01061                               << phi << "/" << lay << ") Weight " << wt;
01062 #endif
01063     }
01064     infile.close();
01065   }
01066   edm::LogInfo("HcalSim") << "HCalSD::readWeightFromFile: reads " << entry
01067                           << " weights from " << fName;
01068   if (entry <= 0) useLayerWt = false;
01069 }
01070 
01071 double HCalSD::layerWeight(int det, G4ThreeVector pos, int depth, int lay) { 
01072 
01073   double wt = 1.;
01074   if (numberingFromDDD) {
01075     //get the ID's as eta, phi, depth, ... indices
01076     HcalNumberingFromDDD::HcalID tmp = numberingFromDDD->unitID(det, pos, 
01077                                                                 depth, lay);
01078     uint32_t id = HcalTestNumbering::packHcalIndex(tmp.subdet, tmp.zside, 1,
01079                                                    tmp.etaR, tmp.phis,tmp.lay);
01080     std::map<uint32_t,double>::const_iterator ite = layerWeights.find(id);
01081     if (ite != layerWeights.end()) wt = ite->second;
01082 #ifdef DebugLog
01083     edm::LogInfo("HcalSim") << "HCalSD::layerWeight: ID " << std::hex << id 
01084                             << std::dec << " (" << tmp.subdet << "/"  
01085                             << tmp.zside << "/1/" << tmp.etaR << "/" 
01086                             << tmp.phis << "/"  << tmp.lay << ") Weight " <<wt;
01087 #endif
01088   }
01089   return wt;
01090 }
01091 
01092 void HCalSD::plotProfile(G4Step* aStep, G4ThreeVector global, double edep,
01093                          double time, int id) { 
01094 
01095   const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
01096   static G4String modName[8] = {"HEModule", "HVQF" , "HBModule", "MBAT",
01097                                 "MBBT"    , "MBBTC", "MBBT_R1P", "MBBT_R1M"};
01098   G4ThreeVector local;
01099   bool found=false;
01100   double depth=-2000;
01101   int idx = 4;
01102   for (int n=0; n<touch->GetHistoryDepth(); ++n) {
01103     G4String name = touch->GetVolume(n)->GetName();
01104 #ifdef DebugLog
01105     LogDebug("HcalSim") << "plotProfile Depth " << n << " Name " << name;
01106 #endif
01107     for (unsigned int ii=0; ii<8; ++ii) {
01108       if (name == modName[ii]) {
01109         found = true;
01110         int dn = touch->GetHistoryDepth() - n;
01111         local = touch->GetHistory()->GetTransform(dn).TransformPoint(global);
01112         if      (ii == 0) {depth = local.z() - 4006.5; idx = 1;}
01113         else if (ii == 1) {depth = local.z() + 825.0;  idx = 3;}
01114         else if (ii == 2) {depth = local.x() - 1775.;  idx = 0;}
01115         else              {depth = local.y() + 15.;    idx = 2;}
01116         break;
01117       }
01118     }
01119     if (found) break;
01120   }
01121   if (!found) depth = std::abs(global.z()) - 11500;
01122 #ifdef DebugLog
01123   LogDebug("HcalSim") << "plotProfile Found " << found << " Global " << global
01124                       << " Local " << local << " depth " << depth << " ID " << id
01125                       << " EDEP " << edep << " Time " << time;
01126 #endif
01127   if (hit_[idx]  != 0) hit_[idx]->Fill(edep);
01128   if (time_[idx] != 0) time_[idx]->Fill(time,edep);
01129   if (dist_[idx] != 0) dist_[idx]->Fill(depth,edep);
01130   int jd = 2*idx + id - 7;
01131   if (jd >= 0 && jd < 4) {
01132     jd += 5;
01133     if (hit_[jd]  != 0) hit_[jd]->Fill(edep);
01134     if (time_[jd] != 0) time_[jd]->Fill(time,edep);
01135     if (dist_[jd] != 0) dist_[jd]->Fill(depth,edep);
01136   }
01137 }
01138 
01139 void HCalSD::plotHF(G4ThreeVector& hitPoint, bool emType) {
01140   double zv  = std::abs(hitPoint.z()) - gpar[4];
01141   if (emType) {
01142     if (hzvem  != 0) hzvem->Fill(zv);
01143   } else {
01144     if (hzvhad != 0) hzvhad->Fill(zv);
01145   }
01146 }