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