CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
SteppingAction.cc
Go to the documentation of this file.
3 
4 #include "G4LogicalVolumeStore.hh"
5 #include "G4ParticleTable.hh"
6 #include "G4PhysicalVolumeStore.hh"
7 #include "G4RegionStore.hh"
8 #include "G4Track.hh"
9 #include "G4UnitsTable.hh"
10 
12 
14  : eventAction_(e), initialized(false), tracker(0), calo(0) {
15 
16  killBeamPipe = (p.getParameter<bool>("KillBeamPipe"));
17  theCriticalEnergyForVacuum = (p.getParameter<double>("CriticalEnergyForVacuum")*MeV);
18  theCriticalDensity = (p.getParameter<double>("CriticalDensity")*g/cm3);
19  maxTrackTime = (p.getParameter<double>("MaxTrackTime")*ns);
20  maxTrackTimes = (p.getParameter<std::vector<double> >("MaxTrackTimes"));
21  maxTimeNames = (p.getParameter<std::vector<std::string> >("MaxTimeNames"));
22  ekinMins = (p.getParameter<std::vector<double> >("EkinThresholds"));
23  ekinNames = (p.getParameter<std::vector<std::string> >("EkinNames"));
24  ekinParticles = (p.getParameter<std::vector<std::string> >("EkinParticles"));
25  verbose = (p.getUntrackedParameter<int>("Verbosity",0));
26 
27  edm::LogInfo("SimG4CoreApplication") << "SteppingAction:: KillBeamPipe = "
28  << killBeamPipe << " CriticalDensity = "
29  << theCriticalDensity << " g/cc;"
30  << " CriticalEnergyForVacuum = "
31  << theCriticalEnergyForVacuum << " Mev;"
32  << " MaxTrackTime = " << maxTrackTime
33  << " ns";
34  for (unsigned int i=0; i<maxTrackTimes.size(); i++) {
35  maxTrackTimes[i] *= ns;
36  edm::LogInfo("SimG4CoreApplication") << "SteppingAction::MaxTrackTime for "
37  << maxTimeNames[i] << " is "
38  << maxTrackTimes[i];
39  }
40  edm::LogInfo("SimG4CoreApplication") << "SteppingAction::Kill following "
41  << ekinParticles.size()
42  << " particles in " << ekinNames.size()
43  << " volumes";
44  for (unsigned int i=0; i<ekinParticles.size(); i++) {
45  ekinMins[i] *= GeV;
46  edm::LogInfo("SimG4CoreApplication") << "SteppingAction::Particle " << i
47  << " " << ekinParticles[i]
48  << " (Threshold = " << ekinMins[i]
49  << " MeV)";
50  }
51  for (unsigned int i=0; i<ekinNames.size(); i++)
52  edm::LogInfo("SimG4CoreApplication") << "SteppingAction::Volume[" << i
53  << "] = " << ekinNames[i];
54 }
55 
57 
58 void SteppingAction::UserSteppingAction(const G4Step * aStep) {
60  m_g4StepSignal(aStep);
61 
62  if (killBeamPipe) {
65  }
66 
67  if (aStep->GetPostStepPoint()->GetPhysicalVolume() != 0) {
68  bool ok = catchLongLived(aStep);
69  if (ok) ok = catchLongLived(aStep);
70 
71  ok = (isThisVolume(aStep->GetPreStepPoint()->GetTouchable(),tracker)&&
72  isThisVolume(aStep->GetPostStepPoint()->GetTouchable(),calo));
73  if (ok) {
74 
75  math::XYZVectorD pos((aStep->GetPreStepPoint()->GetPosition()).x(),
76  (aStep->GetPreStepPoint()->GetPosition()).y(),
77  (aStep->GetPreStepPoint()->GetPosition()).z());
78 
79  math::XYZTLorentzVectorD mom((aStep->GetPreStepPoint()->GetMomentum()).x(),
80  (aStep->GetPreStepPoint()->GetMomentum()).y(),
81  (aStep->GetPreStepPoint()->GetMomentum()).z(),
82  aStep->GetPreStepPoint()->GetTotalEnergy());
83 
84  uint32_t id = aStep->GetTrack()->GetTrackID();
85 
86  std::pair<math::XYZVectorD,math::XYZTLorentzVectorD> p(pos,mom);
88  }
89  }
90 }
91 
92 void SteppingAction::catchLowEnergyInVacuumHere(const G4Step * aStep) {
93  G4Track * theTrack = aStep->GetTrack();
94  double theKenergy = theTrack->GetKineticEnergy();
95  if (theTrack->GetVolume()!=0) {
96  double density = theTrack->GetVolume()->GetLogicalVolume()->GetMaterial()->GetDensity();
97  if (theKenergy <= theCriticalEnergyForVacuum && theKenergy > 0.0 &&
98  density <= theCriticalDensity && theTrack->GetDefinition()->GetPDGCharge() != 0 &&
99  theTrack->GetTrackStatus() != fStopAndKill) {
100  if (verbose>1)
101  edm::LogInfo("SimG4CoreApplication")
102  << " SteppingAction: LoopCatchSteppingAction:catchLowEnergyInVacuumHere: "
103  << " Track from " << theTrack->GetDefinition()->GetParticleName()
104  << " of kinetic energy " << theKenergy/MeV << " MeV "
105  << " killed in " << theTrack->GetVolume()->GetLogicalVolume()->GetName()
106  << " of density " << density/(g/cm3) << " g/cm3" ;
107  theTrack->SetTrackStatus(fStopAndKill);
108  }
109  }
110 }
111 
112 void SteppingAction::catchLowEnergyInVacuumNext(const G4Step * aStep) {
113  G4Track * theTrack = aStep->GetTrack();
114  double theKenergy = theTrack->GetKineticEnergy();
115  if (theTrack->GetNextVolume()) {
116  double density = theTrack->GetNextVolume()->GetLogicalVolume()->GetMaterial()->GetDensity();
117  if (theKenergy <= theCriticalEnergyForVacuum && theKenergy > 0.0 &&
118  density <= theCriticalDensity && theTrack->GetDefinition()->GetPDGCharge() != 0 &&
119  theTrack->GetTrackStatus() != fStopAndKill) {
120  if (verbose>1)
121  edm::LogInfo("SimG4CoreApplication")
122  << " SteppingAction: LoopCatchSteppingAction::catchLowEnergyInVacuumNext: "
123  << " Track from " << theTrack->GetDefinition()->GetParticleName()
124  << " of kinetic energy " << theKenergy/MeV << " MeV "
125  << " stopped in " << theTrack->GetVolume()->GetLogicalVolume()->GetName()
126  << " before going into "<< theTrack->GetNextVolume()->GetLogicalVolume()->GetName()
127  << " of density " << density/(g/cm3) << " g/cm3" ;
128  theTrack->SetTrackStatus(fStopButAlive);
129  }
130  }
131 }
132 
133 bool SteppingAction::catchLongLived(const G4Step * aStep) {
134 
135  bool flag = true;
136  double time = (aStep->GetPostStepPoint()->GetGlobalTime())/nanosecond;
137  double tofM = maxTrackTime;
138  if (maxTimeRegions.size() > 0) {
139  G4Region* reg = aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetRegion();
140  for (unsigned int i=0; i<maxTimeRegions.size(); i++) {
141  if (reg == maxTimeRegions[i]) {
142  tofM = maxTrackTimes[i];
143  break;
144  }
145  }
146  }
147  if (time > tofM) {
148  killTrack(aStep);
149  flag = false;
150  }
151  return flag;
152 }
153 
154 bool SteppingAction::killLowEnergy(const G4Step * aStep) {
155 
156  bool ok = true;
157  if (ekinVolumes.size() > 0) {
158  bool flag = false;
159  G4LogicalVolume* lv = aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume();
160  for (unsigned int i=0; i<ekinVolumes.size(); i++) {
161  if (lv == ekinVolumes[i]) {
162  flag = true;
163  break;
164  }
165  }
166  if (flag) {
167  G4Track * track = aStep->GetTrack();
168  double ekin = track->GetKineticEnergy();
169  double ekinM = 0;
170  int pCode = track->GetDefinition()->GetPDGEncoding();
171  for (unsigned int i=0; i<ekinPDG.size(); i++) {
172  if (pCode == ekinPDG[i]) {
173  ekinM = ekinMins[i];
174  break;
175  }
176  }
177  if (ekin > ekinM) {
178  killTrack(aStep);
179  ok = false;
180  }
181  }
182  }
183  return ok;
184 }
185 
187 
188  bool flag = true;
189  const G4PhysicalVolumeStore * pvs = G4PhysicalVolumeStore::GetInstance();
190  if (pvs) {
191  std::vector<G4VPhysicalVolume*>::const_iterator pvcite;
192  for (pvcite = pvs->begin(); pvcite != pvs->end(); pvcite++) {
193  if ((*pvcite)->GetName() == "Tracker") tracker = (*pvcite);
194  if ((*pvcite)->GetName() == "CALO") calo = (*pvcite);
195  if (tracker && calo) break;
196  }
197  edm::LogInfo("SimG4CoreApplication") << "Pointer for Tracker " << tracker
198  << " and for Calo " << calo;
199  if (tracker) LogDebug("SimG4CoreApplication") << "Tracker vol name "
200  << tracker->GetName();
201  if (calo) LogDebug("SimG4CoreApplication") << "Calorimeter vol name "
202  << calo->GetName();
203  } else {
204  flag = false;
205  }
206 
207  const G4LogicalVolumeStore * lvs = G4LogicalVolumeStore::GetInstance();
208  unsigned int num = ekinNames.size();
209  if (num > 0) {
210  if (lvs) {
211  std::vector<G4LogicalVolume*>::const_iterator lvcite;
212  for (lvcite = lvs->begin(); lvcite != lvs->end(); lvcite++) {
213  for (unsigned int i=0; i<num; i++) {
214  if ((*lvcite)->GetName() == (G4String)(ekinNames[i])) {
215  ekinVolumes.push_back(*lvcite);
216  break;
217  }
218  }
219  if (ekinVolumes.size() == num) break;
220  }
221  }
222  if (ekinVolumes.size() != num) flag = false;
223  for (unsigned int i=0; i<ekinVolumes.size(); i++) {
224  edm::LogInfo("SimG4CoreApplication") << ekinVolumes[i]->GetName()
225  <<" with pointer " <<ekinVolumes[i];
226  }
227  }
228 
229  G4ParticleTable * theParticleTable = G4ParticleTable::GetParticleTable();
230  G4String particleName;
231  for (unsigned int i=0; i<ekinParticles.size(); i++) {
232  int pdg = theParticleTable->FindParticle(particleName=ekinParticles[i])->GetPDGEncoding();
233  ekinPDG.push_back(pdg);
234  edm::LogInfo("SimG4CoreApplication") << "Particle " << ekinParticles[i]
235  << " with code " << ekinPDG[i]
236  << " and KE cut off " << ekinMins[i];
237  }
238  if (!flag) edm::LogInfo("SimG4CoreApplication") << "SteppingAction fails to"
239  << " initialize some the "
240  << "LV pointers correctly";
241 
242  const G4RegionStore * rs = G4RegionStore::GetInstance();
243  num = maxTimeNames.size();
244  if (num > 0) {
245  std::vector<double> tofs;
246  if (rs) {
247  std::vector<G4Region*>::const_iterator rcite;
248  for (rcite = rs->begin(); rcite != rs->end(); rcite++) {
249  for (unsigned int i=0; i<num; i++) {
250  if ((*rcite)->GetName() == (G4String)(maxTimeNames[i])) {
251  maxTimeRegions.push_back(*rcite);
252  tofs.push_back(maxTrackTimes[i]);
253  break;
254  }
255  }
256  if (tofs.size() == num) break;
257  }
258  }
259  for (unsigned int i=0; i<tofs.size(); i++) {
260  maxTrackTimes[i] = tofs[i];
261  G4String name = "Unknown";
262  if (maxTimeRegions[i]) name = maxTimeRegions[i]->GetName();
263  edm::LogInfo("SimG4CoreApplication") << name << " with pointer "
264  << maxTimeRegions[i]<<" KE cut off "
265  << maxTrackTimes[i];
266  }
267  if (tofs.size() != num)
268  edm::LogInfo("SimG4CoreApplication") << "SteppingAction fails to "
269  << "initialize some the region "
270  << "pointers correctly";
271  }
272  return true;
273 }
274 
275 bool SteppingAction::isThisVolume(const G4VTouchable* touch,
276  G4VPhysicalVolume* pv) {
277 
278  int level = ((touch->GetHistoryDepth())+1);
279  if (level > 0 && level >= 3) {
280  unsigned int ii = (unsigned int)(level - 3);
281  return (touch->GetVolume(ii) == pv);
282  }
283  return false;
284 }
285 
286 void SteppingAction::killTrack(const G4Step * aStep) {
287 
288  aStep->GetTrack()->SetTrackStatus(fStopAndKill);
289  G4TrackVector tv = *(aStep->GetSecondary());
290  for (unsigned int kk=0; kk<tv.size(); kk++) {
291  if (tv[kk]->GetVolume() == aStep->GetPreStepPoint()->GetPhysicalVolume())
292  tv[kk]->SetTrackStatus(fStopAndKill);
293  }
294  LogDebug("SimG4CoreApplication") << "SteppingAction: Kills track "
295  << aStep->GetTrack()->GetTrackID() << " ("
296  << aStep->GetTrack()->GetDefinition()->GetParticleName()
297  << ") at " << aStep->GetPostStepPoint()->GetGlobalTime()/nanosecond
298  << " ns in " << aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetName()
299  << " from region " << aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetRegion()->GetName();
300 }
#define LogDebug(id)
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
long int flag
Definition: mlp_lapack.h:47
std::vector< int > ekinPDG
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzE4D< double > > XYZTLorentzVectorD
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:15
double theCriticalDensity
SimActivityRegistry::G4StepSignal m_g4StepSignal
bool catchLongLived(const G4Step *aStep)
G4VPhysicalVolume * calo
bool isThisVolume(const G4VTouchable *touch, G4VPhysicalVolume *pv)
void catchLowEnergyInVacuumHere(const G4Step *aStep)
int ii
Definition: cuy.py:588
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
float float float z
void UserSteppingAction(const G4Step *aStep)
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > XYZVectorD
spatial vector with cartesian internal representation
Definition: Vector3D.h:9
std::vector< double > maxTrackTimes
SteppingAction(EventAction *ea, const edm::ParameterSet &ps)
std::vector< G4LogicalVolume * > ekinVolumes
double theCriticalEnergyForVacuum
static const G4LogicalVolume * GetVolume(const std::string &name)
EventAction * eventAction_
void killTrack(const G4Step *aStep)
std::vector< double > ekinMins
std::vector< std::string > maxTimeNames
std::vector< std::string > ekinNames
long long int num
Definition: procUtils.cc:71
bool killLowEnergy(const G4Step *aStep)
void addTkCaloStateInfo(uint32_t t, const std::pair< math::XYZVectorD, math::XYZTLorentzVectorD > &p)
Definition: EventAction.cc:75
G4VPhysicalVolume * tracker
tuple level
Definition: testEve_cfg.py:34
Definition: DDAxes.h:10
void catchLowEnergyInVacuumNext(const G4Step *aStep)
std::vector< std::string > ekinParticles
std::vector< G4Region * > maxTimeRegions