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