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  timeFactor = val;
81 #ifdef debug
82  edm::LogVerbatim("TimingSim")
83  << "TimingSD : for " << GetName()
84  << " time slice factor is set to " << timeFactor;
85 #endif
86 }
87 
88 void TimingSD::setCuts(double eCut, double historyCut)
89 {
90  if(eCut > 0.) { energyCut = eCut; }
91  if(historyCut > 0.) { energyHistoryCut = historyCut; }
92 #ifdef debug
93  edm::LogVerbatim("TimingSim")
94  << "TimingSD : for " << GetName()
95  << " MC truth cuts in are " << energyCut/CLHEP::GeV
96  << " GeV and " << energyHistoryCut/CLHEP::GeV << " GeV";
97 #endif
98 }
99 
100 bool TimingSD::ProcessHits(G4Step * aStep, G4TouchableHistory * ) {
101 
102  edeposit = aStep->GetTotalEnergyDeposit();
103  if (edeposit>0.f){
104  getStepInfo(aStep);
105  if (!hitExists(aStep)){
106  createNewHit(aStep);
107  }
108  }
109  return true;
110 }
111 
112 void TimingSD::getStepInfo(const G4Step* aStep) {
113 
114  preStepPoint = aStep->GetPreStepPoint();
115  postStepPoint= aStep->GetPostStepPoint();
116  hitPointExit = postStepPoint->GetPosition();
118  const G4Track* newTrack = aStep->GetTrack();
119 
120  // neutral particles deliver energy post step
121  // charged particle start deliver energy pre step
122  if(newTrack->GetDefinition()->GetPDGCharge() == 0.0) {
125  tof = (float)(postStepPoint->GetGlobalTime()*invns);
126  } else {
127  hitPoint = preStepPoint->GetPosition();
129  tof = (float)(preStepPoint->GetGlobalTime()*invns);
130  }
131 
132 #ifdef debug
133  double distGlobal = std::sqrt(std::pow(hitPoint.x()-hitPointExit.x(),2)+
134  std::pow(hitPoint.y()-hitPointExit.y(),2)+
135  std::pow(hitPoint.z()-hitPointExit.z(),2));
136  double distLocal = std::sqrt(std::pow(hitPointLocal.x()-hitPointLocalExit.x(),2)+
139  LogDebug("TimingSim") << "TimingSD:"
140  << "\n Global entry point: " << hitPoint
141  << "\n Global exit point: " << hitPointExit
142  << "\n Global step length: " << distGlobal
143  << "\n Local entry point: " << hitPointLocal
144  << "\n Local exit point: " << hitPointLocalExit
145  << "\n Local step length: " << distLocal;
146  if ( std::fabs(distGlobal - distLocal) > 1.e-6 ) { LogDebug("TimingSim") << "DIFFERENCE IN DISTANCE \n"; }
147 #endif
148 
149 
150  incidentEnergy = preStepPoint->GetKineticEnergy();
151 
152  // should MC truth be saved
153  if (newTrack != theTrack) {
154  theTrack = newTrack;
155  TrackInformation* info = nullptr;
156  if (incidentEnergy > energyCut) {
158  info->storeTrack(true);
159  }
161  if(!info) { info = cmsTrackInformation(theTrack); }
162  info->putInHistory();
163  }
164  }
165 
166  edeposit *= invgev;
169  } else {
171  }
172  // time slice is defined for the entry point
173  tSlice = timeFactor*preStepPoint->GetGlobalTime()*invns;
174  tSliceID = (int) tSlice;
175 
176  unitID = setDetUnitId(aStep);
177  primaryID = theTrack->GetTrackID();
178 }
179 
180 bool TimingSD::hitExists(const G4Step* aStep) {
181 
182  if(!currentHit) { return false; }
183 
184  // Update if in the same detector and time-slice
185  if (tSliceID == tsID && unitID == previousUnitID) {
186  updateHit();
187  return true;
188  }
189 
190  //look in the HitContainer whether a hit with the same primID, unitID,
191  //tSliceID already exists:
192 
193  bool found = false;
194  for (int j=0; j<theHC->entries(); ++j) {
195  BscG4Hit* aHit = (*theHC)[j];
196  if (aHit->getTimeSliceID() == tSliceID && aHit->getUnitID() == unitID) {
197  if(checkHit(aStep, aHit)) {
198  currentHit = aHit;
199  found = true;
200  break;
201  }
202  }
203  }
204  if (found) { updateHit(); }
205  return found;
206 }
207 
208 bool TimingSD::checkHit(const G4Step*, BscG4Hit* hit) {
209 
210  // change hit info to fastest primary particle
211  if(tof < hit->getTof()) {
212  hit->setTrackID(primaryID);
213  hit->setIncidentEnergy((float)incidentEnergy);
214  hit->setPabs(float(preStepPoint->GetMomentum().mag())*invgev);
215  hit->setTof(tof);
216  hit->setParticleType(theTrack->GetDefinition()->GetPDGEncoding());
217 
218  float ThetaAtEntry = (float)(hitPointLocal.theta()*invdeg);
219  float PhiAtEntry = (float)(hitPointLocal.phi()*invdeg);
220 
221  hit->setThetaAtEntry(ThetaAtEntry);
222  hit->setPhiAtEntry(PhiAtEntry);
223 
224  hit->setEntry(hitPoint);
227 
228  hit->setParentId(theTrack->GetParentID());
229  hit->setProcessId(theEnumerator->processId(theTrack->GetCreatorProcess()));
230 
231  hit->setVertexPosition(theTrack->GetVertexPosition());
232  }
233  return true;
234 }
235 
237 
238  if (primID<0) return;
239  if (hit == nullptr ) {
240  edm::LogWarning("BscSim") << "BscSD: hit to be stored is NULL !!";
241  return;
242  }
243 
244  theHC->insert( hit );
245 }
246 
247 void TimingSD::createNewHit(const G4Step* aStep) {
248 
249 #ifdef debug
250  const G4VPhysicalVolume* currentPV = preStepPoint->GetPhysicalVolume();
251  edm::LogVerbatim("TimingSim")
252  << "TimingSD CreateNewHit for " << GetName()
253  << " PV " << currentPV->GetName()
254  << " PVid = " << currentPV->GetCopyNo()
255  << " Unit " << unitID
256  << "\n primary " << primaryID
257  << " Tof(ns)= " << tof
258  << " time slice " << tSliceID
259  << " E(GeV)= " << incidentEnergy
260  << " trackID " << theTrack->GetTrackID()
261  << " " << theTrack->GetDefinition()->GetParticleName()
262  << " parentID " << theTrack->GetParentID();
263 
264  if (theTrack->GetCreatorProcess()!=nullptr) {
265  edm::LogVerbatim("TimingSim")
266  << theTrack->GetCreatorProcess()->GetProcessName();
267  } else {
268  edm::LogVerbatim("TimingSim") << " is primary particle";
269  }
270 #endif
271 
272  currentHit = new BscG4Hit;
277 
278  currentHit->setPabs(float(preStepPoint->GetMomentum().mag()*invgev));
280  currentHit->setParticleType(theTrack->GetDefinition()->GetPDGEncoding());
281 
282  float ThetaAtEntry = hitPointLocal.theta()*invdeg;
283  float PhiAtEntry = hitPointLocal.phi()*invdeg;
284 
285  currentHit->setThetaAtEntry(ThetaAtEntry);
286  currentHit->setPhiAtEntry(PhiAtEntry);
287 
291 
292  currentHit->setParentId(theTrack->GetParentID());
293  currentHit->setProcessId(theEnumerator->processId(theTrack->GetCreatorProcess()));
294 
295  currentHit->setVertexPosition(theTrack->GetVertexPosition());
296 
297  updateHit();
299 }
300 
302 
304 
305 #ifdef debug
306  edm::LogVerbatim("TimingSim")
307  << "updateHit: " << GetName() << " add eloss(GeV) " << edeposit
308  << "CurrentHit=" << currentHit
309  << ", PostStepPoint= " << postStepPoint->GetPosition();
310 #endif
311 
312  // buffer for next steps:
313  tsID = tSliceID;
314  primID = primaryID;
316 }
317 
318 void TimingSD::setToLocal(const G4StepPoint* stepPoint,
319  const G4ThreeVector& globalPoint,
320  G4ThreeVector& localPoint) {
321 
322  const G4VTouchable* touch= stepPoint->GetTouchable();
323  localPoint =
324  touch->GetHistory()->GetTopTransform().TransformPoint(globalPoint);
325 }
326 
327 void TimingSD::EndOfEvent(G4HCofThisEvent* ) {
328 
329  int nhits = theHC->entries();
330  if(0 == nhits) { return; }
331  // here we loop over transient hits and make them persistent
332  for (int j=0; j<nhits; ++j) {
333 
334  BscG4Hit* aHit = (*theHC)[j];
335  Local3DPoint locEntryPoint= ConvertToLocal3DPoint(aHit->getEntryLocalP());
336  Local3DPoint locExitPoint = ConvertToLocal3DPoint(aHit->getExitLocalP());
337 
338 #ifdef debug
339  edm::LogInfo("TimingSim") << "TimingSD: Hit for storage \n" << *aHit
340  << "\n Entry point: " << locEntryPoint
341  << "\n Exit point: " << locExitPoint << "\n";
342 #endif
343 
344 
345  slave->processHits(PSimHit(locEntryPoint,locExitPoint,
346  aHit->getPabs(),
347  aHit->getTof(),
348  aHit->getEnergyLoss(),
349  aHit->getParticleType(),
350  aHit->getUnitID(),
351  aHit->getTrackID(),
352  aHit->getThetaAtEntry(),
353  aHit->getPhiAtEntry(),
354  aHit->getProcessId()));
355  }
356 }
357 
359  LogDebug("TimingSim") << "TimingSD: Collection " << theHC->GetName() << "\n";
360  theHC->PrintAllHits();
361 }
362 
364  if (slave->name() == hname) { cc=slave->hits(); }
365 }
366 
368  LogDebug("TimingSim") << " Dispatched BeginOfEvent for " << GetName();
369  clearHits();
370 }
371 
373  slave->Initialize();
374 }
#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:327
void clearHits() override
Definition: TimingSD.cc:372
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:363
void setTrackID(int id)
Definition: BscG4Hit.h:51
void setParentId(int p)
Definition: BscG4Hit.h:96
#define nullptr
int primID
Definition: TimingSD.h:92
virtual uint32_t setDetUnitId(const G4Step *step)=0
virtual bool checkHit(const G4Step *, BscG4Hit *)
Definition: TimingSD.cc:208
G4ThreeVector hitPointLocalExit
Definition: TimingSD.h:101
void createNewHit(const G4Step *)
Definition: TimingSD.cc:247
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:88
Compact representation of the geometrical detector hierarchy.
Definition: DDCompactView.h:80
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:318
void setThetaAtEntry(float t)
Definition: BscG4Hit.h:77
void storeHit(BscG4Hit *)
Definition: TimingSD.cc:236
void setPabs(float e)
Definition: BscG4Hit.h:69
std::vector< PSimHit > & hits()
void getStepInfo(const G4Step *)
Definition: TimingSD.cc:112
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:367
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:100
void setPhiAtEntry(float f)
Definition: BscG4Hit.h:78
int tsID
Definition: TimingSD.h:94
T sqrt(T t)
Definition: SSEVec.h:18
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:180
TrackInformation * cmsTrackInformation(const G4Track *aTrack)
const G4Track * theTrack
Definition: TimingSD.h:86
double energyHistoryCut
Definition: TimingSD.h:107
void PrintAll() override
Definition: TimingSD.cc:358
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:301
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
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
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