CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MuonSensitiveDetector.cc
Go to the documentation of this file.
7 
9 
12 
16 
20 
21 #include "G4SDManager.hh"
22 #include "G4VProcess.hh"
23 #include "G4EventManager.hh"
24 #include "G4SystemOfUnits.hh"
25 
27 
28 #include <iostream>
29 
31  const DDCompactView & cpv,
33  edm::ParameterSet const & p,
34  const SimTrackManager* manager)
35  : SensitiveTkDetector(name, cpv, clg, p),
36  thePV(0), theHit(0), theDetUnitId(0), theTrackID(0), theManager(manager)
37 {
38  edm::ParameterSet m_MuonSD = p.getParameter<edm::ParameterSet>("MuonSD");
39  STenergyPersistentCut = m_MuonSD.getParameter<double>("EnergyThresholdForPersistency");//Default 1. GeV
40  STallMuonsPersistent = m_MuonSD.getParameter<bool>("AllMuonsPersistent");
41  printHits = m_MuonSD.getParameter<bool>("PrintHits");
42 
43  //
44  // Here simply create 1 MuonSlaveSD for the moment
45  //
46 
47  LogDebug("MuonSimDebug") << "create MuonSubDetector "<<name<<std::endl;
48 
49  detector = new MuonSubDetector(name);
50 
51  LogDebug("MuonSimDebug") << "create MuonFrameRotation"<<std::endl;
52 
53  if (detector->isEndcap()) {
54  // cout << "MuonFrameRotation create MuonEndcapFrameRotation"<<endl;
56  } else if (detector->isRpc()) {
57  // cout << "MuonFrameRotation create MuonRpcFrameRotation"<<endl;
59  } else if (detector->isGem()) {
60  // cout << "MuonFrameRotation create MuonGemFrameRotation"<<endl;
62  } else {
63  theRotation = 0;
64  }
65  LogDebug("MuonSimDebug") << "create MuonSlaveSD"<<std::endl;
67  LogDebug("MuonSimDebug") << "create MuonSimHitNumberingScheme"<<std::endl;
69  g4numbering = new MuonG4Numbering(cpv);
70 
71 
72  //
73  // Now attach the right detectors (LogicalVolumes) to me
74  //
75  std::vector<std::string> lvNames = clg.logicalNames(name);
76  this->Register();
77  for (std::vector<std::string>::iterator it = lvNames.begin(); it != lvNames.end(); it++){
78  LogDebug("MuonSimDebug") << name << " MuonSensitiveDetector:: attaching SD to LV " << *it << std::endl;
79  this->AssignSD(*it);
80  }
81 
82  if (printHits) {
83  thePrinter = new SimHitPrinter("HitPositionOSCAR.dat");
84  }
85 
86 
87  LogDebug("MuonSimDebug") << " EnergyThresholdForPersistency " << STenergyPersistentCut << " AllMuonsPersistent " << STallMuonsPersistent << std::endl;
88 
91 
92 }
93 
94 
96  delete g4numbering;
97  delete numbering;
98  delete slaveMuon;
99  delete theRotation;
100  delete detector;
101 
103 
104  delete myG4TrackToParticleID;
105 }
106 
108  clearHits();
109 
110  //----- Initialize variables to check if two steps belong to same hit
111  thePV = 0;
112  theDetUnitId = 0;
113  theTrackID = 0;
114 
115 }
116 
117 void MuonSensitiveDetector::update(const ::EndOfEvent * ev)
118 {
119  //slaveMuon->renumbering(theManager);
120 }
121 
122 
124 {
125  LogDebug("MuonSimDebug") << "MuonSensitiveDetector::clearHits"<<std::endl;
127 }
128 
129 bool MuonSensitiveDetector::ProcessHits(G4Step * aStep, G4TouchableHistory * ROhist)
130 {
131  LogDebug("MuonSimDebug") <<" MuonSensitiveDetector::ProcessHits "<<InitialStepPosition(aStep,WorldCoordinates)<<std::endl;
132 
133  // TimeMe t1( theHitTimer, false);
134 
135  if (aStep->GetTotalEnergyDeposit()>0.){
136  // do not count neutrals that are killed by User Limits MinEKine
137  if( aStep->GetTrack()->GetDynamicParticle()->GetCharge() != 0 ){
138 
139  if (newHit(aStep)) {
140  saveHit();
141  createHit(aStep);
142  } else {
143  updateHit(aStep);
144  }
145  return true;
146  } else {
147  storeVolumeAndTrack(aStep);
148  return false;
149  }
150  }
151  return false;
152 }
153 
154 uint32_t MuonSensitiveDetector::setDetUnitId(G4Step * aStep)
155 {
156  // G4VPhysicalVolume * pv = aStep->GetPreStepPoint()->GetPhysicalVolume();
158  return numbering->baseNumberToUnitNumber(num);
159 }
160 
161 
163  if (theRotation !=0 ) {
164  return theRotation->transformPoint(in,s);
165  }
166  return (in);
167 }
168 
170  return Local3DPoint(in.x()/cm,in.y()/cm,in.z()/cm);
171 }
172 
174  return Global3DPoint(in.x()/cm,in.y()/cm,in.z()/cm);
175 }
176 
178  G4VPhysicalVolume* pv = aStep->GetPreStepPoint()->GetPhysicalVolume();
179  G4Track * t = aStep->GetTrack();
180  thePV=pv;
181  theTrackID=t->GetTrackID();
182 }
183 
184 bool MuonSensitiveDetector::newHit(G4Step * aStep){
185 
186  G4VPhysicalVolume* pv = aStep->GetPreStepPoint()->GetPhysicalVolume();
187  G4Track * t = aStep->GetTrack();
188  uint32_t currentUnitId=setDetUnitId(aStep);
189  unsigned int currentTrackID=t->GetTrackID();
190  //unsigned int currentEventID=G4EventManager::GetEventManager()->GetConstCurrentEvent()->GetEventID();
191  bool changed=((pv!=thePV) ||
192  (currentUnitId!=theDetUnitId) ||
193  (currentTrackID!=theTrackID));
194  return changed;
195 }
196 
197 void MuonSensitiveDetector::createHit(G4Step * aStep){
198 
199  G4Track * theTrack = aStep->GetTrack();
200 
201  Local3DPoint theEntryPoint;
202  Local3DPoint theExitPoint;
203 
204  if (detector->isBarrel()) {
205  theEntryPoint= toOrcaUnits(toOrcaRef(InitialStepPositionVsParent(aStep,1),aStep)); // 1 level up
206  theExitPoint= toOrcaUnits(toOrcaRef(FinalStepPositionVsParent(aStep,1),aStep));
207  } else if (detector->isEndcap()) {
208  // save local z at current level
209  theEntryPoint= toOrcaUnits(toOrcaRef(InitialStepPosition(aStep,LocalCoordinates),aStep));
210  theExitPoint= toOrcaUnits(toOrcaRef(FinalStepPosition(aStep,LocalCoordinates),aStep));
211  float zentry = theEntryPoint.z();
212  float zexit = theExitPoint.z();
213  Local3DPoint tempEntryPoint= toOrcaUnits(toOrcaRef(InitialStepPositionVsParent(aStep,4),aStep)); // 4 levels up
214  Local3DPoint tempExitPoint= toOrcaUnits(toOrcaRef(FinalStepPositionVsParent(aStep,4),aStep));
215  // reset local z from z wrt deep-parent volume to z wrt low-level volume
216  theEntryPoint = Local3DPoint( tempEntryPoint.x(), tempEntryPoint.y(), zentry );
217  theExitPoint = Local3DPoint( tempExitPoint.x(), tempExitPoint.y(), zexit );
218  } else {
219  theEntryPoint= toOrcaUnits(toOrcaRef(InitialStepPosition(aStep,LocalCoordinates),aStep));
220  theExitPoint= toOrcaUnits(toOrcaRef(FinalStepPosition(aStep,LocalCoordinates),aStep));
221  }
222 
223  float thePabs = aStep->GetPreStepPoint()->GetMomentum().mag()/GeV;
224  float theTof = aStep->GetPreStepPoint()->GetGlobalTime()/nanosecond;
225  float theEnergyLoss = aStep->GetTotalEnergyDeposit()/GeV;
226  // int theParticleType = theTrack->GetDefinition()->GetPDGEncoding();
227  int theParticleType = myG4TrackToParticleID->particleID(theTrack);
228  G4ThreeVector gmd = aStep->GetPreStepPoint()->GetMomentumDirection();
229  G4ThreeVector lmd = ((const G4TouchableHistory *)(aStep->GetPreStepPoint()->GetTouchable()))->GetHistory()
230  ->GetTopTransform().TransformAxis(gmd);
231  Local3DPoint lnmd = toOrcaRef(ConvertToLocal3DPoint(lmd),aStep);
232  float theThetaAtEntry = lnmd.theta();
233  float thePhiAtEntry = lnmd.phi();
234 
235  storeVolumeAndTrack( aStep );
236  theDetUnitId = setDetUnitId(aStep);
237 
238  Global3DPoint theGlobalPos;
239  if (printHits) {
240  Local3DPoint theGlobalHelp = InitialStepPosition(aStep,WorldCoordinates);
241  theGlobalEntry = toOrcaUnits(Global3DPoint (theGlobalHelp.x(),theGlobalHelp.y(),theGlobalHelp.z()));
242 
243  G4StepPoint * preStepPoint = aStep->GetPreStepPoint();
244  const G4TouchableHistory * theTouchable=(const G4TouchableHistory *)
245  (preStepPoint->GetTouchable());
246  theGlobalHelp=ConvertToLocal3DPoint(theTouchable->GetTranslation());
247  theGlobalPos = toOrcaUnits(Global3DPoint (theGlobalHelp.x(),theGlobalHelp.y(),theGlobalHelp.z()));
248  // const G4RotationMatrix * theGlobalRot = theTouchable->GetRotation();
249  }
250 
251  LogDebug("MuonSimDebug") << "MuonSensitiveDetector::createHit UpdatablePSimHit"<<std::endl;
252 
253  theHit = new UpdatablePSimHit(theEntryPoint,theExitPoint,thePabs,theTof,
254  theEnergyLoss,theParticleType,theDetUnitId,
255  theTrackID,theThetaAtEntry,thePhiAtEntry,
256  theG4ProcessTypeEnumerator->processId(theTrack->GetCreatorProcess()));
257 
258 
259  LogDebug("MuonSimDebug") <<"=== NEW ==================> ELOSS = "<<theEnergyLoss<<" "
260  <<thePV->GetLogicalVolume()->GetName()<<std::endl;
261  const G4VProcess* p = aStep->GetPostStepPoint()->GetProcessDefinedStep();
262  const G4VProcess* p2 = aStep->GetPreStepPoint()->GetProcessDefinedStep();
263  if (p)
264  LogDebug("MuonSimDebug") <<" POST PROCESS = "<<p->GetProcessName()<<std::endl;
265  if (p2)
266  LogDebug("MuonSimDebug") <<" PRE PROCESS = "<<p2->GetProcessName()<<std::endl;
267  LogDebug("MuonSimDebug") << "newhit theta " << theThetaAtEntry<<std::endl;
268  LogDebug("MuonSimDebug") << "newhit phi " << thePhiAtEntry<<std::endl;
269  LogDebug("MuonSimDebug") << "newhit pabs " << thePabs<<std::endl;
270  LogDebug("MuonSimDebug") << "newhit tof " << theTof<<std::endl;
271  LogDebug("MuonSimDebug") << "newhit track " << theTrackID<<std::endl;
272  LogDebug("MuonSimDebug") << "newhit entry " << theEntryPoint<<std::endl;
273  LogDebug("MuonSimDebug") << "newhit exit " << theExitPoint<<std::endl;
274  LogDebug("MuonSimDebug") << "newhit eloss " << theEnergyLoss << std::endl;
275  LogDebug("MuonSimDebug") << "newhit detid " << theDetUnitId<<std::endl;
276  LogDebug("MuonSimDebug") << "newhit delta " << (theExitPoint-theEntryPoint)<<std::endl;
277  LogDebug("MuonSimDebug") << "newhit deltu " << (theExitPoint-theEntryPoint).unit();
278  LogDebug("MuonSimDebug") << " " << (theExitPoint-theEntryPoint).mag()<<std::endl;
279  LogDebug("MuonSimDebug") << "newhit glob " << theGlobalEntry<<std::endl;
280  LogDebug("MuonSimDebug") << "newhit dpos " << theGlobalPos<<std::endl;
281  LogDebug("MuonSimDebug") << "newhit drot " << std::endl;
282  // theGlobalRot->print(LogDebug("MuonSimDebug"));
283 
284 
285  //
286  //----- SimTracks: Make it persistent?
287  //
288  int thePID = theTrack->GetDefinition()->GetPDGEncoding();
289  LogDebug("MuonSimDebug") << " checking simtrack " << thePID << " " << thePabs << " STenergyPersistentCut " << STenergyPersistentCut << std::endl;
290 
291  if( thePabs*GeV > STenergyPersistentCut
292  || ( abs(thePID) == 13 && STallMuonsPersistent ) ){
294  LogDebug("MuonSimDebug") <<" track leaving hit in muons made selected for persistency"<<std::endl;
295 
296  info->storeTrack(true);
297  }
298 
299 }
300 
301 void MuonSensitiveDetector::updateHit(G4Step * aStep){
302  // float thePabs = aStep->GetPreStepPoint()->GetMomentum().mag()/GeV;
303  // Local3DPoint theEntryPoint= InitialStepPosition(aStep,LocalCoordinates);
304 
305 
306  Local3DPoint theExitPoint;
307 
308  if (detector->isBarrel()) {
309  theExitPoint= toOrcaUnits(toOrcaRef(FinalStepPositionVsParent(aStep,1),aStep));
310  } else if (detector->isEndcap()) {
311  // save local z at current level
312  theExitPoint= toOrcaUnits(toOrcaRef(FinalStepPosition(aStep,LocalCoordinates),aStep));
313  float zexit = theExitPoint.z();
314  Local3DPoint tempExitPoint= toOrcaUnits(toOrcaRef(FinalStepPositionVsParent(aStep,4),aStep));
315  theExitPoint = Local3DPoint( tempExitPoint.x(), tempExitPoint.y(), zexit );
316  } else {
317  theExitPoint= toOrcaUnits(toOrcaRef(FinalStepPosition(aStep,LocalCoordinates),aStep));
318  }
319 
320  float theEnergyLoss = aStep->GetTotalEnergyDeposit()/GeV;
321 
322  if( theHit == 0 ){
323  std::cerr << "!!ERRROR in MuonSensitiveDetector::updateHit. It is called when there is no hit " << std::endl;
324  }
325 
326  theHit->updateExitPoint(theExitPoint);
327  theHit->addEnergyLoss(theEnergyLoss);
328 
329  LogDebug("MuonSimDebug") <<"=== UPDATE ===============> ELOSS = "<<theEnergyLoss<<" "
330  <<thePV->GetLogicalVolume()->GetName()<<std::endl;
331  const G4VProcess* p = aStep->GetPostStepPoint()->GetProcessDefinedStep();
332  const G4VProcess* p2 = aStep->GetPreStepPoint()->GetProcessDefinedStep();
333  if (p)
334  LogDebug("MuonSimDebug") <<" POST PROCESS = "<<p->GetProcessName()<<std::endl;
335  if (p2)
336  LogDebug("MuonSimDebug") <<" PRE PROCESS = "<<p2->GetProcessName()<<std::endl;
337  LogDebug("MuonSimDebug") << "updhit exit " << theExitPoint<<std::endl;
338  LogDebug("MuonSimDebug") << "updhit eloss " << theHit->energyLoss() <<std::endl;
339  LogDebug("MuonSimDebug") << "updhit detid " << theDetUnitId<<std::endl;
340  LogDebug("MuonSimDebug") << "updhit delta " << (theExitPoint-theHit->entryPoint())<<std::endl;
341  LogDebug("MuonSimDebug") << "updhit deltu " << (theExitPoint-theHit->entryPoint()).unit();
342  LogDebug("MuonSimDebug") << " " << (theExitPoint-theHit->entryPoint()).mag()<<std::endl;
343 
344 }
345 
347 
348  if (theHit) {
349  if (printHits) {
352  // thePrinter->printTrack(theHit->trackId());
353  //thePrinter->printPabs(theHit->pabs());
354  //thePrinter->printEloss(theHit->energyLoss());
357  }
359  // seems the hit does not want to be deleted
360  // done by the hit collection?
361  delete theHit;
362  theHit = 0; //set it to 0, because you are checking that is 0
363  }
364 
365 }
366 
368 {
369  G4VUserTrackInformation* temp = gTrack->GetUserInformation();
370  if (temp == 0){
371  std::cerr <<" ERROR: no G4VUserTrackInformation available"<<std::endl;
372  abort();
373  }else{
374  TrackInformation* info = dynamic_cast<TrackInformation*>(temp);
375  if (info ==0){
376  std::cerr <<" ERROR: TkSimTrackSelection: the UserInformation does not appear to be a TrackInformation"<<std::endl;
377  abort();
378  }
379  return info;
380  }
381 }
382 
383 void MuonSensitiveDetector::EndOfEvent(G4HCofThisEvent*)
384 {
385 // TimeMe t("MuonSensitiveDetector::EndOfEvent", false);
386  // LogDebug("MuonSimDebug") << "MuonSensitiveDetector::EndOfEvent saving last hit en event " << std::endl;
387  saveHit();
388 }
389 
390 
392  //
393  // do it once for low, once for High
394  //
395 
396  if (slaveMuon->name() == n) c=slaveMuon->hits();
397 
398 }
399 
400 std::vector<std::string> MuonSensitiveDetector::getNames(){
401  std::vector<std::string> temp;
402  temp.push_back(slaveMuon->name());
403  return temp;
404 }
405 
407 
408  G4StepPoint * preStepPoint = currentStep->GetPreStepPoint();
409  G4ThreeVector globalCoordinates = preStepPoint->GetPosition();
410 
411  const G4TouchableHistory * theTouchable=(const G4TouchableHistory *)
412  (preStepPoint->GetTouchable());
413 
414  G4int depth = theTouchable->GetHistory()->GetDepth();
415  G4ThreeVector localCoordinates = theTouchable->GetHistory()
416  ->GetTransform(depth-levelsUp).TransformPoint(globalCoordinates);
417 
418  return ConvertToLocal3DPoint(localCoordinates);
419 }
420 
421 Local3DPoint MuonSensitiveDetector::FinalStepPositionVsParent(G4Step * currentStep, G4int levelsUp) {
422 
423  G4StepPoint * postStepPoint = currentStep->GetPostStepPoint();
424  G4StepPoint * preStepPoint = currentStep->GetPreStepPoint();
425  G4ThreeVector globalCoordinates = postStepPoint->GetPosition();
426 
427  const G4TouchableHistory * theTouchable = (const G4TouchableHistory *)
428  (preStepPoint->GetTouchable());
429 
430  G4int depth = theTouchable->GetHistory()->GetDepth();
431  G4ThreeVector localCoordinates = theTouchable->GetHistory()
432  ->GetTransform(depth-levelsUp).TransformPoint(globalCoordinates);
433 
434  return ConvertToLocal3DPoint(localCoordinates);
435 }
#define LogDebug(id)
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
Local3DPoint FinalStepPositionVsParent(G4Step *currentStep, G4int levelsUp)
std::vector< std::string > logicalNames(std::string &readoutName)
static const TGPicture * info(bool iBackgroundIsBlack)
bool storeTrack() const
void printLocal(LocalPoint, LocalPoint) const
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
std::string name() const
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
T y() const
Definition: PV3DBase.h:63
void fillHits(edm::PSimHitContainer &, std::string use)
virtual Local3DPoint transformPoint(const Local3DPoint &, const G4Step *) const =0
std::string name()
type of data representation of DDCompactView
Definition: DDCompactView.h:77
MuonSubDetector * detector
virtual void EndOfEvent(G4HCofThisEvent *)
unsigned int processId(const G4VProcess *p)
Geom::Theta< T > theta() const
Definition: PV3DBase.h:75
std::vector< PSimHit > & hits()
Point3DBase< float, GlobalTag > Global3DPoint
Definition: GlobalPoint.h:7
Local3DPoint exitPoint() const
Exit point in the local Det frame.
Definition: PSimHit.h:38
Local3DPoint ConvertToLocal3DPoint(const G4ThreeVector &point)
void updateExitPoint(const Local3DPoint &exit)
virtual void Initialize()
G4ProcessTypeEnumerator * theG4ProcessTypeEnumerator
string unit
Definition: csvLumiCalc.py:46
T z() const
Definition: PV3DBase.h:64
Local3DPoint toOrcaUnits(Local3DPoint)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::vector< std::string > getNames()
double p2[4]
Definition: TauolaWrapper.h:90
const SimTrackManager * theManager
void printGlobal(GlobalPoint) const
static int particleID(const G4Track *)
MuonFrameRotation * theRotation
virtual int baseNumberToUnitNumber(const MuonBaseNumber &)
MuonBaseNumber PhysicalVolumeToBaseNumber(const G4Step *aStep)
Point3DBase< float, LocalTag > Local3DPoint
Definition: LocalPoint.h:9
void addEnergyLoss(float eloss)
void startNewSimHit(std::string)
MuonSimHitNumberingScheme * numbering
MuonSensitiveDetector(std::string, const DDCompactView &, SensitiveDetectorCatalog &, edm::ParameterSet const &, const SimTrackManager *)
Local3DPoint toOrcaRef(Local3DPoint in, G4Step *s)
G4TrackToParticleID * myG4TrackToParticleID
void printId(int) const
virtual void AssignSD(std::string &vname)
float energyLoss() const
The energy deposit in the PSimHit, in ???.
Definition: PSimHit.h:75
G4VPhysicalVolume * thePV
virtual bool processHits(const PSimHit &)
void update(const BeginOfEvent *)
This routine will be called when the appropriate signal arrives.
std::vector< PSimHit > PSimHitContainer
Local3DPoint InitialStepPositionVsParent(G4Step *currentStep, G4int levelsUp)
Local3DPoint FinalStepPosition(G4Step *s, coordinates)
virtual uint32_t setDetUnitId(G4Step *)
T x() const
Definition: PV3DBase.h:62
TrackInformation * getOrCreateTrackInformation(const G4Track *theTrack)
Local3DPoint entryPoint() const
Entry point in the local Det frame.
Definition: PSimHit.h:35
Local3DPoint InitialStepPosition(G4Step *s, coordinates)
unsigned int detUnitId() const
Definition: PSimHit.h:93
UpdatablePSimHit * theHit
MuonG4Numbering * g4numbering
virtual G4bool ProcessHits(G4Step *, G4TouchableHistory *)