CMS 3D CMS Logo

PltSD.cc
Go to the documentation of this file.
2 
5 
9 
12 
14 
19 
20 #include "G4Track.hh"
21 #include "G4SDManager.hh"
22 #include "G4VProcess.hh"
23 #include "G4EventManager.hh"
24 #include "G4Event.hh"
25 #include "G4VProcess.hh"
26 
27 #include "CLHEP/Units/GlobalSystemOfUnits.h"
28 #include "CLHEP/Units/GlobalPhysicalConstants.h"
29 
30 #include <string>
31 #include <vector>
32 #include <iostream>
33 
34 
36  const DDCompactView & cpv,
37  const SensitiveDetectorCatalog & clg,
38  edm::ParameterSet const & p,
39  const SimTrackManager* manager) :
40 SensitiveTkDetector(name, cpv, clg, p), mySimHit(nullptr),
41 oldVolume(nullptr), lastId(0), lastTrack(0), eventno(0) {
42 
43  edm::ParameterSet m_TrackerSD = p.getParameter<edm::ParameterSet>("PltSD");
44  energyCut = m_TrackerSD.getParameter<double>("EnergyThresholdForPersistencyInGeV")*GeV; //default must be 0.5 (?)
45  energyHistoryCut = m_TrackerSD.getParameter<double>("EnergyThresholdForHistoryInGeV")*GeV;//default must be 0.05 (?)
46 
47  edm::LogInfo("PltSD") <<"Criteria for Saving Tracker SimTracks: \n "
48  <<" History: "<<energyHistoryCut<< " MeV ; Persistency: "<< energyCut<<" MeV\n"
49  <<" Constructing a PltSD";
50 
51  slave = new TrackingSlaveSD(name);
52 
55 }
56 
58  delete slave;
60  delete myG4TrackToParticleID;
61 }
62 
63 bool PltSD::ProcessHits(G4Step * aStep, G4TouchableHistory *) {
64 
65  LogDebug("PltSD") << " Entering a new Step "
66  << aStep->GetTotalEnergyDeposit() << " "
67  << aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetName();
68 
69  G4Track * gTrack = aStep->GetTrack();
70  if ((unsigned int)(gTrack->GetTrackID()) != lastTrack) {
71 
72  if (gTrack->GetKineticEnergy() > energyCut){
74  info->storeTrack(true);
75  }
76  if (gTrack->GetKineticEnergy() > energyHistoryCut){
78  info->putInHistory();
79  }
80  }
81 
82  if (aStep->GetTotalEnergyDeposit()>0.) {
83  if (newHit(aStep) == true) {
84  sendHit();
85  createHit(aStep);
86  } else {
87  updateHit(aStep);
88  }
89  return true;
90  }
91  return false;
92 }
93 
94 uint32_t PltSD::setDetUnitId(const G4Step * aStep ) {
95 
96  unsigned int detId = 0;
97 
98  LogDebug("PltSD")<< " DetID = "<<detId;
99 
100  //Find number of levels
101  const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
102  int level = 0;
103  if (touch) level = ((touch->GetHistoryDepth())+1);
104 
105  //Get name and copy numbers
106  if ( level > 1 ) {
107  //some debugging with the names
108  G4String sensorName = touch->GetVolume(2)->GetName();
109  G4String telName = touch->GetVolume(3)->GetName();
110  G4String volumeName = touch->GetVolume(4)->GetName();
111  if ( sensorName != "PLTSensorPlane" )
112  std::cout << " PltSD::setDetUnitId -w- Sensor name not PLTSensorPlane " << std::endl;
113  if ( telName != "Telescope" )
114  std::cout << " PltSD::setDetUnitId -w- Telescope name not Telescope " << std::endl;
115  if ( volumeName != "PLT" )
116  std::cout << " PltSD::setDetUnitId -w- Volume name not PLT " << std::endl;
117 
118  //Get the information about which telescope, plane, row/column was hit
119  int columnNum = touch->GetReplicaNumber(0);
120  int rowNum = touch->GetReplicaNumber(1);
121  int sensorNum = touch->GetReplicaNumber(2);
122  int telNum = touch->GetReplicaNumber(3);
123  //temp stores the PLTBCM volume the hit occured in (i.e. was the hit on the + or -z side?)
124  int temp = touch->GetReplicaNumber(5);
125  //convert to the PLT hit id standard
126  int pltNum;
127  if (temp == 2) pltNum = 0;
128  else pltNum = 1;
129 
130  //correct the telescope numbers on the -z side to have the same naming convention in phi as the +z side
131  if (pltNum == 0){
132  if (telNum == 0){
133  telNum = 7;
134  }
135  else if (telNum == 1){
136  telNum = 6;
137  }
138  else if (telNum == 2){
139  telNum = 5;
140  }
141  else if (telNum == 3){
142  telNum = 4;
143  }
144  else if (telNum == 4){
145  telNum = 3;
146  }
147  else if (telNum == 5){
148  telNum = 2;
149  }
150  else if (telNum == 6){
151  telNum = 1;
152  }
153  else if (telNum == 7){
154  telNum = 0;
155  }
156  }
157  //the PLT is divided into sets of telescopes on the + and -x sides
158  int halfCarriageNum = -1;
159 
160  //If the telescope is on the -x side of the carriage, halfCarriageNum=0. If on the +x side, it is = 1.
161  if(telNum == 0 || telNum == 1 || telNum == 2 || telNum == 3)
162  halfCarriageNum = 0;
163  else
164  halfCarriageNum = 1;
165  //correct the telescope numbers of the +x half-carriage to range from 0 to 3
166  if(halfCarriageNum == 1){
167  if(telNum == 4){
168  telNum = 0;
169  }
170  else if (telNum == 5){
171  telNum = 1;
172  }
173  else if (telNum == 6){
174  telNum = 2;
175  }
176  else if (telNum == 7){
177  telNum = 3;
178  }
179  }
180  //Define unique detId for each pixel. See https://twiki.cern.ch/twiki/bin/viewauth/CMS/PLTSimulationGuide for more information
181  detId = 10000000*pltNum+1000000*halfCarriageNum+100000*telNum+10000*sensorNum+100*rowNum+columnNum;
182  //std::cout << "Hit Recorded at " << "plt:" << pltNum << " hc:" << halfCarriageNum << " tel:" << telNum << " plane:" << sensorNum << std::endl;
183  }
184 
185  return detId;
186 }
187 
188 void PltSD::EndOfEvent(G4HCofThisEvent *) {
189 
190  LogDebug("PltSD")<< " Saving the last hit in a ROU " << GetName();
191 
192  if (mySimHit == nullptr) return;
193  sendHit();
194 }
195 
197  if (slave->name() == hname) { cc=slave->hits(); }
198 }
199 
201  if (mySimHit == nullptr) return;
202  LogDebug("PltSD") << " Storing PSimHit: " << pname << " " << mySimHit->detUnitId()
203  << " " << mySimHit->trackId() << " " << mySimHit->energyLoss()
204  << " " << mySimHit->entryPoint() << " " << mySimHit->exitPoint();
205 
207 
208  // clean up
209  delete mySimHit;
210  mySimHit = nullptr;
211  lastTrack = 0;
212  lastId = 0;
213 }
214 
215 void PltSD::updateHit(G4Step * aStep) {
216 
218  float theEnergyLoss = aStep->GetTotalEnergyDeposit()/GeV;
219  mySimHit->setExitPoint(theExitPoint);
220  LogDebug("PltSD")<< " Before : " << mySimHit->energyLoss();
221  mySimHit->addEnergyLoss(theEnergyLoss);
223 
224  LogDebug("PltSD") << " Updating: new exitpoint " << pname << " "
225  << theExitPoint << " new energy loss " << theEnergyLoss
226  << "\n Updated PSimHit: " << mySimHit->detUnitId()
227  << " " << mySimHit->trackId()
228  << " " << mySimHit->energyLoss() << " "
229  << mySimHit->entryPoint() << " " << mySimHit->exitPoint();
230 }
231 
232 bool PltSD::newHit(G4Step * aStep) {
233 
234  G4Track * theTrack = aStep->GetTrack();
235  uint32_t theDetUnitId = setDetUnitId(aStep);
236  unsigned int theTrackID = theTrack->GetTrackID();
237 
238  LogDebug("PltSD") << " OLD (d,t) = (" << lastId << "," << lastTrack
239  << "), new = (" << theDetUnitId << "," << theTrackID << ") return "
240  << ((theTrackID == lastTrack) && (lastId == theDetUnitId));
241  if ((mySimHit != nullptr) && (theTrackID == lastTrack) && (lastId == theDetUnitId) && closeHit(aStep))
242  return false;
243  return true;
244 }
245 
246 bool PltSD::closeHit(G4Step * aStep) {
247 
248  if (mySimHit == nullptr) return false;
249  const float tolerance = 0.05 * mm; // 50 micron are allowed between the exit
250  // point of the current hit and the entry point of the new hit
252  LogDebug("PltSD")<< " closeHit: distance = " << (mySimHit->exitPoint()-theEntryPoint).mag();
253 
254  if ((mySimHit->exitPoint()-theEntryPoint).mag()<tolerance) return true;
255  return false;
256 }
257 
258 void PltSD::createHit(G4Step * aStep) {
259 
260  if (mySimHit != nullptr) {
261  delete mySimHit;
262  mySimHit=nullptr;
263  }
264 
265  G4Track * theTrack = aStep->GetTrack();
266  G4VPhysicalVolume * v = aStep->GetPreStepPoint()->GetPhysicalVolume();
267 
270 
271  float thePabs = aStep->GetPreStepPoint()->GetMomentum().mag()/GeV;
272  float theTof = aStep->GetPreStepPoint()->GetGlobalTime()/nanosecond;
273  float theEnergyLoss = aStep->GetTotalEnergyDeposit()/GeV;
274  int theParticleType = myG4TrackToParticleID->particleID(theTrack);
275  uint32_t theDetUnitId = setDetUnitId(aStep);
276 
279  pname = theTrack->GetDynamicParticle()->GetDefinition()->GetParticleName();
280 
281  unsigned int theTrackID = theTrack->GetTrackID();
282 
283  G4ThreeVector gmd = aStep->GetPreStepPoint()->GetMomentumDirection();
284  // convert it to local frame
285  G4ThreeVector lmd = ((G4TouchableHistory *)(aStep->GetPreStepPoint()->GetTouchable()))->GetHistory()->GetTopTransform().TransformAxis(gmd);
287  float theThetaAtEntry = lnmd.theta();
288  float thePhiAtEntry = lnmd.phi();
289 
290  mySimHit = new UpdatablePSimHit(theEntryPoint,theExitPoint,thePabs,theTof,
291  theEnergyLoss,theParticleType,theDetUnitId,
292  theTrackID,theThetaAtEntry,thePhiAtEntry,
293  theG4ProcessTypeEnumerator->processId(theTrack->GetCreatorProcess()));
294 
295  LogDebug("PltSD") << " Created PSimHit: " << pname << " "
296  << mySimHit->detUnitId() << " " << mySimHit->trackId()
297  << " " << mySimHit->energyLoss() << " "
298  << mySimHit->entryPoint() << " " << mySimHit->exitPoint();
299  lastId = theDetUnitId;
300  lastTrack = theTrackID;
301  oldVolume = v;
302 }
303 
304 void PltSD::update(const BeginOfJob * ) { }
305 
306 void PltSD::update(const BeginOfEvent * i) {
307 
308  clearHits();
309  eventno = (*i)()->GetEventID();
310  mySimHit = nullptr;
311 }
312 
313 void PltSD::update(const BeginOfTrack *bot) {
314 
315  const G4Track* gTrack = (*bot)();
316  pname = gTrack->GetDynamicParticle()->GetDefinition()->GetParticleName();
317 }
318 
320  slave->Initialize();
321 }
322 
324  G4VUserTrackInformation* temp = gTrack->GetUserInformation();
325  if (temp == nullptr){
326  edm::LogError("PltSD") <<" ERROR: no G4VUserTrackInformation available";
327  abort();
328  }else{
329  TrackInformation* info = dynamic_cast<TrackInformation*>(temp);
330  if (info == nullptr){
331  edm::LogError("PltSD") <<" ERROR: TkSimTrackSelection: the UserInformation does not appear to be a TrackInformation";
332  abort();
333  }
334  return info;
335  }
336 }
#define LogDebug(id)
T getParameter(std::string const &) const
static const TGPicture * info(bool iBackgroundIsBlack)
const double GeV
Definition: MathUtil.h:16
UpdatablePSimHit * mySimHit
Definition: PltSD.h:66
virtual bool newHit(G4Step *)
Definition: PltSD.cc:232
bool storeTrack() const
PltSD(const std::string &, const DDCompactView &, const SensitiveDetectorCatalog &, edm::ParameterSet const &, const SimTrackManager *)
Definition: PltSD.cc:35
Local3DPoint ConvertToLocal3DPoint(const G4ThreeVector &point) const
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
std::string name() const
G4TrackToParticleID * myG4TrackToParticleID
Definition: PltSD.h:65
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
void setExitPoint(const Local3DPoint &exit)
virtual void updateHit(G4Step *)
Definition: PltSD.cc:215
int eventno
Definition: PltSD.h:75
TrackingSlaveSD * slave
Definition: PltSD.h:63
#define nullptr
type of data representation of DDCompactView
Definition: DDCompactView.h:90
Geom::Theta< T > theta() const
Definition: PV3DBase.h:75
std::vector< PSimHit > & hits()
float energyCut
Definition: PltSD.h:67
unsigned int processId(const G4VProcess *p) const
Local3DPoint exitPoint() const
Exit point in the local Det frame.
Definition: PSimHit.h:38
virtual void Initialize()
Local3DPoint FinalStepPosition(const G4Step *step, coordinates) const
virtual void sendHit()
Definition: PltSD.cc:200
float energyHistoryCut
Definition: PltSD.h:68
static int particleID(const G4Track *)
Local3DPoint globalExitPoint
Definition: PltSD.h:71
void addEnergyLoss(float eloss)
virtual void createHit(G4Step *)
Definition: PltSD.cc:258
~PltSD() override
Definition: PltSD.cc:57
void update(const BeginOfEvent *) override
This routine will be called when the appropriate signal arrives.
Definition: PltSD.cc:306
float energyLoss() const
The energy deposit in the PSimHit, in ???.
Definition: PSimHit.h:75
G4VPhysicalVolume * oldVolume
Definition: PltSD.h:72
virtual bool closeHit(G4Step *)
Definition: PltSD.cc:246
unsigned int trackId() const
Definition: PSimHit.h:102
void clearHits() override
Definition: PltSD.cc:319
void EndOfEvent(G4HCofThisEvent *) override
Definition: PltSD.cc:188
unsigned int lastTrack
Definition: PltSD.h:74
virtual bool processHits(const PSimHit &)
std::vector< PSimHit > PSimHitContainer
std::string pname
Definition: PltSD.h:76
TrackInformation * getOrCreateTrackInformation(const G4Track *)
Definition: PltSD.cc:323
uint32_t lastId
Definition: PltSD.h:73
G4ProcessTypeEnumerator * theG4ProcessTypeEnumerator
Definition: PltSD.h:64
bool ProcessHits(G4Step *, G4TouchableHistory *) override
Definition: PltSD.cc:63
Local3DPoint entryPoint() const
Entry point in the local Det frame.
Definition: PSimHit.h:35
void fillHits(edm::PSimHitContainer &, const std::string &) override
Definition: PltSD.cc:196
uint32_t setDetUnitId(const G4Step *) override
Definition: PltSD.cc:94
unsigned int detUnitId() const
Definition: PSimHit.h:93
Local3DPoint globalEntryPoint
Definition: PltSD.h:70
Local3DPoint InitialStepPosition(const G4Step *step, coordinates) const