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