CMS 3D CMS Logo

HCalSD.cc
Go to the documentation of this file.
1 // File: HCalSD.cc
3 // Description: Sensitive Detector class for calorimeters
5 
17 
26 
27 #include "G4LogicalVolumeStore.hh"
28 #include "G4LogicalVolume.hh"
29 #include "G4Step.hh"
30 #include "G4Track.hh"
31 #include "G4ParticleTable.hh"
32 #include "G4VProcess.hh"
33 
34 #include "G4SystemOfUnits.hh"
35 #include "G4PhysicalConstants.hh"
36 
37 #include <iostream>
38 #include <fstream>
39 #include <iomanip>
40 
41 //#define EDM_ML_DEBUG
42 //#define plotDebug
43 
44 HCalSD::HCalSD(G4String name, const DDCompactView & cpv,
45  const SensitiveDetectorCatalog & clg,
46  edm::ParameterSet const & p, const SimTrackManager* manager) :
47  CaloSD(name, cpv, clg, p, manager,
48  (float)(p.getParameter<edm::ParameterSet>("HCalSD").getParameter<double>("TimeSliceUnit")),
49  p.getParameter<edm::ParameterSet>("HCalSD").getParameter<bool>("IgnoreTrackID")),
50  hcalConstants(0), numberingFromDDD(0), numberingScheme(0), showerLibrary(0),
51  hfshower(0), showerParam(0), showerPMT(0), showerBundle(0), m_HBDarkening(nullptr), m_HEDarkening(nullptr),
52  m_HFDarkening(nullptr), hcalTestNS_(0), depth_(1) {
53 
54  //static SimpleConfigurable<double> bk1(0.013, "HCalSD:BirkC1");
55  //static SimpleConfigurable<double> bk2(0.0568,"HCalSD:BirkC2");
56  //static SimpleConfigurable<double> bk3(1.75, "HCalSD:BirkC3");
57  // Values from NIM 80 (1970) 239-244: as implemented in Geant3
58 
60  useBirk = m_HC.getParameter<bool>("UseBirkLaw");
61  birk1 = m_HC.getParameter<double>("BirkC1")*(g/(MeV*cm2));
62  birk2 = m_HC.getParameter<double>("BirkC2");
63  birk3 = m_HC.getParameter<double>("BirkC3");
64  useShowerLibrary = m_HC.getParameter<bool>("UseShowerLibrary");
65  useParam = m_HC.getParameter<bool>("UseParametrize");
66  testNumber = m_HC.getParameter<bool>("TestNumberingScheme");
67  neutralDensity = m_HC.getParameter<bool>("doNeutralDensityFilter");
68  usePMTHit = m_HC.getParameter<bool>("UsePMTHits");
69  betaThr = m_HC.getParameter<double>("BetaThreshold");
70  eminHitHB = m_HC.getParameter<double>("EminHitHB")*MeV;
71  eminHitHE = m_HC.getParameter<double>("EminHitHE")*MeV;
72  eminHitHO = m_HC.getParameter<double>("EminHitHO")*MeV;
73  eminHitHF = m_HC.getParameter<double>("EminHitHF")*MeV;
74  useFibreBundle = m_HC.getParameter<bool>("UseFibreBundleHits");
75  deliveredLumi = m_HC.getParameter<double>("DelivLuminosity");
76  agingFlagHB = m_HC.getParameter<bool>("HBDarkening");
77  agingFlagHE = m_HC.getParameter<bool>("HEDarkening");
78  bool agingFlagHF = m_HC.getParameter<bool>("HFDarkening");
79  useHF = m_HC.getUntrackedParameter<bool>("UseHF",true);
80  bool forTBH2 = m_HC.getUntrackedParameter<bool>("ForTBH2",false);
81  useLayerWt = m_HC.getUntrackedParameter<bool>("UseLayerWt",false);
82  std::string file = m_HC.getUntrackedParameter<std::string>("WtFile","None");
83  testNS_ = m_HC.getUntrackedParameter<bool>("TestNS",false);
84  edm::ParameterSet m_HF = p.getParameter<edm::ParameterSet>("HFShower");
85  applyFidCut = m_HF.getParameter<bool>("ApplyFiducialCut");
86 
87 #ifdef EDM_ML_DEBUG
88  LogDebug("HcalSim") << "***************************************************"
89  << "\n"
90  << "* *"
91  << "\n"
92  << "* Constructing a HCalSD with name " << name << "\n"
93  << "* *"
94  << "\n"
95  << "***************************************************";
96 #endif
97  edm::LogInfo("HcalSim") << "HCalSD:: Use of HF code is set to " << useHF
98  << "\nUse of shower parametrization set to "
99  << useParam << "\nUse of shower library is set to "
100  << useShowerLibrary << "\nUse PMT Hit is set to "
101  << usePMTHit << " with beta Threshold "<< betaThr
102  << "\nUSe of FibreBundle Hit set to "<<useFibreBundle
103  << "\n Use of Birks law is set to "
104  << useBirk << " with three constants kB = "
105  << birk1 << ", C1 = " << birk2 << ", C2 = " << birk3;
106  edm::LogInfo("HcalSim") << "HCalSD:: Suppression Flag " << suppressHeavy
107  << " protons below " << kmaxProton << " MeV,"
108  << " neutrons below " << kmaxNeutron << " MeV and"
109  << " ions below " << kmaxIon << " MeV\n"
110  << " Threshold for storing hits in HB: "
111  << eminHitHB << " HE: " << eminHitHE << " HO: "
112  << eminHitHO << " HF: " << eminHitHF << "\n"
113  << "Delivered luminosity for Darkening "
114  << deliveredLumi << " Flag (HE) " << agingFlagHE
115  << " Flag (HB) " << agingFlagHB
116  << " Flag (HF) " << agingFlagHF << "\n"
117  << "Application of Fiducial Cut " << applyFidCut
118  << "Flag for test number|neutral density filter "
119  << testNumber << " " << neutralDensity;
120 
121  HcalNumberingScheme* scheme;
122  if (testNumber || forTBH2)
123  scheme = dynamic_cast<HcalNumberingScheme*>(new HcalTestNumberingScheme(forTBH2));
124  else
125  scheme = new HcalNumberingScheme();
126  setNumberingScheme(scheme);
127 
128  const G4LogicalVolumeStore * lvs = G4LogicalVolumeStore::GetInstance();
129  std::vector<G4LogicalVolume *>::const_iterator lvcite;
130  G4LogicalVolume* lv;
131  std::string attribute, value;
132  if (useHF) {
133  if (useParam) {
134  showerParam = new HFShowerParam(name, cpv, p);
135  } else {
136  if (useShowerLibrary) showerLibrary = new HFShowerLibrary(name, cpv, p);
137  hfshower = new HFShower(name, cpv, p, 0);
138  }
139 
140  // HF volume names
141  attribute = "Volume";
142  value = "HF";
143  DDSpecificsMatchesValueFilter filter0{DDValue(attribute,value,0)};
144  DDFilteredView fv0(cpv,filter0);
145  hfNames = getNames(fv0);
146  fv0.firstChild();
147  DDsvalues_type sv0(fv0.mergedSpecifics());
148  std::vector<double> temp = getDDDArray("Levels",sv0);
149  edm::LogInfo("HcalSim") << "HCalSD: Names to be tested for " << attribute
150  << " = " << value << " has " << hfNames.size()
151  << " elements";
152  for (unsigned int i=0; i < hfNames.size(); ++i) {
153  G4String namv = hfNames[i];
154  lv = 0;
155  for(lvcite=lvs->begin(); lvcite!=lvs->end(); lvcite++)
156  if((*lvcite)->GetName()==namv) {
157  lv = (*lvcite);
158  break;
159  }
160  hfLV.push_back(lv);
161  int level = static_cast<int>(temp[i]);
162  hfLevels.push_back(level);
163  edm::LogInfo("HcalSim") << "HCalSD: HF[" << i << "] = " << hfNames[i]
164  << " LV " << hfLV[i] << " at level "
165  << hfLevels[i];
166  }
167 
168  // HF Fibre volume names
169  value = "HFFibre";
170  DDSpecificsMatchesValueFilter filter1{DDValue(attribute,value,0)};
171  DDFilteredView fv1(cpv,filter1);
172  fibreNames = getNames(fv1);
173  edm::LogInfo("HcalSim") << "HCalSD: Names to be tested for " << attribute
174  << " = " << value << ":";
175  for (unsigned int i=0; i<fibreNames.size(); ++i) {
176  G4String namv = fibreNames[i];
177  lv = 0;
178  for (lvcite = lvs->begin(); lvcite != lvs->end(); ++lvcite) {
179  if ((*lvcite)->GetName() == namv) {
180  lv = (*lvcite);
181  break;
182  }
183  }
184  fibreLV.push_back(lv);
185  edm::LogInfo("HcalSim") << "HCalSD: (" << i << ") " << fibreNames[i]
186  << " LV " << fibreLV[i];
187  }
188 
189  // HF PMT volume names
190  value = "HFPMT";
191  DDSpecificsMatchesValueFilter filter3{DDValue(attribute,value,0)};
192  DDFilteredView fv3(cpv,filter3);
193  std::vector<G4String> pmtNames = getNames(fv3);
194  edm::LogInfo("HcalSim") << "HCalSD: Names to be tested for " << attribute
195  << " = " << value << " have " << pmtNames.size()
196  << " entries";
197  for (unsigned int i=0; i<pmtNames.size(); ++i) {
198  G4String namv = pmtNames[i];
199  lv = 0;
200  for (lvcite = lvs->begin(); lvcite != lvs->end(); ++lvcite)
201  if ((*lvcite)->GetName() == namv) {
202  lv = (*lvcite);
203  break;
204  }
205  pmtLV.push_back(lv);
206  edm::LogInfo("HcalSim") << "HCalSD: (" << i << ") " << pmtNames[i]
207  << " LV " << pmtLV[i];
208  }
209  if (pmtNames.size() > 0) showerPMT = new HFShowerPMT (name, cpv, p);
210 
211  // HF Fibre bundles
212  value = "HFFibreBundleStraight";
213  DDSpecificsMatchesValueFilter filter4{DDValue(attribute,value,0)};
214  DDFilteredView fv4(cpv,filter4);
215  std::vector<G4String> fibreNames = getNames(fv4);
216  edm::LogInfo("HcalSim") << "HCalSD: Names to be tested for " << attribute
217  << " = " << value << " have " << fibreNames.size()
218  << " entries";
219  for (unsigned int i=0; i<fibreNames.size(); ++i) {
220  G4String namv = fibreNames[i];
221  lv = 0;
222  for (lvcite = lvs->begin(); lvcite != lvs->end(); lvcite++)
223  if ((*lvcite)->GetName() == namv) {
224  lv = (*lvcite);
225  break;
226  }
227  fibre1LV.push_back(lv);
228  edm::LogInfo("HcalSim") << "HCalSD: (" << i << ") " << fibreNames[i]
229  << " LV " << fibre1LV[i];
230  }
231 
232  // Geometry parameters for HF
233  value = "HFFibreBundleConical";
234  DDSpecificsMatchesValueFilter filter5{DDValue(attribute,value,0)};
235  DDFilteredView fv5(cpv,filter5);
236  fibreNames = getNames(fv5);
237  edm::LogInfo("HcalSim") << "HCalSD: Names to be tested for " << attribute
238  << " = " << value << " have " << fibreNames.size()
239  << " entries";
240  for (unsigned int i=0; i<fibreNames.size(); ++i) {
241  G4String namv = fibreNames[i];
242  lv = 0;
243  for (lvcite = lvs->begin(); lvcite != lvs->end(); ++lvcite)
244  if ((*lvcite)->GetName() == namv) {
245  lv = (*lvcite);
246  break;
247  }
248  fibre2LV.push_back(lv);
249  edm::LogInfo("HcalSim") << "HCalSD: (" << i << ") " << fibreNames[i]
250  << " LV " << fibre2LV[i];
251  }
252  if (fibre1LV.size() > 0 || fibre2LV.size() > 0)
253  showerBundle = new HFShowerFibreBundle (name, cpv, p);
254  }
255 
256  //Material list for HB/HE/HO sensitive detectors
257  const G4MaterialTable * matTab = G4Material::GetMaterialTable();
258  std::vector<G4Material*>::const_iterator matite;
259  attribute = "OnlyForHcalSimNumbering";
260  DDSpecificsHasNamedValueFilter filter2{attribute};
261  DDFilteredView fv2(cpv,filter2);
262  bool dodet = fv2.firstChild();
264 
265  while (dodet) {
266  const DDLogicalPart & log = fv2.logicalPart();
267  G4String namx = log.name().name();
268  if (!isItHF(namx) && !isItFibre(namx)) {
269  bool notIn = true;
270  for (unsigned int i=0; i<matNames.size(); ++i) {
271  if (!strcmp(matNames[i].c_str(),log.material().name().name().c_str())){
272  notIn = false;
273  break;
274  }
275  }
276  if (notIn) {
277  namx = log.material().name().name();
278  matNames.push_back(namx);
279  G4Material* mat = nullptr;
280  for (matite = matTab->begin(); matite != matTab->end(); ++matite) {
281  if ((*matite)->GetName() == namx) {
282  mat = (*matite);
283  break;
284  }
285  }
286  materials.push_back(mat);
287  }
288  }
289  dodet = fv2.next();
290  }
291 
292  edm::LogInfo("HcalSim") << "HCalSD: Material names for " << attribute
293  << " = " << name << ":";
294  for (unsigned int i=0; i<matNames.size(); ++i)
295  edm::LogInfo("HcalSim") << "HCalSD: (" << i << ") " << matNames[i]
296  << " pointer " << materials[i];
297 
298  mumPDG = mupPDG = 0;
299 
300  if (useLayerWt) readWeightFromFile(file);
301 
302  for (int i=0; i<9; ++i) hit_[i] = time_[i]= dist_[i] = 0;
303  hzvem = hzvhad = 0;
304 
305  if (agingFlagHF) m_HFDarkening.reset(new HFDarkening(m_HC.getParameter<edm::ParameterSet>("HFDarkeningParameterBlock")));
306 #ifdef plotDebug
308 
309  if ( tfile.isAvailable() ) {
310  static const char * const labels[] = {"HB", "HE", "HO", "HF Absorber", "HF PMT",
311  "HF Absorber Long", "HF Absorber Short",
312  "HF PMT Long", "HF PMT Short"};
313  TFileDirectory hcDir = tfile->mkdir("ProfileFromHCalSD");
314  char name[20], title[60];
315  for (int i=0; i<9; ++i) {
316  sprintf (title, "Hit energy in %s", labels[i]);
317  sprintf (name, "HCalSDHit%d", i);
318  hit_[i] = hcDir.make<TH1F>(name, title, 2000, 0., 2000.);
319  sprintf (title, "Energy (MeV)");
320  hit_[i]->GetXaxis()->SetTitle(title);
321  hit_[i]->GetYaxis()->SetTitle("Hits");
322  sprintf (title, "Time of the hit in %s", labels[i]);
323  sprintf (name, "HCalSDTime%d", i);
324  time_[i] = hcDir.make<TH1F>(name, title, 2000, 0., 2000.);
325  sprintf (title, "Time (ns)");
326  time_[i]->GetXaxis()->SetTitle(title);
327  time_[i]->GetYaxis()->SetTitle("Hits");
328  sprintf (title, "Longitudinal profile in %s", labels[i]);
329  sprintf (name, "HCalSDDist%d", i);
330  dist_[i] = hcDir.make<TH1F>(name, title, 2000, 0., 2000.);
331  sprintf (title, "Distance (mm)");
332  dist_[i]->GetXaxis()->SetTitle(title);
333  dist_[i]->GetYaxis()->SetTitle("Hits");
334  }
335  if (useHF && (!useParam)) {
336  hzvem = hcDir.make<TH1F>("hzvem", "Longitudinal Profile (EM Part)",330,0.0,1650.0);
337  hzvem->GetXaxis()->SetTitle("Longitudinal Profile (EM Part)");
338  hzvhad = hcDir.make<TH1F>("hzvhad","Longitudinal Profile (Had Part)",330,0.0,1650.0);
339  hzvhad->GetXaxis()->SetTitle("Longitudinal Profile (Hadronic Part)");
340  }
341  }
342 #endif
343 }
344 
346 
348  if (numberingScheme) delete numberingScheme;
349  if (showerLibrary) delete showerLibrary;
350  if (hfshower) delete hfshower;
351  if (showerParam) delete showerParam;
352  if (showerPMT) delete showerPMT;
353  if (showerBundle) delete showerBundle;
354  if (hcalTestNS_) delete hcalTestNS_;
355 }
356 
357 bool HCalSD::ProcessHits(G4Step * aStep, G4TouchableHistory * ) {
358 
359  NaNTrap( aStep ) ;
360 
361  if (aStep == NULL) {
362  return true;
363  } else {
364  depth_ = (aStep->GetPreStepPoint()->GetTouchable()->GetReplicaNumber(0))%10;
365  G4LogicalVolume* lv =
366  aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume();
367  G4String nameVolume = lv->GetName();
368  if (isItHF(aStep)) {
369  G4int parCode = aStep->GetTrack()->GetDefinition()->GetPDGEncoding();
370  double weight(1.0);
371  if (m_HFDarkening) {
372  G4ThreeVector hitPoint = aStep->GetPreStepPoint()->GetPosition();
373  double r = hitPoint.perp()/CLHEP::cm;
374  double z = std::abs(hitPoint.z())/CLHEP::cm;
375  double dose_acquired = 0.;
377  unsigned int hfZLayer = (int)((z - HFDarkening::lowZLimit)/5);
378  if (hfZLayer >= HFDarkening::upperZLimit) hfZLayer = (HFDarkening::upperZLimit-1);
379  float normalized_lumi = m_HFDarkening->int_lumi(deliveredLumi);
380  for (int i = hfZLayer; i != HFDarkening::numberOfZLayers; ++i) {
381  dose_acquired = m_HFDarkening->dose(i,r);
382  weight *= m_HFDarkening->degradation(normalized_lumi*dose_acquired);
383  }
384  }
385 #ifdef EDM_ML_DEBUG
386  LogDebug("HcalSim") << "HCalSD: HFLumiDarkening at r = " << r
387  << ", z = " << z << " Dose " << dose_acquired
388  << " weight " << weight;
389 #endif
390  }
391  if (useParam) {
392 #ifdef EDM_ML_DEBUG
393  LogDebug("HcalSim") << "HCalSD: " << getNumberOfHits()
394  << " hits from parametrization in " << nameVolume
395  << " for Track " << aStep->GetTrack()->GetTrackID()
396  <<" (" << aStep->GetTrack()->GetDefinition()->GetParticleName()
397  <<")";
398 #endif
399  getFromParam(aStep, weight);
400 #ifdef EDM_ML_DEBUG
401  LogDebug("HcalSim") << "HCalSD: " << getNumberOfHits()
402  << " hits afterParamS*";
403 #endif
404  } else {
405  bool notaMuon = true;
406  if (parCode == mupPDG || parCode == mumPDG ) notaMuon = false;
407  if (useShowerLibrary && notaMuon) {
408 #ifdef EDM_ML_DEBUG
409  LogDebug("HcalSim") << "HCalSD: Starts shower library from "
410  << nameVolume << " for Track "
411  << aStep->GetTrack()->GetTrackID() << " ("
412  << aStep->GetTrack()->GetDefinition()->GetParticleName() << ")";
413 #endif
414  getFromLibrary(aStep, weight);
415  } else if (isItFibre(lv)) {
416 #ifdef EDM_ML_DEBUG
417  LogDebug("HcalSim") << "HCalSD: Hit at Fibre in " << nameVolume
418  << " for Track "
419  << aStep->GetTrack()->GetTrackID() <<" ("
420  << aStep->GetTrack()->GetDefinition()->GetParticleName() << ")";
421 #endif
422  hitForFibre(aStep, weight);
423  }
424  }
425  } else if (isItPMT(lv)) {
426 #ifdef EDM_ML_DEBUG
427  LogDebug("HcalSim") << "HCalSD: Hit from PMT parametrization from "
428  << nameVolume << " for Track "
429  << aStep->GetTrack()->GetTrackID() << " ("
430  << aStep->GetTrack()->GetDefinition()->GetParticleName() << ")";
431 #endif
432  if (usePMTHit && showerPMT) getHitPMT(aStep);
433  } else if (isItStraightBundle(lv) || isItConicalBundle(lv)) {
434 #ifdef EDM_ML_DEBUG
435  LogDebug("HcalSim") << "HCalSD: Hit from FibreBundle from "
436  << nameVolume << " for Track "
437  << aStep->GetTrack()->GetTrackID() << " ("
438  << aStep->GetTrack()->GetDefinition()->GetParticleName() << ")";
439 #endif
442  } else {
443 #ifdef EDM_ML_DEBUG
444  LogDebug("HcalSim") << "HCalSD: Hit from standard path from "
445  << nameVolume << " for Track "
446  << aStep->GetTrack()->GetTrackID() << " ("
447  << aStep->GetTrack()->GetDefinition()->GetParticleName() << ")";
448 #endif
449  if (getStepInfo(aStep)) {
450 #ifdef plotDebug
451  if (edepositEM+edepositHAD > 0)
452  plotProfile(aStep, aStep->GetPreStepPoint()->GetPosition(),
453  edepositEM+edepositHAD,aStep->GetPostStepPoint()->GetGlobalTime(),0);
454 #endif
455  if (hitExists() == false && edepositEM+edepositHAD>0.) currentHit = createNewHit();
456  }
457  }
458  return true;
459  }
460 }
461 
462 double HCalSD::getEnergyDeposit(G4Step* aStep) {
463  double destep = aStep->GetTotalEnergyDeposit();
464  double weight = 1;
465  G4Track* theTrack = aStep->GetTrack();
466 
467  const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
468  uint32_t detid = setDetUnitId(aStep);
469  int det(0), ieta(0), phi(0), z(0), lay, depth(-1);
470  if (testNumber) {
471  HcalTestNumbering::unpackHcalIndex(detid,det,z,depth,ieta,phi,lay);
472  if (z==0) z = -1;
473  } else {
474  HcalDetId hcid(detid);
475  det = hcid.subdetId();
476  ieta = hcid.ietaAbs();
477  phi = hcid.iphi();
478  z = hcid.zside();
479  }
480  lay = (touch->GetReplicaNumber(0)/10)%100 + 1;
481 #ifdef EDM_ML_DEBUG
482  edm::LogInfo("HcalSim") << "HCalSD: det: " << det << " ieta: "<< ieta
483  << " iphi: " << phi << " zside " << z << " lay: "
484  << lay-2;
485 #endif
486  if (depth_==0 && (det==1 || det==2) && ((!testNumber) || neutralDensity))
487  weight = hcalConstants->getLayer0Wt(det,phi,z);
488  if (useLayerWt) {
489  G4ThreeVector hitPoint = aStep->GetPreStepPoint()->GetPosition();
490  weight = layerWeight(det+2, hitPoint, depth_, lay);
491  }
492 
493  if (m_HBDarkening && det == 1) {
494  float dweight = m_HBDarkening->degradation(deliveredLumi,ieta,lay);
495  weight *= dweight;
496 #ifdef EDM_ML_DEBUG
497  edm::LogInfo("HcalSim") << "HCalSD: >>> HB Lumi: " << deliveredLumi
498  << " coefficient = " << dweight;
499 #endif
500  }
501 
502  if (m_HEDarkening && det == 2) {
503  float dweight = m_HEDarkening->degradation(deliveredLumi,ieta,lay);
504  weight *= dweight;
505 #ifdef EDM_ML_DEBUG
506  edm::LogInfo("HcalSim") << "HCalSD: >>> HE Lumi: " << deliveredLumi
507  << " coefficient = " << dweight;
508 #endif
509  }
510 
511  if (suppressHeavy) {
512  TrackInformation * trkInfo = (TrackInformation *)(theTrack->GetUserInformation());
513  if (trkInfo) {
514  int pdg = theTrack->GetDefinition()->GetPDGEncoding();
515  if (!(trkInfo->isPrimary())) { // Only secondary particles
516  double ke = theTrack->GetKineticEnergy()/MeV;
517  if ( pdg/1000000000 == 1 && (pdg/10000)%100 > 0 &&
518  (pdg/10)%100 > 0 && ke <kmaxIon ) weight = 0;
519  if ((pdg == 2212) && (ke < kmaxProton)) weight = 0;
520  if ((pdg == 2112) && (ke < kmaxNeutron)) weight = 0;
521 #ifdef EDM_ML_DEBUG
522  if (weight == 0)
523  edm::LogInfo("HcalSim") << "HCalSD:Ignore Track "
524  << theTrack->GetTrackID() << " Type "
525  << theTrack->GetDefinition()->GetParticleName()
526  << " Kinetic Energy " << ke << " MeV";
527 #endif
528  }
529  }
530  }
531 #ifdef EDM_ML_DEBUG
532  double weight0 = weight;
533 #endif
534  if (useBirk) {
535  G4Material* mat = aStep->GetPreStepPoint()->GetMaterial();
536  if (isItScintillator(mat)) weight *= getAttenuation(aStep, birk1, birk2, birk3);
537  }
538  double wt1 = getResponseWt(theTrack);
539  double wt2 = theTrack->GetWeight();
540 #ifdef EDM_ML_DEBUG
541  edm::LogInfo("HcalSim") << "HCalSD: Detector " << det+2 << " Depth " << depth_
542  << " weight " << weight0 << " " << weight << " " << wt1
543  << " " << wt2;
544 #endif
545  double edep = weight*wt1*destep;
546  if (wt2 > 0.0) { edep *= wt2; }
547  return edep;
548 }
549 
550 uint32_t HCalSD::setDetUnitId(G4Step * aStep) {
551 
552  G4StepPoint* preStepPoint = aStep->GetPreStepPoint();
553  const G4VTouchable* touch = preStepPoint->GetTouchable();
554  G4ThreeVector hitPoint = preStepPoint->GetPosition();
555 
556  int depth = (touch->GetReplicaNumber(0))%10 + 1;
557  int lay = (touch->GetReplicaNumber(0)/10)%100 + 1;
558  int det = (touch->GetReplicaNumber(1))/1000;
559 
560  return setDetUnitId (det, hitPoint, depth, lay);
561 }
562 
564  if (scheme != 0) {
565  edm::LogInfo("HcalSim") << "HCalSD: updates numbering scheme for " << GetName();
566  if (numberingScheme) delete numberingScheme;
567  numberingScheme = scheme;
568  }
569 }
570 
571 void HCalSD::update(const BeginOfJob * job) {
572 
573  const edm::EventSetup* es = (*job)();
575  es->get<HcalSimNumberingRecord>().get(hdc);
576  if (hdc.isValid()) {
577  hcalConstants = (HcalDDDSimConstants*)(&(*hdc));
578  } else {
579  edm::LogError("HcalSim") << "HCalSD : Cannot find HcalDDDSimConstant";
580  throw cms::Exception("Unknown", "HCalSD") << "Cannot find HcalDDDSimConstant" << "\n";
581  }
582 
584 
585  edm::LogInfo("HcalSim") << "Maximum depth for HF " << hcalConstants->getMaxDepth(2);
586 
587  //Special Geometry parameters
589  edm::LogInfo("HcalSim") << "HCalSD: " << gpar.size()<< " gpar (cm)";
590  for (unsigned int ig=0; ig<gpar.size(); ig++)
591  edm::LogInfo("HcalSim") << "HCalSD: gpar[" << ig << "] = "
592  << gpar[ig]/cm << " cm";
593  //Test Hcal Numbering Scheme
594  if (testNS_) hcalTestNS_ = new HcalTestNS(es);
595 
596  if (agingFlagHB) {
598  es->get<HBHEDarkeningRecord>().get("HB",hdark);
599  m_HBDarkening = &*hdark;
600  }
601  if (agingFlagHE) {
603  es->get<HBHEDarkeningRecord>().get("HE",hdark);
604  m_HEDarkening = &*hdark;
605  }
606 }
607 
609  G4ParticleTable * theParticleTable = G4ParticleTable::GetParticleTable();
610  G4String particleName;
611  mumPDG = theParticleTable->FindParticle(particleName="mu-")->GetPDGEncoding();
612  mupPDG = theParticleTable->FindParticle(particleName="mu+")->GetPDGEncoding();
613 #ifdef EDM_ML_DEBUG
614  LogDebug("HcalSim") << "HCalSD: Particle code for mu- = " << mumPDG
615  << " for mu+ = " << mupPDG;
616 #endif
617  if (showerLibrary) showerLibrary->initRun(theParticleTable,hcalConstants);
618  if (showerParam) showerParam->initRun(theParticleTable,hcalConstants);
619  if (hfshower) hfshower->initRun(theParticleTable,hcalConstants);
620  if (showerPMT) showerPMT->initRun(theParticleTable,hcalConstants);
621  if (showerBundle) showerBundle->initRun(theParticleTable,hcalConstants);
622 }
623 
624 bool HCalSD::filterHit(CaloG4Hit* aHit, double time) {
625  double threshold=0;
626  DetId theId(aHit->getUnitID());
627  switch (theId.subdetId()) {
628  case HcalBarrel:
629  threshold = eminHitHB; break;
630  case HcalEndcap:
631  threshold = eminHitHE; break;
632  case HcalOuter:
633  threshold = eminHitHO; break;
634  case HcalForward:
635  threshold = eminHitHF; break;
636  default:
637  break;
638  }
639  return ((time <= tmaxHit) && (aHit->getEnergyDeposit() > threshold));
640 }
641 
642 uint32_t HCalSD::setDetUnitId (int det, const G4ThreeVector& pos, int depth, int lay=1) {
643  uint32_t id = 0;
644  if (numberingFromDDD) {
645  //get the ID's as eta, phi, depth, ... indices
646  HcalNumberingFromDDD::HcalID tmp = numberingFromDDD->unitID(det, pos, depth, lay);
647  id = setDetUnitId(tmp);
648  }
649  return id;
650 }
651 
653  modifyDepth(tmp);
654  uint32_t id = (numberingScheme) ? numberingScheme->getUnitID(tmp) : 0;
655  if ((!testNumber) && hcalTestNS_) {
656  bool ok = hcalTestNS_->compare(tmp,id);
657  if (!ok)
658  edm::LogWarning("HcalSim") << "Det ID from HCalSD " << HcalDetId(id)
659  << " " << std::hex << id << std::dec
660  << " does not match one from relabller for "
661  << tmp.subdet << ":" << tmp.etaR << ":"
662  << tmp.phi << ":" << tmp.phis << ":"
663  << tmp.depth << ":" << tmp.lay << std::endl;
664  }
665  return id;
666 }
667 
668 std::vector<double> HCalSD::getDDDArray(const std::string & str,
669  const DDsvalues_type & sv) {
670 #ifdef EDM_ML_DEBUG
671  LogDebug("HcalSim") << "HCalSD:getDDDArray called for " << str;
672 #endif
673  DDValue value(str);
674  if (DDfetch(&sv,value)) {
675 #ifdef EDM_ML_DEBUG
676  LogDebug("HcalSim") << value;
677 #endif
678  const std::vector<double> & fvec = value.doubles();
679  int nval = fvec.size();
680  if (nval < 1) {
681  edm::LogError("HcalSim") << "HCalSD : # of " << str << " bins " << nval
682  << " < 2 ==> illegal";
683  throw cms::Exception("Unknown", "HCalSD") << "nval < 2 for array " << str << "\n";
684  }
685 
686  return fvec;
687  } else {
688  edm::LogError("HcalSim") << "HCalSD : cannot get array " << str;
689  throw cms::Exception("Unknown", "HCalSD") << "cannot get array " << str << "\n";
690  }
691 }
692 
693 std::vector<G4String> HCalSD::getNames(DDFilteredView& fv) {
694 
695  std::vector<G4String> tmp;
696  bool dodet = fv.firstChild();
697  while (dodet) {
698  const DDLogicalPart & log = fv.logicalPart();
699  bool ok = true;
700 
701  for (unsigned int i=0; i<tmp.size(); ++i) {
702  if (!strcmp(tmp[i].c_str(), log.name().name().c_str())) {
703  ok = false;
704  break;
705  }
706  }
707  if (ok) tmp.push_back(log.name().name());
708  dodet = fv.next();
709  }
710  return tmp;
711 }
712 
713 bool HCalSD::isItHF(G4Step * aStep) {
714  const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
715  int levels = (touch->GetHistoryDepth()) + 1;
716  for (unsigned int it=0; it < hfNames.size(); ++it) {
717  if (levels >= hfLevels[it]) {
718  G4LogicalVolume* lv = touch->GetVolume(levels-hfLevels[it])->GetLogicalVolume();
719  if (lv == hfLV[it]) return true;
720  }
721  }
722  return false;
723 }
724 
725 bool HCalSD::isItHF (G4String name) {
726  std::vector<G4String>::const_iterator it = hfNames.begin();
727  for (; it != hfNames.end(); ++it) if (name == *it) return true;
728  return false;
729 }
730 
731 bool HCalSD::isItFibre (G4LogicalVolume* lv) {
732  std::vector<G4LogicalVolume*>::const_iterator ite = fibreLV.begin();
733  for (; ite != fibreLV.end(); ++ite) if (lv == *ite) return true;
734  return false;
735 }
736 
737 bool HCalSD::isItFibre (G4String name) {
738  std::vector<G4String>::const_iterator it = fibreNames.begin();
739  for (; it != fibreNames.end(); ++it) if (name == *it) return true;
740  return false;
741 }
742 
743 bool HCalSD::isItPMT (G4LogicalVolume* lv) {
744  std::vector<G4LogicalVolume*>::const_iterator ite = pmtLV.begin();
745  for (; ite != pmtLV.end(); ++ite) if (lv == *ite) return true;
746  return false;
747 }
748 
749 bool HCalSD::isItStraightBundle (G4LogicalVolume* lv) {
750  std::vector<G4LogicalVolume*>::const_iterator ite = fibre1LV.begin();
751  for (; ite != fibre1LV.end(); ++ite) if (lv == *ite) return true;
752  return false;
753 }
754 
755 bool HCalSD::isItConicalBundle (G4LogicalVolume* lv) {
756  std::vector<G4LogicalVolume*>::const_iterator ite = fibre2LV.begin();
757  for (; ite != fibre2LV.end(); ++ite) if (lv == *ite) return true;
758  return false;
759 }
760 
761 bool HCalSD::isItScintillator (G4Material* mat) {
762  std::vector<G4Material*>::const_iterator ite = materials.begin();
763  for (; ite != materials.end(); ++ite) if (mat == *ite) return true;
764  return false;
765 }
766 
767 bool HCalSD::isItinFidVolume (G4ThreeVector& hitPoint) {
768  bool flag = true;
769  if (applyFidCut) {
770  int npmt = HFFibreFiducial:: PMTNumber(hitPoint);
771 #ifdef EDM_ML_DEBUG
772  edm::LogInfo("HcalSim") << "HCalSD::isItinFidVolume:#PMT= " << npmt
773  << " for hit point " << hitPoint;
774 #endif
775  if (npmt <= 0) flag = false;
776  }
777 #ifdef EDM_ML_DEBUG
778  edm::LogInfo("HcalSim") << "HCalSD::isItinFidVolume: point " << hitPoint
779  << " return flag " << flag;
780 #endif
781  return flag;
782 }
783 
784 void HCalSD::getFromLibrary (G4Step* aStep, double weight) {
785  preStepPoint = aStep->GetPreStepPoint();
786  theTrack = aStep->GetTrack();
787  int det = 5;
788  bool ok;
789 
790  std::vector<HFShowerLibrary::Hit> hits = showerLibrary->getHits(aStep, ok, weight, false);
791 
792  double etrack = preStepPoint->GetKineticEnergy();
793  int primaryID = setTrackID(aStep);
794 
795  // Reset entry point for new primary
796  posGlobal = preStepPoint->GetPosition();
797  resetForNewPrimary(posGlobal, etrack);
798 
799  G4int particleCode = theTrack->GetDefinition()->GetPDGEncoding();
800  if (particleCode==emPDG || particleCode==epPDG || particleCode==gammaPDG) {
801  edepositEM = 1.*GeV;
802  edepositHAD = 0.;
803  } else {
804  edepositEM = 0.;
805  edepositHAD = 1.*GeV;
806  }
807 #ifdef EDM_ML_DEBUG
808  edm::LogInfo("HcalSim") << "HCalSD::getFromLibrary " <<hits.size()
809  << " hits for " << GetName() << " of " << primaryID
810  << " with " << theTrack->GetDefinition()->GetParticleName()
811  << " of " << preStepPoint->GetKineticEnergy()/GeV << " GeV";
812 #endif
813  for (unsigned int i=0; i<hits.size(); ++i) {
814  G4ThreeVector hitPoint = hits[i].position;
815  if (isItinFidVolume (hitPoint)) {
816  int depth = hits[i].depth;
817  double time = hits[i].time;
818  unsigned int unitID = setDetUnitId(det, hitPoint, depth);
819  currentID.setID(unitID, time, primaryID, 0);
820 #ifdef plotDebug
821  plotProfile(aStep, hitPoint, 1.0*GeV, time, depth);
822  bool emType = false;
823  if (particleCode==emPDG || particleCode==epPDG || particleCode==gammaPDG)
824  emType = true;
825  plotHF(hitPoint,emType);
826 #endif
827 
828  // check if it is in the same unit and timeslice as the previous one
829  if (currentID == previousID) {
831  } else {
832  if (!checkHit()) currentHit = createNewHit();
833  }
834  }
835  }
836 
837  //Now kill the current track
838  if (ok) {
839  theTrack->SetTrackStatus(fStopAndKill);
840  G4TrackVector tv = *(aStep->GetSecondary());
841  for (unsigned int kk=0; kk<tv.size(); ++kk)
842  if (tv[kk]->GetVolume() == preStepPoint->GetPhysicalVolume())
843  tv[kk]->SetTrackStatus(fStopAndKill);
844  }
845 }
846 
847 void HCalSD::hitForFibre (G4Step* aStep, double weight) { // if not ParamShower
848 
849  preStepPoint = aStep->GetPreStepPoint();
850  theTrack = aStep->GetTrack();
851  int primaryID = setTrackID(aStep);
852 
853  int det = 5;
854  std::vector<HFShower::Hit> hits = hfshower->getHits(aStep, weight);
855 
856  G4int particleCode = theTrack->GetDefinition()->GetPDGEncoding();
857  if (particleCode==emPDG || particleCode==epPDG || particleCode==gammaPDG) {
858  edepositEM = 1.*GeV;
859  edepositHAD = 0.;
860  } else {
861  edepositEM = 0.;
862  edepositHAD = 1.*GeV;
863  }
864 
865 #ifdef EDM_ML_DEBUG
866  edm::LogInfo("HcalSim") << "HCalSD::hitForFibre " << hits.size()
867  << " hits for " << GetName() << " of " << primaryID
868  << " with " << theTrack->GetDefinition()->GetParticleName()
869  << " of " << preStepPoint->GetKineticEnergy()/GeV
870  << " GeV in detector type " << det;
871 #endif
872  if (hits.size() > 0) {
873  for (unsigned int i=0; i<hits.size(); ++i) {
874  G4ThreeVector hitPoint = hits[i].position;
875  if (isItinFidVolume (hitPoint)) {
876  int depth = hits[i].depth;
877  double time = hits[i].time;
878  unsigned int unitID = setDetUnitId(det, hitPoint, depth);
879  currentID.setID(unitID, time, primaryID, 0);
880 #ifdef plotDebug
881  plotProfile(aStep, hitPoint, edepositEM, time, depth);
882  bool emType = false;
883  if (particleCode==emPDG || particleCode==epPDG || particleCode==gammaPDG)
884  emType = true;
885  plotHF(hitPoint,emType);
886 #endif
887  // check if it is in the same unit and timeslice as the previous one
888  if (currentID == previousID) {
890  } else {
891  posGlobal = preStepPoint->GetPosition();
892  if (!checkHit()) currentHit = createNewHit();
893  }
894  }
895  }
896  }
897 }
898 
899 void HCalSD::getFromParam (G4Step* aStep, double weight) {
900  std::vector<HFShowerParam::Hit> hits = showerParam->getHits(aStep, weight);
901  int nHit = static_cast<int>(hits.size());
902 
903  if (nHit > 0) {
904  preStepPoint = aStep->GetPreStepPoint();
905  int primaryID = setTrackID(aStep);
906 
907  int det = 5;
908 #ifdef EDM_ML_DEBUG
909  edm::LogInfo("HcalSim") << "HCalSD::getFromParam " << nHit << " hits for "
910  << GetName() << " of " << primaryID << " with "
911  << aStep->GetTrack()->GetDefinition()->GetParticleName()
912  << " of " << preStepPoint->GetKineticEnergy()/GeV
913  << " GeV in detector type " << det;
914 #endif
915  for (int i = 0; i<nHit; ++i) {
916  G4ThreeVector hitPoint = hits[i].position;
917  int depth = hits[i].depth;
918  double time = hits[i].time;
919  unsigned int unitID = setDetUnitId(det, hitPoint, depth);
920  currentID.setID(unitID, time, primaryID, 0);
921  edepositEM = hits[i].edep*GeV;
922  edepositHAD = 0.;
923 #ifdef plotDebug
924  plotProfile(aStep, hitPoint, edepositEM, time, depth);
925 #endif
926 
927  // check if it is in the same unit and timeslice as the previous one
928  if (currentID == previousID) {
930  } else {
931  posGlobal = preStepPoint->GetPosition();
932  if (!checkHit()) currentHit = createNewHit();
933  }
934  }
935  }
936 }
937 
938 void HCalSD::getHitPMT (G4Step * aStep) {
939 
940  preStepPoint = aStep->GetPreStepPoint();
941  theTrack = aStep->GetTrack();
942  double edep = showerPMT->getHits(aStep);
943 
944  if (edep >= 0) {
945  double etrack = preStepPoint->GetKineticEnergy();
946  int primaryID = 0;
947  if (etrack >= energyCut) {
948  primaryID = theTrack->GetTrackID();
949  } else {
950  primaryID = theTrack->GetParentID();
951  if (primaryID == 0) primaryID = theTrack->GetTrackID();
952  }
953  // Reset entry point for new primary
954  posGlobal = preStepPoint->GetPosition();
955  resetForNewPrimary(posGlobal, etrack);
956 
957  //
958  int det = static_cast<int>(HcalForward);
959  G4ThreeVector hitPoint = preStepPoint->GetPosition();
960  double rr = (hitPoint.x()*hitPoint.x() + hitPoint.y()*hitPoint.y());
961  double phi = (rr == 0. ? 0. :atan2(hitPoint.y(),hitPoint.x()));
962  double etaR = showerPMT->getRadius();
963  int depth = 1;
964  if (etaR < 0) {
965  depth = 2;
966  etaR =-etaR;
967  }
968  if (hitPoint.z() < 0) etaR =-etaR;
969 #ifdef EDM_ML_DEBUG
970  edm::LogInfo("HcalSim") << "HCalSD::Hit for Detector " << det << " etaR "
971  << etaR << " phi " << phi/deg << " depth " <<depth;
972 #endif
973  double time = (aStep->GetPostStepPoint()->GetGlobalTime());
974  uint32_t unitID = 0;
975  if (numberingFromDDD) {
977  depth,1);
978  unitID = setDetUnitId(tmp);
979  }
980  currentID.setID(unitID, time, primaryID, 1);
981 
982  edepositHAD = aStep->GetTotalEnergyDeposit();
983  edepositEM =-edepositHAD + (edep*GeV);
984 #ifdef plotDebug
985  plotProfile(aStep, hitPoint, edep*GeV, time, depth);
986 #endif
987 #ifdef EDM_ML_DEBUG
988  double beta = preStepPoint->GetBeta();
989  LogDebug("HcalSim") << "HCalSD::getHitPMT 1 hit for " << GetName()
990  << " of " << primaryID << " with "
991  << theTrack->GetDefinition()->GetParticleName()
992  << " of " << preStepPoint->GetKineticEnergy()/GeV
993  << " GeV with velocity " << beta << " UnitID "
994  << std::hex << unitID << std::dec;
995 #endif
996  // check if it is in the same unit and timeslice as the previous one
997  if (currentID == previousID) {
999  } else {
1000  if (!checkHit()) currentHit = createNewHit();
1001  }
1002  }
1003 }
1004 
1005 void HCalSD::getHitFibreBundle (G4Step* aStep, bool type) {
1006  preStepPoint = aStep->GetPreStepPoint();
1007  theTrack = aStep->GetTrack();
1008  double edep = showerBundle->getHits(aStep, type);
1009 
1010  if (edep >= 0) {
1011  double etrack = preStepPoint->GetKineticEnergy();
1012  int primaryID = 0;
1013  if (etrack >= energyCut) {
1014  primaryID = theTrack->GetTrackID();
1015  } else {
1016  primaryID = theTrack->GetParentID();
1017  if (primaryID == 0) primaryID = theTrack->GetTrackID();
1018  }
1019  // Reset entry point for new primary
1020  posGlobal = preStepPoint->GetPosition();
1021  resetForNewPrimary(posGlobal, etrack);
1022 
1023  //
1024  int det = static_cast<int>(HcalForward);
1025  G4ThreeVector hitPoint = preStepPoint->GetPosition();
1026  double rr = (hitPoint.x()*hitPoint.x() + hitPoint.y()*hitPoint.y());
1027  double phi = (rr == 0. ? 0. :atan2(hitPoint.y(),hitPoint.x()));
1028  double etaR = showerBundle->getRadius();
1029  int depth = 1;
1030  if (etaR < 0) {
1031  depth = 2;
1032  etaR =-etaR;
1033  }
1034  if (hitPoint.z() < 0) etaR =-etaR;
1035 #ifdef EDM_ML_DEBUG
1036  LogDebug("HcalSim") << "HCalSD::Hit for Detector " << det << " etaR "
1037  << etaR << " phi " << phi/deg << " depth " <<depth;
1038 #endif
1039  double time = (aStep->GetPostStepPoint()->GetGlobalTime());
1040  uint32_t unitID = 0;
1041  if (numberingFromDDD) {
1042  HcalNumberingFromDDD::HcalID tmp = numberingFromDDD->unitID(det,etaR,phi,depth,1);
1043  unitID = setDetUnitId(tmp);
1044  }
1045  if (type) currentID.setID(unitID, time, primaryID, 3);
1046  else currentID.setID(unitID, time, primaryID, 2);
1047 
1048  edepositHAD = aStep->GetTotalEnergyDeposit();
1049  edepositEM =-edepositHAD + (edep*GeV);
1050 #ifdef plotDebug
1051  plotProfile(aStep, hitPoint, edep*GeV, time, depth);
1052 #endif
1053 #ifdef EDM_ML_DEBUG
1054  double beta = preStepPoint->GetBeta();
1055  LogDebug("HcalSim") << "HCalSD::getHitFibreBundle 1 hit for " << GetName()
1056  << " of " << primaryID << " with "
1057  << theTrack->GetDefinition()->GetParticleName()
1058  << " of " << preStepPoint->GetKineticEnergy()/GeV
1059  << " GeV with velocity " << beta << " UnitID "
1060  << std::hex << unitID << std::dec;
1061 #endif
1062  // check if it is in the same unit and timeslice as the previous one
1064  else if (!checkHit()) currentHit = createNewHit();
1065  } // non-zero energy deposit
1066 }
1067 
1068 int HCalSD::setTrackID (G4Step* aStep) {
1069  theTrack = aStep->GetTrack();
1070 
1071  double etrack = preStepPoint->GetKineticEnergy();
1072  TrackInformation * trkInfo = (TrackInformation *)(theTrack->GetUserInformation());
1073  int primaryID = trkInfo->getIDonCaloSurface();
1074  if (primaryID == 0) {
1075 #ifdef EDM_ML_DEBUG
1076  edm::LogInfo("HcalSim") << "HCalSD: Problem with primaryID **** set by "
1077  << "force to TkID **** " <<theTrack->GetTrackID();
1078 #endif
1079  primaryID = theTrack->GetTrackID();
1080  }
1081 
1082  if (primaryID != previousID.trackID())
1083  resetForNewPrimary(preStepPoint->GetPosition(), etrack);
1084 
1085  return primaryID;
1086 }
1087 
1089 
1090  std::ifstream infile;
1091  int entry=0;
1092  infile.open(fName.c_str(), std::ios::in);
1093  if (infile) {
1094  int det, zside, etaR, phi, lay;
1095  double wt;
1096  while (infile >> det >> zside >> etaR >> phi >> lay >> wt) {
1097  uint32_t id = HcalTestNumbering::packHcalIndex(det,zside,1,etaR,phi,lay);
1098  layerWeights.insert(std::pair<uint32_t,double>(id,wt));
1099  ++entry;
1100 #ifdef EDM_ML_DEBUG
1101  edm::LogInfo("HcalSim") << "HCalSD::readWeightFromFile:Entry " << entry
1102  << " ID " << std::hex << id << std::dec << " ("
1103  << det << "/" << zside << "/1/" << etaR << "/"
1104  << phi << "/" << lay << ") Weight " << wt;
1105 #endif
1106  }
1107  infile.close();
1108  }
1109  edm::LogInfo("HcalSim") << "HCalSD::readWeightFromFile: reads " << entry
1110  << " weights from " << fName;
1111  if (entry <= 0) useLayerWt = false;
1112 }
1113 
1114 double HCalSD::layerWeight(int det, const G4ThreeVector& pos, int depth, int lay) {
1115 
1116  double wt = 1.;
1117  if (numberingFromDDD) {
1118  //get the ID's as eta, phi, depth, ... indices
1120  depth, lay);
1121  modifyDepth(tmp);
1122  uint32_t id = HcalTestNumbering::packHcalIndex(tmp.subdet, tmp.zside, 1,
1123  tmp.etaR, tmp.phis,tmp.lay);
1124  std::map<uint32_t,double>::const_iterator ite = layerWeights.find(id);
1125  if (ite != layerWeights.end()) wt = ite->second;
1126 #ifdef EDM_ML_DEBUG
1127  edm::LogInfo("HcalSim") << "HCalSD::layerWeight: ID " << std::hex << id
1128  << std::dec << " (" << tmp.subdet << "/"
1129  << tmp.zside << "/1/" << tmp.etaR << "/"
1130  << tmp.phis << "/" << tmp.lay << ") Weight " <<wt;
1131 #endif
1132  }
1133  return wt;
1134 }
1135 
1136 void HCalSD::plotProfile(G4Step* aStep,const G4ThreeVector& global, double edep,
1137  double time, int id) {
1138 
1139  const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
1140  static const G4String modName[8] = {"HEModule", "HVQF" , "HBModule", "MBAT",
1141  "MBBT" , "MBBTC", "MBBT_R1P", "MBBT_R1M"};
1142  G4ThreeVector local;
1143  bool found=false;
1144  double depth=-2000;
1145  int idx = 4;
1146  for (int n=0; n<touch->GetHistoryDepth(); ++n) {
1147  G4String name = touch->GetVolume(n)->GetName();
1148 #ifdef EDM_ML_DEBUG
1149  LogDebug("HcalSim") << "plotProfile Depth " << n << " Name " << name;
1150 #endif
1151  for (unsigned int ii=0; ii<8; ++ii) {
1152  if (name == modName[ii]) {
1153  found = true;
1154  int dn = touch->GetHistoryDepth() - n;
1155  local = touch->GetHistory()->GetTransform(dn).TransformPoint(global);
1156  if (ii == 0) {depth = local.z() - 4006.5; idx = 1;}
1157  else if (ii == 1) {depth = local.z() + 825.0; idx = 3;}
1158  else if (ii == 2) {depth = local.x() - 1775.; idx = 0;}
1159  else {depth = local.y() + 15.; idx = 2;}
1160  break;
1161  }
1162  }
1163  if (found) break;
1164  }
1165  if (!found) depth = std::abs(global.z()) - 11500;
1166 #ifdef EDM_ML_DEBUG
1167  LogDebug("HcalSim") << "plotProfile Found " << found << " Global " << global
1168  << " Local " << local << " depth " << depth << " ID "
1169  << id << " EDEP " << edep << " Time " << time;
1170 #endif
1171  if (hit_[idx] != 0) hit_[idx]->Fill(edep);
1172  if (time_[idx] != 0) time_[idx]->Fill(time,edep);
1173  if (dist_[idx] != 0) dist_[idx]->Fill(depth,edep);
1174  int jd = 2*idx + id - 7;
1175  if (jd >= 0 && jd < 4) {
1176  jd += 5;
1177  if (hit_[jd] != 0) hit_[jd]->Fill(edep);
1178  if (time_[jd] != 0) time_[jd]->Fill(time,edep);
1179  if (dist_[jd] != 0) dist_[jd]->Fill(depth,edep);
1180  }
1181 }
1182 
1183 void HCalSD::plotHF(G4ThreeVector& hitPoint, bool emType) {
1184  double zv = std::abs(hitPoint.z()) - gpar[4];
1185  if (emType) {
1186  if (hzvem != 0) hzvem->Fill(zv);
1187  } else {
1188  if (hzvhad != 0) hzvhad->Fill(zv);
1189  }
1190 }
1191 
1193  if (id.subdet == 4) {
1194  int ieta = (id.zside == 0) ? -id.etaR : id.etaR;
1195  if (hcalConstants->maxHFDepth(ieta,id.phis) > 2) {
1196  if (id.depth <= 2) {
1197  if (G4UniformRand() > 0.5) id.depth += 2;
1198  }
1199  }
1200  } else if ((id.subdet == 1 || id.subdet ==2) && testNumber) {
1201  if (depth_ == 0) id.depth = 1;
1202  else id.depth = 2;
1203  }
1204 }
#define LogDebug(id)
float edepositEM
Definition: CaloSD.h:121
const double beta
double energyCut
Definition: CaloSD.h:123
HCalSD(G4String, const DDCompactView &, const SensitiveDetectorCatalog &, edm::ParameterSet const &, const SimTrackManager *)
Definition: HCalSD.cc:44
type
Definition: HCALResponse.h:21
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
bool useParam
Definition: HCalSD.h:99
double eminHitHE
Definition: HCalSD.h:100
HFShowerParam * showerParam
Definition: HCalSD.h:88
TH1F * time_[9]
Definition: HCalSD.h:109
G4int emPDG
Definition: CaloSD.h:136
double getRadius()
Definition: HFShowerPMT.cc:134
const DDLogicalPart & logicalPart() const
The logical-part of the current node in the filtered-view.
const std::vector< double > & doubles() const
a reference to the double-valued values stored in the given instance of DDValue
Definition: DDValue.cc:140
const double GeV
Definition: MathUtil.h:16
double kmaxNeutron
Definition: CaloSD.h:134
#define EDM_ML_DEBUG
void updateHit(CaloG4Hit *)
Definition: CaloSD.cc:440
void hitForFibre(G4Step *step, double weight)
Definition: HCalSD.cc:847
const N & name() const
Definition: DDBase.h:78
void getFromParam(G4Step *step, double weight)
Definition: HCalSD.cc:899
G4int depth_
Definition: HCalSD.h:102
int getIDonCaloSurface() const
bool useLayerWt
Definition: HCalSD.h:96
Definition: CaloSD.h:42
virtual void update(const BeginOfJob *)
This routine will be called when the appropriate signal arrives.
Definition: HCalSD.cc:571
bool isItStraightBundle(G4LogicalVolume *)
Definition: HCalSD.cc:749
virtual bool ProcessHits(G4Step *, G4TouchableHistory *)
Definition: HCalSD.cc:357
std::vector< double > gpar
Definition: HCalSD.h:103
bool useFibreBundle
Definition: HCalSD.h:96
bool isItinFidVolume(G4ThreeVector &)
Definition: HCalSD.cc:767
int zside() const
get the z-side of the cell (1/-1)
Definition: HcalDetId.cc:93
double betaThr
Definition: HCalSD.h:98
void initRun(G4ParticleTable *, HcalDDDSimConstants *)
Definition: HFShower.cc:454
double deliveredLumi
Definition: HCalSD.h:101
std::vector< Hit > getHits(G4Step *aStep, bool &ok, double weight, bool onlyLong=false)
virtual uint32_t getUnitID(const HcalNumberingFromDDD::HcalID &id)
HFShowerFibreBundle * showerBundle
Definition: HCalSD.h:90
std::vector< G4LogicalVolume * > fibre1LV
Definition: HCalSD.h:107
std::vector< G4LogicalVolume * > fibreLV
Definition: HCalSD.h:107
double eminHitHB
Definition: HCalSD.h:100
bool useShowerLibrary
Definition: HCalSD.h:99
std::vector< double > getDDDArray(const std::string &, const DDsvalues_type &)
Definition: HCalSD.cc:668
double getHits(G4Step *aStep, bool type)
#define NULL
Definition: scimark2.h:8
Definition: weight.py:1
virtual uint32_t setDetUnitId(G4Step *step)
Definition: HCalSD.cc:550
double birk2
Definition: HCalSD.h:98
int setTrackID(G4Step *step)
Definition: HCalSD.cc:1068
void getFromLibrary(G4Step *step, double weight)
Definition: HCalSD.cc:784
bool usePMTHit
Definition: HCalSD.h:96
G4ThreeVector posGlobal
Definition: CaloSD.h:113
static const unsigned int numberOfZLayers
Definition: HFDarkening.h:26
void modifyDepth(HcalNumberingFromDDD::HcalID &id)
Definition: HCalSD.cc:1192
#define nullptr
void setNumberingScheme(HcalNumberingScheme *)
Definition: HCalSD.cc:563
type of data representation of DDCompactView
Definition: DDCompactView.h:90
bool agingFlagHE
Definition: HCalSD.h:91
double birk1
Definition: HCalSD.h:98
double kmaxProton
Definition: CaloSD.h:134
bool DDfetch(const DDsvalues_type *, DDValue &)
helper for retrieving DDValues from DDsvalues_type *.
Definition: DDsvalues.cc:81
bool compare(HcalNumberingFromDDD::HcalID const &, uint32_t const &)
Definition: HcalTestNS.cc:25
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
static int PMTNumber(const G4ThreeVector &pe_effect)
bool isItHF(G4Step *)
Definition: HCalSD.cc:713
G4bool checkHit()
Definition: CaloSD.cc:331
static TrackerG4SimHitNumberingScheme & numberingScheme(const DDCompactView &cpv, const GeometricDet &det)
TH1F * hzvhad
Definition: HCalSD.h:109
void initRun(G4ParticleTable *, HcalDDDSimConstants *)
Definition: HFShowerPMT.cc:77
double eminHitHF
Definition: HCalSD.h:100
const double MeV
bool isItConicalBundle(G4LogicalVolume *)
Definition: HCalSD.cc:755
static uint32_t packHcalIndex(int det, int z, int depth, int eta, int phi, int lay)
TH1F * hit_[9]
Definition: HCalSD.h:109
void resetForNewPrimary(const G4ThreeVector &, double)
Definition: CaloSD.cc:454
int getMaxDepth(const int &type) const
virtual void initRun()
Definition: HCalSD.cc:608
bool agingFlagHB
Definition: HCalSD.h:91
bool testNumber
Definition: HCalSD.h:97
std::vector< G4LogicalVolume * > pmtLV
Definition: HCalSD.h:107
std::vector< G4LogicalVolume * > hfLV
Definition: HCalSD.h:107
double kmaxIon
Definition: CaloSD.h:134
bool suppressHeavy
Definition: CaloSD.h:132
bool isItScintillator(G4Material *)
Definition: HCalSD.cc:761
bool next()
set current node to the next node in the filtered tree
HFShower * hfshower
Definition: HCalSD.h:87
bool useBirk
Definition: HCalSD.h:96
float edepositHAD
Definition: CaloSD.h:121
std::unique_ptr< HFDarkening > m_HFDarkening
Definition: HCalSD.h:94
double birk3
Definition: HCalSD.h:98
int trackID() const
Definition: CaloHitID.h:25
virtual double getEnergyDeposit(G4Step *)
Definition: HCalSD.cc:462
G4int epPDG
Definition: CaloSD.h:136
const HBHEDarkening * m_HEDarkening
Definition: HCalSD.h:93
void plotHF(G4ThreeVector &pos, bool emType)
Definition: HCalSD.cc:1183
std::vector< std::pair< unsigned int, DDValue > > DDsvalues_type
std::maps an index to a DDValue. The index corresponds to the index assigned to the name of the std::...
Definition: DDsvalues.h:20
G4int gammaPDG
Definition: CaloSD.h:136
bool isAvailable() const
Definition: Service.h:46
bool applyFidCut
Definition: HCalSD.h:99
std::vector< Hit > getHits(G4Step *aStep, double weight)
Definition: HFShower.cc:47
TH1F * dist_[9]
Definition: HCalSD.h:109
virtual ~HCalSD()
Definition: HCalSD.cc:345
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
static void unpackHcalIndex(const uint32_t &idx, int &det, int &z, int &depth, int &eta, int &phi, int &lay)
A DDLogicalPart aggregates information concerning material, solid and sensitveness ...
Definition: DDLogicalPart.h:92
HcalNumberingScheme * numberingScheme
Definition: HCalSD.h:85
void getHitPMT(G4Step *step)
Definition: HCalSD.cc:938
T * make(const Args &...args) const
make new ROOT object
int getNumberOfHits()
Definition: CaloSD.cc:361
CaloHitID previousID
Definition: CaloSD.h:117
double getAttenuation(G4Step *aStep, double birk1, double birk2, double birk3)
Definition: CaloSD.cc:465
CaloG4Hit * currentHit
Definition: CaloSD.h:128
std::vector< int > hfLevels
Definition: HCalSD.h:104
virtual std::vector< std::string > getNames()
void plotProfile(G4Step *step, const G4ThreeVector &pos, double edep, double time, int id)
Definition: HCalSD.cc:1136
void initRun(G4ParticleTable *, HcalDDDSimConstants *)
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:37
void NaNTrap(G4Step *step)
G4Track * theTrack
Definition: CaloSD.h:118
double getLayer0Wt(const int &det, const int &phi, const int &zside) const
virtual G4bool getStepInfo(G4Step *aStep)
Definition: CaloSD.cc:250
bool isItPMT(G4LogicalVolume *)
Definition: HCalSD.cc:743
bool testNS_
Definition: HCalSD.h:97
G4int mupPDG
Definition: HCalSD.h:102
ii
Definition: cuy.py:588
double eminHitHO
Definition: HCalSD.h:100
double tmaxHit
Definition: CaloSD.h:123
int ietaAbs() const
get the absolute value of the cell ieta
Definition: HcalDetId.cc:98
void setID(uint32_t unitID, double timeSlice, int trackID, uint16_t depth=0)
Definition: CaloHitID.cc:44
TH1F * hzvem
Definition: HCalSD.h:109
G4StepPoint * preStepPoint
Definition: CaloSD.h:120
int iphi() const
get the cell iphi
Definition: HcalDetId.cc:103
const std::vector< double > & getGparHF() const
Definition: DetId.h:18
static const unsigned int lowZLimit
Definition: HFDarkening.h:29
static const G4LogicalVolume * GetVolume(const std::string &name)
TFileDirectory mkdir(const std::string &dir, const std::string &descr="")
create a new subdirectory
Definition: TFileService.h:69
CaloHitID currentID
Definition: CaloSD.h:117
std::vector< Hit > getHits(G4Step *aStep, double weight)
static const unsigned int upperZLimit
Definition: HFDarkening.h:30
void readWeightFromFile(std::string)
Definition: HCalSD.cc:1088
bool neutralDensity
Definition: HCalSD.h:97
void initRun(G4ParticleTable *, HcalDDDSimConstants *)
void getHitFibreBundle(G4Step *step, bool type)
Definition: HCalSD.cc:1005
const T & get() const
Definition: EventSetup.h:55
int ke
bool isPrimary() const
DDsvalues_type mergedSpecifics() const
double getHits(G4Step *aStep)
Definition: HFShowerPMT.cc:88
HcalNumberingFromDDD * numberingFromDDD
Definition: HCalSD.h:84
double layerWeight(int, const G4ThreeVector &, int, int)
Definition: HCalSD.cc:1114
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
double getResponseWt(G4Track *)
Definition: CaloSD.cc:607
HLT enums.
std::vector< G4String > fibreNames
Definition: HCalSD.h:105
G4bool hitExists()
Definition: CaloSD.cc:310
bool firstChild()
set the current node to the first child ...
std::vector< G4Material * > materials
Definition: HCalSD.h:106
virtual bool filterHit(CaloG4Hit *, double)
Definition: HCalSD.cc:624
std::vector< G4String > hfNames
Definition: HCalSD.h:105
G4int mumPDG
Definition: HCalSD.h:102
HcalTestNS * hcalTestNS_
Definition: HCalSD.h:95
std::map< uint32_t, double > layerWeights
Definition: HCalSD.h:108
HFShowerPMT * showerPMT
Definition: HCalSD.h:89
uint32_t getUnitID() const
Definition: CaloG4Hit.h:69
HcalID unitID(int det, const CLHEP::Hep3Vector &pos, int depth, int lay=-1) const
HFShowerLibrary * showerLibrary
Definition: HCalSD.h:86
int maxHFDepth(const int &ieta, const int &iphi) const
void initRun(G4ParticleTable *, HcalDDDSimConstants *)
std::vector< G4LogicalVolume * > fibre2LV
Definition: HCalSD.h:107
const HBHEDarkening * m_HBDarkening
Definition: HCalSD.h:92
const std::string & name() const
Returns the name.
Definition: DDName.cc:90
const DDMaterial & material(void) const
Returns a reference object of the material this LogicalPart is made of.
CaloG4Hit * createNewHit()
Definition: CaloSD.cc:363
std::vector< G4String > matNames
Definition: HCalSD.h:105
float degradation(float intlumi, int ieta, int lay) const
bool isItFibre(G4LogicalVolume *)
Definition: HCalSD.cc:731
levels
correction levels
double getEnergyDeposit() const
Definition: CaloG4Hit.h:81
bool useHF
Definition: HCalSD.h:99
HcalDDDSimConstants * hcalConstants
Definition: HCalSD.h:83