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 
13 
18 
19 #include "G4LogicalVolumeStore.hh"
20 #include "G4LogicalVolume.hh"
21 #include "G4Step.hh"
22 #include "G4Track.hh"
23 
24 #include "G4SystemOfUnits.hh"
25 #include "G4PhysicalConstants.hh"
26 #include "Randomize.hh"
27 
28 #include "DD4hep/Filter.h"
29 
30 #include <iostream>
31 #include <fstream>
32 #include <iomanip>
33 #include <sstream>
34 
35 //#define EDM_ML_DEBUG
36 //#define plotDebug
37 //#define printDebug
38 
39 #ifdef plotDebug
40 #include <TH1F.h>
41 #endif
42 
44  const HcalDDDSimConstants* hcns,
45  const HcalDDDRecConstants* hcnr,
46  const HcalSimulationConstants* hscs,
47  const HBHEDarkening* hbd,
48  const HBHEDarkening* hed,
49  const SensitiveDetectorCatalog& clg,
50  edm::ParameterSet const& p,
51  const SimTrackManager* manager)
52  : CaloSD(name,
53  clg,
54  p,
55  manager,
56  (float)(p.getParameter<edm::ParameterSet>("HCalSD").getParameter<double>("TimeSliceUnit")),
57  p.getParameter<edm::ParameterSet>("HCalSD").getParameter<bool>("IgnoreTrackID")),
58  hcalConstants_(hcns),
59  hcalSimConstants_(hscs),
60  m_HBDarkening(hbd),
61  m_HEDarkening(hed),
62  isHF(false),
63  weight_(1.0),
64  depth_(1) {
65  numberingFromDDD.reset(nullptr);
66  numberingScheme.reset(nullptr);
67  showerLibrary.reset(nullptr);
68  hfshower.reset(nullptr);
69  showerParam.reset(nullptr);
70  showerPMT.reset(nullptr);
71  showerBundle.reset(nullptr);
72  m_HFDarkening.reset(nullptr);
73  m_HcalTestNS.reset(nullptr);
74 
75  //static SimpleConfigurable<double> bk1(0.013, "HCalSD:BirkC1");
76  //static SimpleConfigurable<double> bk2(0.0568,"HCalSD:BirkC2");
77  //static SimpleConfigurable<double> bk3(1.75, "HCalSD:BirkC3");
78  // Values from NIM 80 (1970) 239-244: as implemented in Geant3
79 
80  bool dd4hep = p.getParameter<bool>("g4GeometryDD4hepSource");
81  edm::ParameterSet m_HC = p.getParameter<edm::ParameterSet>("HCalSD");
82  useBirk = m_HC.getParameter<bool>("UseBirkLaw");
83  double bunit = (CLHEP::g / (CLHEP::MeV * CLHEP::cm2));
84  birk1 = m_HC.getParameter<double>("BirkC1") * bunit;
85  birk2 = m_HC.getParameter<double>("BirkC2");
86  birk3 = m_HC.getParameter<double>("BirkC3");
87  useShowerLibrary = m_HC.getParameter<bool>("UseShowerLibrary");
88  useParam = m_HC.getParameter<bool>("UseParametrize");
89  testNumber = m_HC.getParameter<bool>("TestNumberingScheme");
90  neutralDensity = m_HC.getParameter<bool>("doNeutralDensityFilter");
91  usePMTHit = m_HC.getParameter<bool>("UsePMTHits");
92  betaThr = m_HC.getParameter<double>("BetaThreshold");
93  eminHitHB = m_HC.getParameter<double>("EminHitHB") * MeV;
94  eminHitHE = m_HC.getParameter<double>("EminHitHE") * MeV;
95  eminHitHO = m_HC.getParameter<double>("EminHitHO") * MeV;
96  eminHitHF = m_HC.getParameter<double>("EminHitHF") * MeV;
97  useFibreBundle = m_HC.getParameter<bool>("UseFibreBundleHits");
98  deliveredLumi = m_HC.getParameter<double>("DelivLuminosity");
99  agingFlagHB = m_HC.getParameter<bool>("HBDarkening");
100  agingFlagHE = m_HC.getParameter<bool>("HEDarkening");
101  bool agingFlagHF = m_HC.getParameter<bool>("HFDarkening");
102  useHF = m_HC.getUntrackedParameter<bool>("UseHF", true);
103  bool forTBHC = m_HC.getUntrackedParameter<bool>("ForTBHCAL", false);
104  bool forTBH2 = m_HC.getUntrackedParameter<bool>("ForTBH2", false);
105  useLayerWt = m_HC.getUntrackedParameter<bool>("UseLayerWt", false);
106  std::string file = m_HC.getUntrackedParameter<std::string>("WtFile", "None");
107  testNS_ = m_HC.getUntrackedParameter<bool>("TestNS", false);
108  edm::ParameterSet m_HF = p.getParameter<edm::ParameterSet>("HFShower");
109  applyFidCut = m_HF.getParameter<bool>("ApplyFiducialCut");
110  bool dumpGeom = m_HC.getUntrackedParameter<bool>("DumpGeometry", false);
111 
112 #ifdef EDM_ML_DEBUG
113  edm::LogVerbatim("HcalSim") << "***************************************************"
114  << "\n"
115  << "* Constructing a HCalSD with name " << name << "\n"
116  << "\n"
117  << "***************************************************";
118 #endif
119  edm::LogVerbatim("HcalSim") << "HCalSD:: Use of HF code is set to " << useHF
120  << "\n Use of shower parametrization set to " << useParam
121  << "\n Use of shower library is set to " << useShowerLibrary
122  << "\n Use PMT Hit is set to " << usePMTHit << " with beta Threshold " << betaThr
123  << "\n USe of FibreBundle Hit set to " << useFibreBundle
124  << "\n Use of Birks law is set to " << useBirk
125  << " with three constants kB = " << birk1 / bunit << ", C1 = " << birk2
126  << ", C2 = " << birk3;
127  edm::LogVerbatim("HcalSim") << "HCalSD:: Suppression Flag " << suppressHeavy << " protons below " << kmaxProton
128  << " MeV,"
129  << " neutrons below " << kmaxNeutron << " MeV and"
130  << " ions below " << kmaxIon << " MeV\n"
131  << " Threshold for storing hits in HB: " << eminHitHB << " HE: " << eminHitHE
132  << " HO: " << eminHitHO << " HF: " << eminHitHF << "\n"
133  << "Delivered luminosity for Darkening " << deliveredLumi << " Flag (HE) " << agingFlagHE
134  << " Flag (HB) " << agingFlagHB << " Flag (HF) " << agingFlagHF << "\n"
135  << "Application of Fiducial Cut " << applyFidCut
136  << "Flag for test number|neutral density filter " << testNumber << " " << neutralDensity;
137 
138  if (forTBHC) {
139  useHF = false;
140  matNames.emplace_back("Scintillator");
141  } else {
143  }
144 
146  if (testNumber || forTBH2) {
147  scheme = dynamic_cast<HcalNumberingScheme*>(new HcalTestNumberingScheme(forTBH2));
148  } else {
149  scheme = new HcalNumberingScheme();
150  }
152 
153  // always call getFromLibrary() method to identify HF region
154  setParameterized(true);
155 
156  const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
157  // std::vector<G4LogicalVolume *>::const_iterator lvcite;
158  const G4LogicalVolume* lv;
159  std::string attribute, value;
160 
161  if (useHF) {
162  if (useParam) {
163  showerParam = std::make_unique<HFShowerParam>(name, hcalConstants_, hcalSimConstants_->hcalsimpar(), p);
164  } else {
165  if (useShowerLibrary) {
166  showerLibrary = std::make_unique<HFShowerLibrary>(name, hcalConstants_, hcalSimConstants_->hcalsimpar(), p);
167  }
168  hfshower = std::make_unique<HFShower>(name, hcalConstants_, hcalSimConstants_->hcalsimpar(), p, 0);
169  }
170 
171  // HF volume names
173  const std::vector<int>& temp = hcalSimConstants_->hcalsimpar()->hfLevels_;
174 #ifdef EDM_ML_DEBUG
175  std::stringstream ss0;
176  ss0 << "HCalSD: Names to be tested for Volume = HF has " << hfNames.size() << " elements";
177 #endif
178  int addlevel = dd4hep ? 1 : 0;
179  for (unsigned int i = 0; i < hfNames.size(); ++i) {
180  G4String namv(static_cast<std::string>(dd4hep::dd::noNamespace(hfNames[i])));
181  lv = nullptr;
182  for (auto lvol : *lvs) {
183  if (dd4hep::dd::noNamespace(lvol->GetName()) == namv) {
184  lv = lvol;
185  break;
186  }
187  }
188  hfLV.emplace_back(lv);
189  hfLevels.emplace_back(temp[i] + addlevel);
190 #ifdef EDM_ML_DEBUG
191  ss0 << "\n HF[" << i << "] = " << namv << " LV " << lv << " at level " << (temp[i] + addlevel);
192 #endif
193  }
194 #ifdef EDM_ML_DEBUG
195  edm::LogVerbatim("HcalSim") << ss0.str();
196 #endif
197  // HF Fibre volume names
200  const std::vector<std::string>& pmtNames = hcalSimConstants_->hcalsimpar()->hfPMTNames_;
201  fillLogVolumeVector("HFPMT", pmtNames, pmtLV);
202  const std::vector<std::string>& straightNames = hcalSimConstants_->hcalsimpar()->hfFibreStraightNames_;
203  fillLogVolumeVector("HFFibreBundleStraight", straightNames, fibre1LV);
204  const std::vector<std::string>& conicalNames = hcalSimConstants_->hcalsimpar()->hfFibreConicalNames_;
205  fillLogVolumeVector("HFFibreBundleConical", conicalNames, fibre2LV);
206  }
207 
208  //Material list for HB/HE/HO sensitive detectors
209  const G4MaterialTable* matTab = G4Material::GetMaterialTable();
210  std::vector<G4Material*>::const_iterator matite;
211  for (auto const& namx : matNames) {
212  const G4Material* mat = nullptr;
213  for (matite = matTab->begin(); matite != matTab->end(); ++matite) {
214  if (static_cast<std::string>(dd4hep::dd::noNamespace((*matite)->GetName())) == namx) {
215  mat = (*matite);
216  break;
217  }
218  }
219  materials.emplace_back(mat);
220  }
221 #ifdef EDM_ML_DEBUG
222  std::stringstream ss1;
223  for (unsigned int i = 0; i < matNames.size(); ++i) {
224  if (i / 10 * 10 == i) {
225  ss1 << "\n";
226  }
227  ss1 << " " << matNames[i];
228  }
229  edm::LogVerbatim("HcalSim") << "HCalSD: Material names for HCAL: " << ss1.str();
230 #endif
231  if (useLayerWt) {
233  }
234  numberingFromDDD = std::make_unique<HcalNumberingFromDDD>(hcalConstants_);
235 
236  //Special Geometry parameters
238 #ifdef EDM_ML_DEBUG
239  std::stringstream ss2;
240  for (unsigned int ig = 0; ig < gpar.size(); ig++) {
241  ss2 << "\n gpar[" << ig << "] = " << gpar[ig] / cm << " cm";
242  }
243  edm::LogVerbatim("HcalSim") << "Maximum depth for HF " << hcalConstants_->getMaxDepth(2) << gpar.size()
244  << " gpar (cm)" << ss2.str();
245 #endif
246 
247  //Test Hcal Numbering Scheme
248  if (testNS_)
249  m_HcalTestNS = std::make_unique<HcalTestNS>(hcnr);
250 
251  for (int i = 0; i < 9; ++i) {
252  hit_[i] = time_[i] = dist_[i] = nullptr;
253  }
254  hzvem = hzvhad = nullptr;
255 
256  if (agingFlagHF) {
257  m_HFDarkening = std::make_unique<HFDarkening>(m_HC.getParameter<edm::ParameterSet>("HFDarkeningParameterBlock"));
258  }
259 #ifdef plotDebug
261 
262  if (tfile.isAvailable()) {
263  static const char* const labels[] = {"HB",
264  "HE",
265  "HO",
266  "HF Absorber",
267  "HF PMT",
268  "HF Absorber Long",
269  "HF Absorber Short",
270  "HF PMT Long",
271  "HF PMT Short"};
272  TFileDirectory hcDir = tfile->mkdir("ProfileFromHCalSD");
273  char name[20], title[60];
274  for (int i = 0; i < 9; ++i) {
275  sprintf(title, "Hit energy in %s", labels[i]);
276  sprintf(name, "HCalSDHit%d", i);
277  hit_[i] = hcDir.make<TH1F>(name, title, 2000, 0., 2000.);
278  sprintf(title, "Energy (MeV)");
279  hit_[i]->GetXaxis()->SetTitle(title);
280  hit_[i]->GetYaxis()->SetTitle("Hits");
281  sprintf(title, "Time of the hit in %s", labels[i]);
282  sprintf(name, "HCalSDTime%d", i);
283  time_[i] = hcDir.make<TH1F>(name, title, 2000, 0., 2000.);
284  sprintf(title, "Time (ns)");
285  time_[i]->GetXaxis()->SetTitle(title);
286  time_[i]->GetYaxis()->SetTitle("Hits");
287  sprintf(title, "Longitudinal profile in %s", labels[i]);
288  sprintf(name, "HCalSDDist%d", i);
289  dist_[i] = hcDir.make<TH1F>(name, title, 2000, 0., 2000.);
290  sprintf(title, "Distance (mm)");
291  dist_[i]->GetXaxis()->SetTitle(title);
292  dist_[i]->GetYaxis()->SetTitle("Hits");
293  }
294  if (useHF && (!useParam)) {
295  hzvem = hcDir.make<TH1F>("hzvem", "Longitudinal Profile (EM Part)", 330, 0.0, 1650.0);
296  hzvem->GetXaxis()->SetTitle("Longitudinal Profile (EM Part)");
297  hzvhad = hcDir.make<TH1F>("hzvhad", "Longitudinal Profile (Had Part)", 330, 0.0, 1650.0);
298  hzvhad->GetXaxis()->SetTitle("Longitudinal Profile (Hadronic Part)");
299  }
300  }
301 #endif
302  if (dumpGeom) {
303  std::unique_ptr<HcalNumberingFromDDD> hcn = std::make_unique<HcalNumberingFromDDD>(hcalConstants_);
304  const auto& lvNames = clg.logicalNames(name);
305  HcalDumpGeometry geom(lvNames, hcn.get(), testNumber, false);
306  geom.update();
307  }
308 }
309 
311  const std::vector<std::string>& lvnames,
312  std::vector<const G4LogicalVolume*>& lvvec) {
313  const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
314  const G4LogicalVolume* lv;
315  std::stringstream ss3;
316  ss3 << "HCalSD: " << lvnames.size() << " names to be tested for Volume <" << value << ">:";
317  for (unsigned int i = 0; i < lvnames.size(); ++i) {
318  G4String namv(static_cast<std::string>(dd4hep::dd::noNamespace(lvnames[i])));
319  lv = nullptr;
320  for (auto lvol : *lvs) {
321  if (dd4hep::dd::noNamespace(lvol->GetName()) == namv) {
322  lv = lvol;
323  break;
324  }
325  }
326  lvvec.emplace_back(lv);
327  if (i / 10 * 10 == i) {
328  ss3 << "\n";
329  }
330  ss3 << " " << namv;
331  }
332  edm::LogVerbatim("HcalSim") << ss3.str();
333 }
334 
335 bool HCalSD::getFromLibrary(const G4Step* aStep) {
336  auto const track = aStep->GetTrack();
337  depth_ = (aStep->GetPreStepPoint()->GetTouchable()->GetReplicaNumber(0)) % 10;
338  weight_ = 1.0;
339  bool kill(false);
340  isHF = isItHF(aStep);
341 #ifdef EDM_ML_DEBUG
342  edm::LogVerbatim("HcalSim") << "GetFromLibrary: "
343  << (aStep->GetPreStepPoint()->GetTouchable()->GetVolume(0)->GetName())
344 
345  << " isHF " << isHF << " darken " << (m_HFDarkening != nullptr) << " useParam "
346  << useParam << " useShowerLibrary " << useShowerLibrary << " Muon? "
347  << G4TrackToParticleID::isMuon(track) << " electron? "
348  << G4TrackToParticleID::isGammaElectronPositron(track) << " Stable Hadron? "
350 #endif
351  if (isHF) {
352  if (m_HFDarkening) {
353  G4ThreeVector hitPoint = aStep->GetPreStepPoint()->GetPosition();
354  const double invcm = 1. / CLHEP::cm;
355  double r = hitPoint.perp() * invcm;
356  double z = std::abs(hitPoint.z()) * invcm;
357  double dose_acquired = 0.;
359  unsigned int hfZLayer = (unsigned int)((z - HFDarkening::lowZLimit) / 5);
360  if (hfZLayer >= HFDarkening::upperZLimit)
361  hfZLayer = (HFDarkening::upperZLimit - 1);
362  float normalized_lumi = m_HFDarkening->int_lumi(deliveredLumi);
363  for (int i = hfZLayer; i != HFDarkening::numberOfZLayers; ++i) {
364  dose_acquired = m_HFDarkening->dose(i, r);
365  weight_ *= m_HFDarkening->degradation(normalized_lumi * dose_acquired);
366  }
367  }
368 #ifdef EDM_ML_DEBUG
369  edm::LogVerbatim("HcalSim") << "HCalSD::getFromLibrary: HFLumiDarkening at "
370  << "r= " << r << ", z= " << z << " Dose= " << dose_acquired << " weight= " << weight_;
371 #endif
372  }
373 
374  if (useParam) {
375  getFromParam(aStep, kill);
376 #ifdef EDM_ML_DEBUG
377  G4String nameVolume = aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetName();
378  edm::LogVerbatim("HcalSim") << "HCalSD: " << getNumberOfHits() << " hits from parametrization in " << nameVolume
379  << " for Track " << track->GetTrackID() << " ("
380  << track->GetDefinition()->GetParticleName() << ")";
381 #endif
384 #ifdef EDM_ML_DEBUG
385  auto nameVolume = aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetName();
386  edm::LogVerbatim("HcalSim") << "HCalSD: Starts shower library from " << nameVolume << " for Track "
387  << track->GetTrackID() << " (" << track->GetDefinition()->GetParticleName() << ")";
388 
389 #endif
390  getFromHFLibrary(aStep, kill);
391  }
392  }
393  }
394 #ifdef EDM_ML_DEBUG
395  edm::LogVerbatim("HcalSim") << "HCalSD::getFromLibrary ID= " << track->GetTrackID() << " ("
396  << track->GetDefinition()->GetParticleName() << ") kill= " << kill
397  << " weight= " << weight_ << " depth= " << depth_ << " isHF: " << isHF;
398 #endif
399  return kill;
400 }
401 
402 double HCalSD::getEnergyDeposit(const G4Step* aStep) {
403  double destep(0.0);
404  auto const lv = aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume();
405  auto const theTrack = aStep->GetTrack();
406 
407  if (isHF) {
408  if (useShowerLibrary && G4TrackToParticleID::isMuon(theTrack) && isItFibre(lv)) {
409 #ifdef EDM_ML_DEBUG
410  edm::LogVerbatim("HcalSim") << "HCalSD: Hit at Fibre in LV " << lv->GetName() << " for track "
411  << aStep->GetTrack()->GetTrackID() << " ("
412  << aStep->GetTrack()->GetDefinition()->GetParticleName() << ")";
413 #endif
414  hitForFibre(aStep);
415  }
416  return destep;
417  }
418 
419  if (isItPMT(lv)) {
420  if (usePMTHit && showerPMT) {
421  getHitPMT(aStep);
422  }
423 #ifdef EDM_ML_DEBUG
424  edm::LogVerbatim("HcalSim") << "HCalSD: Hit from PMT parametrization in LV " << lv->GetName() << " for Track "
425  << aStep->GetTrack()->GetTrackID() << " ("
426  << aStep->GetTrack()->GetDefinition()->GetParticleName() << ")";
427 #endif
428  return destep;
429 
430  } else if (isItStraightBundle(lv)) {
431  if (useFibreBundle && showerBundle) {
432  getHitFibreBundle(aStep, false);
433  }
434 #ifdef EDM_ML_DEBUG
435  edm::LogVerbatim("HcalSim") << "HCalSD: Hit from straight FibreBundle in LV: " << lv->GetName() << " for track "
436  << aStep->GetTrack()->GetTrackID() << " ("
437  << aStep->GetTrack()->GetDefinition()->GetParticleName() << ")";
438 #endif
439  return destep;
440 
441  } else if (isItConicalBundle(lv)) {
442  if (useFibreBundle && showerBundle) {
443  getHitFibreBundle(aStep, true);
444  }
445 #ifdef EDM_ML_DEBUG
446  edm::LogVerbatim("HcalSim") << "HCalSD: Hit from conical FibreBundle PV: " << lv->GetName() << " for track "
447  << aStep->GetTrack()->GetTrackID() << " ("
448  << aStep->GetTrack()->GetDefinition()->GetParticleName() << ")";
449 #endif
450  return destep;
451  }
452 
453  // normal hit
454  destep = aStep->GetTotalEnergyDeposit();
455 
456  const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
457  uint32_t detid = setDetUnitId(aStep);
458  int det(0), ieta(0), phi(0), z(0), lay, depth(-1);
459  if (testNumber) {
460  HcalTestNumbering::unpackHcalIndex(detid, det, z, depth, ieta, phi, lay);
461  if (z == 0) {
462  z = -1;
463  }
464  } else {
465  HcalDetId hcid(detid);
466  det = hcid.subdetId();
467  ieta = hcid.ietaAbs();
468  phi = hcid.iphi();
469  z = hcid.zside();
470  }
471  lay = (touch->GetReplicaNumber(0) / 10) % 100 + 1;
472 #ifdef EDM_ML_DEBUG
473  edm::LogVerbatim("HcalSim") << "HCalSD: det: " << det << " ieta: " << ieta << " iphi: " << phi << " zside " << z
474  << " lay: " << lay - 2;
475 #endif
476  if (depth_ == 0 && (det == 1 || det == 2) && ((!testNumber) || neutralDensity))
478  if (useLayerWt) {
479  G4ThreeVector hitPoint = aStep->GetPreStepPoint()->GetPosition();
480  weight_ = layerWeight(det + 2, hitPoint, depth_, lay);
481  }
482 
483  if (agingFlagHB && m_HBDarkening && det == 1) {
484  double dweight = m_HBDarkening->degradation(deliveredLumi, ieta, lay);
485  weight_ *= dweight;
486 #ifdef EDM_ML_DEBUG
487  edm::LogVerbatim("HcalSim") << "HCalSD: HB Lumi: " << deliveredLumi << " coefficient = " << dweight
488  << " Weight= " << weight_;
489 #endif
490  }
491 
492  if (agingFlagHE && m_HEDarkening && det == 2) {
493  double dweight = m_HEDarkening->degradation(deliveredLumi, ieta, lay);
494  weight_ *= dweight;
495 #ifdef EDM_ML_DEBUG
496  edm::LogVerbatim("HcalSim") << "HCalSD: HB Lumi: " << deliveredLumi << " coefficient = " << dweight
497  << " Weight= " << weight_;
498 #endif
499  }
500 
501  if (suppressHeavy) {
502  TrackInformation* trkInfo = (TrackInformation*)(theTrack->GetUserInformation());
503  if (trkInfo) {
504  int pdg = theTrack->GetDefinition()->GetPDGEncoding();
505  if (!(trkInfo->isPrimary())) { // Only secondary particles
506  double ke = theTrack->GetKineticEnergy();
507  if (pdg / 1000000000 == 1 && (pdg / 10000) % 100 > 0 && (pdg / 10) % 100 > 0 && ke < kmaxIon)
508  weight_ = 0;
509  if ((pdg == 2212) && (ke < kmaxProton))
510  weight_ = 0;
511  if ((pdg == 2112) && (ke < kmaxNeutron))
512  weight_ = 0;
513  }
514  }
515  }
516  double wt0(1.0);
517  if (useBirk) {
518  const G4Material* mat = aStep->GetPreStepPoint()->GetMaterial();
519  if (isItScintillator(mat))
520  wt0 = getAttenuation(aStep, birk1, birk2, birk3);
521  }
522  weight_ *= wt0;
523  double wt1 = getResponseWt(theTrack);
524  double wt2 = theTrack->GetWeight();
525  double edep = weight_ * wt1 * destep;
526  if (wt2 > 0.0) {
527  edep *= wt2;
528  }
529 #ifdef EDM_ML_DEBUG
530  edm::LogVerbatim("HcalSim") << "HCalSD: edep= " << edep << " Det: " << det + 2 << " depth= " << depth_
531  << " weight= " << weight_ << " wt0= " << wt0 << " wt1= " << wt1 << " wt2= " << wt2;
532 #endif
533  return edep;
534 }
535 
536 uint32_t HCalSD::setDetUnitId(const G4Step* aStep) {
537  auto const prePoint = aStep->GetPreStepPoint();
538  auto const touch = prePoint->GetTouchable();
539  const G4ThreeVector& hitPoint = prePoint->GetPosition();
540 
541  int depth = (touch->GetReplicaNumber(0)) % 10 + 1;
542  int lay = (touch->GetReplicaNumber(0) / 10) % 100 + 1;
543  int det = (touch->GetReplicaNumber(1)) / 1000;
544 
545  uint32_t idx = setDetUnitId(det, hitPoint, depth, lay);
546 #ifdef EDM_ML_DEBUG
547  if (depth == 1) {
548  edm::LogVerbatim("HcalSim") << "HCalSD: Check for " << det << ":" << depth << ":" << lay << " ID " << std::hex
549  << idx << std::dec;
550  int det0, z0, depth0, eta0, phi0, lay0(-1);
551  if (testNumber) {
552  HcalTestNumbering::unpackHcalIndex(idx, det0, z0, depth0, eta0, phi0, lay0);
553  } else {
554  HcalDetId hcid0(idx);
555  det0 = hcid0.subdetId();
556  eta0 = hcid0.ietaAbs();
557  phi0 = hcid0.iphi();
558  z0 = hcid0.zside();
559  depth0 = hcid0.depth();
560  }
561  edm::LogVerbatim("HcalSim") << "HCalSD: det|z|depth|eta|phi|lay " << det0 << ":" << z0 << ":" << depth0 << ":"
562  << eta0 << ":" << phi0 << ":" << lay0;
563  printVolume(touch);
564  }
565 #endif
566  return idx;
567 }
568 
570  if (scheme != nullptr) {
571  edm::LogVerbatim("HcalSim") << "HCalSD: updates numbering scheme for " << GetName();
572  numberingScheme.reset(scheme);
573  }
574 }
575 
576 void HCalSD::update(const BeginOfJob* job) {}
577 
579 
580 bool HCalSD::filterHit(CaloG4Hit* aHit, double time) {
581  double threshold = 0;
582  DetId theId(aHit->getUnitID());
583  switch (theId.subdetId()) {
584  case HcalBarrel:
586  break;
587  case HcalEndcap:
589  break;
590  case HcalOuter:
592  break;
593  case HcalForward:
595  break;
596  default:
597  break;
598  }
599  return ((time <= tmaxHit) && (aHit->getEnergyDeposit() > threshold));
600 }
601 
602 uint32_t HCalSD::setDetUnitId(int det, const G4ThreeVector& pos, int depth, int lay = 1) {
603  uint32_t id = 0;
604  if (det == 0) {
605 #ifdef printDebug
606  double eta = std::abs(pos.eta());
607 #endif
608  if (std::abs(pos.z()) > maxZ_) {
609  det = 5;
610 #ifdef printDebug
611  if (eta < 2.868)
612  ++detNull_[2];
613 #endif
614  } else if (!(hcalConstants_->isHE())) {
615  det = 3;
616 #ifdef printDebug
617  ++detNull_[0];
618 #endif
619  } else {
620  double minR = minRoff_ + slopeHE_ * std::abs(pos.z());
621  double maxR = maxRoff_ + slopeHE_ * std::abs(pos.z());
622  det = ((pos.perp() > minR) && (pos.perp() < maxR)) ? 4 : 3;
623 #ifdef printDebug
624  ++detNull_[det - 3];
625 #endif
626  }
627 #ifdef printDEBUG
628  edm::LogVerbatim("HcalSim") << "Position " << pos.perp() << ":" << std::abs(pos.z()) << " Limits "
629  << !(hcalConstants_->isHE()) << ":" << maxZ_ << " det " << det;
630  } else {
631  ++detNull_[3];
632 #endif
633  }
634 
635  if (numberingFromDDD.get()) {
636  //get the ID's as eta, phi, depth, ... indices
638  numberingFromDDD->unitID(det, math::XYZVectorD(pos.x(), pos.y(), pos.z()), depth, lay);
639  id = setDetUnitId(tmp);
640  }
641  return id;
642 }
643 
645  modifyDepth(tmp);
646  uint32_t id = (numberingScheme.get()) ? numberingScheme->getUnitID(tmp) : 0;
647  if ((!testNumber) && m_HcalTestNS.get()) {
648  bool ok = m_HcalTestNS->compare(tmp, id);
649  if (!ok)
650  edm::LogWarning("HcalSim") << "Det ID from HCalSD " << HcalDetId(id) << " " << std::hex << id << std::dec
651  << " does not match one from relabller for " << tmp.subdet << ":" << tmp.etaR << ":"
652  << tmp.phi << ":" << tmp.phis << ":" << tmp.depth << ":" << tmp.lay << std::endl;
653  }
654  return id;
655 }
656 
657 bool HCalSD::isItHF(const G4Step* aStep) {
658  const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
659  int levels = (touch->GetHistoryDepth()) + 1;
660  for (unsigned int it = 0; it < hfNames.size(); ++it) {
661  if (levels >= hfLevels[it]) {
662  const G4LogicalVolume* lv = touch->GetVolume(levels - hfLevels[it])->GetLogicalVolume();
663  if (lv == hfLV[it])
664  return true;
665  }
666  }
667  return false;
668 }
669 
670 bool HCalSD::isItHF(const G4String& name) {
671  for (const auto& nam : hfNames)
672  if (name == static_cast<G4String>(nam)) {
673  return true;
674  }
675  return false;
676 }
677 
678 bool HCalSD::isItFibre(const G4LogicalVolume* lv) {
679  for (auto lvol : fibreLV)
680  if (lv == lvol) {
681  return true;
682  }
683  return false;
684 }
685 
686 bool HCalSD::isItFibre(const G4String& name) {
687  for (const auto& nam : fibreNames)
688  if (name == static_cast<G4String>(nam)) {
689  return true;
690  }
691  return false;
692 }
693 
694 bool HCalSD::isItPMT(const G4LogicalVolume* lv) {
695  for (auto lvol : pmtLV)
696  if (lv == lvol) {
697  return true;
698  }
699  return false;
700 }
701 
702 bool HCalSD::isItStraightBundle(const G4LogicalVolume* lv) {
703  for (auto lvol : fibre1LV)
704  if (lv == lvol) {
705  return true;
706  }
707  return false;
708 }
709 
710 bool HCalSD::isItConicalBundle(const G4LogicalVolume* lv) {
711  for (auto lvol : fibre2LV)
712  if (lv == lvol) {
713  return true;
714  }
715  return false;
716 }
717 
718 bool HCalSD::isItScintillator(const G4Material* mat) {
719  for (auto amat : materials)
720  if (amat == mat) {
721  return true;
722  }
723  return false;
724 }
725 
726 bool HCalSD::isItinFidVolume(const G4ThreeVector& hitPoint) {
727  bool flag = true;
728  if (applyFidCut) {
729  int npmt = HFFibreFiducial::PMTNumber(hitPoint);
730 #ifdef EDM_ML_DEBUG
731  edm::LogVerbatim("HcalSim") << "HCalSD::isItinFidVolume:#PMT= " << npmt << " for hit point " << hitPoint;
732 #endif
733  if (npmt <= 0)
734  flag = false;
735  }
736 #ifdef EDM_ML_DEBUG
737  edm::LogVerbatim("HcalSim") << "HCalSD::isItinFidVolume: point " << hitPoint << " return flag " << flag;
738 #endif
739  return flag;
740 }
741 
742 void HCalSD::getFromHFLibrary(const G4Step* aStep, bool& isKilled) {
743  std::vector<HFShowerLibrary::Hit> hits = showerLibrary->getHits(aStep, isKilled, weight_, false);
744  if (!isKilled || hits.empty()) {
745  return;
746  }
747 
748  int primaryID = setTrackID(aStep);
749 
750  // Reset entry point for new primary
751  resetForNewPrimary(aStep);
752 
753  auto const theTrack = aStep->GetTrack();
754  int det = 5;
755 
757  edepositEM = 1. * GeV;
758  edepositHAD = 0.;
759  } else {
760  edepositEM = 0.;
761  edepositHAD = 1. * GeV;
762  }
763 #ifdef EDM_ML_DEBUG
764  edm::LogVerbatim("HcalSim") << "HCalSD::getFromLibrary " << hits.size() << " hits for " << GetName() << " of "
765  << primaryID << " with " << theTrack->GetDefinition()->GetParticleName() << " of "
766  << aStep->GetPreStepPoint()->GetKineticEnergy() / GeV << " GeV";
767 #endif
768  for (unsigned int i = 0; i < hits.size(); ++i) {
769  G4ThreeVector hitPoint = hits[i].position;
770  if (isItinFidVolume(hitPoint)) {
771  int depth = hits[i].depth;
772  double time = hits[i].time;
773  unsigned int unitID = setDetUnitId(det, hitPoint, depth);
774  currentID[0].setID(unitID, time, primaryID, 0);
775 #ifdef plotDebug
776  plotProfile(aStep, hitPoint, 1.0 * GeV, time, depth);
777  bool emType = G4TrackToParticleID::isGammaElectronPositron(theTrack->GetDefinition()->GetPDGEncoding());
778  plotHF(hitPoint, emType);
779 #endif
780  processHit(aStep);
781  }
782  }
783 }
784 
785 void HCalSD::hitForFibre(const G4Step* aStep) { // if not ParamShower
786 
787  std::vector<HFShower::Hit> hits = hfshower->getHits(aStep, weight_);
788  if (hits.empty()) {
789  return;
790  }
791 
792  auto const theTrack = aStep->GetTrack();
793  int primaryID = setTrackID(aStep);
794  int det = 5;
795 
797  edepositEM = 1. * GeV;
798  edepositHAD = 0.;
799  } else {
800  edepositEM = 0.;
801  edepositHAD = 1. * GeV;
802  }
803 
804 #ifdef EDM_ML_DEBUG
805  edm::LogVerbatim("HcalSim") << "HCalSD::hitForFibre " << hits.size() << " hits for " << GetName() << " of "
806  << primaryID << " with " << theTrack->GetDefinition()->GetParticleName() << " of "
807  << aStep->GetPreStepPoint()->GetKineticEnergy() / GeV << " GeV in detector type " << det;
808 #endif
809 
810  for (unsigned int i = 0; i < hits.size(); ++i) {
811  G4ThreeVector hitPoint = hits[i].position;
812  if (isItinFidVolume(hitPoint)) {
813  int depth = hits[i].depth;
814  double time = hits[i].time;
815  unsigned int unitID = setDetUnitId(det, hitPoint, depth);
816  currentID[0].setID(unitID, time, primaryID, 0);
817 #ifdef plotDebug
818  plotProfile(aStep, hitPoint, edepositEM, time, depth);
819  bool emType = (edepositEM > 0.) ? true : false;
820  plotHF(hitPoint, emType);
821 #endif
822  processHit(aStep);
823  }
824  }
825 }
826 
827 void HCalSD::getFromParam(const G4Step* aStep, bool& isKilled) {
828  std::vector<HFShowerParam::Hit> hits = showerParam->getHits(aStep, weight_, isKilled);
829  if (!isKilled || hits.empty()) {
830  return;
831  }
832 
833  int primaryID = setTrackID(aStep);
834  int det = 5;
835 
836 #ifdef EDM_ML_DEBUG
837  edm::LogVerbatim("HcalSim") << "HCalSD::getFromParam " << hits.size() << " hits for " << GetName() << " of "
838  << primaryID << " with " << aStep->GetTrack()->GetDefinition()->GetParticleName()
839  << " of " << aStep->GetPreStepPoint()->GetKineticEnergy() / GeV
840  << " GeV in detector type " << det;
841 #endif
842  for (unsigned int i = 0; i < hits.size(); ++i) {
843  G4ThreeVector hitPoint = hits[i].position;
844  int depth = hits[i].depth;
845  double time = hits[i].time;
846  unsigned int unitID = setDetUnitId(det, hitPoint, depth);
847  currentID[0].setID(unitID, time, primaryID, 0);
848  edepositEM = hits[i].edep * GeV;
849  edepositHAD = 0.;
850 #ifdef plotDebug
851  plotProfile(aStep, hitPoint, edepositEM, time, depth);
852 #endif
853  processHit(aStep);
854  }
855 }
856 
857 void HCalSD::getHitPMT(const G4Step* aStep) {
858  auto const preStepPoint = aStep->GetPreStepPoint();
859  auto const theTrack = aStep->GetTrack();
860  double edep = showerPMT->getHits(aStep);
861 
862  if (edep >= 0.) {
863  edep *= GeV;
864  double etrack = preStepPoint->GetKineticEnergy();
865  int primaryID = 0;
866  if (etrack >= energyCut) {
867  primaryID = theTrack->GetTrackID();
868  } else {
869  primaryID = theTrack->GetParentID();
870  if (primaryID == 0)
871  primaryID = theTrack->GetTrackID();
872  }
873  // Reset entry point for new primary
874  resetForNewPrimary(aStep);
875  //
876  int det = static_cast<int>(HcalForward);
877  const G4ThreeVector& hitPoint = preStepPoint->GetPosition();
878  double rr = (hitPoint.x() * hitPoint.x() + hitPoint.y() * hitPoint.y());
879  double phi = (rr == 0. ? 0. : atan2(hitPoint.y(), hitPoint.x()));
880  double etaR = showerPMT->getRadius();
881  int depth = 1;
882  if (etaR < 0) {
883  depth = 2;
884  etaR = -etaR;
885  }
886  if (hitPoint.z() < 0)
887  etaR = -etaR;
888 #ifdef EDM_ML_DEBUG
889  edm::LogVerbatim("HcalSim") << "HCalSD::Hit for Detector " << det << " etaR " << etaR << " phi " << phi / deg
890  << " depth " << depth;
891 #endif
892  double time = (aStep->GetPostStepPoint()->GetGlobalTime());
893  uint32_t unitID = 0;
894  if (numberingFromDDD) {
895  HcalNumberingFromDDD::HcalID tmp = numberingFromDDD->unitID(det, etaR, phi, depth, 1);
896  unitID = setDetUnitId(tmp);
897  }
898  currentID[0].setID(unitID, time, primaryID, 1);
899 
900  edepositHAD = aStep->GetTotalEnergyDeposit();
901  edepositEM = -edepositHAD + edep;
902 #ifdef plotDebug
903  plotProfile(aStep, hitPoint, edep, time, depth);
904 #endif
905 #ifdef EDM_ML_DEBUG
906  double beta = preStepPoint->GetBeta();
907  edm::LogVerbatim("HcalSim") << "HCalSD::getHitPMT 1 hit for " << GetName() << " of " << primaryID << " with "
908  << theTrack->GetDefinition()->GetParticleName() << " of "
909  << preStepPoint->GetKineticEnergy() / GeV << " GeV with velocity " << beta << " UnitID "
910  << std::hex << unitID << std::dec;
911 #endif
912  processHit(aStep);
913  }
914 }
915 
916 void HCalSD::getHitFibreBundle(const G4Step* aStep, bool type) {
917  auto const preStepPoint = aStep->GetPreStepPoint();
918  auto const theTrack = aStep->GetTrack();
919  double edep = showerBundle->getHits(aStep, type);
920 
921  if (edep >= 0.0) {
922  edep *= GeV;
923  double etrack = preStepPoint->GetKineticEnergy();
924  int primaryID = 0;
925  if (etrack >= energyCut) {
926  primaryID = theTrack->GetTrackID();
927  } else {
928  primaryID = theTrack->GetParentID();
929  if (primaryID == 0)
930  primaryID = theTrack->GetTrackID();
931  }
932  // Reset entry point for new primary
933  resetForNewPrimary(aStep);
934  //
935  int det = static_cast<int>(HcalForward);
936  const G4ThreeVector& hitPoint = preStepPoint->GetPosition();
937  double rr = hitPoint.x() * hitPoint.x() + hitPoint.y() * hitPoint.y();
938  double phi = rr == 0. ? 0. : atan2(hitPoint.y(), hitPoint.x());
939  double etaR = showerBundle->getRadius();
940  int depth = 1;
941  if (etaR < 0.) {
942  depth = 2;
943  etaR = -etaR;
944  }
945  if (hitPoint.z() < 0.)
946  etaR = -etaR;
947 #ifdef EDM_ML_DEBUG
948  edm::LogVerbatim("HcalSim") << "HCalSD::Hit for Detector " << det << " etaR " << etaR << " phi " << phi / deg
949  << " depth " << depth;
950 #endif
951  double time = (aStep->GetPostStepPoint()->GetGlobalTime());
952  uint32_t unitID = 0;
953  if (numberingFromDDD) {
954  HcalNumberingFromDDD::HcalID tmp = numberingFromDDD->unitID(det, etaR, phi, depth, 1);
955  unitID = setDetUnitId(tmp);
956  }
957  if (type)
958  currentID[0].setID(unitID, time, primaryID, 3);
959  else
960  currentID[0].setID(unitID, time, primaryID, 2);
961 
962  edepositHAD = aStep->GetTotalEnergyDeposit();
963  edepositEM = -edepositHAD + edep;
964 #ifdef plotDebug
965  plotProfile(aStep, hitPoint, edep, time, depth);
966 #endif
967 #ifdef EDM_ML_DEBUG
968  double beta = preStepPoint->GetBeta();
969  edm::LogVerbatim("HcalSim") << "HCalSD::getHitFibreBundle 1 hit for " << GetName() << " of " << primaryID
970  << " with " << theTrack->GetDefinition()->GetParticleName() << " of "
971  << preStepPoint->GetKineticEnergy() / GeV << " GeV with velocity " << beta << " UnitID "
972  << std::hex << unitID << std::dec;
973 #endif
974  processHit(aStep);
975  } // non-zero energy deposit
976 }
977 
979  std::ifstream infile;
980  int entry = 0;
981  infile.open(fName.c_str(), std::ios::in);
982  if (infile) {
983  int det, zside, etaR, phi, lay;
984  double wt;
985  while (infile >> det >> zside >> etaR >> phi >> lay >> wt) {
986  uint32_t id = HcalTestNumbering::packHcalIndex(det, zside, 1, etaR, phi, lay);
987  layerWeights.insert(std::pair<uint32_t, double>(id, wt));
988  ++entry;
989 #ifdef EDM_ML_DEBUG
990  edm::LogVerbatim("HcalSim") << "HCalSD::readWeightFromFile:Entry " << entry << " ID " << std::hex << id
991  << std::dec << " (" << det << "/" << zside << "/1/" << etaR << "/" << phi << "/"
992  << lay << ") Weight " << wt;
993 #endif
994  }
995  infile.close();
996  }
997  edm::LogVerbatim("HcalSim") << "HCalSD::readWeightFromFile: reads " << entry << " weights from " << fName;
998  if (entry <= 0)
999  useLayerWt = false;
1000 }
1001 
1002 double HCalSD::layerWeight(int det, const G4ThreeVector& pos, int depth, int lay) {
1003  double wt = 1.;
1004  if (numberingFromDDD) {
1005  //get the ID's as eta, phi, depth, ... indices
1007  numberingFromDDD->unitID(det, math::XYZVectorD(pos.x(), pos.y(), pos.z()), depth, lay);
1008  modifyDepth(tmp);
1009  uint32_t id = HcalTestNumbering::packHcalIndex(tmp.subdet, tmp.zside, 1, tmp.etaR, tmp.phis, tmp.lay);
1010  std::map<uint32_t, double>::const_iterator ite = layerWeights.find(id);
1011  if (ite != layerWeights.end())
1012  wt = ite->second;
1013 #ifdef EDM_ML_DEBUG
1014  edm::LogVerbatim("HcalSim") << "HCalSD::layerWeight: ID " << std::hex << id << std::dec << " (" << tmp.subdet << "/"
1015  << tmp.zside << "/1/" << tmp.etaR << "/" << tmp.phis << "/" << tmp.lay << ") Weight "
1016  << wt;
1017 #endif
1018  }
1019  return wt;
1020 }
1021 
1022 void HCalSD::plotProfile(const G4Step* aStep, const G4ThreeVector& global, double edep, double time, int id) {
1023  const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
1024  static const unsigned int names = 10;
1025  static const G4String modName[names] = {
1026  "HEModule", "HVQF", "HBModule", "MBAT", "MBBT", "MBBTC", "MBBT_R1P", "MBBT_R1M", "MBBT_R1PX", "MBBT_R1MX"};
1027  G4ThreeVector local;
1028  bool found = false;
1029  double depth = -2000;
1030  int idx = 4;
1031  for (int n = 0; n < touch->GetHistoryDepth(); ++n) {
1032  G4String name(static_cast<std::string>(dd4hep::dd::noNamespace(touch->GetVolume(n)->GetName())));
1033 #ifdef EDM_ML_DEBUG
1034  edm::LogVerbatim("HcalSim") << "plotProfile Depth " << n << " Name " << name;
1035 #endif
1036  for (unsigned int ii = 0; ii < names; ++ii) {
1037  if (name == modName[ii]) {
1038  found = true;
1039  int dn = touch->GetHistoryDepth() - n;
1040  local = touch->GetHistory()->GetTransform(dn).TransformPoint(global);
1041  if (ii == 0) {
1042  depth = local.z() - 4006.5;
1043  idx = 1;
1044  } else if (ii == 1) {
1045  depth = local.z() + 825.0;
1046  idx = 3;
1047  } else if (ii == 2) {
1048  depth = local.x() - 1775.;
1049  idx = 0;
1050  } else {
1051  depth = local.y() + 15.;
1052  idx = 2;
1053  }
1054  break;
1055  }
1056  }
1057  if (found)
1058  break;
1059  }
1060  if (!found)
1061  depth = std::abs(global.z()) - 11500;
1062 #ifdef EDM_ML_DEBUG
1063  edm::LogVerbatim("HcalSim") << "plotProfile Found " << found << " Global " << global << " Local " << local
1064  << " depth " << depth << " ID " << id << " EDEP " << edep << " Time " << time;
1065 #endif
1066  if (hit_[idx] != nullptr)
1067  hit_[idx]->Fill(edep);
1068  if (time_[idx] != nullptr)
1069  time_[idx]->Fill(time, edep);
1070  if (dist_[idx] != nullptr)
1071  dist_[idx]->Fill(depth, edep);
1072  int jd = 2 * idx + id - 7;
1073  if (jd >= 0 && jd < 4) {
1074  jd += 5;
1075  if (hit_[jd] != nullptr)
1076  hit_[jd]->Fill(edep);
1077  if (time_[jd] != nullptr)
1078  time_[jd]->Fill(time, edep);
1079  if (dist_[jd] != nullptr)
1080  dist_[jd]->Fill(depth, edep);
1081  }
1082 }
1083 
1084 void HCalSD::plotHF(const G4ThreeVector& hitPoint, bool emType) {
1085  double zv = std::abs(hitPoint.z()) - gpar[4];
1086  if (emType) {
1087  if (hzvem != nullptr)
1088  hzvem->Fill(zv);
1089  } else {
1090  if (hzvhad != nullptr)
1091  hzvhad->Fill(zv);
1092  }
1093 }
1094 
1096  if (id.subdet == 4) {
1097  int ieta = (id.zside == 0) ? -id.etaR : id.etaR;
1098  if (hcalConstants_->maxHFDepth(ieta, id.phis) > 2) {
1099  if (id.depth <= 2) {
1100  if (G4UniformRand() > 0.5)
1101  id.depth += 2;
1102  }
1103  }
1104  } else if ((id.subdet == 1 || id.subdet == 2) && testNumber) {
1105  id.depth = (depth_ == 0) ? 1 : 2;
1106  }
1107 }
1108 
1110 #ifdef printDebug
1111  detNull_ = {0, 0, 0, 0};
1112 #endif
1113 }
1114 
1116 #ifdef printDebug
1117  int sum = detNull_[0] + detNull_[1] + detNull_[2];
1118  if (sum > 0)
1119  edm::LogVerbatim("HcalSim") << "NullDets " << detNull_[0] << " " << detNull_[1] << " " << detNull_[2] << " "
1120  << detNull_[3] << " " << (static_cast<float>(sum) / (sum + detNull_[3]));
1121 #endif
1122 }
1123 
1124 void HCalSD::printVolume(const G4VTouchable* touch) const {
1125  if (touch) {
1126 #ifdef EDM_ML_DEBUG
1127  int level = ((touch->GetHistoryDepth()) + 1);
1128  edm::LogVerbatim("CaloSimX") << "HCalSD::printVolume with " << level << " levels";
1129  static const std::string unknown("Unknown");
1130  //Get name and copy numbers
1131  for (int ii = 0; ii < level; ii++) {
1132  int i = level - ii - 1;
1133  G4VPhysicalVolume* pv = touch->GetVolume(i);
1134  G4String name = (pv != nullptr) ? pv->GetName() : unknown;
1135  G4int copyno = touch->GetReplicaNumber(i);
1136  edm::LogVerbatim("HcalSim") << "[" << ii << "] " << name << ":" << copyno;
1137  }
1138 #endif
1139  }
1140 }
float edepositEM
Definition: CaloSD.h:144
int getNumberOfHits(int k=0)
Definition: CaloSD.cc:520
double energyCut
Definition: CaloSD.h:148
Log< level::Info, true > LogVerbatim
std::vector< std::string > matNames
Definition: HCalSD.h:121
void readWeightFromFile(const std::string &)
Definition: HCalSD.cc:978
bool isPrimary() const
std::vector< const G4LogicalVolume * > hfLV
Definition: HCalSD.h:123
bool useParam
Definition: HCalSD.h:112
double eminHitHE
Definition: HCalSD.h:113
TH1F * time_[9]
Definition: HCalSD.h:125
double kmaxNeutron
Definition: CaloSD.h:155
void hitForFibre(const G4Step *step)
Definition: HCalSD.cc:785
void initEvent(const BeginOfEvent *) override
Definition: HCalSD.cc:1109
static bool isMuon(int pdgCode)
constexpr int zside() const
get the z-side of the cell (1/-1)
Definition: HcalDetId.h:141
bool useLayerWt
Definition: HCalSD.h:109
Definition: CaloSD.h:40
std::vector< std::string > fibreNames
Definition: HCalSD.h:120
static constexpr double slopeHE_
Definition: HCalSD.h:106
std::unique_ptr< HFShowerParam > showerParam
Definition: HCalSD.h:92
double weight_
Definition: HCalSD.h:115
std::vector< double > gpar
Definition: HCalSD.h:117
bool useFibreBundle
Definition: HCalSD.h:109
constexpr int ietaAbs() const
get the absolute value of the cell ieta
Definition: HcalDetId.h:148
const HcalDDDSimConstants * hcalConstants_
Definition: HCalSD.h:96
double betaThr
Definition: HCalSD.h:111
std::vector< std::string > hfNames_
double deliveredLumi
Definition: HCalSD.h:114
int maxHFDepth(const int &ieta, const int &iphi) const
float degradation(float intlumi, int ieta, int lay) const
float *__restrict__ zv
std::vector< std::string > hfFibreNames_
void endEvent() override
Definition: HCalSD.cc:1115
double eminHitHB
Definition: HCalSD.h:113
bool useShowerLibrary
Definition: HCalSD.h:112
std::vector< std::string > hfNames
Definition: HCalSD.h:119
void plotProfile(const G4Step *step, const G4ThreeVector &pos, double edep, double time, int id)
Definition: HCalSD.cc:1022
double birk2
Definition: HCalSD.h:111
bool usePMTHit
Definition: HCalSD.h:109
double getLayer0Wt(const int &det, const int &phi, const int &zside) const
std::vector< const G4LogicalVolume * > fibre2LV
Definition: HCalSD.h:123
int zside(DetId const &)
static const unsigned int numberOfZLayers
Definition: HFDarkening.h:24
void modifyDepth(HcalNumberingFromDDD::HcalID &id)
Definition: HCalSD.cc:1095
void update(const BeginOfJob *) override
This routine will be called when the appropriate signal arrives.
Definition: HCalSD.cc:576
void setNumberingScheme(HcalNumberingScheme *)
Definition: HCalSD.cc:569
void processHit(const G4Step *step)
Definition: CaloSD.h:117
bool agingFlagHE
Definition: HCalSD.h:108
double birk1
Definition: HCalSD.h:111
double kmaxProton
Definition: CaloSD.h:155
const std::vector< std::string_view > logicalNames(const std::string &readoutName) const
std::unique_ptr< HFShowerPMT > showerPMT
Definition: HCalSD.h:93
const std::vector< double > & getGparHF() const
const std::string names[nVars_]
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
TH1F * hzvhad
Definition: HCalSD.h:125
bool isItConicalBundle(const G4LogicalVolume *)
Definition: HCalSD.cc:710
HCalSD(const std::string &, const HcalDDDSimConstants *, const HcalDDDRecConstants *, const HcalSimulationConstants *, const HBHEDarkening *, const HBHEDarkening *, const SensitiveDetectorCatalog &, edm::ParameterSet const &, const SimTrackManager *)
Definition: HCalSD.cc:43
double eminHitHF
Definition: HCalSD.h:113
const HcalSimulationParameters * hcalsimpar() const
T * make(const Args &...args) const
make new ROOT object
static constexpr double minRoff_
Definition: HCalSD.h:104
static uint32_t packHcalIndex(int det, int z, int depth, int eta, int phi, int lay)
std::unique_ptr< HcalNumberingFromDDD > numberingFromDDD
Definition: HCalSD.h:88
TH1F * hit_[9]
Definition: HCalSD.h:125
double getResponseWt(const G4Track *, int k=0)
Definition: CaloSD.cc:927
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > XYZVectorD
spatial vector with cartesian internal representation
Definition: Vector3D.h:8
#define EDM_ML_DEBUG
Definition: MPUnpacker.cc:1
bool agingFlagHB
Definition: HCalSD.h:108
bool testNumber
Definition: HCalSD.h:110
double kmaxIon
Definition: CaloSD.h:155
bool suppressHeavy
Definition: CaloSD.h:154
std::vector< std::string > hfFibreConicalNames_
bool useBirk
Definition: HCalSD.h:109
float edepositHAD
Definition: CaloSD.h:144
std::unique_ptr< HFDarkening > m_HFDarkening
Definition: HCalSD.h:100
double birk3
Definition: HCalSD.h:111
void resetForNewPrimary(const G4Step *)
Definition: CaloSD.cc:713
Definition: tfile.py:1
const HBHEDarkening * m_HEDarkening
Definition: HCalSD.h:99
bool applyFidCut
Definition: HCalSD.h:112
TH1F * dist_[9]
Definition: HCalSD.h:125
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void plotHF(const G4ThreeVector &pos, bool emType)
Definition: HCalSD.cc:1084
std::unique_ptr< HcalTestNS > m_HcalTestNS
Definition: HCalSD.h:101
static void unpackHcalIndex(const uint32_t &idx, int &det, int &z, int &depth, int &eta, int &phi, int &lay)
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
Definition: value.py:1
std::vector< int > hfLevels
Definition: HCalSD.h:118
void getFromParam(const G4Step *step, bool &isKilled)
Definition: HCalSD.cc:827
void getFromHFLibrary(const G4Step *step, bool &isKilled)
Definition: HCalSD.cc:742
uint32_t setDetUnitId(const G4Step *step) override
Definition: HCalSD.cc:536
bool isItStraightBundle(const G4LogicalVolume *)
Definition: HCalSD.cc:702
bool testNS_
Definition: HCalSD.h:110
ii
Definition: cuy.py:589
bool getFromLibrary(const G4Step *) override
Definition: HCalSD.cc:335
double eminHitHO
Definition: HCalSD.h:113
double tmaxHit
Definition: CaloSD.h:148
static bool isStableHadronIon(const G4Track *)
void setID(uint32_t unitID, double timeSlice, int trackID, uint16_t depth=0)
Definition: CaloHitID.cc:41
TH1F * hzvem
Definition: HCalSD.h:125
std::vector< const G4LogicalVolume * > pmtLV
Definition: HCalSD.h:123
int PMTNumber(const G4ThreeVector &pe_effect)
Definition: DetId.h:17
static const unsigned int lowZLimit
Definition: HFDarkening.h:27
bool filterHit(CaloG4Hit *, double) override
Definition: HCalSD.cc:580
static const unsigned int upperZLimit
Definition: HFDarkening.h:28
bool neutralDensity
Definition: HCalSD.h:110
bool isHF
Definition: HCalSD.h:107
void fillLogVolumeVector(const std::string &, const std::vector< std::string > &, std::vector< const G4LogicalVolume *> &)
Definition: HCalSD.cc:310
static constexpr double maxZ_
Definition: HCalSD.h:103
void getHitFibreBundle(const G4Step *step, bool type)
Definition: HCalSD.cc:916
std::vector< std::string > hcalMaterialNames_
double getEnergyDeposit(const G4Step *) override
Definition: HCalSD.cc:402
double getAttenuation(const G4Step *aStep, double birk1, double birk2, double birk3) const
Definition: CaloSD.cc:726
double getEnergyDeposit() const
Definition: CaloG4Hit.h:79
std::unique_ptr< HFShowerFibreBundle > showerBundle
Definition: HCalSD.h:94
std::vector< std::string > hfPMTNames_
bool isItPMT(const G4LogicalVolume *)
Definition: HCalSD.cc:694
bool isItinFidVolume(const G4ThreeVector &)
Definition: HCalSD.cc:726
uint32_t getUnitID() const
Definition: CaloG4Hit.h:66
bool isHF(int etabin, int depth)
void printVolume(const G4VTouchable *touch) const
Definition: HCalSD.cc:1124
void getHitPMT(const G4Step *step)
Definition: HCalSD.cc:857
std::vector< int > detNull_
Definition: HCalSD.h:126
std::unique_ptr< HFShowerLibrary > showerLibrary
Definition: HCalSD.h:90
double layerWeight(int, const G4ThreeVector &, int, int)
Definition: HCalSD.cc:1002
const HcalSimulationConstants * hcalSimConstants_
Definition: HCalSD.h:97
int depth_
Definition: HCalSD.h:116
HLT enums.
virtual int setTrackID(const G4Step *)
Definition: CaloSD.cc:890
std::map< uint32_t, double > layerWeights
Definition: HCalSD.h:124
bool isItHF(const G4Step *)
Definition: HCalSD.cc:657
static bool isGammaElectronPositron(int pdgCode)
bool isItScintillator(const G4Material *)
Definition: HCalSD.cc:718
std::vector< std::string > hfFibreStraightNames_
std::unique_ptr< HcalNumberingScheme > numberingScheme
Definition: HCalSD.h:89
CaloHitID currentID[2]
Definition: CaloSD.h:146
std::unique_ptr< HFShower > hfshower
Definition: HCalSD.h:91
std::vector< const G4LogicalVolume * > fibreLV
Definition: HCalSD.h:123
Log< level::Warning, false > LogWarning
std::vector< const G4LogicalVolume * > fibre1LV
Definition: HCalSD.h:123
tmp
align.sh
Definition: createJobs.py:716
std::vector< const G4Material * > materials
Definition: HCalSD.h:122
int getMaxDepth(const int &type) const
void initRun() override
Definition: HCalSD.cc:578
const HBHEDarkening * m_HBDarkening
Definition: HCalSD.h:98
constexpr int iphi() const
get the cell iphi
Definition: HcalDetId.h:157
static constexpr double maxRoff_
Definition: HCalSD.h:105
bool useHF
Definition: HCalSD.h:112
bool isItFibre(const G4LogicalVolume *)
Definition: HCalSD.cc:678
void setParameterized(bool val)
Definition: CaloSD.h:114
constexpr int depth() const
get the tower depth
Definition: HcalDetId.h:164