CMS 3D CMS Logo

MuonSensitiveDetector.cc
Go to the documentation of this file.
9 
13 
17 
21 
22 #include "G4VProcess.hh"
23 #include "G4EventManager.hh"
24 #include "G4SystemOfUnits.hh"
25 #include "G4Step.hh"
26 #include "G4StepPoint.hh"
27 #include "G4Track.hh"
28 
30 
31 #include <iostream>
32 
33 //#define DebugLog
34 
36  const DDCompactView & cpv,
37  const SensitiveDetectorCatalog & clg,
38  edm::ParameterSet const & p,
39  const SimTrackManager* manager)
40  : SensitiveTkDetector(name, cpv, clg, p),
41  thePV(nullptr), theHit(nullptr), theDetUnitId(0), newDetUnitId(0),
42  theTrackID(0), theManager(manager)
43 {
44  edm::ParameterSet m_MuonSD = p.getParameter<edm::ParameterSet>("MuonSD");
45  ePersistentCutGeV = m_MuonSD.getParameter<double>("EnergyThresholdForPersistency")/CLHEP::GeV;//Default 1. GeV
46  allMuonsPersistent = m_MuonSD.getParameter<bool>("AllMuonsPersistent");
47  printHits = m_MuonSD.getParameter<bool>("PrintHits");
48 
49  //
50  // Here simply create 1 MuonSlaveSD for the moment
51  //
52  LogDebug("MuonSimDebug") << "create MuonSubDetector "<<name;
53  detector = new MuonSubDetector(name);
54 
55  //The constants take time to calculate and are needed by many helpers
57  G4String sdet = "unknown";
58  if (detector->isEndcap()) {
60  sdet = "Endcap";
61  } else if (detector->isRPC()) {
62  theRotation=new MuonRPCFrameRotation( constants );
63  sdet = "RPC";
64  } else if (detector->isGEM()) {
65  theRotation=new MuonGEMFrameRotation( constants );
66  sdet = "GEM";
67  } else if (detector->isME0()) {
68  theRotation=new MuonME0FrameRotation( constants );
69  sdet = "ME0";
70  } else {
72  }
75  g4numbering = new MuonG4Numbering(constants);
76 
77  if (printHits) {
78  thePrinter = new SimHitPrinter("HitPositionOSCAR.dat");
79  }
80 
81  edm::LogVerbatim("MuonSensitiveDetector")
82  << " of type " << sdet << " <" << GetName()
83  << "> EnergyThresholdForPersistency(GeV) " << ePersistentCutGeV/CLHEP::GeV
84  << " allMuonsPersistent: " << allMuonsPersistent;
85 
87 }
88 
90  delete g4numbering;
91  delete numbering;
92  delete slaveMuon;
93  delete theRotation;
94  delete detector;
96 }
97 
99  clearHits();
100  //----- Initialize variables to check if two steps belong to same hit
101  thePV = nullptr;
102  theDetUnitId = 0;
103  theTrackID = 0;
104 }
105 
107 {
108  LogDebug("MuonSimDebug") << "MuonSensitiveDetector::clearHits";
110 }
111 
112 bool MuonSensitiveDetector::ProcessHits(G4Step * aStep, G4TouchableHistory * ROhist)
113 {
114  LogDebug("MuonSimDebug") <<" MuonSensitiveDetector::ProcessHits "
116 
117  if (aStep->GetTotalEnergyDeposit()>0.){
118  newDetUnitId = setDetUnitId(aStep);
119 
120  // do not count neutrals that are killed by User Limits MinEKine
121  //---VI: this is incorrect, neutral particle, like neutron may have local
122  // energy deposit, which potentially may make a hit
123  if( aStep->GetTrack()->GetDynamicParticle()->GetCharge() != 0 ){
124 
125  if (newHit(aStep)) {
126  saveHit();
127  createHit(aStep);
128  } else {
129  updateHit(aStep);
130  }
131  } else {
132  thePV = aStep->GetPreStepPoint()->GetPhysicalVolume();
133  theTrackID = aStep->GetTrack()->GetTrackID();
135  }
136  }
137  return true;
138 }
139 
140 uint32_t MuonSensitiveDetector::setDetUnitId(const G4Step * aStep)
141 {
143 
144 #ifdef DebugLog
145  std::stringstream MuonBaseNumber;
146  MuonBaseNumber << "MuonNumbering :: number of levels = "<<num.getLevels()<<std::endl;
147  MuonBaseNumber << "Level \t SuperNo \t BaseNo"<<std::endl;
148  for (int level=1;level<=num.getLevels();level++) {
149  MuonBaseNumber << level << " \t " << num.getSuperNo(level)
150  << " \t " << num.getBaseNo(level) << std::endl;
151  }
152  std::string MuonBaseNumbr = MuonBaseNumber.str();
153 
154  LogDebug("MuonSimDebug") <<"MuonSensitiveDetector::setDetUnitId :: "<<MuonBaseNumbr;
155  LogDebug("MuonSimDebug") <<"MuonSensitiveDetector::setDetUnitId :: MuonDetUnitId = "
157 #endif
158  return numbering->baseNumberToUnitNumber(num);
159 }
160 
161 bool MuonSensitiveDetector::newHit(const G4Step * aStep){
162 
163  return (!theHit || (aStep->GetTrack()->GetTrackID() != theTrackID)
164  || (aStep->GetPreStepPoint()->GetPhysicalVolume() != thePV)
165  || newDetUnitId != theDetUnitId);
166 }
167 
168 void MuonSensitiveDetector::createHit(const G4Step * aStep){
169 
170  Local3DPoint theEntryPoint;
171  Local3DPoint theExitPoint;
172 
173  if (detector->isBarrel()) {
174  // 1 levels up
175  theEntryPoint = cmsUnits(theRotation->transformPoint(InitialStepPositionVsParent(aStep,1),aStep));
176  theExitPoint = cmsUnits(theRotation->transformPoint(FinalStepPositionVsParent(aStep,1),aStep));
177  } else if (detector->isEndcap()) {
178  // save local z at current level
179  theEntryPoint = theRotation->transformPoint(InitialStepPosition(aStep,LocalCoordinates),aStep);
180  theExitPoint = theRotation->transformPoint(FinalStepPosition(aStep,LocalCoordinates),aStep);
181  float zentry = theEntryPoint.z();
182  float zexit = theExitPoint.z();
183  // 4 levels up
186  // reset local z from z wrt deep-parent volume to z wrt low-level volume
187  theEntryPoint = cmsUnits(Local3DPoint( tempEntry.x(), tempEntry.y(), zentry ));
188  theExitPoint = cmsUnits(Local3DPoint( tempExit.x(), tempExit.y(), zexit ));
189  } else {
191  theExitPoint = cmsUnits(theRotation->transformPoint(FinalStepPosition(aStep,LocalCoordinates),aStep));
192  }
193 
194  const G4Track* theTrack = aStep->GetTrack();
195  const G4StepPoint* preStepPoint = aStep->GetPreStepPoint();
196 
197  float thePabs = preStepPoint->GetMomentum().mag()/CLHEP::GeV;
198  float theTof = preStepPoint->GetGlobalTime()/CLHEP::nanosecond;
199  float theEnergyLoss = aStep->GetTotalEnergyDeposit()/CLHEP::GeV;
200  int theParticleType = G4TrackToParticleID::particleID(theTrack);
201 
203  thePV = preStepPoint->GetPhysicalVolume();
204  theTrackID = theTrack->GetTrackID();
205 
206  // convert momentum direction it to local frame
207  const G4ThreeVector& gmd = preStepPoint->GetMomentumDirection();
208  G4ThreeVector lmd = ((G4TouchableHistory *)(preStepPoint->GetTouchable()))->GetHistory()
209  ->GetTopTransform().TransformAxis(gmd);
211  lnmd = theRotation->transformPoint(lnmd, aStep);
212  float theThetaAtEntry = lnmd.theta();
213  float thePhiAtEntry = lnmd.phi();
214 
215  theHit = new UpdatablePSimHit(theEntryPoint,theExitPoint,thePabs,theTof,
216  theEnergyLoss,theParticleType,theDetUnitId,
217  theTrackID,theThetaAtEntry,thePhiAtEntry,
218  theG4ProcessTypeEnumerator->processId(theTrack->GetCreatorProcess()));
219 
220  // Make track persistent
221  int thePID = std::abs(theTrack->GetDefinition()->GetPDGEncoding());
222  //---VI - in parameters cut in energy is declared but applied to momentum
223  if(thePabs > ePersistentCutGeV || ( thePID == 13 && allMuonsPersistent ) ){
225  info->storeTrack(true);
226  }
227 
228 #ifdef DebugLog
229  edm::LogVerbatim("MuonSimDebug") <<"=== NEW Muon hit for "<< GetName()
230  << " Edep(GeV)= " << theEnergyLoss
231  <<" " <<thePV->GetLogicalVolume()->GetName();
232  const G4VProcess* p = aStep->GetPostStepPoint()->GetProcessDefinedStep();
233  const G4VProcess* p2 = preStepPoint->GetProcessDefinedStep();
234  G4String sss = "";
235  if (p) sss += " POST PROCESS: " + p->GetProcessName();
236  if (p2)sss += "; PRE PROCESS: " + p2->GetProcessName();
237  if("" != sss) edm::LogVerbatim("MuonSimDebug") << sss;
238  edm::LogVerbatim("MuonSimDebug") << " theta= " << theThetaAtEntry
239  << " phi= " << thePhiAtEntry
240  << " Pabs(GeV/c) " << thePabs
241  << " Eloss(GeV)= " << theEnergyLoss
242  << " Tof(ns)= " << theTof
243  << " trackID= " << theTrackID
244  << " detID= " << theDetUnitId
245  << "\n Local: entry " << theEntryPoint
246  << " exit " << theExitPoint
247  << " delta " << (theExitPoint-theEntryPoint)
248  << "\n Global: entry " << preStepPoint->GetPosition()
249  << " exit " << aStep->GetPostStepPoint()->GetPosition();
250 #endif
251 }
252 
253 void MuonSensitiveDetector::updateHit(const G4Step * aStep){
254 
255  Local3DPoint theExitPoint;
256 
257  if (detector->isBarrel()) {
258  theExitPoint = cmsUnits(theRotation->transformPoint(FinalStepPositionVsParent(aStep,1),aStep));
259  } else if (detector->isEndcap()) {
260  // save local z at current level
261  theExitPoint = theRotation->transformPoint(FinalStepPosition(aStep,LocalCoordinates),aStep);
262  float zexit = theExitPoint.z();
263  Local3DPoint tempExitPoint = theRotation->transformPoint(FinalStepPositionVsParent(aStep,4),aStep);
264  theExitPoint = cmsUnits(Local3DPoint( tempExitPoint.x(), tempExitPoint.y(), zexit));
265  } else {
266  theExitPoint = cmsUnits(theRotation->transformPoint(FinalStepPosition(aStep,LocalCoordinates),aStep));
267  }
268 
269  float theEnergyLoss = aStep->GetTotalEnergyDeposit()/CLHEP::GeV;
270 
271  theHit->updateExitPoint(theExitPoint);
272  theHit->addEnergyLoss(theEnergyLoss);
273 
274 #ifdef DebugLog
275  edm::LogVerbatim("MuonSimDebug") <<"=== NEW Update muon hit for "<< GetName()
276  << " Edep(GeV)= " << theEnergyLoss
277  <<" " <<thePV->GetLogicalVolume()->GetName();
278  const G4VProcess* p = aStep->GetPostStepPoint()->GetProcessDefinedStep();
279  const G4VProcess* p2 = preStepPoint->GetProcessDefinedStep();
280  G4String sss = "";
281  if (p) sss += " POST PROCESS: " + p->GetProcessName();
282  if (p2)sss += "; PRE PROCESS: " + p2->GetProcessName();
283  if("" != sss) edm::LogVerbatim("MuonSimDebug") << sss;
284  edm::LogVerbatim("MuonSimDebug") << " delEloss(GeV)= " << theEnergyLoss
285  << " Tof(ns)= " << theTof
286  << " trackID= " << theTrackID
287  << " detID= " << theDetUnitId
288  << " exit " << theExitPoint;
289 #endif
290 }
291 
293  if (theHit) {
294  if (printHits) {
298  }
299  // hit is included into hit collection
301  delete theHit;
302  theHit = nullptr;
303  }
304 }
305 
306 void MuonSensitiveDetector::EndOfEvent(G4HCofThisEvent*)
307 {
308  saveHit();
309 }
310 
312  if (slaveMuon->name() == hname) { cc=slaveMuon->hits(); }
313 }
314 
315 Local3DPoint MuonSensitiveDetector::InitialStepPositionVsParent(const G4Step * currentStep, G4int levelsUp) {
316 
317  const G4StepPoint * preStepPoint = currentStep->GetPreStepPoint();
318  const G4ThreeVector& globalCoordinates = preStepPoint->GetPosition();
319 
320  const G4TouchableHistory * theTouchable=(const G4TouchableHistory *)
321  (preStepPoint->GetTouchable());
322 
323  G4int depth = theTouchable->GetHistory()->GetDepth();
324  G4ThreeVector localCoordinates = theTouchable->GetHistory()
325  ->GetTransform(depth-levelsUp).TransformPoint(globalCoordinates);
326 
327  return ConvertToLocal3DPoint(localCoordinates);
328 }
329 
330 Local3DPoint MuonSensitiveDetector::FinalStepPositionVsParent(const G4Step* currentStep, G4int levelsUp) {
331 
332  const G4StepPoint * postStepPoint = currentStep->GetPostStepPoint();
333  const G4StepPoint * preStepPoint = currentStep->GetPreStepPoint();
334  const G4ThreeVector& globalCoordinates = postStepPoint->GetPosition();
335 
336  const G4TouchableHistory * theTouchable = (const G4TouchableHistory *)
337  (preStepPoint->GetTouchable());
338 
339  G4int depth = theTouchable->GetHistory()->GetDepth();
340  G4ThreeVector localCoordinates = theTouchable->GetHistory()
341  ->GetTransform(depth-levelsUp).TransformPoint(globalCoordinates);
342 
343  return ConvertToLocal3DPoint(localCoordinates);
344 }
#define LogDebug(id)
T getParameter(std::string const &) const
const G4VPhysicalVolume * thePV
static const TGPicture * info(bool iBackgroundIsBlack)
const double GeV
Definition: MathUtil.h:16
Local3DPoint FinalStepPositionVsParent(const G4Step *currentStep, G4int levelsUp)
bool storeTrack() const
G4bool ProcessHits(G4Step *, G4TouchableHistory *) override
Local3DPoint ConvertToLocal3DPoint(const G4ThreeVector &point) const
void updateHit(const G4Step *)
void printLocal(LocalPoint, LocalPoint) const
std::string name() const
int getBaseNo(int level) const
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
T y() const
Definition: PV3DBase.h:63
std::string name()
#define nullptr
Compact representation of the geometrical detector hierarchy.
Definition: DDCompactView.h:83
MuonSubDetector * detector
void fillHits(edm::PSimHitContainer &, const std::string &) override
Geom::Theta< T > theta() const
Definition: PV3DBase.h:75
Local3DPoint cmsUnits(const Local3DPoint &v)
std::vector< PSimHit > & hits()
unsigned int processId(const G4VProcess *p) const
Local3DPoint exitPoint() const
Exit point in the local Det frame.
Definition: PSimHit.h:38
T mag() const
Definition: PV3DBase.h:67
void createHit(const G4Step *)
void updateExitPoint(const Local3DPoint &exit)
virtual void Initialize()
G4ProcessTypeEnumerator * theG4ProcessTypeEnumerator
Local3DPoint FinalStepPosition(const G4Step *step, coordinates) const
T z() const
Definition: PV3DBase.h:64
bool newHit(const G4Step *)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
virtual Local3DPoint transformPoint(const Local3DPoint &, const G4Step *) const
double p2[4]
Definition: TauolaWrapper.h:90
const SimTrackManager * theManager
TrackInformation * cmsTrackInformation(const G4Track *aTrack)
static int particleID(const G4Track *)
MuonFrameRotation * theRotation
MuonSensitiveDetector(const std::string &, const DDCompactView &, const SensitiveDetectorCatalog &, edm::ParameterSet const &, const SimTrackManager *)
MuonBaseNumber PhysicalVolumeToBaseNumber(const G4Step *aStep)
uint32_t setDetUnitId(const G4Step *) override
Point3DBase< float, LocalTag > Local3DPoint
Definition: LocalPoint.h:9
void addEnergyLoss(float eloss)
void startNewSimHit(std::string)
void EndOfEvent(G4HCofThisEvent *) override
MuonSimHitNumberingScheme * numbering
void printId(int) const
int getLevels() const
void update(const BeginOfEvent *) override
This routine will be called when the appropriate signal arrives.
int getSuperNo(int level) const
virtual bool processHits(const PSimHit &)
std::vector< PSimHit > PSimHitContainer
T x() const
Definition: PV3DBase.h:62
int baseNumberToUnitNumber(const MuonBaseNumber &) override
Local3DPoint entryPoint() const
Entry point in the local Det frame.
Definition: PSimHit.h:35
unsigned int detUnitId() const
Definition: PSimHit.h:93
Local3DPoint InitialStepPositionVsParent(const G4Step *currentStep, G4int levelsUp)
UpdatablePSimHit * theHit
MuonG4Numbering * g4numbering
Local3DPoint InitialStepPosition(const G4Step *step, coordinates) const