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 
11 
12 #include "G4EventManager.hh"
13 #include "G4SDManager.hh"
14 #include "G4Step.hh"
15 #include "G4Track.hh"
16 #include "G4VProcess.hh"
17 #include "G4GFlashSpot.hh"
18 #include "G4ParticleTable.hh"
19 
20 #include "G4SystemOfUnits.hh"
21 #include "G4PhysicalConstants.hh"
22 
23 #include <iostream>
24 #include <fstream>
25 
26 //#define DebugLog
27 
29  const SensitiveDetectorCatalog & clg,
30  edm::ParameterSet const & p, const SimTrackManager* manager,
31  float timeSliceUnit, bool ignoreTkID) :
32  SensitiveCaloDetector(name, cpv, clg, p),
33  G4VGFlashSensitiveDetector(), eminHit(0.),currentHit(nullptr),
34  m_trackManager(manager), theHC(nullptr), ignoreTrackID(ignoreTkID), hcID(-1),
35  timeSlice(timeSliceUnit), eminHitD(0.) {
36 
37  //Parameters
38  edm::ParameterSet m_CaloSD = p.getParameter<edm::ParameterSet>("CaloSD");
39  energyCut = m_CaloSD.getParameter<double>("EminTrack")*GeV;
40  tmaxHit = m_CaloSD.getParameter<double>("TmaxHit")*ns;
41  std::vector<double> eminHits = m_CaloSD.getParameter<std::vector<double> >("EminHits");
42  std::vector<double> tmaxHits = m_CaloSD.getParameter<std::vector<double> >("TmaxHits");
43  std::vector<std::string> hcn = m_CaloSD.getParameter<std::vector<std::string> >("HCNames");
44  std::vector<int> useResMap = m_CaloSD.getParameter<std::vector<int> >("UseResponseTables");
45  std::vector<double> eminHitX = m_CaloSD.getParameter<std::vector<double> >("EminHitsDepth");
46  suppressHeavy= m_CaloSD.getParameter<bool>("SuppressHeavy");
47  kmaxIon = m_CaloSD.getParameter<double>("IonThreshold")*MeV;
48  kmaxProton = m_CaloSD.getParameter<double>("ProtonThreshold")*MeV;
49  kmaxNeutron = m_CaloSD.getParameter<double>("NeutronThreshold")*MeV;
50  nCheckedHits = m_CaloSD.getUntrackedParameter<int>("CheckHits", 25);
51  useMap = m_CaloSD.getUntrackedParameter<bool>("UseMap", true);
52  int verbn = m_CaloSD.getUntrackedParameter<int>("Verbosity", 0);
53  corrTOFBeam = m_CaloSD.getParameter<bool>("CorrectTOFBeam");
54  double beamZ = m_CaloSD.getParameter<double>("BeamPosition")*cm;
55  correctT = beamZ/c_light/nanosecond;
56 
57  SetVerboseLevel(verbn);
58  meanResponse.reset(nullptr);
59  for (unsigned int k=0; k<hcn.size(); ++k) {
60  if (name == hcn[k]) {
61  if (k < eminHits.size()) eminHit = eminHits[k]*MeV;
62  if (k < eminHitX.size()) eminHitD= eminHitX[k]*MeV;
63  if (k < tmaxHits.size()) tmaxHit = tmaxHits[k]*ns;
64  if (k < useResMap.size() && useResMap[k] > 0) {
65  meanResponse.reset(new CaloMeanResponse(p));
66  break;
67  }
68  }
69  }
70  slave.reset(new CaloSlaveSD(name));
71 
74  isParameterized = false;
75 
76  entrancePoint.set(0.,0.,0.);
77  entranceLocal.set(0.,0.,0.);
78  posGlobal.set(0.,0.,0.);
80 
82  forceSave = false;
83 
84  edm::LogInfo("CaloSim") << "CaloSD: Minimum energy of track for saving it "
85  << energyCut/GeV << " GeV" << "\n"
86  << " Use of HitID Map " << useMap << "\n"
87  << " Check last " << nCheckedHits
88  << " before saving the hit\n"
89  << " Correct TOF globally by " << correctT
90  << " ns (Flag =" << corrTOFBeam << ")\n"
91  << " Save hits recorded before " << tmaxHit
92  << " ns and if energy is above " << eminHit/MeV
93  << " MeV (for depth 0) or " << eminHitD/MeV
94  << " MeV (for nonzero depths);\n"
95  << " Time Slice Unit "
96  << timeSlice << " Ignore TrackID Flag " << ignoreTrackID;
97 }
98 
100 {
101  delete theHC;
102 }
103 
104 G4bool CaloSD::ProcessHits(G4Step * aStep, G4TouchableHistory * ) {
105 
106  NaNTrap( aStep );
107 
108 #ifdef DebugLog
109  edm::LogVerbatim("CaloSim") << "CaloSD::" << GetName()
110  << " ID= " << aStep->GetTrack()->GetTrackID()
111  << " prID= " << aStep->GetTrack()->GetParentID()
112  << " Eprestep= " << aStep->GetPreStepPoint()->GetKineticEnergy()
113  << " step= " << aStep->GetStepLength()
114  << " Edep= " << aStep->GetTotalEnergyDeposit();
115 #endif
116  // apply shower library or parameterisation
117  if(isParameterized) {
118  if(getFromLibrary(aStep)) {
119 
120  // for parameterized showers the primary track should be killed
121  aStep->GetTrack()->SetTrackStatus(fStopAndKill);
122  auto tv = aStep->GetSecondary();
123  auto vol = aStep->GetPreStepPoint()->GetPhysicalVolume();
124  for(auto & tk : *tv) {
125  if (tk->GetVolume() == vol) {
126  tk->SetTrackStatus(fStopAndKill);
127  }
128  }
129  return true;
130  }
131  }
132 
133  // ignore steps without energy deposit
134  edepositEM = edepositHAD = 0.f;
135  unsigned int unitID = setDetUnitId(aStep);
136  auto const theTrack = aStep->GetTrack();
137  uint16_t depth = getDepth(aStep);
138 
139  double time = theTrack->GetGlobalTime()/nanosecond;
140  int primaryID = getTrackID(theTrack);
141  if(unitID > 0) {
142  currentID.setID(unitID, time, primaryID, depth);
143  } else {
144  if(aStep->GetTotalEnergyDeposit() > 0.0) {
145  G4TouchableHistory* touch =(G4TouchableHistory*)(theTrack->GetTouchable());
146  edm::LogInfo("CaloSim") << "CaloSD::ProcessHits: unitID= " << unitID
147  << " currUnit= " << currentID.unitID()
148  << " Detector: " << GetName()
149  << " trackID= " << theTrack->GetTrackID()
150  << " " << theTrack->GetDefinition()->GetParticleName()
151  << "\n Edep= " << aStep->GetTotalEnergyDeposit()
152  << " PV: " << touch->GetVolume(0)->GetName()
153  << " PVid= " << touch->GetReplicaNumber(0)
154  << " MVid= " << touch->GetReplicaNumber(1);
155  }
156  return false;
157  }
158 
159  if(aStep->GetTotalEnergyDeposit() == 0.0) {
160  //---VI: This line is for backward compatibility and should be removed
161  hitExists(aStep);
162  //---
163  return false;
164  }
165 
166  double energy = getEnergyDeposit(aStep);
167  if(energy > 0.0) {
169  edepositEM = energy;
170  } else {
171  edepositHAD = energy;
172  }
173 #ifdef DebugLog
174  G4TouchableHistory* touch =(G4TouchableHistory*)(theTrack->GetTouchable());
175  edm::LogVerbatim("CaloSim")
176  << "CaloSD::" << GetName()
177  << " PV:" << touch->GetVolume(0)->GetName()
178  << " PVid=" << touch->GetReplicaNumber(0)
179  << " MVid=" << touch->GetReplicaNumber(1)
180  << " Unit:" << std::hex << unitID << std::dec
181  << " Edep=" << edepositEM << " " << edepositHAD
182  << " ID=" << theTrack->GetTrackID()
183  << " pID=" << theTrack->GetParentID()
184  << " E=" << theTrack->GetKineticEnergy()
185  << " S=" << aStep->GetStepLength()
186  << "\n " << theTrack->GetDefinition()->GetParticleName()
187  << " primaryID= " << primaryID
188  << " currentID= (" << currentID
189  << ") previousID= (" << previousID << ")";
190 #endif
191  if(!hitExists(aStep)) {
192  currentHit = createNewHit(aStep);
193  }
194  return true;
195  }
196  return false;
197 }
198 
199 bool CaloSD::ProcessHits(G4GFlashSpot* aSpot, G4TouchableHistory * ) {
200 
201  edepositEM = edepositHAD = 0.f;
202  const G4Track* track = aSpot->GetOriginatorTrack()->GetPrimaryTrack();
203  if(!G4TrackToParticleID::isGammaElectronPositron(track)) { return false; }
204  double edep = aSpot->GetEnergySpot()->GetEnergy();
205  if (edep <= 0.0) { return false; }
206  edepositEM = edep;
207  G4Step fFakeStep;
208  G4StepPoint * fFakePreStepPoint = fFakeStep.GetPreStepPoint();
209  G4StepPoint * fFakePostStepPoint = fFakeStep.GetPostStepPoint();
210  fFakePreStepPoint->SetPosition(aSpot->GetPosition());
211  fFakePostStepPoint->SetPosition(aSpot->GetPosition());
212 
213  G4TouchableHandle fTouchableHandle = aSpot->GetTouchableHandle();
214  fFakePreStepPoint->SetTouchableHandle(fTouchableHandle);
215  fFakeStep.SetTotalEnergyDeposit(edep);
216 
217  unsigned int unitID = setDetUnitId(&fFakeStep);
218 
219  if (unitID > 0) {
220  double time = 0;
221  int primaryID = getTrackID(track);
222  uint16_t depth = getDepth(&fFakeStep);
223  currentID.setID(unitID, time, primaryID, depth);
224 #ifdef DebugLog
225  edm::LogVerbatim("CaloSim") << "CaloSD:: GetSpotInfo for"
226  << " Unit 0x" << std::hex << currentID.unitID()
227  << std::dec << " Edeposit = " << edepositEM << " "
228  << edepositHAD;
229 #endif
230  // Update if in the same detector, time-slice and for same track
231  if (currentID == previousID) {
233  } else {
234  posGlobal = aSpot->GetEnergySpot()->GetPosition();
235  // Reset entry point for new primary
236  if (currentID.trackID() != previousID.trackID()) {
237  entrancePoint = aSpot->GetPosition();
238  entranceLocal = aSpot->GetTouchableHandle()->GetHistory()->
239  GetTopTransform().TransformPoint(entrancePoint);
240  incidentEnergy = track->GetKineticEnergy();
241 #ifdef DebugLog
242  LogDebug("CaloSim") << "CaloSD: Incident energy "
243  << incidentEnergy/GeV << " GeV and"
244  << " entrance point " << entrancePoint
245  << " (Global) " << entranceLocal << " (Local)";
246 #endif
247  }
248  if (!checkHit()) { currentHit = createNewHit(&fFakeStep); }
249  }
250  return true;
251  }
252  return false;
253 }
254 
255 double CaloSD::getEnergyDeposit(const G4Step* aStep) {
256  return aStep->GetTotalEnergyDeposit();
257 }
258 
259 bool CaloSD::getFromLibrary(const G4Step*) {
260  return false;
261 }
262 
263 void CaloSD::Initialize(G4HCofThisEvent * HCE) {
264  totalHits = 0;
265 
266 #ifdef DebugLog
267  edm::LogVerbatim("CaloSim") << "CaloSD : Initialize called for " << GetName();
268 #endif
269 
270  //This initialization is performed at the beginning of an event
271  //------------------------------------------------------------
272  theHC = new CaloG4HitCollection(GetName(), collectionName[0]);
273 
274  if (hcID<0) {
275  hcID = G4SDManager::GetSDMpointer()->GetCollectionID(collectionName[0]);
276  }
277  HCE->AddHitsCollection(hcID, theHC);
278 }
279 
280 void CaloSD::EndOfEvent(G4HCofThisEvent* ) {
281  // clean the hits for the last tracks
282 
284 
285 #ifdef DebugLog
286  edm::LogVerbatim("CaloSim") << "CaloSD: EndofEvent entered with " << theHC->entries()
287  << " entries";
288 #endif
289 }
290 
291 void CaloSD::clear() {}
292 
293 void CaloSD::DrawAll() {}
294 
296 #ifdef DebugLog
297  edm::LogVerbatim("CaloSim") << "CaloSD: Collection " << theHC->GetName();
298 #endif
299  theHC->PrintAllHits();
300 }
301 
303  if (slave.get()->name() == hname) { cc=slave.get()->hits(); }
304  slave.get()->Clean();
305 }
306 
307 G4ThreeVector CaloSD::setToLocal(const G4ThreeVector& global, const G4VTouchable* touch) const {
308  return touch->GetHistory()->GetTopTransform().TransformPoint(global);
309 }
310 
311 G4ThreeVector CaloSD::setToGlobal(const G4ThreeVector& local, const G4VTouchable* touch) const {
312  return touch->GetHistory()->GetTopTransform().Inverse().TransformPoint(local);
313 }
314 
315 bool CaloSD::hitExists(const G4Step* aStep) {
316  // Update if in the same detector, time-slice and for same track
317  if (currentID == previousID) {
319  return true;
320  }
321 
322  // Reset entry point for new primary
323  posGlobal = aStep->GetPreStepPoint()->GetPosition();
324  if (currentID.trackID() != previousID.trackID()) {
325  resetForNewPrimary(aStep);
326  }
327  return checkHit();
328 }
329 
331  //look in the HitContainer whether a hit with the same ID already exists:
332  bool found = false;
333  if (useMap) {
334  std::map<CaloHitID,CaloG4Hit*>::const_iterator it = hitMap.find(currentID);
335  if (it != hitMap.end()) {
336  currentHit = it->second;
337  found = true;
338  }
339  } else if (nCheckedHits > 0) {
340  int minhit= (theHC->entries()>nCheckedHits ? theHC->entries()-nCheckedHits : 0);
341  int maxhit= theHC->entries()-1;
342 
343  for (int j=maxhit; j>minhit; --j) {
344  if ((*theHC)[j]->getID() == currentID) {
345  currentHit = (*theHC)[j];
346  found = true;
347  break;
348  }
349  }
350  }
351 
352  if (found) { updateHit(currentHit); }
353  return found;
354 }
355 
356 int CaloSD::getNumberOfHits() { return theHC->entries(); }
357 
358 CaloG4Hit* CaloSD::createNewHit(const G4Step* aStep) {
359 
360  auto const theTrack = aStep->GetTrack();
361 #ifdef DebugLog
362  edm::LogVerbatim("CaloSim") << "CaloSD::CreateNewHit " << getNumberOfHits()
363  << " for " << GetName()
364  << " Unit:" << currentID.unitID()
365  << " " << currentID.depth()
366  << " Edep= " << edepositEM << " " << edepositHAD
367  << " primaryID= " << currentID.trackID()
368  << " timeSlice= " << currentID.timeSliceID()
369  << " ID= " << theTrack->GetTrackID()
370  << " " <<theTrack->GetDefinition()->GetParticleName()
371  << " E(GeV)= " << theTrack->GetKineticEnergy()/GeV
372  << " parentID= " << theTrack->GetParentID()
373  << "\n Ein= " << incidentEnergy
374  << " entranceGlobal: " << entrancePoint
375  << " entranceLocal: " << entranceLocal
376  << " posGlobal: " << posGlobal;
377 #endif
378 
379  CaloG4Hit* aHit;
380  if (!reusehit.empty()) {
381  aHit = reusehit[0];
382  aHit->setEM(0.f);
383  aHit->setHadr(0.f);
384  reusehit.erase(reusehit.begin());
385  } else {
386  aHit = new CaloG4Hit;
387  }
388 
389  aHit->setID(currentID);
392  aHit->setPosition(posGlobal.x(),posGlobal.y(),posGlobal.z());
394  updateHit(aHit);
395 
396  storeHit(aHit);
397  double etrack = 0;
398  if (currentID.trackID() == primIDSaved) { // The track is saved; nothing to be done
399  } else if (currentID.trackID() == theTrack->GetTrackID()) {
400  etrack= theTrack->GetKineticEnergy();
401 #ifdef DebugLog
402  edm::LogVerbatim("CaloSim") << "CaloSD: set save the track " << currentID.trackID()
403  << " etrack " << etrack << " eCut " << energyCut
404  << " force: " << forceSave
405  << " save: " << (etrack >= energyCut || forceSave);
406 #endif
407  if (etrack >= energyCut || forceSave) {
408  TrackInformation* trkInfo = cmsTrackInformation(theTrack);
409  trkInfo->storeTrack(true);
410  trkInfo->putInHistory();
411  }
412  } else {
414 #ifdef DebugLog
415  edm::LogVerbatim("CaloSim") << "CaloSD : TrackwithHistory pointer for "
416  << currentID.trackID() << " is " << trkh;
417 #endif
418  if (trkh != nullptr) {
419  etrack = sqrt(trkh->momentum().Mag2());
420  if (etrack >= energyCut) {
421  trkh->save();
422 #ifdef DebugLog
423  edm::LogVerbatim("CaloSim") << "CaloSD: set save the track "
424  << currentID.trackID() << " with Hit";
425 #endif
426  }
427  }
428  }
430  if (useMap) ++totalHits;
431  return aHit;
432 }
433 
435 
437 #ifdef DebugLog
438  edm::LogVerbatim("CaloSim") << "CaloSD:" << GetName() << " Add energy deposit in "
439  << currentID << " Edep_em(MeV)= "
440  << edepositEM << " Edep_had(MeV)= " << edepositHAD;
441 #endif
442 
443  // buffer for next steps:
445 }
446 
447 void CaloSD::resetForNewPrimary(const G4Step* aStep) {
448  auto const preStepPoint = aStep->GetPreStepPoint();
449  entrancePoint = preStepPoint->GetPosition();
450  entranceLocal = setToLocal(entrancePoint, preStepPoint->GetTouchable());
451  incidentEnergy = preStepPoint->GetKineticEnergy();
452 #ifdef DebugLog
453  edm::LogVerbatim("CaloSim")
454  << "CaloSD::resetForNewPrimary for " << GetName()
455  << " ID= " << aStep->GetTrack()->GetTrackID()
456  << " Ein= " << incidentEnergy/GeV
457  << " GeV and" << " entrance point global: " << entrancePoint
458  << " local: " << entranceLocal;
459 #endif
460 }
461 
462 double CaloSD::getAttenuation(const G4Step* aStep, double birk1, double birk2, double birk3) const {
463  double weight = 1.;
464  double charge = aStep->GetPreStepPoint()->GetCharge();
465  double length = aStep->GetStepLength();
466 
467  if (charge != 0. && length > 0.) {
468  double density = aStep->GetPreStepPoint()->GetMaterial()->GetDensity();
469  double dedx = aStep->GetTotalEnergyDeposit()/length;
470  double rkb = birk1/density;
471  double c = birk2*rkb*rkb;
472  if (std::abs(charge) >= 2.) rkb /= birk3; // based on alpha particle data
473  weight = 1./(1.+rkb*dedx+c*dedx*dedx);
474 #ifdef DebugLog
475  edm::LogVerbatim("CaloSim") << "CaloSD::getAttenuation in " << mat->GetName()
476  << " Charge " << charge << " dE/dx " << dedx
477  << " Birk Const " << rkb << ", " << c << " Weight = "
478  << weight << " dE " << aStep->GetTotalEnergyDeposit();
479 #endif
480  }
481  return weight;
482 }
483 
484 void CaloSD::update(const BeginOfRun *) {
485  initRun();
486 }
487 
489 #ifdef DebugLog
490  edm::LogVerbatim("CaloSim") << "CaloSD: Dispatched BeginOfEvent for "
491  << GetName() << " !" ;
492 #endif
493  clearHits();
494 }
495 
496 void CaloSD::update(const EndOfTrack * trk) {
497  int id = (*trk)()->GetTrackID();
498  TrackInformation *trkI = cmsTrackInformation((*trk)());
499  int lastTrackID = -1;
500  if (trkI) lastTrackID = trkI->getIDonCaloSurface();
501  if (id == lastTrackID) {
502  const TrackContainer * trksForThisEvent = m_trackManager->trackContainer();
503  if (trksForThisEvent != nullptr) {
504  int it = (int)(trksForThisEvent->size()) - 1;
505  if (it >= 0) {
506  TrackWithHistory * trkH = (*trksForThisEvent)[it];
507  if (trkH->trackID() == (unsigned int)(id)) tkMap[id] = trkH;
508 #ifdef DebugLog
509  edm::LogVerbatim("CaloSim") << "CaloSD: get track " << it << " from "
510  << "Container of size " << trksForThisEvent->size()
511  << " with ID " << trkH->trackID();
512  } else {
513  edm::LogVerbatim("CaloSim") << "CaloSD: get track " << it << " from "
514  << "Container of size " << trksForThisEvent->size()
515  << " with no ID";
516 #endif
517  }
518  }
519  }
520 }
521 
522 void CaloSD::update(const ::EndOfEvent * ) {
523 
524  slave.get()->ReserveMemory(theHC->entries());
525 
526  int count(0);
527  int wrong(0);
528  double eEM(0.0);
529  double eHAD(0.0);
530  double eEM2(0.0);
531  double eHAD2(0.0);
532  double tt(0.0);
533  double zloc(0.0);
534  double zglob(0.0);
535  double ee(0.0);
536 
537  for (int i=0; i<theHC->entries(); ++i) {
538  if(!saveHit((*theHC)[i])) { ++wrong; }
539  ++count;
540  double x = (*theHC)[i]->getEM();
541  eEM += x;
542  eEM2 += x*x;
543  x = (*theHC)[i]->getHadr();
544  eHAD += x;
545  eHAD2 += x*x;
546  tt += (*theHC)[i]->getTimeSlice();
547  ee += (*theHC)[i]->getIncidentEnergy();
548  zglob += std::abs((*theHC)[i]->getEntry().z());
549  zloc += std::abs((*theHC)[i]->getEntryLocal().z());
550  }
551 
552  double norm = (count>0) ? 1.0/count : 0.0;
553  eEM *= norm;
554  eEM2 *= norm;
555  eHAD *= norm;
556  eHAD2 *= norm;
557  eEM2 = std::sqrt(eEM2 - eEM*eEM);
558  eHAD2 = std::sqrt(eHAD2 - eHAD*eHAD);
559  tt *= norm;
560  ee *= norm;
561  zglob *= norm;
562  zloc *= norm;
563 
564  edm::LogVerbatim("CaloSim") << "CaloSD: " << GetName() << " store " << count
565  << " hits; " << wrong
566  << " track IDs not given properly and "
567  << totalHits-count << " hits not passing cuts"
568  << "\n EmeanEM= " << eEM << " ErmsEM= " << eEM2
569  << "\n EmeanHAD= " << eHAD << " ErmsHAD= " << eHAD2
570  << " TimeMean= " << tt << " E0mean= " << ee
571  << " Zglob= " << zglob << " Zloc= " << zloc
572  << " ";
573 
574  tkMap.erase (tkMap.begin(), tkMap.end());
575 }
576 
578  if (useMap) hitMap.erase (hitMap.begin(), hitMap.end());
579  for (unsigned int i = 0; i<reusehit.size(); ++i) delete reusehit[i];
580  std::vector<CaloG4Hit*>().swap(reusehit);
581  cleanIndex = 0;
582  previousID.reset();
583  primIDSaved = -99;
584 #ifdef DebugLog
585  edm::LogVerbatim("CaloSim") << "CaloSD: Clears hit vector for " << GetName()
586  << " and initialise slave: " << slave;
587 #endif
588  slave.get()->Initialize();
589 }
590 
592 
593 int CaloSD::getTrackID(const G4Track* aTrack) {
594 
595  int primaryID = 0;
596  forceSave = false;
597  TrackInformation* trkInfo = cmsTrackInformation(aTrack);
598  if (trkInfo) {
599  primaryID = trkInfo->getIDonCaloSurface();
600 #ifdef DebugLog
601  edm::LogVerbatim("CaloSim") << "CaloSD: hit update from track Id on Calo Surface "
602  << trkInfo->getIDonCaloSurface();
603 #endif
604  } else {
605  primaryID = aTrack->GetTrackID();
606 #ifdef DebugLog
607  edm::LogWarning("CaloSim") << "CaloSD: Problem with primaryID **** set by "
608  << "force to TkID **** " << primaryID << " in "
609  << preStepPoint->GetTouchable()->GetVolume(0)->GetName();
610 #endif
611  }
612  return primaryID;
613 }
614 
615 int CaloSD::setTrackID(const G4Step* aStep) {
616 
617  auto const theTrack = aStep->GetTrack();
618  TrackInformation * trkInfo = cmsTrackInformation(theTrack);
619  int primaryID = trkInfo->getIDonCaloSurface();
620  if (primaryID == 0) { primaryID = theTrack->GetTrackID(); }
621 
622  if (primaryID != previousID.trackID()) {
623  resetForNewPrimary(aStep);
624  }
625 #ifdef DebugLog
626  edm::LogVerbatim("CaloSim") << "CaloSD::setTrackID for " << GetName()
627  << " trackID= " << aStep->GetTrack()->GetTrackID()
628  << " primaryID= " << primaryID;
629 #endif
630  return primaryID;
631 }
632 
633 uint16_t CaloSD::getDepth(const G4Step*) { return 0; }
634 
636  double emin(eminHit);
637  if (hit->getDepth() > 0) emin = eminHitD;
638 #ifdef DebugLog
639  edm::LogVerbatim("CaloSim") << "CaloSD::filterHit(..) Depth " << hit->getDepth()
640  << " Emin = " << emin
641  << " (" << eminHit << ", " << eminHitD << ")";
642 #endif
643  return ((time <= tmaxHit) && (hit->getEnergyDeposit() > emin));
644 }
645 
646 double CaloSD::getResponseWt(const G4Track* aTrack) {
647  double wt = 1.0;
648  if (meanResponse.get()) {
649  TrackInformation * trkInfo = cmsTrackInformation(aTrack);
650  wt = meanResponse.get()->getWeight(trkInfo->genParticlePID(), trkInfo->genParticleP());
651  }
652  return wt;
653 }
654 
656  if (hit == nullptr || previousID.trackID()<0) {
657  edm::LogWarning("CaloSim") << "CaloSD: hit to be stored is nullptr !!"
658  << " previousID.trackID()= " << previousID.trackID();
659  return;
660  }
661 
662  theHC->insert(hit);
663  if (useMap) hitMap.insert(std::pair<CaloHitID,CaloG4Hit*>(previousID,hit));
664 }
665 
667  int tkID;
668  bool ok = true;
669  if (m_trackManager) {
670  tkID = m_trackManager->giveMotherNeeded(aHit->getTrackID());
671  if (tkID == 0) {
672  if (m_trackManager->trackExists(aHit->getTrackID())) tkID = (aHit->getTrackID());
673  else {
674  ok = false;
675  }
676  }
677  } else {
678  tkID = aHit->getTrackID();
679  ok = false;
680  }
681 #ifdef DebugLog
682  edm::LogVerbatim("CaloSim") << "CalosD: Track ID " << aHit->getTrackID()
683  << " changed to " << tkID << " by SimTrackManager"
684  << " Status " << ok;
685 #endif
686  double time = aHit->getTimeSlice();
687  if (corrTOFBeam) time += correctT;
688  slave.get()->processHits(aHit->getUnitID(), aHit->getEM()/GeV,
689  aHit->getHadr()/GeV, time, tkID, aHit->getDepth());
690 #ifdef DebugLog
691  edm::LogVerbatim("CaloSim") << "CaloSD: Store Hit at " << std::hex
692  << aHit->getUnitID() << std::dec << " "
693  << aHit->getDepth() << " due to " << tkID
694  << " in time " << time << " of energy "
695  << aHit->getEM()/GeV << " GeV (EM) and "
696  << aHit->getHadr()/GeV << " GeV (Hadr)";
697 #endif
698  return ok;
699 }
700 
701 void CaloSD::update(const BeginOfTrack * trk) {
702  int primary = -1;
703  TrackInformation * trkInfo = cmsTrackInformation((*trk)());
704  if ( trkInfo->isPrimary() ) primary = (*trk)()->GetTrackID();
705 
706 #ifdef DebugLog
707  edm::LogVerbatim("CaloSim") << "New track: isPrimary " << trkInfo->isPrimary()
708  << " primary ID = " << primary
709  << " primary ancestor ID " << primAncestor;
710 #endif
711 
712  // update the information if a different primary track ID
713 
714  if (primary > 0 && primary != primAncestor) {
715  primAncestor = primary;
716 
717  // clean the hits information
718 
719  if (theHC->entries()>0) cleanHitCollection();
720 
721  }
722 }
723 
725  std::vector<CaloG4Hit*>* theCollection = theHC->GetVector();
726 
727 #ifdef DebugLog
728  edm::LogVerbatim("CaloSim") << "CaloSD: collection before merging, size = "
729  << theHC->entries();
730 #endif
731 
732  selIndex.reserve(theHC->entries()-cleanIndex);
733  if ( reusehit.empty() ) reusehit.reserve(theHC->entries()-cleanIndex);
734 
735  // if no map used, merge before hits to have the save situation as a map
736  if ( !useMap ) {
737  hitvec.swap(*theCollection);
738  sort((hitvec.begin()+cleanIndex), hitvec.end(), CaloG4HitLess());
739 #ifdef DebugLog
740  edm::LogVerbatim("CaloSim") << "CaloSD::cleanHitCollection: sort hits in buffer "
741  << "starting from element = " << cleanIndex;
742  for (unsigned int i = 0; i<hitvec.size(); ++i)
743  edm::LogVerbatim("CaloSim") << i << " " << *hitvec[i];
744 #endif
745  unsigned int i, j;
747  for (i=cleanIndex; i<hitvec.size(); ++i) {
748  selIndex.push_back(i-cleanIndex);
749  int jump = 0;
750  for (j = i+1; j <hitvec.size() && equal(hitvec[i], hitvec[j]); ++j) {
751  ++jump;
752  // merge j to i
753  (*hitvec[i]).addEnergyDeposit(*hitvec[j]);
754  (*hitvec[j]).setEM(0.);
755  (*hitvec[j]).setHadr(0.);
756  reusehit.push_back(hitvec[j]);
757  }
758  i+=jump;
759  }
760 #ifdef DebugLog
761  edm::LogVerbatim("CaloSim") << "CaloSD: cleanHitCollection merge the hits in buffer ";
762  for (unsigned int i = 0; i<hitvec.size(); ++i)
763  edm::LogVerbatim("CaloSim") << i << " " << *hitvec[i];
764 #endif
765  for ( unsigned int i = cleanIndex; i < cleanIndex+selIndex.size(); ++i ) {
766  hitvec[i] = hitvec[selIndex[i-cleanIndex]+cleanIndex];
767  }
768  hitvec.resize(cleanIndex+selIndex.size());
769 #ifdef DebugLog
770  edm::LogVerbatim("CaloSim")
771  << "CaloSD::cleanHitCollection: remove the merged hits in buffer,"
772  << " new size = " << hitvec.size();
773  for (unsigned int i = 0; i<hitvec.size(); ++i)
774  edm::LogVerbatim("CaloSim") << i << " " << *hitvec[i];
775 #endif
776  hitvec.swap(*theCollection);
777  std::vector<CaloG4Hit*>().swap(hitvec);
778  selIndex.clear();
779  totalHits = theHC->entries();
780  }
781 
782 #ifdef DebugLog
783  edm::LogVerbatim("CaloSim") << "CaloSD: collection after merging, size= "
784  << theHC->entries()
785  << " Size of reusehit= " << reusehit.size()
786  << "\n starting hit selection from index = "
787  << cleanIndex;
788 #endif
789 
790  int addhit = 0;
791  selIndex.reserve(theCollection->size()-cleanIndex);
792  for (unsigned int i = cleanIndex; i<theCollection->size(); ++i) {
793  CaloG4Hit* aHit((*theCollection)[i]);
794 
795  // selection
796 
797  double time = aHit->getTimeSlice();
798  if (corrTOFBeam) time += correctT;
799  if (!filterHit(aHit,time)) {
800 #ifdef DebugLog
801  edm::LogVerbatim("CaloSim") << "CaloSD: dropped CaloG4Hit " << " " << *aHit;
802 #endif
803 
804  // create the list of hits to be reused
805 
806  reusehit.push_back((*theCollection)[i]);
807  ++addhit;
808  } else {
809  selIndex.push_back(i-cleanIndex);
810  }
811  }
812 
813 #ifdef DebugLog
814  edm::LogVerbatim("CaloSim") << "CaloSD: Size of reusehit after selection = "
815  << reusehit.size() << " Number of added hit = "
816  << addhit;
817 #endif
818  if (useMap) {
819  if ( addhit>0 ) {
820  int offset = reusehit.size()-addhit;
821  for (int ii = addhit-1; ii>=0; --ii) {
822  CaloHitID theID = reusehit[offset+ii]->getID();
823  hitMap.erase(theID);
824  }
825  }
826  }
827  for (unsigned int j = 0; j<selIndex.size(); ++j) {
828  (*theCollection)[cleanIndex+j] = (*theCollection)[cleanIndex+selIndex[j]];
829  }
830 
831  theCollection->resize(cleanIndex+selIndex.size());
832  std::vector<unsigned int>().swap(selIndex);
833 
834 #ifdef DebugLog
835  edm::LogVerbatim("CaloSim")
836  << "CaloSD: hit collection after selection, size = "
837  << theHC->entries();
838  theHC->PrintAllHits();
839 #endif
840 
841  cleanIndex = theHC->entries();
842 }
#define LogDebug(id)
float edepositEM
Definition: CaloSD.h:128
Int_t getEntry(TBranch *branch, EntryNumber entryNumber)
Definition: RootTree.cc:510
double energyCut
Definition: CaloSD.h:132
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
virtual bool getFromLibrary(const G4Step *step)
Definition: CaloSD.cc:259
std::vector< PCaloHit > PCaloHitContainer
const double GeV
Definition: MathUtil.h:16
double kmaxNeutron
Definition: CaloSD.h:137
void updateHit(CaloG4Hit *)
Definition: CaloSD.cc:434
virtual uint16_t getDepth(const G4Step *)
Definition: CaloSD.cc:633
virtual double getEnergyDeposit(const G4Step *step)
Definition: CaloSD.cc:255
bool storeTrack() const
int getIDonCaloSurface() const
bool corrTOFBeam
Definition: CaloSD.h:153
int totalHits
Definition: CaloSD.h:158
void setIncidentEnergy(double e)
Definition: CaloG4Hit.h:66
void setEntryLocal(double x, double y, double z)
Definition: CaloG4Hit.h:54
void DrawAll() override
Definition: CaloSD.cc:293
void clear() override
Definition: CaloSD.cc:291
uint32_t setDetUnitId(const G4Step *step) override=0
double genParticleP() const
bool useMap
Definition: CaloSD.h:152
uint16_t getDepth() const
Definition: CaloG4Hit.h:72
int hcID
Definition: CaloSD.h:155
double eminHitD
Definition: CaloSD.h:163
Definition: weight.py:1
G4ThreeVector posGlobal
Definition: CaloSD.h:126
virtual int getTrackID(const G4Track *)
Definition: CaloSD.cc:593
int primIDSaved
Definition: CaloSD.h:159
void Initialize(G4HCofThisEvent *HCE) override
Definition: CaloSD.cc:263
int primAncestor
Definition: CaloSD.h:156
#define nullptr
uint16_t depth() const
Definition: CaloHitID.h:26
Compact representation of the geometrical detector hierarchy.
Definition: DDCompactView.h:83
double kmaxProton
Definition: CaloSD.h:137
void fillHits(edm::PCaloHitContainer &, const std::string &) override
Definition: CaloSD.cc:302
double eminHit
Definition: CaloSD.h:132
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:116
std::vector< CaloG4Hit * > reusehit
Definition: CaloSD.h:169
bool equal(const T &first, const T &second)
Definition: Equal.h:34
void cleanHitCollection()
Definition: CaloSD.cc:724
void reset()
Definition: CaloHitID.cc:53
const double MeV
bool forceSave
Definition: CaloSD.h:139
void addEnergyDeposit(double em, double hd)
Definition: CaloG4Hit.cc:47
float timeSlice
Definition: CaloSD.h:162
const TrackContainer * trackContainer() const
int genParticlePID() const
bool checkHit()
Definition: CaloSD.cc:330
std::string const collectionName[nCollections]
Definition: Collections.h:47
double kmaxIon
Definition: CaloSD.h:137
bool suppressHeavy
Definition: CaloSD.h:136
std::unique_ptr< CaloSlaveSD > slave
Definition: CaloSD.h:145
int timeSliceID() const
Definition: CaloHitID.h:23
std::vector< TrackWithHistory * > TrackContainer
Definition: TrackContainer.h:8
float edepositHAD
Definition: CaloSD.h:128
T sqrt(T t)
Definition: SSEVec.h:18
unsigned int trackID() const
int trackID() const
Definition: CaloHitID.h:25
void resetForNewPrimary(const G4Step *)
Definition: CaloSD.cc:447
bool trackExists(unsigned int i) const
void setEM(double e)
Definition: CaloG4Hit.h:60
void setID(uint32_t i, double d, int j, uint16_t k=0)
Definition: CaloG4Hit.h:75
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
CaloG4Hit * createNewHit(const G4Step *)
Definition: CaloSD.cc:358
G4bool ProcessHits(G4Step *step, G4TouchableHistory *) override
Definition: CaloSD.cc:104
double f[11][100]
std::vector< CaloG4Hit * > hitvec
Definition: CaloSD.h:170
int getNumberOfHits()
Definition: CaloSD.cc:356
G4ThreeVector setToGlobal(const G4ThreeVector &, const G4VTouchable *) const
Definition: CaloSD.cc:311
CaloSD(const std::string &aSDname, const DDCompactView &cpv, const SensitiveDetectorCatalog &clg, edm::ParameterSet const &p, const SimTrackManager *, float timeSlice=1., bool ignoreTkID=false)
Definition: CaloSD.cc:28
CaloHitID previousID
Definition: CaloSD.h:130
~CaloSD() override
Definition: CaloSD.cc:99
CaloG4Hit * currentHit
Definition: CaloSD.h:134
int giveMotherNeeded(int i) const
std::vector< unsigned int > selIndex
Definition: CaloSD.h:171
void storeHit(CaloG4Hit *)
Definition: CaloSD.cc:655
TrackInformation * cmsTrackInformation(const G4Track *aTrack)
virtual bool filterHit(CaloG4Hit *, double)
Definition: CaloSD.cc:635
ii
Definition: cuy.py:589
double tmaxHit
Definition: CaloSD.h:132
int k[5][pyjets_maxn]
void setID(uint32_t unitID, double timeSlice, int trackID, uint16_t depth=0)
Definition: CaloHitID.cc:44
G4ThreeVector setToLocal(const G4ThreeVector &, const G4VTouchable *) const
Definition: CaloSD.cc:307
bool hitExists(const G4Step *)
Definition: CaloSD.cc:315
int getTrackID() const
Definition: CaloG4Hit.h:68
std::unique_ptr< CaloMeanResponse > meanResponse
Definition: CaloSD.h:146
CaloHitID currentID
Definition: CaloSD.h:130
virtual void initRun()
Definition: CaloSD.cc:591
double correctT
Definition: CaloSD.h:164
const math::XYZVectorD & momentum() const
bool isPrimary() const
void EndOfEvent(G4HCofThisEvent *eventHC) override
Definition: CaloSD.cc:280
CSCCFEBTimeSlice const *const timeSlice(T const &data, int nCFEB, int nSample)
std::map< CaloHitID, CaloG4Hit * > hitMap
Definition: CaloSD.h:166
double getAttenuation(const G4Step *aStep, double birk1, double birk2, double birk3) const
Definition: CaloSD.cc:462
double getEM() const
Definition: CaloG4Hit.h:59
int nCheckedHits
Definition: CaloSD.h:160
CaloG4HitCollection * theHC
Definition: CaloSD.h:148
void setHadr(double e)
Definition: CaloG4Hit.h:63
float incidentEnergy
Definition: CaloSD.h:127
virtual int setTrackID(const G4Step *)
Definition: CaloSD.cc:615
void setPosition(double x, double y, double z)
Definition: CaloG4Hit.h:57
void setEntry(double x, double y, double z)
Definition: CaloG4Hit.h:51
G4THitsCollection< CaloG4Hit > CaloG4HitCollection
static bool isGammaElectronPositron(int pdgCode)
bool isParameterized
Definition: CaloSD.h:151
double getTimeSlice() const
Definition: CaloG4Hit.h:70
std::map< int, TrackWithHistory * > tkMap
Definition: CaloSD.h:167
const SimTrackManager * m_trackManager
Definition: CaloSD.h:143
uint32_t getUnitID() const
Definition: CaloG4Hit.h:69
uint32_t unitID() const
Definition: CaloHitID.h:22
void clearHits() override
Definition: CaloSD.cc:577
double getResponseWt(const G4Track *)
Definition: CaloSD.cc:646
bool saveHit(CaloG4Hit *)
Definition: CaloSD.cc:666
void PrintAll() override
Definition: CaloSD.cc:295
G4ThreeVector entrancePoint
Definition: CaloSD.h:124
G4ThreeVector entranceLocal
Definition: CaloSD.h:125
double getHadr() const
Definition: CaloG4Hit.h:62
void update(const BeginOfRun *) override
This routine will be called when the appropriate signal arrives.
Definition: CaloSD.cc:484
double getEnergyDeposit() const
Definition: CaloG4Hit.h:81
int cleanIndex
Definition: CaloSD.h:157
void NaNTrap(const G4Step *step) const
bool ignoreTrackID
Definition: CaloSD.h:150