00001
00002
00003
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
00033
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
00045
00046
00047
00048
00049
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
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
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
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
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
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
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
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
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);
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())) {
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
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
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
00609 HcalNumberingFromDDD::HcalID tmp = numberingFromDDD->unitID(det, pos, depth, lay);
00610
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
00744
00745
00746
00747
00748
00749
00750
00751
00752
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
00786 if (currentID == previousID) {
00787 updateHit(currentHit);
00788 } else {
00789 if (!checkHit()) currentHit = createNewHit();
00790 }
00791 }
00792 }
00793
00794
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) {
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
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
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
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
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
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
01020 if (currentID == previousID) updateHit(currentHit);
01021 else if (!checkHit()) currentHit = createNewHit();
01022 }
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
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 }