CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CaloSD.cc
Go to the documentation of this file.
1 // File: CaloSD.cc
3 // Description: Sensitive Detector class for calorimeters
5 
10 
11 #include "G4EventManager.hh"
12 #include "G4SDManager.hh"
13 #include "G4Step.hh"
14 #include "G4Track.hh"
15 #include "G4VProcess.hh"
16 #include "G4GFlashSpot.hh"
17 #include "G4ParticleTable.hh"
18 
19 #include "G4SystemOfUnits.hh"
20 #include "G4PhysicalConstants.hh"
21 
22 //#define DebugLog
23 
24 CaloSD::CaloSD(G4String name, const DDCompactView & cpv,
25  const SensitiveDetectorCatalog & clg,
26  edm::ParameterSet const & p, const SimTrackManager* manager,
27  float timeSliceUnit, bool ignoreTkID) :
28  SensitiveCaloDetector(name, cpv, clg, p),
29  G4VGFlashSensitiveDetector(), theTrack(0), preStepPoint(0), eminHit(0),
30  eminHitD(0), m_trackManager(manager), currentHit(0), runInit(false),
31  timeSlice(timeSliceUnit), ignoreTrackID(ignoreTkID), hcID(-1), theHC(0),
32  meanResponse(0) {
33  //Add Hcal Sentitive Detector Names
34 
35  collectionName.insert(name);
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  checkHits = 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  for (unsigned int k=0; k<hcn.size(); ++k) {
59  if (name == (G4String)(hcn[k])) {
60  if (k < eminHits.size()) eminHit = eminHits[k]*MeV;
61  if (k < eminHitX.size()) eminHitD= eminHitX[k]*MeV;
62  if (k < tmaxHits.size()) tmaxHit = tmaxHits[k]*ns;
63  if (k < useResMap.size() && useResMap[k] > 0) meanResponse = new CaloMeanResponse(p);
64  break;
65  }
66  }
67 #ifdef DebugLog
68  LogDebug("CaloSim") << "***************************************************"
69  << "\n"
70  << "* *"
71  << "\n"
72  << "* Constructing a CaloSD with name " << GetName()
73  << "\n"
74  << "* *"
75  << "\n"
76  << "***************************************************";
77 #endif
78  slave = new CaloSlaveSD(name);
81 
82  primAncestor = 0;
83  cleanIndex = 0;
84  totalHits = 0;
85  forceSave = false;
86 
87  //
88  // Now attach the right detectors (LogicalVolumes) to me
89  //
90  const std::vector<std::string>& lvNames = clg.logicalNames(name);
91  this->Register();
92  for (std::vector<std::string>::const_iterator it=lvNames.begin(); it !=lvNames.end(); ++it) {
93  this->AssignSD(*it);
94 #ifdef DebugLog
95  LogDebug("CaloSim") << "CaloSD : Assigns SD to LV " << (*it);
96 #endif
97  }
98 
99  edm::LogInfo("CaloSim") << "CaloSD: Minimum energy of track for saving it "
100  << energyCut/GeV << " GeV" << "\n"
101  << " Use of HitID Map " << useMap << "\n"
102  << " Check last " << checkHits
103  << " before saving the hit\n"
104  << " Correct TOF globally by " << correctT
105  << " ns (Flag =" << corrTOFBeam << ")\n"
106  << " Save hits recorded before " << tmaxHit
107  << " ns and if energy is above " << eminHit/MeV
108  << " MeV (for depth 0) or " << eminHitD/MeV
109  << " MeV (for nonzero depths); Time Slice Unit "
110  << timeSlice << " Ignore TrackID Flag " << ignoreTrackID;
111 }
112 
114  if (slave) delete slave;
115  if (theHC) delete theHC;
116  if (meanResponse) delete meanResponse;
117 }
118 
119 bool CaloSD::ProcessHits(G4Step * aStep, G4TouchableHistory * ) {
120 
121  NaNTrap( aStep ) ;
122 
123  if (aStep == NULL) {
124  return true;
125  } else {
126  if (getStepInfo(aStep)) {
127  if (hitExists() == false && edepositEM+edepositHAD>0.)
129  }
130  }
131  return true;
132 }
133 
134 bool CaloSD::ProcessHits(G4GFlashSpot* aSpot, G4TouchableHistory*) {
135 
136  if (aSpot != NULL) {
137  theTrack = const_cast<G4Track *>(aSpot->GetOriginatorTrack()->GetPrimaryTrack());
138  G4int particleCode = theTrack->GetDefinition()->GetPDGEncoding();
139 
140  if (particleCode == emPDG ||
141  particleCode == epPDG ||
142  particleCode == gammaPDG ) {
143  edepositEM = aSpot->GetEnergySpot()->GetEnergy();
144  edepositHAD = 0.;
145  } else {
146  edepositEM = 0.;
147  edepositHAD = 0.;
148  }
149 
150  if (edepositEM>0.) {
151  G4Step * fFakeStep = new G4Step();
152  preStepPoint = fFakeStep->GetPreStepPoint();
153  G4StepPoint * fFakePostStepPoint = fFakeStep->GetPostStepPoint();
154  preStepPoint->SetPosition(aSpot->GetPosition());
155  fFakePostStepPoint->SetPosition(aSpot->GetPosition());
156 
157  G4TouchableHandle fTouchableHandle = aSpot->GetTouchableHandle();
158  preStepPoint->SetTouchableHandle(fTouchableHandle);
159  fFakeStep->SetTotalEnergyDeposit(aSpot->GetEnergySpot()->GetEnergy());
160 
161  double time = 0;
162  unsigned int unitID = setDetUnitId(fFakeStep);
163  int primaryID = getTrackID(theTrack);
164  uint16_t depth = getDepth(fFakeStep);
165 
166  if (unitID > 0) {
167  currentID.setID(unitID, time, primaryID, depth);
168 #ifdef DebugLog
169  LogDebug("CaloSim") << "CaloSD:: GetSpotInfo for"
170  << " Unit 0x" << std::hex << currentID.unitID()
171  << std::dec << " Edeposit = " << edepositEM << " "
172  << edepositHAD;
173 #endif
174  // Update if in the same detector, time-slice and for same track
175  if (currentID == previousID) {
177  } else {
178  posGlobal = aSpot->GetEnergySpot()->GetPosition();
179  // Reset entry point for new primary
180  if (currentID.trackID() != previousID.trackID()) {
181  entrancePoint = aSpot->GetPosition();
182  entranceLocal = aSpot->GetTouchableHandle()->GetHistory()->
183  GetTopTransform().TransformPoint(entrancePoint);
184  incidentEnergy = theTrack->GetKineticEnergy();
185 #ifdef DebugLog
186  LogDebug("CaloSim") << "CaloSD: Incident energy "
187  << incidentEnergy/GeV << " GeV and"
188  << " entrance point " << entrancePoint
189  << " (Global) " << entranceLocal << " (Local)";
190 #endif
191  }
192 
193  if (checkHit() == false) currentHit = createNewHit();
194  }
195  }
196  delete fFakeStep;
197  }
198  return true;
199  }
200  return false;
201 }
202 
203 double CaloSD::getEnergyDeposit(G4Step* aStep) {
204  return aStep->GetTotalEnergyDeposit();
205 }
206 
207 void CaloSD::Initialize(G4HCofThisEvent * HCE) {
208  totalHits = 0;
209 
210 #ifdef DebugLog
211  edm::LogInfo("CaloSim") << "CaloSD : Initialize called for " << GetName();
212 #endif
213 
214  //This initialization is performed at the beginning of an event
215  //------------------------------------------------------------
216  theHC = new CaloG4HitCollection(GetName(), collectionName[0]);
217 
218  if (hcID<0) hcID = G4SDManager::GetSDMpointer()->GetCollectionID(collectionName[0]);
219  HCE->AddHitsCollection(hcID, theHC);
220 }
221 
222 void CaloSD::EndOfEvent(G4HCofThisEvent* ) {
223  // clean the hits for the last tracks
224 
226 
227 #ifdef DebugLog
228  edm::LogInfo("CaloSim") << "CaloSD: EndofEvent entered with " << theHC->entries()
229  << " entries";
230 #endif
231  // TimeMe("CaloSD:sortAndMergeHits",false);
232 }
233 
234 void CaloSD::clear() {}
235 
236 void CaloSD::DrawAll() {}
237 
239 #ifdef DebugLog
240  edm::LogInfo("CaloSim") << "CaloSD: Collection " << theHC->GetName();
241 #endif
242  theHC->PrintAllHits();
243 }
244 
246  if (slave->name() == n) c=slave->hits();
247  slave->Clean();
248 }
249 
250 bool CaloSD::getStepInfo(G4Step* aStep) {
251 
252  preStepPoint = aStep->GetPreStepPoint();
253  theTrack = aStep->GetTrack();
254 
255  double time = (aStep->GetPostStepPoint()->GetGlobalTime())/nanosecond;
256  unsigned int unitID= setDetUnitId(aStep);
257  uint16_t depth = getDepth(aStep);
258  int primaryID = getTrackID(theTrack);
259 
260  bool flag = (unitID > 0);
261  if (flag) {
262  currentID.setID(unitID, time, primaryID, depth);
263 #ifdef DebugLog
264  G4TouchableHistory* touch =(G4TouchableHistory*)(theTrack->GetTouchable());
265  edm::LogInfo("CaloSim") << "CaloSD:: GetStepInfo for"
266  << " PV " << touch->GetVolume(0)->GetName()
267  << " PVid = " << touch->GetReplicaNumber(0)
268  << " MVid = " << touch->GetReplicaNumber(1)
269  << " Unit " << currentID.unitID()
270  << " Edeposit = " << edepositEM << " " << edepositHAD;
271  } else {
272  G4TouchableHistory* touch =(G4TouchableHistory*)(theTrack->GetTouchable());
273  edm::LogInfo("CaloSim") << "CaloSD:: GetStepInfo for"
274  << " PV " << touch->GetVolume(0)->GetName()
275  << " PVid = " << touch->GetReplicaNumber(0)
276  << " MVid = " << touch->GetReplicaNumber(1)
277  << " Unit " << std::hex << unitID << std::dec
278  << " Edeposit = " << edepositEM << " " << edepositHAD;
279 #endif
280  }
281 
282  G4int particleCode = theTrack->GetDefinition()->GetPDGEncoding();
283  if (particleCode == emPDG ||
284  particleCode == epPDG ||
285  particleCode == gammaPDG ) {
286  edepositEM = getEnergyDeposit(aStep);
287  edepositHAD = 0.;
288  } else {
289  edepositEM = 0.;
290  edepositHAD = getEnergyDeposit(aStep);
291  }
292 
293  return flag;
294 }
295 
296 G4ThreeVector CaloSD::setToLocal(const G4ThreeVector& global, const G4VTouchable* touch) {
297 
298  G4ThreeVector localPoint = touch->GetHistory()->GetTopTransform().TransformPoint(global);
299 
300  return localPoint;
301 }
302 
303 G4ThreeVector CaloSD::setToGlobal(const G4ThreeVector& local, const G4VTouchable* touch) {
304 
305  G4ThreeVector globalPoint = touch->GetHistory()->GetTopTransform().Inverse().TransformPoint(local);
306 
307  return globalPoint;
308 }
309 
311 #ifdef DebugLog
312  if (currentID.trackID()<1)
313  edm::LogWarning("CaloSim") << "***** CaloSD error: primaryID = "
314  << currentID.trackID()
315  << " maybe detector name changed";
316 #endif
317  // Update if in the same detector, time-slice and for same track
318  if (currentID == previousID) {
320  return true;
321  }
322 
323  // Reset entry point for new primary
324  posGlobal = preStepPoint->GetPosition();
325  if (currentID.trackID() != previousID.trackID())
326  resetForNewPrimary(preStepPoint->GetPosition(), preStepPoint->GetKineticEnergy());
327 
328  return checkHit();
329 }
330 
331 G4bool CaloSD::checkHit() {
332  //look in the HitContainer whether a hit with the same ID already exists:
333  bool found = false;
334  if (useMap) {
335  std::map<CaloHitID,CaloG4Hit*>::const_iterator it = hitMap.find(currentID);
336  if (it != hitMap.end()) {
337  currentHit = it->second;
338  found = true;
339  }
340  } else {
341  if (checkHits <= 0) return false;
342  int minhit= (theHC->entries()>checkHits ? theHC->entries()-checkHits : 0);
343  int maxhit= theHC->entries()-1;
344 
345  for (int j=maxhit; j>minhit&&!found; --j) {
346  if ((*theHC)[j]->getID() == currentID) {
347  currentHit = (*theHC)[j];
348  found = true;
349  }
350  }
351  }
352 
353  if (found) {
355  return true;
356  } else {
357  return false;
358  }
359 }
360 
361 int CaloSD::getNumberOfHits() { return theHC->entries(); }
362 
364 #ifdef DebugLog
365  edm::LogInfo("CaloSim") << "CaloSD::CreateNewHit for"
366  << " Unit " << currentID.unitID()
367  << " " << currentID.depth()
368  << " Edeposit = " << edepositEM << " " << edepositHAD;
369  edm::LogInfo("CaloSim") << " primary " << currentID.trackID()
370  << " time slice " << currentID.timeSliceID()
371  << " For Track " << theTrack->GetTrackID()
372  << " which is a " <<theTrack->GetDefinition()->GetParticleName()
373  << " of energy " << theTrack->GetKineticEnergy()/GeV
374  << " " << theTrack->GetMomentum().mag()/GeV
375  << " daughter of part. " << theTrack->GetParentID()
376  << " and created by " ;
377 
378  if (theTrack->GetCreatorProcess()!=NULL)
379  edm::LogInfo("CaloSim") << theTrack->GetCreatorProcess()->GetProcessName();
380  else
381  edm::LogInfo("CaloSim") << "NO process";
382 #endif
383 
384  CaloG4Hit* aHit;
385  if (reusehit.size() > 0) {
386  aHit = reusehit[0];
387  aHit->setEM(0.);
388  aHit->setHadr(0.);
389  reusehit.erase(reusehit.begin());
390  } else {
391  aHit = new CaloG4Hit;
392  }
393 
394  aHit->setID(currentID);
397  aHit->setPosition(posGlobal.x(),posGlobal.y(),posGlobal.z());
399  updateHit(aHit);
400 
401  storeHit(aHit);
402  double etrack = 0;
403  if (currentID.trackID() == primIDSaved) { // The track is saved; nothing to be done
404  } else if (currentID.trackID() == theTrack->GetTrackID()) {
405  etrack= theTrack->GetKineticEnergy();
406  //edm::LogInfo("CaloSim") << "CaloSD: set save the track " << currentID.trackID()
407  // << " etrack " << etrack << " eCut " << energyCut << " flag " << forceSave;
408  if (etrack >= energyCut || forceSave) {
409  TrackInformation* trkInfo = (TrackInformation *)(theTrack->GetUserInformation());
410  trkInfo->storeTrack(true);
411  trkInfo->putInHistory();
412  // trkInfo->setAncestor();
413 #ifdef DebugLog
414  edm::LogInfo("CaloSim") << "CaloSD: set save the track "
415  << currentID.trackID() << " with Hit";
416 #endif
417  }
418  } else {
420 #ifdef DebugLog
421  edm::LogInfo("CaloSim") << "CaloSD : TrackwithHistory pointer for "
422  << currentID.trackID() << " is " << trkh;
423 #endif
424  if (trkh != NULL) {
425  etrack = sqrt(trkh->momentum().Mag2());
426  if (etrack >= energyCut) {
427  trkh->save();
428 #ifdef DebugLog
429  edm::LogInfo("CaloSim") << "CaloSD: set save the track "
430  << currentID.trackID() << " with Hit";
431 #endif
432  }
433  }
434  }
436  if (useMap) totalHits++;
437  return aHit;
438 }
439 
441  if (edepositEM+edepositHAD != 0) {
443 #ifdef DebugLog
444  edm::LogInfo("CaloSim") << "CaloSD: Add energy deposit in " << currentID
445  << " em " << edepositEM/MeV << " hadronic "
446  << edepositHAD/MeV << " MeV";
447 #endif
448  }
449 
450  // buffer for next steps:
452 }
453 
454 void CaloSD::resetForNewPrimary(const G4ThreeVector& point, double energy) {
458 #ifdef DebugLog
459  edm::LogInfo("CaloSim") << "CaloSD: Incident energy " << incidentEnergy/GeV
460  << " GeV and" << " entrance point " << entrancePoint
461  << " (Global) " << entranceLocal << " (Local)";
462 #endif
463 }
464 
465 double CaloSD::getAttenuation(G4Step* aStep, double birk1, double birk2, double birk3) {
466  double weight = 1.;
467  double charge = aStep->GetPreStepPoint()->GetCharge();
468 
469  if (charge != 0. && aStep->GetStepLength() > 0) {
470  G4Material* mat = aStep->GetPreStepPoint()->GetMaterial();
471  double density = mat->GetDensity();
472  double dedx = aStep->GetTotalEnergyDeposit()/aStep->GetStepLength();
473  double rkb = birk1/density;
474  double c = birk2*rkb*rkb;
475  if (std::abs(charge) >= 2.) rkb /= birk3; // based on alpha particle data
476  weight = 1./(1.+rkb*dedx+c*dedx*dedx);
477 #ifdef DebugLog
478  edm::LogInfo("CaloSim") << "CaloSD::getAttenuation in " << mat->GetName()
479  << " Charge " << charge << " dE/dx " << dedx
480  << " Birk Const " << rkb << ", " << c << " Weight = "
481  << weight << " dE " << aStep->GetTotalEnergyDeposit();
482 #endif
483  }
484  return weight;
485 }
486 
487 void CaloSD::update(const BeginOfRun *) {
488  G4ParticleTable * theParticleTable = G4ParticleTable::GetParticleTable();
489  G4String particleName;
490  emPDG = theParticleTable->FindParticle(particleName="e-")->GetPDGEncoding();
491  epPDG = theParticleTable->FindParticle(particleName="e+")->GetPDGEncoding();
492  gammaPDG = theParticleTable->FindParticle(particleName="gamma")->GetPDGEncoding();
493 #ifdef DebugLog
494  edm::LogInfo("CaloSim") << "CaloSD: Particle code for e- = " << emPDG
495  << " for e+ = " << epPDG << " for gamma = " << gammaPDG;
496 #endif
497  initRun();
498  runInit = true;
499 }
500 
502 #ifdef DebugLog
503  edm::LogInfo("CaloSim") << "CaloSD: Dispatched BeginOfEvent for "
504  << GetName() << " !" ;
505 #endif
506  clearHits();
507 }
508 
509 void CaloSD::update(const EndOfTrack * trk) {
510  int id = (*trk)()->GetTrackID();
511  TrackInformation *trkI =(TrackInformation *)((*trk)()->GetUserInformation());
512  int lastTrackID = -1;
513  if (trkI) lastTrackID = trkI->getIDonCaloSurface();
514  if (id == lastTrackID) {
515  const TrackContainer * trksForThisEvent = m_trackManager->trackContainer();
516  if (trksForThisEvent != NULL) {
517  int it = (int)(trksForThisEvent->size()) - 1;
518  if (it >= 0) {
519  TrackWithHistory * trkH = (*trksForThisEvent)[it];
520  if (trkH->trackID() == (unsigned int)(id)) tkMap[id] = trkH;
521 #ifdef DebugLog
522  edm::LogInfo("CaloSim") << "CaloSD: get track " << it << " from "
523  << "Container of size " << trksForThisEvent->size()
524  << " with ID " << trkH->trackID();
525  } else {
526  edm::LogInfo("CaloSim") << "CaloSD: get track " << it << " from "
527  << "Container of size " << trksForThisEvent->size()
528  << " with no ID";
529 #endif
530  }
531  }
532  }
533 }
534 
535 void CaloSD::update(const ::EndOfEvent * ) {
536  int count = 0, wrong = 0;
537  bool ok;
538 
539  slave->ReserveMemory(theHC->entries());
540 
541  for (int i=0; i<theHC->entries(); ++i) {
542  ok = saveHit((*theHC)[i]);
543  ++count;
544  if (!ok) ++wrong;
545  }
546 
547  edm::LogInfo("CaloSim") << "CaloSD: " << GetName() << " store " << count
548  << " hits recorded with " << wrong
549  << " track IDs not given properly and "
550  << totalHits-count << " hits not passing cuts";
551  summarize();
552 
553  tkMap.erase (tkMap.begin(), tkMap.end());
554 }
555 
557  if (useMap) hitMap.erase (hitMap.begin(), hitMap.end());
558  for (unsigned int i = 0; i<reusehit.size(); ++i) delete reusehit[i];
559  std::vector<CaloG4Hit*>().swap(reusehit);
560  cleanIndex = 0;
561  previousID.reset();
562  primIDSaved = -99;
563 #ifdef DebugLog
564  edm::LogInfo("CaloSim") << "CaloSD: Clears hit vector for " << GetName() << " " << slave;
565 #endif
566  slave->Initialize();
567 #ifdef DebugLog
568  edm::LogInfo("CaloSim") << "CaloSD: Initialises slave SD for " << GetName();
569 #endif
570 }
571 
573 
574 int CaloSD::getTrackID(G4Track* aTrack) {
575  int primaryID = 0;
576  forceSave = false;
577  TrackInformation* trkInfo=(TrackInformation *)(aTrack->GetUserInformation());
578  if (trkInfo) {
579  primaryID = trkInfo->getIDonCaloSurface();
580 #ifdef DebugLog
581  edm::LogInfo("CaloSim") << "CaloSD: hit update from track Id on Calo Surface "
582  << trkInfo->getIDonCaloSurface();
583 #endif
584  } else {
585  primaryID = aTrack->GetTrackID();
586 #ifdef DebugLog
587  edm::LogWarning("CaloSim") << "CaloSD: Problem with primaryID **** set by "
588  << "force to TkID **** " << primaryID << " in "
589  << preStepPoint->GetTouchable()->GetVolume(0)->GetName();
590 #endif
591  }
592  return primaryID;
593 }
594 
595 uint16_t CaloSD::getDepth(G4Step*) { return 0; }
596 
597 bool CaloSD::filterHit(CaloG4Hit* hit, double time) {
598  double emin(eminHit);
599  if (hit->getDepth() > 0) emin = eminHitD;
600 #ifdef DebugLog
601  edm::LogInfo("CaloSim") << "Depth " << hit->getDepth() << " Emin = " << emin
602  << " (" << eminHit << ", " << eminHitD << ")";
603 #endif
604  return ((time <= tmaxHit) && (hit->getEnergyDeposit() > emin));
605 }
606 
607 double CaloSD::getResponseWt(G4Track* aTrack) {
608  if (meanResponse) {
609  TrackInformation * trkInfo = (TrackInformation *)(aTrack->GetUserInformation());
610  return meanResponse->getWeight(trkInfo->genParticlePID(), trkInfo->genParticleP());
611  } else {
612  return 1;
613  }
614 }
615 
617  if (previousID.trackID()<0) return;
618  if (hit == 0) {
619  edm::LogWarning("CaloSim") << "CaloSD: hit to be stored is NULL !!";
620  return;
621  }
622 
623  theHC->insert(hit);
624  if (useMap) hitMap.insert(std::pair<CaloHitID,CaloG4Hit*>(previousID,hit));
625 }
626 
628  int tkID;
629  bool ok = true;
630  if (m_trackManager) {
631  tkID = m_trackManager->giveMotherNeeded(aHit->getTrackID());
632  if (tkID == 0) {
633  if (m_trackManager->trackExists(aHit->getTrackID())) tkID = (aHit->getTrackID());
634  else {
635  ok = false;
636  }
637  }
638  } else {
639  tkID = aHit->getTrackID();
640  ok = false;
641  }
642  // edm::LogInfo("CaloSim") << "CalosD: Track ID " << aHit->getTrackID() << " changed to " << tkID << " by SimTrackManager" << " Status " << ok;
643 #ifdef DebugLog
644  edm::LogInfo("CaloSim") << "CalosD: Track ID " << aHit->getTrackID()
645  << " changed to " << tkID << " by SimTrackManager"
646  << " Status " << ok;
647 #endif
648  double time = aHit->getTimeSlice();
649  if (corrTOFBeam) time += correctT;
650  slave->processHits(aHit->getUnitID(), aHit->getEM()/GeV,
651  aHit->getHadr()/GeV, time, tkID, aHit->getDepth());
652 #ifdef DebugLog
653  edm::LogInfo("CaloSim") << "CaloSD: Store Hit at " << std::hex
654  << aHit->getUnitID() << std::dec << " "
655  << aHit->getDepth() << " due to " << tkID
656  << " in time " << time << " of energy "
657  << aHit->getEM()/GeV << " GeV (EM) and "
658  << aHit->getHadr()/GeV << " GeV (Hadr)";
659 #endif
660  return ok;
661 }
662 
664 
665 void CaloSD::update(const BeginOfTrack * trk) {
666  int primary = -1;
667  TrackInformation * trkInfo = (TrackInformation *)((*trk)()->GetUserInformation());
668  if ( trkInfo->isPrimary() ) primary = (*trk)()->GetTrackID();
669 
670 #ifdef DebugLog
671  edm::LogInfo("CaloSim") << "New track: isPrimary " << trkInfo->isPrimary()
672  << " primary ID = " << primary
673  << " primary ancestor ID " << primAncestor;
674 #endif
675 
676  // update the information if a different primary track ID
677 
678  if (primary > 0 && primary != primAncestor) {
679  primAncestor = primary;
680 
681  // clean the hits information
682 
683  if (theHC->entries()>0) cleanHitCollection();
684 
685  }
686 }
687 
689  std::vector<CaloG4Hit*>* theCollection = theHC->GetVector();
690 
691 #ifdef DebugLog
692  edm::LogInfo("CaloSim") << "CaloSD: collection before merging, size = " << theHC->entries();
693 #endif
694 
695  selIndex.reserve(theHC->entries()-cleanIndex);
696  if ( reusehit.size() == 0 ) reusehit.reserve(theHC->entries()-cleanIndex);
697 
698  // if no map used, merge before hits to have the save situation as a map
699  if ( !useMap ) {
700  hitvec.swap(*theCollection);
701  sort((hitvec.begin()+cleanIndex), hitvec.end(), CaloG4HitLess());
702 #ifdef DebugLog
703  edm::LogInfo("CaloSim") << "CaloSD::cleanHitCollection: sort hits in buffer "
704  << "starting from element = " << cleanIndex;
705  for (unsigned int i = 0; i<hitvec.size(); ++i)
706  edm::LogInfo("CaloSim") << i << " " << *hitvec[i];
707 #endif
708  unsigned int i, j;
710  for (i=cleanIndex; i<hitvec.size(); ++i) {
711  selIndex.push_back(i-cleanIndex);
712  int jump = 0;
713  for (j = i+1; j <hitvec.size() && equal(hitvec[i], hitvec[j]); ++j) {
714  ++jump;
715  // merge j to i
716  (*hitvec[i]).addEnergyDeposit(*hitvec[j]);
717  (*hitvec[j]).setEM(0.);
718  (*hitvec[j]).setHadr(0.);
719  reusehit.push_back(hitvec[j]);
720  }
721  i+=jump;
722  }
723 #ifdef DebugLog
724  edm::LogInfo("CaloSim") << "CaloSD: cleanHitCollection merge the hits in buffer ";
725  for (unsigned int i = 0; i<hitvec.size(); ++i)
726  edm::LogInfo("CaloSim") << i << " " << *hitvec[i];
727 #endif
728  for ( unsigned int i = cleanIndex; i < cleanIndex+selIndex.size(); ++i ) {
729  hitvec[i] = hitvec[selIndex[i-cleanIndex]+cleanIndex];
730  }
731  hitvec.resize(cleanIndex+selIndex.size());
732 #ifdef DebugLog
733  edm::LogInfo("CaloSim") << "CaloSD::cleanHitCollection: remove the merged hits in buffer,"
734  << " new size = " << hitvec.size();
735  for (unsigned int i = 0; i<hitvec.size(); ++i)
736  edm::LogInfo("CaloSim") << i << " " << *hitvec[i];
737 #endif
738  hitvec.swap(*theCollection);
739  std::vector<CaloG4Hit*>().swap(hitvec);
740  selIndex.clear();
741  totalHits = theHC->entries();
742  }
743 
744 #ifdef DebugLog
745  edm::LogInfo("CaloSim") << "CaloSD: collection after merging, size = " << theHC->entries();
746 #endif
747 
748  int addhit = 0;
749 
750 #ifdef DebugLog
751  edm::LogInfo("CaloSim") << "CaloSD: Size of reusehit after merge = " << reusehit.size();
752  edm::LogInfo("CaloSim") << "CaloSD: Starting hit selection from index = " << cleanIndex;
753 #endif
754 
755  selIndex.reserve(theCollection->size()-cleanIndex);
756  for (unsigned int i = cleanIndex; i<theCollection->size(); ++i) {
757  CaloG4Hit* aHit((*theCollection)[i]);
758 
759  // selection
760 
761  double time = aHit->getTimeSlice();
762  if (corrTOFBeam) time += correctT;
763  if (!filterHit(aHit,time)) {
764 #ifdef DebugLog
765  edm::LogInfo("CaloSim") << "CaloSD: dropped CaloG4Hit " << " " << *aHit;
766 #endif
767 
768  // create the list of hits to be reused
769 
770  reusehit.push_back((*theCollection)[i]);
771  ++addhit;
772  } else {
773  selIndex.push_back(i-cleanIndex);
774  }
775  }
776 
777 #ifdef DebugLog
778  edm::LogInfo("CaloSim") << "CaloSD: Size of reusehit after selection = "
779  << reusehit.size() << " Number of added hit = "
780  << addhit;
781 #endif
782  if (useMap) {
783  if ( addhit>0 ) {
784  int offset = reusehit.size()-addhit;
785  for (int ii = addhit-1; ii>=0; --ii) {
786  CaloHitID theID = reusehit[offset+ii]->getID();
787  hitMap.erase(theID);
788  }
789  }
790  }
791  for (unsigned int j = 0; j<selIndex.size(); ++j) {
792  (*theCollection)[cleanIndex+j] = (*theCollection)[cleanIndex+selIndex[j]];
793  }
794 
795  theCollection->resize(cleanIndex+selIndex.size());
796  std::vector<unsigned int>().swap(selIndex);
797 
798 #ifdef DebugLog
799  edm::LogInfo("CaloSim") << "CaloSD: hit collection after selection, size = "
800  << theHC->entries();
801  theHC->PrintAllHits();
802 #endif
803 
804  cleanIndex = theHC->entries();
805 }
#define LogDebug(id)
float edepositEM
Definition: CaloSD.h:121
double energyCut
Definition: CaloSD.h:123
void swap(ora::Record &rh, ora::Record &lh)
Definition: Record.h:70
virtual bool processHits(uint32_t, double, double, double, int, uint16_t depth=0)
Definition: CaloSlaveSD.cc:34
T getParameter(std::string const &) const
virtual void Initialize()
Definition: CaloSlaveSD.cc:21
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
virtual uint32_t setDetUnitId(G4Step *step)=0
G4int emPDG
Definition: CaloSD.h:136
std::vector< PCaloHit > PCaloHitContainer
const double GeV
Definition: MathUtil.h:16
double kmaxNeutron
Definition: CaloSD.h:134
void updateHit(CaloG4Hit *)
Definition: CaloSD.cc:440
bool storeTrack() const
int getIDonCaloSurface() const
virtual void Initialize(G4HCofThisEvent *HCE)
Definition: CaloSD.cc:207
bool corrTOFBeam
Definition: CaloSD.h:132
int totalHits
Definition: CaloSD.h:156
void setIncidentEnergy(double e)
Definition: CaloG4Hit.h:66
virtual void EndOfEvent(G4HCofThisEvent *eventHC)
Definition: CaloSD.cc:222
void setEntryLocal(double x, double y, double z)
Definition: CaloG4Hit.h:54
Collection & hits()
Definition: CaloSlaveSD.h:29
double genParticleP() const
bool useMap
Definition: CaloSD.h:125
uint16_t getDepth() const
Definition: CaloG4Hit.h:72
virtual int getTrackID(G4Track *)
Definition: CaloSD.cc:574
int hcID
Definition: CaloSD.h:144
double eminHitD
Definition: CaloSD.h:123
#define NULL
Definition: scimark2.h:8
G4ThreeVector posGlobal
Definition: CaloSD.h:113
int primIDSaved
Definition: CaloSD.h:115
const std::vector< std::string > & logicalNames(const std::string &readoutName) const
int primAncestor
Definition: CaloSD.h:151
virtual void Clean()
Definition: CaloSlaveSD.cc:43
void fillHits(edm::PCaloHitContainer &, std::string n)
Definition: CaloSD.cc:245
uint16_t depth() const
Definition: CaloHitID.h:26
int ii
Definition: cuy.py:588
type of data representation of DDCompactView
Definition: DDCompactView.h:77
double kmaxProton
Definition: CaloSD.h:134
virtual void AssignSD(const std::string &vname)
double eminHit
Definition: CaloSD.h:123
std::vector< CaloG4Hit * > reusehit
Definition: CaloSD.h:153
G4bool checkHit()
Definition: CaloSD.cc:331
CaloSD(G4String aSDname, const DDCompactView &cpv, const SensitiveDetectorCatalog &clg, edm::ParameterSet const &p, const SimTrackManager *, float timeSlice=1., bool ignoreTkID=false)
Definition: CaloSD.cc:24
bool equal(const T &first, const T &second)
Definition: Equal.h:34
void cleanHitCollection()
Definition: CaloSD.cc:688
void reset()
Definition: CaloHitID.cc:53
double getWeight(int genPID, double genP)
const double MeV
bool forceSave
Definition: CaloSD.h:137
void addEnergyDeposit(double em, double hd)
Definition: CaloG4Hit.cc:47
virtual void clearHits()
Definition: CaloSD.cc:556
float timeSlice
Definition: CaloSD.h:141
const TrackContainer * trackContainer() const
int genParticlePID() const
virtual void DrawAll()
Definition: CaloSD.cc:236
void resetForNewPrimary(const G4ThreeVector &, double)
Definition: CaloSD.cc:454
virtual void clear()
Definition: CaloSD.cc:234
std::string const collectionName[nCollections]
Definition: Collections.h:45
std::string name() const
Definition: CaloSlaveSD.h:26
double kmaxIon
Definition: CaloSD.h:134
bool suppressHeavy
Definition: CaloSD.h:132
int timeSliceID() const
Definition: CaloHitID.h:23
std::vector< TrackWithHistory * > TrackContainer
Definition: TrackContainer.h:8
float edepositHAD
Definition: CaloSD.h:121
T sqrt(T t)
Definition: SSEVec.h:18
unsigned int trackID() const
int trackID() const
Definition: CaloHitID.h:25
bool trackExists(unsigned int i) const
G4int epPDG
Definition: CaloSD.h:136
virtual void ReserveMemory(unsigned int size)
Definition: CaloSlaveSD.cc:50
CaloSlaveSD * slave
Definition: CaloSD.h:143
void setEM(double e)
Definition: CaloG4Hit.h:60
G4int gammaPDG
Definition: CaloSD.h:136
virtual void update(const BeginOfRun *)
This routine will be called when the appropriate signal arrives.
Definition: CaloSD.cc:487
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
int j
Definition: DBlmapReader.cc:9
std::vector< CaloG4Hit * > hitvec
Definition: CaloSD.h:154
G4ThreeVector setToGlobal(const G4ThreeVector &, const G4VTouchable *)
Definition: CaloSD.cc:303
int getNumberOfHits()
Definition: CaloSD.cc:361
CaloHitID previousID
Definition: CaloSD.h:117
virtual void PrintAll()
Definition: CaloSD.cc:238
double getAttenuation(G4Step *aStep, double birk1, double birk2, double birk3)
Definition: CaloSD.cc:465
CaloG4Hit * currentHit
Definition: CaloSD.h:128
int giveMotherNeeded(int i) const
std::vector< unsigned int > selIndex
Definition: CaloSD.h:155
CaloMeanResponse * meanResponse
Definition: CaloSD.h:149
void NaNTrap(G4Step *step)
void storeHit(CaloG4Hit *)
Definition: CaloSD.cc:616
virtual bool filterHit(CaloG4Hit *, double)
Definition: CaloSD.cc:597
G4Track * theTrack
Definition: CaloSD.h:118
virtual G4bool getStepInfo(G4Step *aStep)
Definition: CaloSD.cc:250
double tmaxHit
Definition: CaloSD.h:123
void setID(uint32_t unitID, double timeSlice, int trackID, uint16_t depth=0)
Definition: CaloHitID.cc:44
G4StepPoint * preStepPoint
Definition: CaloSD.h:120
virtual bool ProcessHits(G4Step *step, G4TouchableHistory *tHistory)
Definition: CaloSD.cc:119
void summarize()
Definition: CaloSD.cc:663
int getTrackID() const
Definition: CaloG4Hit.h:68
CaloHitID currentID
Definition: CaloSD.h:117
virtual void initRun()
Definition: CaloSD.cc:572
double correctT
Definition: CaloSD.h:133
bool runInit
Definition: CaloSD.h:130
const math::XYZVectorD & momentum() const
bool isPrimary() const
CSCCFEBTimeSlice const *const timeSlice(T const &data, int nCFEB, int nSample)
std::map< CaloHitID, CaloG4Hit * > hitMap
Definition: CaloSD.h:146
double getEM() const
Definition: CaloG4Hit.h:59
virtual ~CaloSD()
Definition: CaloSD.cc:113
CaloG4HitCollection * theHC
Definition: CaloSD.h:145
void setHadr(double e)
Definition: CaloG4Hit.h:63
float incidentEnergy
Definition: CaloSD.h:114
double getResponseWt(G4Track *)
Definition: CaloSD.cc:607
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
int checkHits
Definition: CaloSD.h:124
G4bool hitExists()
Definition: CaloSD.cc:310
double getTimeSlice() const
Definition: CaloG4Hit.h:70
std::map< int, TrackWithHistory * > tkMap
Definition: CaloSD.h:148
const SimTrackManager * m_trackManager
Definition: CaloSD.h:127
volatile std::atomic< bool > shutdown_flag false
uint32_t getUnitID() const
Definition: CaloG4Hit.h:69
uint32_t unitID() const
Definition: CaloHitID.h:22
bool saveHit(CaloG4Hit *)
Definition: CaloSD.cc:627
CaloG4Hit * createNewHit()
Definition: CaloSD.cc:363
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5
virtual uint16_t getDepth(G4Step *)
Definition: CaloSD.cc:595
G4ThreeVector entrancePoint
Definition: CaloSD.h:111
G4ThreeVector entranceLocal
Definition: CaloSD.h:112
double getHadr() const
Definition: CaloG4Hit.h:62
double getEnergyDeposit() const
Definition: CaloG4Hit.h:81
int cleanIndex
Definition: CaloSD.h:152
virtual double getEnergyDeposit(G4Step *step)
Definition: CaloSD.cc:203
bool ignoreTrackID
Definition: CaloSD.h:142
G4ThreeVector setToLocal(const G4ThreeVector &, const G4VTouchable *)
Definition: CaloSD.cc:296