CMS 3D CMS Logo

CaloSD.cc
Go to the documentation of this file.
1 // File: CaloSD.cc
3 // Description: Sensitive Detector class for calorimeters
5 
15 
16 #include "G4EventManager.hh"
17 #include "G4LogicalVolumeStore.hh"
18 #include "G4LogicalVolume.hh"
19 #include "G4SDManager.hh"
20 #include "G4Step.hh"
21 #include "G4Track.hh"
22 #include "G4VProcess.hh"
23 #include "G4GFlashSpot.hh"
24 #include "G4ParticleTable.hh"
25 #include "G4SystemOfUnits.hh"
26 #include "G4PhysicalConstants.hh"
27 #include "DD4hep/Filter.h"
28 
29 #include <fstream>
30 #include <memory>
31 #include <sstream>
32 
33 //#define EDM_ML_DEBUG
34 
36  const edm::EventSetup& es,
37  const SensitiveDetectorCatalog& clg,
38  edm::ParameterSet const& p,
39  const SimTrackManager* manager,
40  float timeSliceUnit,
41  bool ignoreTkID)
42  : SensitiveCaloDetector(name, es, clg, p),
43  G4VGFlashSensitiveDetector(),
44  eminHit(0.),
45  currentHit(nullptr),
46  m_trackManager(manager),
47  theHC(nullptr),
48  ignoreTrackID(ignoreTkID),
49  hcID(-1),
50  timeSlice(timeSliceUnit),
51  eminHitD(0.) {
52  //Parameters
53  bool dd4hep = p.getParameter<bool>("g4GeometryDD4hepSource");
54  int addlevel = dd4hep ? 1 : 0;
55  edm::ParameterSet m_CaloSD = p.getParameter<edm::ParameterSet>("CaloSD");
56  energyCut = m_CaloSD.getParameter<double>("EminTrack") * CLHEP::GeV;
57  tmaxHit = m_CaloSD.getParameter<double>("TmaxHit") * CLHEP::ns;
58  std::vector<double> eminHits = m_CaloSD.getParameter<std::vector<double>>("EminHits");
59  std::vector<double> tmaxHits = m_CaloSD.getParameter<std::vector<double>>("TmaxHits");
60  std::vector<std::string> hcn = m_CaloSD.getParameter<std::vector<std::string>>("HCNames");
61  std::vector<int> useResMap = m_CaloSD.getParameter<std::vector<int>>("UseResponseTables");
62  std::vector<double> eminHitX = m_CaloSD.getParameter<std::vector<double>>("EminHitsDepth");
63  suppressHeavy = m_CaloSD.getParameter<bool>("SuppressHeavy");
64  kmaxIon = m_CaloSD.getParameter<double>("IonThreshold") * CLHEP::MeV;
65  kmaxProton = m_CaloSD.getParameter<double>("ProtonThreshold") * CLHEP::MeV;
66  kmaxNeutron = m_CaloSD.getParameter<double>("NeutronThreshold") * CLHEP::MeV;
67  nCheckedHits = m_CaloSD.getUntrackedParameter<int>("CheckHits", 25);
68  useMap = m_CaloSD.getUntrackedParameter<bool>("UseMap", true);
69  int verbn = m_CaloSD.getUntrackedParameter<int>("Verbosity", 0);
70  corrTOFBeam = m_CaloSD.getParameter<bool>("CorrectTOFBeam");
71  double beamZ = m_CaloSD.getParameter<double>("BeamPosition") * CLHEP::cm;
72  correctT = beamZ / CLHEP::c_light / CLHEP::nanosecond;
73  doFineCalo_ = m_CaloSD.getParameter<bool>("DoFineCalo");
74  eMinFine_ = m_CaloSD.getParameter<double>("EminFineTrack") * CLHEP::MeV;
75  std::vector<std::string> fineNames = m_CaloSD.getParameter<std::vector<std::string>>("FineCaloNames");
76  std::vector<int> fineLevels = m_CaloSD.getParameter<std::vector<int>>("FineCaloLevels");
77  std::vector<int> useFines = m_CaloSD.getParameter<std::vector<int>>("UseFineCalo");
78  for (auto& level : fineLevels)
79  level += addlevel;
80 
81  SetVerboseLevel(verbn);
82  meanResponse.reset(nullptr);
83  for (unsigned int k = 0; k < hcn.size(); ++k) {
84  if (name == hcn[k]) {
85  if (k < eminHits.size())
86  eminHit = eminHits[k] * CLHEP::MeV;
87  if (k < eminHitX.size())
88  eminHitD = eminHitX[k] * CLHEP::MeV;
89  if (k < tmaxHits.size())
90  tmaxHit = tmaxHits[k] * CLHEP::ns;
91  if (k < useResMap.size() && useResMap[k] > 0) {
92  meanResponse = std::make_unique<CaloMeanResponse>(p);
93  break;
94  }
95  }
96  }
97  slave = std::make_unique<CaloSlaveSD>(name);
98 
101  isParameterized = false;
102 
103  entrancePoint.set(0., 0., 0.);
104  entranceLocal.set(0., 0., 0.);
105  posGlobal.set(0., 0., 0.);
107 
109  forceSave = false;
110 
111  edm::LogVerbatim("CaloSim") << "CaloSD: Minimum energy of track for saving it " << energyCut / CLHEP::GeV
112  << " GeV\n Use of HitID Map " << useMap << "\n Check last " << nCheckedHits
113  << " before saving the hit\n Correct TOF globally by " << correctT
114  << " ns (Flag =" << corrTOFBeam << ")\n Save hits recorded before " << tmaxHit
115  << " ns and if energy is above " << eminHit / CLHEP::MeV << " MeV (for depth 0) or "
116  << eminHitD / CLHEP::MeV << " MeV (for nonzero depths);\n Time Slice Unit "
117  << timeSlice << "\nIgnore TrackID Flag " << ignoreTrackID << " doFineCalo flag "
118  << doFineCalo_;
119 
120  // Treat fine calorimeters
121  edm::LogVerbatim("CaloSim") << "CaloSD: Have a possibility of " << fineNames.size() << " fine calorimeters of which "
122  << useFines.size() << " are selected";
123  for (unsigned int k = 0; k < fineNames.size(); ++k)
124  edm::LogVerbatim("CaloSim") << "[" << k << "] " << fineNames[k] << " at " << fineLevels[k];
125  std::ostringstream st1;
126  for (unsigned int k = 0; k < useFines.size(); ++k)
127  st1 << " [" << k << "] " << useFines[k] << ":" << fineNames[useFines[k]];
128  edm::LogVerbatim("CaloSim") << "CaloSD used calorimeters" << st1.str();
129  const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
130  std::vector<G4LogicalVolume*>::const_iterator lvcite;
131  for (unsigned int i = 0; i < useFines.size(); i++) {
132  G4LogicalVolume* lv = nullptr;
133  G4String name = static_cast<G4String>(fineNames[useFines[i]]);
134  for (lvcite = lvs->begin(); lvcite != lvs->end(); lvcite++) {
135  G4String namx(static_cast<std::string>(dd4hep::dd::noNamespace((*lvcite)->GetName())));
136  if (namx == name) {
137  lv = (*lvcite);
138  break;
139  }
140  }
141  if (lv != nullptr) {
143  detector.name = name;
144  detector.lv = lv;
145  detector.level = fineLevels[useFines[i]];
146  fineDetectors_.emplace_back(detector);
147  }
148  }
149 #ifdef EDM_ML_DEBUG
150  edm::LogVerbatim("CaloSim") << "CaloSD::Loads information for " << fineDetectors_.size() << " fine detectors";
151  unsigned int k(0);
152  for (const auto& detector : fineDetectors_) {
153  edm::LogVerbatim("CaloSim") << "Detector[" << k << "] " << detector.name << " at level " << detector.level
154  << " pointer to LV: " << detector.lv;
155  }
156 #endif
157 }
158 
160 
161 G4bool CaloSD::ProcessHits(G4Step* aStep, G4TouchableHistory*) {
162  NaNTrap(aStep);
163  ignoreReject = false;
164 
165 #ifdef EDM_ML_DEBUG
166  edm::LogVerbatim("CaloSim") << "CaloSD::" << GetName() << " ID= " << aStep->GetTrack()->GetTrackID()
167  << " prID= " << aStep->GetTrack()->GetParentID()
168  << " Eprestep= " << aStep->GetPreStepPoint()->GetKineticEnergy()
169  << " step= " << aStep->GetStepLength() << " Edep= " << aStep->GetTotalEnergyDeposit();
170 #endif
171  // apply shower library or parameterisation
172  if (isParameterized) {
173  if (getFromLibrary(aStep)) {
174  // for parameterized showers the primary track should be killed
175  aStep->GetTrack()->SetTrackStatus(fStopAndKill);
176  auto tv = aStep->GetSecondary();
177  auto vol = aStep->GetPreStepPoint()->GetPhysicalVolume();
178  for (auto& tk : *tv) {
179  if (tk->GetVolume() == vol) {
180  tk->SetTrackStatus(fStopAndKill);
181  }
182  }
183  return true;
184  }
185  }
186 
187  // ignore steps without energy deposit
188  edepositEM = edepositHAD = 0.f;
189  unsigned int unitID = setDetUnitId(aStep);
190  auto const theTrack = aStep->GetTrack();
191  uint16_t depth = getDepth(aStep);
192 
193  double time = theTrack->GetGlobalTime() / nanosecond;
194  int primaryID = getTrackID(theTrack);
195  if (unitID > 0) {
196  currentID.setID(unitID, time, primaryID, depth);
197  } else {
198  if (aStep->GetTotalEnergyDeposit() > 0.0 && (!ignoreReject)) {
199  const G4TouchableHistory* touch = static_cast<const G4TouchableHistory*>(theTrack->GetTouchable());
200  edm::LogVerbatim("CaloSim") << "CaloSD::ProcessHits: unitID= " << unitID << " currUnit= " << currentID.unitID()
201  << " Detector: " << GetName() << " trackID= " << theTrack->GetTrackID() << " "
202  << theTrack->GetDefinition()->GetParticleName()
203  << "\n Edep= " << aStep->GetTotalEnergyDeposit()
204  << " PV: " << touch->GetVolume(0)->GetName()
205  << " PVid= " << touch->GetReplicaNumber(0) << " MVid= " << touch->GetReplicaNumber(1);
206  }
207  return false;
208  }
209 
210  if (aStep->GetTotalEnergyDeposit() == 0.0) {
211  return false;
212  }
213 
214  double energy = getEnergyDeposit(aStep);
215  if (energy > 0.0) {
217  edepositEM = energy;
218  } else {
220  }
221 #ifdef EDM_ML_DEBUG
222  G4TouchableHistory* touch = (G4TouchableHistory*)(theTrack->GetTouchable());
223  edm::LogVerbatim("CaloSim") << "CaloSD::" << GetName() << " PV:" << touch->GetVolume(0)->GetName()
224  << " PVid=" << touch->GetReplicaNumber(0) << " MVid=" << touch->GetReplicaNumber(1)
225  << " Unit:" << std::hex << unitID << std::dec << " Edep=" << edepositEM << " "
226  << edepositHAD << " ID=" << theTrack->GetTrackID() << " pID=" << theTrack->GetParentID()
227  << " E=" << theTrack->GetKineticEnergy() << " S=" << aStep->GetStepLength() << "\n "
228  << theTrack->GetDefinition()->GetParticleName() << " primaryID= " << primaryID
229  << " currentID= (" << currentID << ") previousID= (" << previousID << ")";
230 #endif
231  if (!hitExists(aStep)) {
232  currentHit = createNewHit(aStep, aStep->GetTrack());
233  } else {
234 #ifdef EDM_ML_DEBUG
235  edm::LogVerbatim("DoFineCalo") << "Not creating new hit, only updating currentHit " << currentHit->getUnitID();
236 #endif
237  }
238  return true;
239  }
240  return false;
241 }
242 
243 bool CaloSD::ProcessHits(G4GFlashSpot* aSpot, G4TouchableHistory*) {
244  edepositEM = edepositHAD = 0.f;
245  const G4Track* track = aSpot->GetOriginatorTrack()->GetPrimaryTrack();
246 
247  double edep = aSpot->GetEnergySpot()->GetEnergy();
248  if (edep <= 0.0) {
249  return false;
250  }
251 
252  G4Step fFakeStep;
253  G4StepPoint* fFakePreStepPoint = fFakeStep.GetPreStepPoint();
254  G4StepPoint* fFakePostStepPoint = fFakeStep.GetPostStepPoint();
255  fFakePreStepPoint->SetPosition(aSpot->GetPosition());
256  fFakePostStepPoint->SetPosition(aSpot->GetPosition());
257 
258  G4TouchableHandle fTouchableHandle = aSpot->GetTouchableHandle();
259  fFakePreStepPoint->SetTouchableHandle(fTouchableHandle);
260  fFakeStep.SetTotalEnergyDeposit(edep);
261  edep = EnergyCorrected(fFakeStep, track);
262  if (edep <= 0.0) {
263  return false;
264  }
265 
267  edepositEM = edep;
268  } else {
269  edepositHAD = edep;
270  }
271 
272  unsigned int unitID = setDetUnitId(&fFakeStep);
273 
274  if (unitID > 0) {
275  double time = 0;
276  int primaryID = getTrackID(track);
277  uint16_t depth = getDepth(&fFakeStep);
278  currentID.setID(unitID, time, primaryID, depth);
279 #ifdef EDM_ML_DEBUG
280  edm::LogVerbatim("CaloSim") << "CaloSD:: GetSpotInfo for Unit 0x" << std::hex << currentID.unitID() << std::dec
281  << " Edeposit = " << edepositEM << " " << edepositHAD;
282 #endif
283  // Update if in the same detector, time-slice and for same track
284  if (currentID == previousID) {
286  } else {
287  posGlobal = aSpot->GetEnergySpot()->GetPosition();
288  // Reset entry point for new primary
289  if (currentID.trackID() != previousID.trackID()) {
290  entrancePoint = aSpot->GetPosition();
291  entranceLocal = aSpot->GetTouchableHandle()->GetHistory()->GetTopTransform().TransformPoint(entrancePoint);
292  incidentEnergy = track->GetKineticEnergy();
293 #ifdef EDM_ML_DEBUG
294  edm::LogVerbatim("CaloSim") << "CaloSD: Incident energy " << incidentEnergy / CLHEP::GeV << " GeV and"
295  << " entrance point " << entrancePoint << " (Global) " << entranceLocal
296  << " (Local)";
297 #endif
298  }
299  if (!checkHit()) {
300  currentHit = createNewHit(&fFakeStep, track);
301  }
302  }
303  return true;
304  }
305  return false;
306 }
307 
308 double CaloSD::getEnergyDeposit(const G4Step* aStep) { return aStep->GetTotalEnergyDeposit(); }
309 
310 double CaloSD::EnergyCorrected(const G4Step& aStep, const G4Track*) { return aStep.GetTotalEnergyDeposit(); }
311 
312 bool CaloSD::getFromLibrary(const G4Step*) { return false; }
313 
314 bool CaloSD::isItFineCalo(const G4VTouchable* touch) {
315  bool ok(false);
316  int level = ((touch->GetHistoryDepth()) + 1);
317  for (const auto& detector : fineDetectors_) {
318  if (level > 0 && level >= detector.level) {
319  int ii = level - detector.level;
320  G4LogicalVolume* lv = touch->GetVolume(ii)->GetLogicalVolume();
321  ok = (lv == detector.lv);
322 #ifdef EDM_ML_DEBUG
323  std::string name1 = (lv == 0) ? "Unknown" : lv->GetName();
324  edm::LogVerbatim("CaloSim") << "CaloSD: volume " << name1 << ":" << detector.name << " at Level "
325  << detector.level << " Flag " << ok;
326 #endif
327  if (ok)
328  break;
329  }
330  }
331  return ok;
332 }
333 
334 void CaloSD::Initialize(G4HCofThisEvent* HCE) {
335  totalHits = 0;
336 
337 #ifdef EDM_ML_DEBUG
338  edm::LogVerbatim("CaloSim") << "CaloSD : Initialize called for " << GetName();
339 #endif
340 
341  //This initialization is performed at the beginning of an event
342  //------------------------------------------------------------
343  theHC = new CaloG4HitCollection(GetName(), collectionName[0]);
344 
345  if (hcID < 0) {
346  hcID = G4SDManager::GetSDMpointer()->GetCollectionID(collectionName[0]);
347  }
348  //theHC ownership is transfered here to HCE
349  HCE->AddHitsCollection(hcID, theHC);
350 }
351 
352 void CaloSD::EndOfEvent(G4HCofThisEvent*) {
353  // clean the hits for the last tracks
354 
356 
357 #ifdef EDM_ML_DEBUG
358  if (theHC == nullptr)
359  edm::LogVerbatim("CaloSim") << "CaloSD: EndofEvent entered with no entries";
360  else
361  edm::LogVerbatim("CaloSim") << "CaloSD: EndofEvent entered with " << theHC->entries() << " entries";
362 #endif
363 }
364 
365 void CaloSD::clear() {}
366 
368 
370 #ifdef EDM_ML_DEBUG
371  edm::LogVerbatim("CaloSim") << "CaloSD: Collection " << theHC->GetName();
372 #endif
373  theHC->PrintAllHits();
374 }
375 
377 #ifdef EDM_ML_DEBUG
378  edm::LogVerbatim("CaloSim") << "CaloSD: Tries to transfer " << slave.get()->hits().size() << " hits for "
379  << slave.get()->name() << " " << hname;
380 #endif
381  if (slave.get()->name() == hname) {
382  cc = slave.get()->hits();
383  }
384  slave.get()->Clean();
385 }
386 
387 G4ThreeVector CaloSD::setToLocal(const G4ThreeVector& global, const G4VTouchable* touch) const {
388  return touch->GetHistory()->GetTopTransform().TransformPoint(global);
389 }
390 
391 G4ThreeVector CaloSD::setToGlobal(const G4ThreeVector& local, const G4VTouchable* touch) const {
392  return touch->GetHistory()->GetTopTransform().Inverse().TransformPoint(local);
393 }
394 
395 bool CaloSD::hitExists(const G4Step* aStep) {
396  // Update if in the same detector, time-slice and for same track
397  if (currentID == previousID) {
399  return true;
400  }
401 
402  // Note T. Klijnsma:
403  // This is a rather strange place to set these class variables.
404  // The code would be much more readable if all logic for determining
405  // whether to update a hit or create a new hit is done in one place,
406  // and only then perform the actual updating or creating of the hit.
407 
408  // Reset entry point for new primary
409  posGlobal = aStep->GetPreStepPoint()->GetPosition();
410  if (currentID.trackID() != previousID.trackID()) {
411  resetForNewPrimary(aStep);
412  }
413  return checkHit();
414 }
415 
417  //look in the HitContainer whether a hit with the same ID already exists:
418  bool found = false;
419  if (useMap) {
420  std::map<CaloHitID, CaloG4Hit*>::const_iterator it = hitMap.find(currentID);
421  if (it != hitMap.end()) {
422  currentHit = it->second;
423  found = true;
424  }
425  } else if (nCheckedHits > 0) {
426  int nhits = theHC->entries();
427  int minhit = std::max(nhits - nCheckedHits, 0);
428  int maxhit = nhits - 1;
429 
430  for (int j = maxhit; j > minhit; --j) {
431  if ((*theHC)[j]->getID() == currentID) {
432  currentHit = (*theHC)[j];
433  found = true;
434  break;
435  }
436  }
437  }
438 
439  if (found) {
441  }
442  return found;
443 }
444 
445 int CaloSD::getNumberOfHits() { return theHC->entries(); }
446 
447 std::string CaloSD::printableDecayChain(const std::vector<unsigned int>& decayChain) {
448  /*
449  Takes a vector of ints (representing trackIDs), and returns a formatted string
450  for debugging purposes
451  */
452  std::stringstream ss;
453  for (long unsigned int i = 0; i < decayChain.size(); i++) {
454  if (i > 0)
455  ss << " <- ";
456  ss << decayChain[i];
457  }
458  return ss.str();
459 }
460 
461 void CaloSD::hitBookkeepingFineCalo(const G4Step* step, const G4Track* currentTrack, CaloG4Hit* hit) {
462  /*
463  Performs bookkeeping: Determines what trackIDs are to be recorded for the hit (typically some
464  some parent trackID), and also sets the right flags on either the TrackInformation object or
465  the TrackWithHistory object to make sure the right track is saved to the SimTrack collection.
466 
467  `currentTrack` is the track that is currently being processed by Geant
468  */
469  TrackInformation* trkInfo = cmsTrackInformation(currentTrack);
470  // Copy the class's currentID so we can freely modify it without influencing
471  // hits created later in possibly non-fine detectors by the same track
472  CaloHitID hitID = currentID;
473  // First check if the current currentTrack passes criteria
474  if (trkInfo->crossedBoundary()) {
475 #ifdef EDM_ML_DEBUG
476  edm::LogVerbatim("DoFineCalo") << "currentTrack " << currentTrack->GetTrackID()
477  << " itself has crossedBoundary=" << trkInfo->crossedBoundary()
478  << " ; recording it for hit " << hit->getUnitID();
479 #endif
480  hitID.setFineTrackID(currentTrack->GetTrackID());
481  hit->setID(hitID); // Actually overwrite the ID for the hit
482  trkInfo->storeTrack(true);
483  return;
484  }
485  // currentTrack itself does not pass thresholds / does not cross boundary; go through its history to find a track that does
486  TrackWithHistory* recordTrackWithHistory;
487  // Keep track of decay chain of this track for debugging purposes
488  std::vector<unsigned int> decayChain;
489  decayChain.push_back(currentTrack->GetTrackID());
490  // Find the first parent of this track that passes the required criteria
491  // Start from first parent
492  unsigned int recordTrackID = currentTrack->GetParentID();
493 #ifdef EDM_ML_DEBUG
494  edm::LogVerbatim("DoFineCalo") << "Trying to find the first parent of hit " << hit->getUnitID()
495  << " that passes saving criterion (crosses boundary or specific criterion)"
496  << "; starting with first parent track " << recordTrackID;
497 #endif
498  // Check whether this first parent actually exists
499  if (recordTrackID <= 0) {
500  // Track ID 0 is not a track;
501  // This means the current currentTrack has no parent, but apparently it also didn't fit saving criteria
502  throw cms::Exception("Unknown", "CaloSD") << "ERROR: Track " << currentTrack->GetTrackID()
503  << " has no parent, does not fit saving criteria, but left hit "
504  << hit->getUnitID() << "; recording it but it's weird!";
505  }
506  // Start progressing through the track's history
507  while (true) {
508  // Record the decay chain for debugging purposes
509  decayChain.push_back(recordTrackID);
510  recordTrackWithHistory = m_trackManager->getTrackByID(recordTrackID);
511  if (recordTrackID < (unsigned int)hitID.trackID()) {
512  // A parent of the currentTrack has a lower trackID than the current
513  // hitID.trackID(). This means the current hitID.trackID() does not point
514  // to the earliest ancestor of the currentTrack.
515  // The current hitID.trackID() might not be a saved track yet, but the
516  // ancestor is *always* a saved track.
517  // Fix this by overwriting the hitID's track ID.
518 #ifdef EDM_ML_DEBUG
519  edm::LogVerbatim("DoFineCalo") << "History-tracking progressed to track " << recordTrackID
520  << ", which is an earlier ancestor than current primary " << hitID.trackID()
521  << "; overwriting it.";
522 #endif
523  hitID.setTrackID(recordTrackID);
524  }
525  // Check if this parent fits the boundary-crossing criteria
526  if (recordTrackWithHistory->crossedBoundary() && recordTrackWithHistory->getIDAtBoundary() == (int)recordTrackID) {
527 #ifdef EDM_ML_DEBUG
528  edm::LogVerbatim("DoFineCalo") << "Recording track " << recordTrackID << " as source of hit " << hit->getUnitID()
529  << "; crossed boundary at pos=("
530  << recordTrackWithHistory->getPositionAtBoundary().x() << ","
531  << recordTrackWithHistory->getPositionAtBoundary().y() << ","
532  << recordTrackWithHistory->getPositionAtBoundary().z() << ")"
533  << " mom=(" << recordTrackWithHistory->getMomentumAtBoundary().x() << ","
534  << recordTrackWithHistory->getMomentumAtBoundary().y() << ","
535  << recordTrackWithHistory->getMomentumAtBoundary().z() << ","
536  << recordTrackWithHistory->getMomentumAtBoundary().e() << ")"
537  << " id@boundary=" << recordTrackWithHistory->getIDAtBoundary()
538  << "; decayChain: " << printableDecayChain(decayChain);
539 #endif
540  break;
541  }
542  // This parent track did not fit criteria - go to the next parent
543 #ifdef EDM_ML_DEBUG
544  edm::LogVerbatim("DoFineCalo") << "Track " << recordTrackID << " did not cross the boundary or fit other criteria";
545 #endif
546  recordTrackID = recordTrackWithHistory->parentID();
547  if (recordTrackID <= 0) {
548  // Track ID 0 is not a track;
549  // This means that no parent of the currentTrack fitted the criteria
550  throw cms::Exception("Unknown", "CaloSD")
551  << "Hit " << hit->getUnitID() << " does not have any parent track that passes the criteria!"
552  << " decayChain so far: " << printableDecayChain(decayChain);
553  }
554  }
555  // Parentage traversal done - do the bookeeping for the found ancestor track
556  recordTrackWithHistory->save();
557  hitID.setFineTrackID(recordTrackID);
558  hit->setID(hitID); // Actually overwrite the ID for the hit
559 #ifdef EDM_ML_DEBUG
560  edm::LogVerbatim("DoFineCalo") << "Stored the following bookeeping for hit " << hit->getUnitID()
561  << " hitID.trackID()=" << hitID.trackID()
562  << " hitID.fineTrackID()=" << hitID.fineTrackID()
563  << " recordTrackWithHistory->trackID()=" << recordTrackWithHistory->trackID()
564  << " recordTrackWithHistory->saved()=" << recordTrackWithHistory->saved();
565 #endif
566 }
567 
568 CaloG4Hit* CaloSD::createNewHit(const G4Step* aStep, const G4Track* theTrack) {
569 #ifdef EDM_ML_DEBUG
570  edm::LogVerbatim("CaloSim") << "CaloSD::CreateNewHit " << getNumberOfHits() << " for " << GetName()
571  << " Unit:" << currentID.unitID() << " " << currentID.depth() << " Edep= " << edepositEM
572  << " " << edepositHAD << " primaryID= " << currentID.trackID()
573  << " timeSlice= " << currentID.timeSliceID() << " ID= " << theTrack->GetTrackID() << " "
574  << theTrack->GetDefinition()->GetParticleName()
575  << " E(GeV)= " << theTrack->GetKineticEnergy() / CLHEP::GeV
576  << " parentID= " << theTrack->GetParentID() << "\n Ein= " << incidentEnergy
577  << " entranceGlobal: " << entrancePoint << " entranceLocal: " << entranceLocal
578  << " posGlobal: " << posGlobal;
579 #endif
580 
581  CaloG4Hit* aHit;
582  if (!reusehit.empty()) {
583  aHit = reusehit.back().release();
584  aHit->setEM(0.f);
585  aHit->setHadr(0.f);
586  reusehit.pop_back();
587  } else {
588  aHit = new CaloG4Hit;
589  }
590 
591  aHit->setID(currentID);
592  aHit->setEntry(entrancePoint.x(), entrancePoint.y(), entrancePoint.z());
594  aHit->setPosition(posGlobal.x(), posGlobal.y(), posGlobal.z());
596  updateHit(aHit);
597 
598  storeHit(aHit);
599  TrackInformation* trkInfo = cmsTrackInformation(theTrack);
600 
601  bool currentlyInsideFineVolume = isItFineCalo(aStep->GetPostStepPoint()->GetTouchable());
602 
603 #ifdef EDM_ML_DEBUG
604  edm::LogVerbatim("DoFineCalo") << "Creating new hit " << aHit->getUnitID() << " using "
605  << (currentlyInsideFineVolume ? "FINECALO" : "normal CaloSD")
606  << "; currentID.trackID=" << currentID.trackID()
607  << " currentID.fineTrackID=" << currentID.fineTrackID()
608  << " isItFineCalo(aStep->GetPostStepPoint()->GetTouchable())="
609  << isItFineCalo(aStep->GetPostStepPoint()->GetTouchable())
610  << " isItFineCalo(aStep->GetPreStepPoint()->GetTouchable())="
611  << isItFineCalo(aStep->GetPreStepPoint()->GetTouchable())
612  << " theTrack=" << theTrack->GetTrackID() << " ("
613  << " parentTrackId=" << theTrack->GetParentID()
614  << " getIDonCaloSurface=" << trkInfo->getIDonCaloSurface() << ")"
615  << " primIDSaved=" << primIDSaved;
616 #endif
617 
618  // If fine calo is activated for the current volume, perform track/hit
619  // saving logic for fineCalo
620  if (doFineCalo_ && currentlyInsideFineVolume) {
621  hitBookkeepingFineCalo(aStep, theTrack, aHit);
622  }
623  // 'Traditional', non-fine history bookkeeping
624  else {
625  double etrack = 0;
626  if (currentID.trackID() == primIDSaved) { // The track is saved; nothing to be done
627  } else if (currentID.trackID() == theTrack->GetTrackID()) {
628  etrack = theTrack->GetKineticEnergy();
629 #ifdef EDM_ML_DEBUG
630  edm::LogVerbatim("CaloSim") << "CaloSD: set save the track " << currentID.trackID() << " etrack " << etrack
631  << " eCut " << energyCut << " force: " << forceSave
632  << " save: " << (etrack >= energyCut || forceSave);
633 #endif
634  if (etrack >= energyCut || forceSave) {
635  trkInfo->storeTrack(true);
636  trkInfo->putInHistory();
637  }
638  } else {
640 #ifdef EDM_ML_DEBUG
641  edm::LogVerbatim("CaloSim") << "CaloSD : TrackWithHistory pointer for " << currentID.trackID() << " is " << trkh;
642 #endif
643  if (trkh != nullptr) {
644  etrack = sqrt(trkh->momentum().Mag2());
645  if (etrack >= energyCut) {
646  trkh->save();
647 #ifdef EDM_ML_DEBUG
648  edm::LogVerbatim("CaloSim") << "CaloSD: set save the track " << currentID.trackID() << " with Hit";
649 #endif
650  }
651  }
652  }
654  }
655 
656  if (useMap)
657  ++totalHits;
658  return aHit;
659 }
660 
663 #ifdef EDM_ML_DEBUG
664  edm::LogVerbatim("CaloSim") << "CaloSD:" << GetName() << " Add energy deposit in " << currentID
665  << " Edep_em(MeV)= " << edepositEM << " Edep_had(MeV)= " << edepositHAD;
666 #endif
667 
668  // buffer for next steps:
670 }
671 
672 void CaloSD::resetForNewPrimary(const G4Step* aStep) {
673  auto const preStepPoint = aStep->GetPreStepPoint();
674  entrancePoint = preStepPoint->GetPosition();
675  entranceLocal = setToLocal(entrancePoint, preStepPoint->GetTouchable());
676  incidentEnergy = preStepPoint->GetKineticEnergy();
677 #ifdef EDM_ML_DEBUG
678  edm::LogVerbatim("CaloSim") << "CaloSD::resetForNewPrimary for " << GetName()
679  << " ID= " << aStep->GetTrack()->GetTrackID() << " Ein= " << incidentEnergy / CLHEP::GeV
680  << " GeV and"
681  << " entrance point global: " << entrancePoint << " local: " << entranceLocal;
682 #endif
683 }
684 
685 double CaloSD::getAttenuation(const G4Step* aStep, double birk1, double birk2, double birk3) const {
686  double weight = 1.;
687  double charge = aStep->GetPreStepPoint()->GetCharge();
688  double length = aStep->GetStepLength();
689 
690  if (charge != 0. && length > 0.) {
691  double density = aStep->GetPreStepPoint()->GetMaterial()->GetDensity();
692  double dedx = aStep->GetTotalEnergyDeposit() / length;
693  double rkb = birk1 / density;
694  double c = birk2 * rkb * rkb;
695  if (std::abs(charge) >= 2.)
696  rkb /= birk3; // based on alpha particle data
697  weight = 1. / (1. + rkb * dedx + c * dedx * dedx);
698 #ifdef EDM_ML_DEBUG
699  edm::LogVerbatim("CaloSim") << "CaloSD::getAttenuation in " << aStep->GetPreStepPoint()->GetMaterial()->GetName()
700  << " Charge " << charge << " dE/dx " << dedx << " Birk Const " << rkb << ", " << c
701  << " Weight = " << weight << " dE " << aStep->GetTotalEnergyDeposit();
702 #endif
703  }
704  return weight;
705 }
706 
707 void CaloSD::update(const BeginOfRun*) { initRun(); }
708 
709 void CaloSD::update(const BeginOfEvent* g4Event) {
710 #ifdef EDM_ML_DEBUG
711  edm::LogVerbatim("CaloSim") << "CaloSD: Dispatched BeginOfEvent for " << GetName() << " !";
712 #endif
713  clearHits();
714  initEvent(g4Event);
715 }
716 
717 void CaloSD::update(const EndOfTrack* trk) {
718  int id = (*trk)()->GetTrackID();
719  TrackInformation* trkI = cmsTrackInformation((*trk)());
720  int lastTrackID = -1;
721  if (trkI)
722  lastTrackID = trkI->getIDonCaloSurface();
723  if (id == lastTrackID) {
724  const TrackContainer* trksForThisEvent = m_trackManager->trackContainer();
725  if (trksForThisEvent != nullptr) {
726  int it = (int)(trksForThisEvent->size()) - 1;
727  if (it >= 0) {
728  TrackWithHistory* trkH = (*trksForThisEvent)[it];
729  if (trkH->trackID() == (unsigned int)(id))
730  tkMap[id] = trkH;
731 #ifdef EDM_ML_DEBUG
732  edm::LogVerbatim("CaloSim") << "CaloSD: get track " << it << " from Container of size "
733  << trksForThisEvent->size() << " with ID " << trkH->trackID();
734  } else {
735  edm::LogVerbatim("CaloSim") << "CaloSD: get track " << it << " from Container of size "
736  << trksForThisEvent->size() << " with no ID";
737 #endif
738  }
739  }
740  }
741 }
742 
743 void CaloSD::update(const ::EndOfEvent*) {
744  endEvent();
745  slave.get()->ReserveMemory(theHC->entries());
746 
747  int count(0);
748  int wrong(0);
749  double eEM(0.0);
750  double eHAD(0.0);
751  double eEM2(0.0);
752  double eHAD2(0.0);
753  double tt(0.0);
754  double zloc(0.0);
755  double zglob(0.0);
756  double ee(0.0);
757  int hc_entries = theHC->entries();
758  for (int i = 0; i < hc_entries; ++i) {
759  if (!saveHit((*theHC)[i])) {
760  ++wrong;
761  }
762  ++count;
763  double x = (*theHC)[i]->getEM();
764  eEM += x;
765  eEM2 += x * x;
766  x = (*theHC)[i]->getHadr();
767  eHAD += x;
768  eHAD2 += x * x;
769  tt += (*theHC)[i]->getTimeSlice();
770  ee += (*theHC)[i]->getIncidentEnergy();
771  zglob += std::abs((*theHC)[i]->getEntry().z());
772  zloc += std::abs((*theHC)[i]->getEntryLocal().z());
773  }
774 
775  double norm = (count > 0) ? 1.0 / count : 0.0;
776  eEM *= norm;
777  eEM2 *= norm;
778  eHAD *= norm;
779  eHAD2 *= norm;
780  eEM2 = std::sqrt(eEM2 - eEM * eEM);
781  eHAD2 = std::sqrt(eHAD2 - eHAD * eHAD);
782  tt *= norm;
783  ee *= norm;
784  zglob *= norm;
785  zloc *= norm;
786 
787 #ifdef EDM_ML_DEBUG
788  edm::LogVerbatim("CaloSim") << "CaloSD: " << GetName() << " store " << count << " hits; " << wrong
789  << " track IDs not given properly and " << totalHits - count
790  << " hits not passing cuts\n EmeanEM= " << eEM << " ErmsEM= " << eEM2
791  << "\n EmeanHAD= " << eHAD << " ErmsHAD= " << eHAD2 << " TimeMean= " << tt
792  << " E0mean= " << ee << " Zglob= " << zglob << " Zloc= " << zloc << " ";
793 #endif
794  tkMap.erase(tkMap.begin(), tkMap.end());
795  std::vector<std::unique_ptr<CaloG4Hit>>().swap(reusehit);
796  if (useMap)
797  hitMap.erase(hitMap.begin(), hitMap.end());
798 }
799 
801  cleanIndex = 0;
802  previousID.reset();
803  primIDSaved = -99;
804 #ifdef EDM_ML_DEBUG
805  edm::LogVerbatim("CaloSim") << "CaloSD: Clears hit vector for " << GetName()
806  << " and initialise slave: " << slave.get()->name();
807 #endif
808  slave.get()->Initialize();
809 }
810 
812  if (fpCaloG4HitAllocator) {
813  fpCaloG4HitAllocator->ResetStorage();
814  }
815 }
816 
818 
820 
822 
823 int CaloSD::getTrackID(const G4Track* aTrack) {
824  int primaryID = 0;
825  TrackInformation* trkInfo = cmsTrackInformation(aTrack);
826  if (trkInfo) {
827  primaryID = trkInfo->getIDonCaloSurface();
828 #ifdef EDM_ML_DEBUG
829  edm::LogVerbatim("CaloSim") << "Track ID: " << trkInfo->getIDonCaloSurface() << ":" << aTrack->GetTrackID() << ":"
830  << primaryID;
831 #endif
832  } else {
833  primaryID = aTrack->GetTrackID();
834 #ifdef EDM_ML_DEBUG
835  edm::LogWarning("CaloSim") << "CaloSD: Problem with primaryID **** set by force to TkID **** " << primaryID;
836 #endif
837  }
838  return primaryID;
839 }
840 
841 int CaloSD::setTrackID(const G4Step* aStep) {
842  auto const theTrack = aStep->GetTrack();
843  TrackInformation* trkInfo = cmsTrackInformation(theTrack);
844  int primaryID = trkInfo->getIDonCaloSurface();
845  if (primaryID <= 0) {
846  primaryID = theTrack->GetTrackID();
847  }
848 #ifdef EDM_ML_DEBUG
849  edm::LogVerbatim("CaloSim") << "Track ID: " << trkInfo->getIDonCaloSurface() << ":" << theTrack->GetTrackID() << ":"
850  << primaryID;
851 #endif
852 
853  if (primaryID != previousID.trackID()) {
854  resetForNewPrimary(aStep);
855  }
856 #ifdef EDM_ML_DEBUG
857  edm::LogVerbatim("CaloSim") << "CaloSD::setTrackID for " << GetName()
858  << " trackID= " << aStep->GetTrack()->GetTrackID() << " primaryID= " << primaryID;
859 #endif
860  return primaryID;
861 }
862 
863 uint16_t CaloSD::getDepth(const G4Step*) { return 0; }
864 
866  double emin(eminHit);
867  if (hit->getDepth() > 0)
868  emin = eminHitD;
869 #ifdef EDM_ML_DEBUG
870  edm::LogVerbatim("CaloSim") << "CaloSD::filterHit(..) Depth " << hit->getDepth() << " Emin = " << emin << " ("
871  << eminHit << ", " << eminHitD << ")";
872 #endif
873  return ((time <= tmaxHit) && (hit->getEnergyDeposit() > emin));
874 }
875 
876 double CaloSD::getResponseWt(const G4Track* aTrack) {
877  double wt = 1.0;
878  if (meanResponse.get()) {
879  TrackInformation* trkInfo = cmsTrackInformation(aTrack);
880  wt = meanResponse.get()->getWeight(trkInfo->genParticlePID(), trkInfo->genParticleP());
881  }
882  return wt;
883 }
884 
886  if (hit == nullptr || previousID.trackID() < 0) {
887  edm::LogWarning("CaloSim") << "CaloSD: hit to be stored is nullptr !!"
888  << " previousID.trackID()= " << previousID.trackID();
889  return;
890  }
891 
892  theHC->insert(hit);
893  if (useMap)
894  hitMap.insert(std::pair<CaloHitID, CaloG4Hit*>(previousID, hit));
895 }
896 
898  int tkID;
899  bool ok = true;
900 
901  double time = aHit->getTimeSlice();
902  if (corrTOFBeam)
903  time += correctT;
904 
905  // Do track bookkeeping a little differently for fine tracking
906  if (doFineCalo_ && aHit->getID().hasFineTrackID()) {
907  tkID = aHit->getID().fineTrackID();
908 #ifdef EDM_ML_DEBUG
909  edm::LogVerbatim("DoFineCalo") << "Saving hit " << aHit->getUnitID() << " with trackID=" << tkID;
910 #endif
911  // Check if the track is actually in the trackManager
912  if (m_trackManager) {
913  if (!m_trackManager->trackExists(tkID)) {
914  ok = false;
915  throw cms::Exception("Unknown", "CaloSD")
916  << "aHit " << aHit->getUnitID() << " has fine trackID " << tkID << ", which is NOT IN THE TRACK MANAGER";
917  }
918  } else {
919  ok = false;
920  throw cms::Exception("Unknown", "CaloSD") << "m_trackManager not set, saveHit ok=false!";
921  }
922  // Take the aHit-information and move it to the actual PCaloHitContainer
923  slave.get()->processHits(
924  aHit->getUnitID(), aHit->getEM() / CLHEP::GeV, aHit->getHadr() / CLHEP::GeV, time, tkID, aHit->getDepth());
925  }
926  // Regular, not-fine way:
927  else {
928  if (m_trackManager) {
929  tkID = m_trackManager->giveMotherNeeded(aHit->getTrackID());
930  if (tkID == 0) {
931  if (m_trackManager->trackExists(aHit->getTrackID()))
932  tkID = (aHit->getTrackID());
933  else {
934  ok = false;
935  }
936  }
937  } else {
938  tkID = aHit->getTrackID();
939  ok = false;
940  }
941 #ifdef EDM_ML_DEBUG
942  edm::LogVerbatim("DoFineCalo") << "Saving hit " << aHit->getUnitID() << " with trackID=" << tkID
943  << " (no fineTrackID)";
944 #endif
945  slave.get()->processHits(
946  aHit->getUnitID(), aHit->getEM() / CLHEP::GeV, aHit->getHadr() / CLHEP::GeV, time, tkID, aHit->getDepth());
947  }
948 
949 #ifdef EDM_ML_DEBUG
950  if (!ok)
951  edm::LogWarning("CaloSim") << "CaloSD:Cannot find track ID for " << aHit->getTrackID();
952  edm::LogVerbatim("CaloSim") << "CalosD: Track ID " << aHit->getTrackID() << " changed to " << tkID
953  << " by SimTrackManager Status " << ok;
954 #endif
955 
956 #ifdef EDM_ML_DEBUG
957  edm::LogVerbatim("CaloSim") << "CaloSD: Store Hit at " << std::hex << aHit->getUnitID() << std::dec << " "
958  << aHit->getDepth() << " due to " << tkID << " in time " << time << " of energy "
959  << aHit->getEM() / CLHEP::GeV << " GeV (EM) and " << aHit->getHadr() / CLHEP::GeV
960  << " GeV (Hadr)";
961 #endif
962  return ok;
963 }
964 
965 void CaloSD::update(const BeginOfTrack* trk) {
966  int primary = -1;
967  TrackInformation* trkInfo = cmsTrackInformation((*trk)());
968  if (trkInfo->isPrimary())
969  primary = (*trk)()->GetTrackID();
970 
971 #ifdef EDM_ML_DEBUG
972  edm::LogVerbatim("CaloSim") << "New track: isPrimary " << trkInfo->isPrimary() << " primary ID = " << primary
973  << " primary ancestor ID " << primAncestor;
974 #endif
975 
976  // update the information if a different primary track ID
977 
978  if (primary > 0 && primary != primAncestor) {
979  primAncestor = primary;
980 
981  // clean the hits information
982 
983  if (theHC->entries() > 0)
985  }
986 }
987 
989  std::vector<CaloG4Hit*>* theCollection = theHC->GetVector();
990 
991 #ifdef EDM_ML_DEBUG
992  edm::LogVerbatim("CaloSim") << "CaloSD: collection before merging, size = " << theHC->entries();
993 #endif
994  if (reusehit.empty())
995  reusehit.reserve(theHC->entries() - cleanIndex);
996 
997  // if no map used, merge before hits to have the save situation as a map
998  if (!useMap) {
999  std::vector<CaloG4Hit*> hitvec;
1000 
1001  hitvec.swap(*theCollection);
1002  sort((hitvec.begin() + cleanIndex), hitvec.end(), CaloG4HitLess());
1003 #ifdef EDM_ML_DEBUG
1004  edm::LogVerbatim("CaloSim") << "CaloSD::cleanHitCollection: sort hits in buffer starting from "
1005  << "element = " << cleanIndex;
1006  for (unsigned int i = 0; i < hitvec.size(); ++i) {
1007  if (hitvec[i] == nullptr)
1008  edm::LogVerbatim("CaloSim") << i << " has a null pointer";
1009  else
1010  edm::LogVerbatim("CaloSim") << i << " " << *hitvec[i];
1011  }
1012 #endif
1014  for (unsigned int i = cleanIndex; i < hitvec.size(); ++i) {
1015  int jump = 0;
1016  for (unsigned int j = i + 1; j < hitvec.size() && equal(hitvec[i], hitvec[j]); ++j) {
1017  ++jump;
1018  // merge j to i
1019  (*hitvec[i]).addEnergyDeposit(*hitvec[j]);
1020  (*hitvec[j]).setEM(0.);
1021  (*hitvec[j]).setHadr(0.);
1022  reusehit.emplace_back(hitvec[j]);
1023  hitvec[j] = nullptr;
1024  }
1025  i += jump;
1026  }
1027 #ifdef EDM_ML_DEBUG
1028  edm::LogVerbatim("CaloSim") << "CaloSD: cleanHitCollection merge the hits in buffer ";
1029  for (unsigned int i = 0; i < hitvec.size(); ++i) {
1030  if (hitvec[i] == nullptr)
1031  edm::LogVerbatim("CaloSim") << i << " has a null pointer";
1032  else
1033  edm::LogVerbatim("CaloSim") << i << " " << *hitvec[i];
1034  }
1035 #endif
1036  //move all nullptr to end of list and then remove them
1037  hitvec.erase(
1038  std::stable_partition(hitvec.begin() + cleanIndex, hitvec.end(), [](CaloG4Hit* p) { return p != nullptr; }),
1039  hitvec.end());
1040 #ifdef EDM_ML_DEBUG
1041  edm::LogVerbatim("CaloSim") << "CaloSD::cleanHitCollection: remove the merged hits in buffer,"
1042  << " new size = " << hitvec.size();
1043 #endif
1044  hitvec.swap(*theCollection);
1045  totalHits = theHC->entries();
1046  }
1047 
1048 #ifdef EDM_ML_DEBUG
1049  edm::LogVerbatim("CaloSim") << "CaloSD: collection after merging, size= " << theHC->entries()
1050  << " Size of reusehit= " << reusehit.size()
1051  << "\n starting hit selection from index = " << cleanIndex;
1052 #endif
1053 
1054  int addhit = 0;
1055  for (unsigned int i = cleanIndex; i < theCollection->size(); ++i) {
1056  CaloG4Hit* aHit((*theCollection)[i]);
1057 
1058  // selection
1059 
1060  double time = aHit->getTimeSlice();
1061  if (corrTOFBeam)
1062  time += correctT;
1063  if (!filterHit(aHit, time)) {
1064 #ifdef EDM_ML_DEBUG
1065  edm::LogVerbatim("CaloSim") << "CaloSD: dropped CaloG4Hit "
1066  << " " << *aHit;
1067 #endif
1068 
1069  // create the list of hits to be reused
1070 
1071  reusehit.emplace_back((*theCollection)[i]);
1072  (*theCollection)[i] = nullptr;
1073  ++addhit;
1074  }
1075  }
1076 
1077 #ifdef EDM_ML_DEBUG
1078  edm::LogVerbatim("CaloSim") << "CaloSD: Size of reusehit after selection = " << reusehit.size()
1079  << " Number of added hit = " << addhit;
1080 #endif
1081  if (useMap) {
1082  if (addhit > 0) {
1083  int offset = reusehit.size() - addhit;
1084  for (int ii = addhit - 1; ii >= 0; --ii) {
1085  CaloHitID theID = reusehit[offset + ii]->getID();
1086  hitMap.erase(theID);
1087  }
1088  }
1089  }
1090 
1091  //move all nullptr to end of list and then remove them
1092  theCollection->erase(
1093  std::stable_partition(
1094  theCollection->begin() + cleanIndex, theCollection->end(), [](CaloG4Hit* p) { return p != nullptr; }),
1095  theCollection->end());
1096 #ifdef EDM_ML_DEBUG
1097  edm::LogVerbatim("CaloSim") << "CaloSD: hit collection after selection, size = " << theHC->entries();
1098  theHC->PrintAllHits();
1099 #endif
1100 
1101  cleanIndex = theHC->entries();
1102 }
1103 
1104 void CaloSD::printDetectorLevels(const G4VTouchable* touch) const {
1105  //Print name and copy numbers
1106  int level = ((touch->GetHistoryDepth()) + 1);
1107  std::ostringstream st1;
1108  st1 << level << " Levels:";
1109  if (level > 0) {
1110  for (int ii = 0; ii < level; ii++) {
1111  int i = level - ii - 1;
1112  G4VPhysicalVolume* pv = touch->GetVolume(i);
1113  std::string name = (pv != nullptr) ? pv->GetName() : "Unknown";
1114  st1 << " " << name << ":" << touch->GetReplicaNumber(i);
1115  }
1116  }
1117  edm::LogVerbatim("CaloSim") << st1.str();
1118 }
personalPlayback.level
level
Definition: personalPlayback.py:22
CaloSD::tkMap
std::map< int, TrackWithHistory * > tkMap
Definition: CaloSD.h:185
CaloSlaveSD.h
CaloSD::filterHit
virtual bool filterHit(CaloG4Hit *, double)
Definition: CaloSD.cc:865
CaloG4Hit::setIncidentEnergy
void setIncidentEnergy(double e)
Definition: CaloG4Hit.h:62
CaloSD::edepositHAD
float edepositHAD
Definition: CaloSD.h:137
SimTrackManager
Definition: SimTrackManager.h:35
CaloSD::tmaxHit
double tmaxHit
Definition: CaloSD.h:141
CaloG4Hit::getTrackID
int getTrackID() const
Definition: CaloG4Hit.h:64
mps_fire.i
i
Definition: mps_fire.py:428
HLT_FULL_cff.track
track
Definition: HLT_FULL_cff.py:11713
CaloSD::storeHit
void storeHit(CaloG4Hit *)
Definition: CaloSD.cc:885
TrackInformation::getIDonCaloSurface
int getIDonCaloSurface() const
Definition: TrackInformation.h:43
TrackWithHistory::parentID
int parentID() const
Definition: TrackWithHistory.h:30
CaloSD::setToGlobal
G4ThreeVector setToGlobal(const G4ThreeVector &, const G4VTouchable *) const
Definition: CaloSD.cc:391
CaloSD::currentHit
CaloG4Hit * currentHit
Definition: CaloSD.h:143
CaloSD::ProcessHits
G4bool ProcessHits(G4Step *step, G4TouchableHistory *) override
Definition: CaloSD.cc:161
CaloSD::kmaxProton
double kmaxProton
Definition: CaloSD.h:146
ESHandle.h
CaloSD::saveHit
bool saveHit(CaloG4Hit *)
Definition: CaloSD.cc:897
groupFilesInBlocks.tt
int tt
Definition: groupFilesInBlocks.py:144
step
step
Definition: StallMonitor.cc:94
f
double f[11][100]
Definition: MuScleFitUtils.cc:78
SensitiveDetector::NaNTrap
void NaNTrap(const G4Step *step) const
Definition: SensitiveDetector.cc:110
CaloHitID::depth
uint16_t depth() const
Definition: CaloHitID.h:24
CaloG4Hit::getUnitID
uint32_t getUnitID() const
Definition: CaloG4Hit.h:66
CaloSD::cleanIndex
int cleanIndex
Definition: CaloSD.h:173
SimTrackManager::trackExists
bool trackExists(unsigned int i) const
Definition: SimTrackManager.h:94
mps_merge.weight
weight
Definition: mps_merge.py:88
AlCaHLTBitMon_ParallelJobs.p
p
Definition: AlCaHLTBitMon_ParallelJobs.py:153
edm::swap
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:117
TrackWithHistory
Definition: TrackWithHistory.h:16
CaloSD::initRun
virtual void initRun()
Definition: CaloSD.cc:817
CaloSD::update
void update(const BeginOfRun *) override
This routine will be called when the appropriate signal arrives.
Definition: CaloSD.cc:707
CaloSD::nCheckedHits
int nCheckedHits
Definition: CaloSD.h:176
CaloHitID::trackID
int trackID() const
Definition: CaloHitID.h:23
CaloSD::getAttenuation
double getAttenuation(const G4Step *aStep, double birk1, double birk2, double birk3) const
Definition: CaloSD.cc:685
protons_cff.time
time
Definition: protons_cff.py:39
CaloSD::edepositEM
float edepositEM
Definition: CaloSD.h:137
CaloSD::hitExists
bool hitExists(const G4Step *)
Definition: CaloSD.cc:395
MeV
const double MeV
TrackWithHistory::getPositionAtBoundary
const math::XYZTLorentzVectorF & getPositionAtBoundary() const
Definition: TrackWithHistory.h:56
edm::ParameterSet::getUntrackedParameter
T getUntrackedParameter(std::string const &, T const &) const
DDAxes::x
TrackInformation::putInHistory
void putInHistory()
Definition: TrackInformation.h:37
TrackInformation::genParticlePID
int genParticlePID() const
Definition: TrackInformation.h:79
CaloHitID::unitID
uint32_t unitID() const
Definition: CaloHitID.h:20
convertSQLiteXML.ok
bool ok
Definition: convertSQLiteXML.py:98
CaloG4Hit::getTimeSlice
double getTimeSlice() const
Definition: CaloG4Hit.h:67
newFWLiteAna.found
found
Definition: newFWLiteAna.py:118
edm::LogWarning
Log< level::Warning, false > LogWarning
Definition: MessageLogger.h:122
CaloSD::kmaxIon
double kmaxIon
Definition: CaloSD.h:146
EndOfTrack
Definition: EndOfTrack.h:6
SimTrackManager::giveMotherNeeded
int giveMotherNeeded(int i) const
Definition: SimTrackManager.h:84
CaloHitID::setTrackID
void setTrackID(int trackID)
Definition: CaloHitID.h:28
G4TrackToParticleID::isGammaElectronPositron
static bool isGammaElectronPositron(int pdgCode)
Definition: G4TrackToParticleID.cc:17
CaloG4Hit::getID
CaloHitID getID() const
Definition: CaloG4Hit.h:71
CaloSD::setTrackID
virtual int setTrackID(const G4Step *)
Definition: CaloSD.cc:841
CaloG4HitEqual
Definition: CaloG4Hit.h:109
contentValuesCheck.ss
ss
Definition: contentValuesCheck.py:33
CaloSD::getResponseWt
double getResponseWt(const G4Track *)
Definition: CaloSD.cc:876
SensitiveCaloDetector
Definition: SensitiveCaloDetector.h:10
CaloSD::setDetUnitId
uint32_t setDetUnitId(const G4Step *step) override=0
HcalParametersRcd.h
CaloSimulationParameters.h
CaloSD::useMap
bool useMap
Definition: CaloSD.h:168
CaloHitID::setID
void setID(uint32_t unitID, double timeSlice, int trackID, uint16_t depth=0)
Definition: CaloHitID.cc:41
TrackInformation::isPrimary
bool isPrimary() const
Definition: TrackInformation.h:27
CaloSD::setToLocal
G4ThreeVector setToLocal(const G4ThreeVector &, const G4VTouchable *) const
Definition: CaloSD.cc:387
CaloSD::isParameterized
bool isParameterized
Definition: CaloSD.h:166
fpCaloG4HitAllocator
G4ThreadLocal G4Allocator< CaloG4Hit > * fpCaloG4HitAllocator
Definition: CaloG4Hit.cc:11
CaloSD::~CaloSD
~CaloSD() override
Definition: CaloSD.cc:159
mathSSE::sqrt
T sqrt(T t)
Definition: SSEVec.h:19
DDAxes::z
CaloSD::primIDSaved
int primIDSaved
Definition: CaloSD.h:175
CaloSD::PrintAll
void PrintAll() override
Definition: CaloSD.cc:369
BeginOfTrack
Definition: BeginOfTrack.h:6
submitPVResolutionJobs.count
count
Definition: submitPVResolutionJobs.py:352
CaloSD::entrancePoint
G4ThreeVector entrancePoint
Definition: CaloSD.h:133
SensitiveDetectorCatalog
Definition: SensitiveDetectorCatalog.h:10
TrackWithHistory::save
void save()
Definition: TrackWithHistory.h:27
HCALHighEnergyHPDFilter_cfi.energy
energy
Definition: HCALHighEnergyHPDFilter_cfi.py:5
CaloSD::posGlobal
G4ThreeVector posGlobal
Definition: CaloSD.h:135
dqmdumpme.k
k
Definition: dqmdumpme.py:60
CaloSD::clearHits
void clearHits() override
Definition: CaloSD.cc:800
CaloSD::meanResponse
std::unique_ptr< CaloMeanResponse > meanResponse
Definition: CaloSD.h:161
bysipixelclustmulteventfilter_cfi.collectionName
collectionName
Definition: bysipixelclustmulteventfilter_cfi.py:5
nhits
Definition: HIMultiTrackSelector.h:42
TrackWithHistory::getMomentumAtBoundary
const math::XYZTLorentzVectorF & getMomentumAtBoundary() const
Definition: TrackWithHistory.h:57
CaloSD::currentID
CaloHitID currentID
Definition: CaloSD.h:139
LEDCalibrationChannels.depth
depth
Definition: LEDCalibrationChannels.py:65
CaloSD::energyCut
double energyCut
Definition: CaloSD.h:141
TrackWithHistory::crossedBoundary
bool crossedBoundary() const
Definition: TrackWithHistory.h:55
CaloSD::reset
void reset() override
Definition: CaloSD.cc:811
AlCaHLTBitMon_QueryRunRegistry.string
string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
ALCARECOTkAlJpsiMuMu_cff.charge
charge
Definition: ALCARECOTkAlJpsiMuMu_cff.py:47
CaloSD::eminHit
double eminHit
Definition: CaloSD.h:141
CaloSD::EndOfEvent
void EndOfEvent(G4HCofThisEvent *eventHC) override
Definition: CaloSD.cc:352
CaloG4Hit::getEM
double getEM() const
Definition: CaloG4Hit.h:55
edm::ParameterSet
Definition: ParameterSet.h:47
CaloSD::hitMap
std::map< CaloHitID, CaloG4Hit * > hitMap
Definition: CaloSD.h:184
CaloSD.h
CaloSD::theHC
CaloG4HitCollection * theHC
Definition: CaloSD.h:163
CaloSD::ignoreTrackID
bool ignoreTrackID
Definition: CaloSD.h:165
SiStripPI::max
Definition: SiStripPayloadInspectorHelper.h:169
CaloSD::totalHits
int totalHits
Definition: CaloSD.h:174
SimTrackManager::getTrackByID
TrackWithHistory * getTrackByID(unsigned int trackID, bool strict=false) const
Definition: SimTrackManager.h:104
CaloSD::incidentEnergy
float incidentEnergy
Definition: CaloSD.h:136
GeV
const double GeV
Definition: MathUtil.h:16
jetUpdater_cfi.sort
sort
Definition: jetUpdater_cfi.py:29
CaloSD::kmaxNeutron
double kmaxNeutron
Definition: CaloSD.h:146
CaloG4Hit::setEntryLocal
void setEntryLocal(double x, double y, double z)
Definition: CaloG4Hit.h:50
CaloSD::eMinFine_
double eMinFine_
Definition: CaloSD.h:182
CaloSD::timeSlice
float timeSlice
Definition: CaloSD.h:178
CaloSD::getEnergyDeposit
virtual double getEnergyDeposit(const G4Step *step)
Definition: CaloSD.cc:308
CaloSD::slave
std::unique_ptr< CaloSlaveSD > slave
Definition: CaloSD.h:160
TrackInformation
Definition: TrackInformation.h:12
createfilelist.int
int
Definition: createfilelist.py:10
MetAnalyzer.pv
def pv(vc)
Definition: MetAnalyzer.py:7
CaloSD::CaloSD
CaloSD(const std::string &aSDname, const edm::EventSetup &es, const SensitiveDetectorCatalog &clg, edm::ParameterSet const &p, const SimTrackManager *, float timeSlice=1., bool ignoreTkID=false)
Definition: CaloSD.cc:35
CaloSD::printDetectorLevels
void printDetectorLevels(const G4VTouchable *) const
Definition: CaloSD.cc:1104
CaloG4Hit::setEntry
void setEntry(double x, double y, double z)
Definition: CaloG4Hit.h:47
CaloSD::resetForNewPrimary
void resetForNewPrimary(const G4Step *)
Definition: CaloSD.cc:672
BeginOfEvent
Definition: BeginOfEvent.h:6
TrackInformation::storeTrack
bool storeTrack() const
Definition: TrackInformation.h:18
BeginOfRun
Definition: BeginOfRun.h:6
CaloSD::getDepth
virtual uint16_t getDepth(const G4Step *)
Definition: CaloSD.cc:863
CaloSD::hcID
int hcID
Definition: CaloSD.h:171
CaloSD::eminHitD
double eminHitD
Definition: CaloSD.h:179
edm::EventSetup
Definition: EventSetup.h:58
CaloSD::DrawAll
void DrawAll() override
Definition: CaloSD.cc:367
CaloSD::reusehit
std::vector< std::unique_ptr< CaloG4Hit > > reusehit
Definition: CaloSD.h:186
TrackInformation.h
CaloG4Hit
Definition: CaloG4Hit.h:32
CaloG4Hit::setHadr
void setHadr(double e)
Definition: CaloG4Hit.h:59
TrackInformation::genParticleP
double genParticleP() const
Definition: TrackInformation.h:81
cc
CaloSD::corrTOFBeam
bool corrTOFBeam
Definition: CaloSD.h:169
TrackInformation::crossedBoundary
bool crossedBoundary() const
Definition: TrackInformation.h:73
CaloHitID::timeSliceID
int timeSliceID() const
Definition: CaloHitID.h:21
CaloG4HitLess
Definition: CaloG4Hit.h:92
CaloSD::doFineCalo_
bool doFineCalo_
Definition: CaloSD.h:181
CaloSD::m_trackManager
const SimTrackManager * m_trackManager
Definition: CaloSD.h:158
TrackWithHistory::trackID
unsigned int trackID() const
Definition: TrackWithHistory.h:28
TrackContainer
std::vector< TrackWithHistory * > TrackContainer
Definition: TrackContainer.h:8
CaloSD::getTrackID
virtual int getTrackID(const G4Track *)
Definition: CaloSD.cc:823
SensitiveDetector::cmsTrackInformation
TrackInformation * cmsTrackInformation(const G4Track *aTrack)
Definition: SensitiveDetector.cc:96
G4TrackToParticleID.h
TrackWithHistory::saved
bool saved() const
Definition: TrackWithHistory.h:44
CaloSD::clear
void clear() override
Definition: CaloSD.cc:365
CaloSD::Detector
Definition: CaloSD.h:151
CaloSD::getNumberOfHits
int getNumberOfHits()
Definition: CaloSD.cc:445
TrackWithHistory::getIDAtBoundary
int getIDAtBoundary() const
Definition: TrackWithHistory.h:58
CaloSD::cleanHitCollection
void cleanHitCollection()
Definition: CaloSD.cc:988
edm::LogVerbatim
Log< level::Info, true > LogVerbatim
Definition: MessageLogger.h:128
dd4hep
Definition: DDPlugins.h:8
CaloSD::primAncestor
int primAncestor
Definition: CaloSD.h:172
CaloHitID::reset
void reset()
Definition: CaloHitID.cc:49
SimTrackManager.h
CaloHitID
Definition: CaloHitID.h:11
CaloSD::fineDetectors_
std::vector< Detector > fineDetectors_
Definition: CaloSD.h:187
Exception
Definition: hltDiff.cc:245
TrackWithHistory::momentum
const math::XYZVectorD & momentum() const
Definition: TrackWithHistory.h:32
CaloSD::entranceLocal
G4ThreeVector entranceLocal
Definition: CaloSD.h:134
CaloHitID::fineTrackID
int fineTrackID() const
Definition: CaloHitID.h:31
edm::PCaloHitContainer
std::vector< PCaloHit > PCaloHitContainer
Definition: PCaloHitContainer.h:8
CaloSD::hitBookkeepingFineCalo
void hitBookkeepingFineCalo(const G4Step *step, const G4Track *currentTrack, CaloG4Hit *hit)
Definition: CaloSD.cc:461
Skims_PA_cff.name
name
Definition: Skims_PA_cff.py:17
edm::ParameterSet::getParameter
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
CaloG4HitCollection
G4THitsCollection< CaloG4Hit > CaloG4HitCollection
Definition: CaloG4HitCollection.h:11
Exception.h
CaloHitID::setFineTrackID
void setFineTrackID(int fineTrackID)
Definition: CaloHitID.h:30
CaloSD::correctT
double correctT
Definition: CaloSD.h:180
CaloSD::getFromLibrary
virtual bool getFromLibrary(const G4Step *step)
Definition: CaloSD.cc:312
CaloSD::Initialize
void Initialize(G4HCofThisEvent *HCE) override
Definition: CaloSD.cc:334
CaloSD::checkHit
bool checkHit()
Definition: CaloSD.cc:416
CaloSD::forceSave
bool forceSave
Definition: CaloSD.h:148
CaloHitID::hasFineTrackID
bool hasFineTrackID() const
Definition: CaloHitID.h:29
hgcalTestNeighbor_cfi.detector
detector
Definition: hgcalTestNeighbor_cfi.py:6
cscdqm::timeSlice
CSCCFEBTimeSlice const *const timeSlice(T const &data, int nCFEB, int nSample)
Definition: CSCDQM_EventProcessor_processCSC.cc:29
CaloSD::fillHits
void fillHits(edm::PCaloHitContainer &, const std::string &) override
Definition: CaloSD.cc:376
CaloSD::ignoreReject
bool ignoreReject
Definition: CaloSD.h:167
DTRecHitClients_cfi.local
local
Definition: DTRecHitClients_cfi.py:10
funct::abs
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
edm::roottree::getEntry
Int_t getEntry(TBranch *branch, EntryNumber entryNumber)
Definition: RootTree.cc:496
CaloG4Hit::setEM
void setEM(double e)
Definition: CaloG4Hit.h:56
c
auto & c
Definition: CAHitNtupletGeneratorKernelsImpl.h:46
CaloSD::initEvent
virtual void initEvent(const BeginOfEvent *)
Definition: CaloSD.cc:819
dqmiolumiharvest.j
j
Definition: dqmiolumiharvest.py:66
CaloSD::printableDecayChain
static std::string printableDecayChain(const std::vector< unsigned int > &decayChain)
Definition: CaloSD.cc:447
CaloG4Hit::setID
void setID(uint32_t i, double d, int j, uint16_t k=0)
Definition: CaloG4Hit.h:72
CaloSD::updateHit
void updateHit(CaloG4Hit *)
Definition: CaloSD.cc:661
hltrates_dqm_sourceclient-live_cfg.offset
offset
Definition: hltrates_dqm_sourceclient-live_cfg.py:82
CaloSD::suppressHeavy
bool suppressHeavy
Definition: CaloSD.h:145
cond::serialization::equal
bool equal(const T &first, const T &second)
Definition: Equal.h:32
CaloSD::EnergyCorrected
virtual double EnergyCorrected(const G4Step &step, const G4Track *)
Definition: CaloSD.cc:310
edm::Log
Definition: MessageLogger.h:70
CaloG4Hit::getHadr
double getHadr() const
Definition: CaloG4Hit.h:58
CaloG4Hit::addEnergyDeposit
void addEnergyDeposit(double em, double hd)
Definition: CaloG4Hit.cc:45
TauDecayModes.dec
dec
Definition: TauDecayModes.py:143
cuy.ii
ii
Definition: cuy.py:590
CaloSD::isItFineCalo
bool isItFineCalo(const G4VTouchable *touch)
Definition: CaloSD.cc:314
weight
Definition: weight.py:1
SimTrackManager::trackContainer
const TrackContainer * trackContainer() const
Definition: SimTrackManager.h:52
hit
Definition: SiStripHitEffFromCalibTree.cc:88
CaloSD::endEvent
virtual void endEvent()
Definition: CaloSD.cc:821
CaloG4Hit::setPosition
void setPosition(double x, double y, double z)
Definition: CaloG4Hit.h:53
CaloG4Hit::getDepth
uint16_t getDepth() const
Definition: CaloG4Hit.h:69
fastSimProducer_cff.density
density
Definition: fastSimProducer_cff.py:61
CaloSD::createNewHit
CaloG4Hit * createNewHit(const G4Step *, const G4Track *)
Definition: CaloSD.cc:568
CaloSD::previousID
CaloHitID previousID
Definition: CaloSD.h:139