CMS 3D CMS Logo

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