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