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