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