CMS 3D CMS Logo

TimingSD.cc
Go to the documentation of this file.
1 // File: TimingSD.cc
3 // Date: 02.2006
4 // Description: Sensitive Detector class for Timing
5 // Modifications:
7 
9 
13 
15 
19 
20 #include "G4Step.hh"
21 #include "G4StepPoint.hh"
22 #include "G4Track.hh"
23 #include "G4VPhysicalVolume.hh"
24 #include "G4SDManager.hh"
25 #include "G4VProcess.hh"
26 
27 #include "G4PhysicalConstants.hh"
28 #include "G4SystemOfUnits.hh"
29 
30 #include <vector>
31 #include <iostream>
32 
33 //#define debug
34 
35 static const float invgev = 1.0/CLHEP::GeV;
36 static const double invns = 1.0/CLHEP::nanosecond;
37 static const double invdeg= 1.0/CLHEP::deg;
38 
39 //-------------------------------------------------------------------
41  const SensitiveDetectorCatalog& clg,
42  edm::ParameterSet const & p, const SimTrackManager* manager) :
43  SensitiveTkDetector(name, cpv, clg, p),
44  theManager(manager), theHC(nullptr), currentHit(nullptr), theTrack(nullptr),
45  preStepPoint(nullptr),postStepPoint(nullptr),
46  unitID(0), previousUnitID(0), primID(-2), hcID(-1), tsID(-2),
47  primaryID(0), tSliceID(-1),
48  timeFactor(1.0), energyCut(1.e+9), energyHistoryCut(1.e+9) {
49 
50  slave = new TrackingSlaveSD(name);
52 }
53 
55  delete slave;
56  delete theEnumerator;
57 }
58 
59 void TimingSD::Initialize(G4HCofThisEvent * HCE) {
60 
61  edm::LogVerbatim("TimingSim")
62  << "TimingSD : Initialize called for " << GetName()
63  << " time slice factor " << timeFactor
64  << "\n MC truth cuts in are " << energyCut/CLHEP::GeV
65  << " GeV and " << energyHistoryCut/CLHEP::GeV << " GeV";
66 
67  theHC = new BscG4HitCollection(GetName(), collectionName[0]);
68  if (hcID<0) {
69  hcID = G4SDManager::GetSDMpointer()->GetCollectionID(collectionName[0]);
70  }
71  HCE->AddHitsCollection(hcID, theHC);
72 
73  tsID = -2;
74  primID = -2;
75 }
76 
78 {
79  if(val <= 0.0) { return; }
80 #ifdef debug
81  edm::LogVerbatim("TimingSim")
82  << "TimingSD : for " << GetName()
83  << " time slice factor is set to " << timeFactor;
84 #endif
85 }
86 
87 void TimingSD::setCuts(double eCut, double historyCut)
88 {
89  if(eCut > 0.) { energyCut = eCut; }
90  if(historyCut > 0.) { energyHistoryCut = historyCut; }
91 #ifdef debug
92  edm::LogVerbatim("TimingSim")
93  << "TimingSD : for " << GetName()
94  << " MC truth cuts in are " << energyCut/CLHEP::GeV
95  << " GeV and " << energyHistoryCut/CLHEP::GeV << " GeV";
96 #endif
97 }
98 
99 bool TimingSD::ProcessHits(G4Step * aStep, G4TouchableHistory * ) {
100 
101  edeposit = aStep->GetTotalEnergyDeposit();
102  if (edeposit>0.f){
103  getStepInfo(aStep);
104  if (!hitExists(aStep)){
105  createNewHit(aStep);
106  }
107  }
108  return true;
109 }
110 
111 void TimingSD::getStepInfo(const G4Step* aStep) {
112 
113  preStepPoint = aStep->GetPreStepPoint();
114  postStepPoint= aStep->GetPostStepPoint();
115  hitPointExit = postStepPoint->GetPosition();
117  const G4Track* newTrack = aStep->GetTrack();
118 
119  // neutral particles deliver energy post step
120  // charged particle start deliver energy pre step
121  if(newTrack->GetDefinition()->GetPDGCharge() == 0.0) {
124  tof = (float)(postStepPoint->GetGlobalTime()*invns);
125  } else {
126  hitPoint = preStepPoint->GetPosition();
128  tof = (float)(preStepPoint->GetGlobalTime()*invns);
129  }
130 
131  incidentEnergy = preStepPoint->GetKineticEnergy();
132 
133  // should MC truth be saved
134  if (newTrack != theTrack) {
135  theTrack = newTrack;
136  TrackInformation* info = nullptr;
137  if (incidentEnergy > energyCut) {
139  info->storeTrack(true);
140  }
142  if(!info) { info = cmsTrackInformation(theTrack); }
143  info->putInHistory();
144  }
145  }
146 
147  edeposit *= invgev;
150  } else {
152  }
153  // time slice is defined for the entry point
154  tSlice = timeFactor*preStepPoint->GetGlobalTime()*invns;
155  tSliceID = (int) tSlice;
156 
157  unitID = setDetUnitId(aStep);
158  primaryID = theTrack->GetTrackID();
159 }
160 
161 bool TimingSD::hitExists(const G4Step* aStep) {
162 
163  if(!currentHit) { return false; }
164 
165  // Update if in the same detector and time-slice
166  if (tSliceID == tsID && unitID == previousUnitID) {
167  updateHit();
168  return true;
169  }
170 
171  //look in the HitContainer whether a hit with the same primID, unitID,
172  //tSliceID already exists:
173 
174  bool found = false;
175  for (int j=0; j<theHC->entries(); ++j) {
176  BscG4Hit* aHit = (*theHC)[j];
177  if (aHit->getTimeSliceID() == tSliceID && aHit->getUnitID() == unitID) {
178  if(checkHit(aStep, aHit)) {
179  currentHit = aHit;
180  found = true;
181  break;
182  }
183  }
184  }
185  if (found) { updateHit(); }
186  return found;
187 }
188 
189 bool TimingSD::checkHit(const G4Step*, BscG4Hit* hit) {
190 
191  // change hit info to fastest primary particle
192  if(tof < hit->getTof()) {
193  hit->setTrackID(primaryID);
194  hit->setIncidentEnergy((float)incidentEnergy);
195  hit->setPabs(float(preStepPoint->GetMomentum().mag())*invgev);
196  hit->setTof(tof);
197  hit->setParticleType(theTrack->GetDefinition()->GetPDGEncoding());
198 
199  float ThetaAtEntry = (float)(hitPointLocal.theta()*invdeg);
200  float PhiAtEntry = (float)(hitPointLocal.phi()*invdeg);
201 
202  hit->setThetaAtEntry(ThetaAtEntry);
203  hit->setPhiAtEntry(PhiAtEntry);
204 
205  hit->setEntry(hitPoint);
208 
209  hit->setParentId(theTrack->GetParentID());
210  hit->setProcessId(theEnumerator->processId(theTrack->GetCreatorProcess()));
211 
212  hit->setVertexPosition(theTrack->GetVertexPosition());
213  }
214  return true;
215 }
216 
218 
219  if (primID<0) return;
220  if (hit == nullptr ) {
221  edm::LogWarning("BscSim") << "BscSD: hit to be stored is NULL !!";
222  return;
223  }
224 
225  theHC->insert( hit );
226 }
227 
228 void TimingSD::createNewHit(const G4Step* aStep) {
229 
230 #ifdef debug
231  const G4VPhysicsVolume* currentPV = preStepPoint->GetPhysicalVolume();
232  edm::LogVerbatim("TimingSim")
233  << "TimingSD CreateNewHit for " << GetName()
234  << " PV " << currentPV->GetName()
235  << " PVid = " << currentPV->GetCopyNo()
236  << " Unit " << unitID <<
237  << "\n primary " << primaryID
238  << " Tof(ns)= " << tof
239  << " time slice " << tSliceID
240  << " E(GeV)= " << incidentEnergy
241  << " trackID " << theTrack->GetTrackID()
242  << " " << theTrack->GetDefinition()->GetParticleName()
243  << " parentID " << theTrack->GetParentID();
244 
245  if (theTrack->GetCreatorProcess()!=nullptr) {
246  edm::LogVerbatim("TimingSim")
247  << theTrack->GetCreatorProcess()->GetProcessName();
248  } else {
249  edm::LogVerbatim("TimingSim") << " is primary particle";
250  }
251 #endif
252 
253  currentHit = new BscG4Hit;
258 
259  currentHit->setPabs(float(preStepPoint->GetMomentum().mag()*invgev));
261  currentHit->setParticleType(theTrack->GetDefinition()->GetPDGEncoding());
262 
263  float ThetaAtEntry = hitPointLocal.theta()*invdeg;
264  float PhiAtEntry = hitPointLocal.phi()*invdeg;
265 
266  currentHit->setThetaAtEntry(ThetaAtEntry);
267  currentHit->setPhiAtEntry(PhiAtEntry);
268 
272 
273  currentHit->setParentId(theTrack->GetParentID());
274  currentHit->setProcessId(theEnumerator->processId(theTrack->GetCreatorProcess()));
275 
276  currentHit->setVertexPosition(theTrack->GetVertexPosition());
277 
278  updateHit();
280 }
281 
283 
285 
286 #ifdef debug
287  edm::LogVerbatim("TimingSim")
288  << "updateHit: " << GetName() << " add eloss(GeV) " << edeposit
289  << "CurrentHit=" << currentHit
290  << ", PostStepPoint= " << postStepPoint->GetPosition();
291 #endif
292 
293  // buffer for next steps:
294  tsID = tSliceID;
295  primID = primaryID;
297 }
298 
299 void TimingSD::setToLocal(const G4StepPoint* stepPoint,
300  const G4ThreeVector& globalPoint,
301  G4ThreeVector& localPoint) {
302 
303  const G4VTouchable* touch= stepPoint->GetTouchable();
304  localPoint =
305  touch->GetHistory()->GetTopTransform().TransformPoint(globalPoint);
306 }
307 
308 void TimingSD::EndOfEvent(G4HCofThisEvent* ) {
309 
310  int nhits = theHC->entries();
311  if(0 == nhits) { return; }
312  // here we loop over transient hits and make them persistent
313  for (int j=0; j<nhits; ++j) {
314 
315  BscG4Hit* aHit = (*theHC)[j];
316  Local3DPoint locEntryPoint= ConvertToLocal3DPoint(aHit->getEntryLocalP());
317  Local3DPoint locExitPoint = ConvertToLocal3DPoint(aHit->getExitLocalP());
318 
319  slave->processHits(PSimHit(locEntryPoint,locExitPoint,
320  aHit->getPabs(),
321  aHit->getTof(),
322  aHit->getEnergyLoss(),
323  aHit->getParticleType(),
324  aHit->getUnitID(),
325  aHit->getTrackID(),
326  aHit->getThetaAtEntry(),
327  aHit->getPhiAtEntry(),
328  aHit->getProcessId()));
329  }
330 }
331 
333  LogDebug("TimingSim") << "TimingSD: Collection " << theHC->GetName() << "\n";
334  theHC->PrintAllHits();
335 }
336 
338  if (slave->name() == hname) { cc=slave->hits(); }
339 }
340 
342  LogDebug("TimingSim") << " Dispatched BeginOfEvent for " << GetName();
343  clearHits();
344 }
345 
347  slave->Initialize();
348 }
#define LogDebug(id)
uint32_t previousUnitID
Definition: TimingSD.h:90
void setTof(float e)
Definition: BscG4Hit.h:70
void setEntryLocalP(const G4ThreeVector &xyz)
Definition: BscG4Hit.h:36
static const TGPicture * info(bool iBackgroundIsBlack)
void setEntry(const G4ThreeVector &xyz)
Definition: BSCG4Hit.cc:97
const double GeV
Definition: MathUtil.h:16
void setTimeFactor(double)
Definition: TimingSD.cc:77
float getPhiAtEntry() const
Definition: BscG4Hit.h:75
int getParticleType() const
Definition: BscG4Hit.h:67
bool storeTrack() const
void EndOfEvent(G4HCofThisEvent *eventHC) override
Definition: TimingSD.cc:308
void clearHits() override
Definition: TimingSD.cc:346
Local3DPoint ConvertToLocal3DPoint(const G4ThreeVector &point) const
double timeFactor
Definition: TimingSD.h:104
void setIncidentEnergy(float e)
Definition: BscG4Hit.h:48
int hcID
Definition: TimingSD.h:93
float edepositHAD
Definition: TimingSD.h:112
G4ThreeVector hitPointLocal
Definition: TimingSD.h:100
int getProcessId() const
Definition: BscG4Hit.h:91
std::string name() const
void fillHits(edm::PSimHitContainer &, const std::string &) override
Definition: TimingSD.cc:337
void setTrackID(int id)
Definition: BscG4Hit.h:51
void setParentId(int p)
Definition: BscG4Hit.h:96
int primID
Definition: TimingSD.h:92
virtual uint32_t setDetUnitId(const G4Step *step)=0
virtual bool checkHit(const G4Step *, BscG4Hit *)
Definition: TimingSD.cc:189
G4ThreeVector hitPointLocalExit
Definition: TimingSD.h:101
void createNewHit(const G4Step *)
Definition: TimingSD.cc:228
float getTof() const
Definition: BscG4Hit.h:65
float getPabs() const
Definition: BscG4Hit.h:64
BscG4Hit * currentHit
Definition: TimingSD.h:85
float edepositEM
Definition: TimingSD.h:112
void setCuts(double eCut, double historyCut)
Definition: TimingSD.cc:87
#define nullptr
Compact representation of the geometrical detector hierarchy.
Definition: DDCompactView.h:83
void setParticleType(int i)
Definition: BscG4Hit.h:72
int getTrackID() const
Definition: BscG4Hit.h:50
int getTimeSliceID() const
Definition: BscG4Hit.h:58
void setToLocal(const G4StepPoint *stepPoint, const G4ThreeVector &globalPoint, G4ThreeVector &localPoint)
Definition: TimingSD.cc:299
void setThetaAtEntry(float t)
Definition: BscG4Hit.h:77
void storeHit(BscG4Hit *)
Definition: TimingSD.cc:217
void setPabs(float e)
Definition: BscG4Hit.h:69
std::vector< PSimHit > & hits()
void getStepInfo(const G4Step *)
Definition: TimingSD.cc:111
unsigned int processId(const G4VProcess *p) const
static const float invgev
Definition: TimingSD.cc:35
void update(const BeginOfEvent *) override
This routine will be called when the appropriate signal arrives.
Definition: TimingSD.cc:341
void setUnitID(uint32_t id)
Definition: BscG4Hit.h:54
std::string const collectionName[nCollections]
Definition: Collections.h:47
float tof
Definition: TimingSD.h:110
virtual void Initialize()
bool ProcessHits(G4Step *, G4TouchableHistory *) override
Definition: TimingSD.cc:99
void setPhiAtEntry(float f)
Definition: BscG4Hit.h:78
int tsID
Definition: TimingSD.h:94
float edeposit
Definition: TimingSD.h:111
TrackingSlaveSD * slave
Definition: TimingSD.h:79
G4ProcessTypeEnumerator * theEnumerator
Definition: TimingSD.h:80
const G4ThreeVector & getExitLocalP() const
Definition: BscG4Hit.h:38
static const double invdeg
Definition: TimingSD.cc:37
double f[11][100]
bool hitExists(const G4Step *)
Definition: TimingSD.cc:161
TrackInformation * cmsTrackInformation(const G4Track *aTrack)
const G4Track * theTrack
Definition: TimingSD.h:86
double energyHistoryCut
Definition: TimingSD.h:107
void PrintAll() override
Definition: TimingSD.cc:332
const G4StepPoint * preStepPoint
Definition: TimingSD.h:87
float getThetaAtEntry() const
Definition: BscG4Hit.h:74
~TimingSD() override
Definition: TimingSD.cc:54
int tSliceID
Definition: TimingSD.h:96
void setTimeSlice(double d)
Definition: BscG4Hit.h:57
void addEnergyDeposit(float em, float hd)
Definition: BSCG4Hit.cc:112
double energyCut
Definition: TimingSD.h:106
uint32_t unitID
Definition: TimingSD.h:90
void setExitLocalP(const G4ThreeVector &xyz)
Definition: BscG4Hit.h:39
double tSlice
Definition: TimingSD.h:103
void setVertexPosition(const G4ThreeVector &)
Definition: BSCG4Hit.cc:122
const G4ThreeVector & getEntryLocalP() const
Definition: BscG4Hit.h:35
static const double invns
Definition: TimingSD.cc:36
void updateHit()
Definition: TimingSD.cc:282
TimingSD(const std::string &, const DDCompactView &, const SensitiveDetectorCatalog &, const edm::ParameterSet &, const SimTrackManager *)
Definition: TimingSD.cc:40
const G4StepPoint * postStepPoint
Definition: TimingSD.h:88
BscG4HitCollection * theHC
Definition: TimingSD.h:83
static bool isGammaElectronPositron(int pdgCode)
virtual bool processHits(const PSimHit &)
uint32_t getUnitID() const
Definition: BscG4Hit.h:53
std::vector< PSimHit > PSimHitContainer
double incidentEnergy
Definition: TimingSD.h:109
G4THitsCollection< BscG4Hit > BscG4HitCollection
void setProcessId(int p)
Definition: BscG4Hit.h:97
void Initialize(G4HCofThisEvent *HCE) override
Definition: TimingSD.cc:59
float getEnergyLoss() const
Definition: BscG4Hit.h:66
G4ThreeVector hitPointExit
Definition: TimingSD.h:99
G4ThreeVector hitPoint
Definition: TimingSD.h:98
int primaryID
Definition: TimingSD.h:95