CMS 3D CMS Logo

SteppingAction.cc
Go to the documentation of this file.
1 
5 
6 #include "G4LogicalVolumeStore.hh"
7 #include "G4ParticleTable.hh"
8 #include "G4PhysicalVolumeStore.hh"
9 #include "G4RegionStore.hh"
10 #include "G4UnitsTable.hh"
11 #include "G4SystemOfUnits.hh"
12 
15 
16 //#define DebugLog
17 
19  : eventAction_(e),
20  tracker(nullptr),
21  calo(nullptr),
22  steppingVerbose(sv),
23  nWarnings(0),
24  initialized(false),
25  killBeamPipe(false),
26  hasWatcher(hasW) {
27  theCriticalEnergyForVacuum = (p.getParameter<double>("CriticalEnergyForVacuum") * CLHEP::MeV);
28  if (0.0 < theCriticalEnergyForVacuum) {
29  killBeamPipe = true;
30  }
31  theCriticalDensity = (p.getParameter<double>("CriticalDensity") * CLHEP::g / CLHEP::cm3);
32  maxZCentralCMS = p.getParameter<double>("MaxZCentralCMS") * CLHEP::m;
33  maxTrackTime = p.getParameter<double>("MaxTrackTime") * CLHEP::ns;
34  maxTrackTimeForward = p.getParameter<double>("MaxTrackTimeForward") * CLHEP::ns;
35  maxTrackTimes = p.getParameter<std::vector<double> >("MaxTrackTimes");
36  maxTimeNames = p.getParameter<std::vector<std::string> >("MaxTimeNames");
37  deadRegionNames = p.getParameter<std::vector<std::string> >("DeadRegions");
38  ekinMins = p.getParameter<std::vector<double> >("EkinThresholds");
39  ekinNames = p.getParameter<std::vector<std::string> >("EkinNames");
40  ekinParticles = p.getParameter<std::vector<std::string> >("EkinParticles");
41 
42  edm::LogVerbatim("SimG4CoreApplication")
43  << "SteppingAction:: KillBeamPipe = " << killBeamPipe
44  << " CriticalDensity = " << theCriticalDensity * CLHEP::cm3 / CLHEP::g << " g/cm3\n"
45  << " CriticalEnergyForVacuum = " << theCriticalEnergyForVacuum / CLHEP::MeV << " Mev;"
46  << " MaxTrackTime = " << maxTrackTime / CLHEP::ns << " ns;"
47  << " MaxZCentralCMS = " << maxZCentralCMS / CLHEP::m << " m"
48  << " MaxTrackTimeForward = " << maxTrackTimeForward / CLHEP::ns << " ns";
49 
50  numberTimes = maxTrackTimes.size();
51  if (numberTimes > 0) {
52  for (unsigned int i = 0; i < numberTimes; i++) {
53  edm::LogVerbatim("SimG4CoreApplication")
54  << "SteppingAction::MaxTrackTime for " << maxTimeNames[i] << " is " << maxTrackTimes[i] << " ns ";
55  maxTrackTimes[i] *= ns;
56  }
57  }
58 
60  if (ndeadRegions > 0) {
61  edm::LogVerbatim("SimG4CoreApplication")
62  << "SteppingAction: Number of DeadRegions where all trackes are killed " << ndeadRegions;
63  for (unsigned int i = 0; i < ndeadRegions; ++i) {
64  edm::LogVerbatim("SimG4CoreApplication") << "SteppingAction: DeadRegion " << i << ". " << deadRegionNames[i];
65  }
66  }
67  numberEkins = ekinNames.size();
68  numberPart = ekinParticles.size();
69  if (0 == numberPart) {
70  numberEkins = 0;
71  }
72 
73  if (numberEkins > 0) {
74  edm::LogVerbatim("SimG4CoreApplication")
75  << "SteppingAction::Kill following " << numberPart << " particles in " << numberEkins << " volumes";
76  for (unsigned int i = 0; i < numberPart; ++i) {
77  edm::LogVerbatim("SimG4CoreApplication")
78  << "SteppingAction::Particle " << i << " " << ekinParticles[i] << " Threshold = " << ekinMins[i] << " MeV";
79  ekinMins[i] *= CLHEP::MeV;
80  }
81  for (unsigned int i = 0; i < numberEkins; ++i) {
82  edm::LogVerbatim("SimG4CoreApplication") << "SteppingAction::LogVolume[" << i << "] = " << ekinNames[i];
83  }
84  }
85 }
86 
88 
89 void SteppingAction::UserSteppingAction(const G4Step* aStep) {
90  if (!initialized) {
92  }
93 
94  //if(hasWatcher) { m_g4StepSignal(aStep); }
95  m_g4StepSignal(aStep);
96 
97  G4Track* theTrack = aStep->GetTrack();
98  TrackStatus tstat = (theTrack->GetTrackStatus() == fAlive) ? sAlive : sKilledByProcess;
99 
100  const G4StepPoint* preStep = aStep->GetPreStepPoint();
101  const G4StepPoint* postStep = aStep->GetPostStepPoint();
102 
103  // NaN energy deposit
104  if (sAlive == tstat && edm::isNotFinite(aStep->GetTotalEnergyDeposit())) {
105  tstat = sEnergyDepNaN;
106  if (nWarnings < 20) {
107  ++nWarnings;
108  edm::LogWarning("SimG4CoreApplication")
109  << "Track #" << theTrack->GetTrackID() << " " << theTrack->GetDefinition()->GetParticleName()
110  << " E(MeV)= " << preStep->GetKineticEnergy() / MeV
111  << " is killed due to edep=NaN inside PV: " << preStep->GetPhysicalVolume()->GetName() << " at "
112  << theTrack->GetPosition() << " StepLen(mm)= " << aStep->GetStepLength();
113  }
114  }
115 
116  // check Z-coordinate
117  if (sAlive == tstat && std::abs(theTrack->GetPosition().z()) >= maxZCentralCMS) {
118  tstat = (theTrack->GetGlobalTime() > maxTrackTimeForward) ? sOutOfTime : sVeryForward;
119  }
120 
121  // check G4Region
122  if (sAlive == tstat && postStep->GetPhysicalVolume() != nullptr) {
123  const G4Region* theRegion = preStep->GetPhysicalVolume()->GetLogicalVolume()->GetRegion();
124 
125  // kill in dead regions
126  if (isInsideDeadRegion(theRegion)) {
127  tstat = sDeadRegion;
128  }
129 
130  // kill out of time
131  if (sAlive == tstat && isOutOfTimeWindow(theTrack, theRegion)) {
132  tstat = sOutOfTime;
133  }
134 
135  // kill low-energy in volumes on demand
136  if (sAlive == tstat && numberEkins > 0 && isLowEnergy(aStep)) {
137  tstat = sLowEnergy;
138  }
139 
140  // kill low-energy in vacuum
141  G4double kinEnergy = theTrack->GetKineticEnergy();
142  if (sAlive == tstat && killBeamPipe && kinEnergy < theCriticalEnergyForVacuum &&
143  theTrack->GetDefinition()->GetPDGCharge() != 0.0 && kinEnergy > 0.0 &&
144  theTrack->GetNextVolume()->GetLogicalVolume()->GetMaterial()->GetDensity() <= theCriticalDensity) {
145  tstat = sLowEnergyInVacuum;
146  }
147 
148  // check transition tracker/calo
149  if (sAlive == tstat || sVeryForward == tstat) {
150  if (isThisVolume(preStep->GetTouchable(), tracker) && isThisVolume(postStep->GetTouchable(), calo)) {
151  math::XYZVectorD pos((preStep->GetPosition()).x(), (preStep->GetPosition()).y(), (preStep->GetPosition()).z());
152 
153  math::XYZTLorentzVectorD mom((preStep->GetMomentum()).x(),
154  (preStep->GetMomentum()).y(),
155  (preStep->GetMomentum()).z(),
156  preStep->GetTotalEnergy());
157 
158  uint32_t id = theTrack->GetTrackID();
159 
160  std::pair<math::XYZVectorD, math::XYZTLorentzVectorD> p(pos, mom);
162  }
163  } else {
164  theTrack->SetTrackStatus(fStopAndKill);
165 #ifdef DebugLog
166  PrintKilledTrack(theTrack, tstat);
167 #endif
168  }
169  }
170  if (nullptr != steppingVerbose) {
171  steppingVerbose->NextStep(aStep, fpSteppingManager, (1 < tstat));
172  }
173 }
174 
175 bool SteppingAction::isLowEnergy(const G4Step* aStep) const {
176  const G4StepPoint* sp = aStep->GetPostStepPoint();
177  const G4LogicalVolume* lv = sp->GetPhysicalVolume()->GetLogicalVolume();
178  double ekin = sp->GetKineticEnergy();
179  int pCode = aStep->GetTrack()->GetDefinition()->GetPDGEncoding();
180 
181  for (auto& vol : ekinVolumes) {
182  if (lv == vol) {
183  for (unsigned int i = 0; i < numberPart; ++i) {
184  if (pCode == ekinPDG[i]) {
185  return (ekin <= ekinMins[i]);
186  }
187  }
188  break;
189  }
190  }
191  return false;
192 }
193 
195  const G4PhysicalVolumeStore* pvs = G4PhysicalVolumeStore::GetInstance();
196  if (pvs) {
197  std::vector<G4VPhysicalVolume*>::const_iterator pvcite;
198  for (pvcite = pvs->begin(); pvcite != pvs->end(); ++pvcite) {
199  if ((*pvcite)->GetName() == "Tracker")
200  tracker = (*pvcite);
201  if ((*pvcite)->GetName() == "CALO")
202  calo = (*pvcite);
203  if (tracker && calo)
204  break;
205  }
206  if (tracker || calo) {
207  edm::LogVerbatim("SimG4CoreApplication") << "Pointer for Tracker " << tracker << " and for Calo " << calo;
208  if (tracker)
209  LogDebug("SimG4CoreApplication") << "Tracker vol name " << tracker->GetName();
210  if (calo)
211  LogDebug("SimG4CoreApplication") << "Calorimeter vol name " << calo->GetName();
212  }
213  }
214 
215  const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
216  if (numberEkins > 0) {
217  if (lvs) {
218  ekinVolumes.resize(numberEkins, nullptr);
219  std::vector<G4LogicalVolume*>::const_iterator lvcite;
220  for (lvcite = lvs->begin(); lvcite != lvs->end(); ++lvcite) {
221  for (unsigned int i = 0; i < numberEkins; ++i) {
222  if ((*lvcite)->GetName() == (G4String)(ekinNames[i])) {
223  ekinVolumes[i] = (*lvcite);
224  break;
225  }
226  }
227  }
228  }
229  for (unsigned int i = 0; i < numberEkins; ++i) {
230  edm::LogVerbatim("SimG4CoreApplication") << ekinVolumes[i]->GetName() << " with pointer " << ekinVolumes[i];
231  }
232  }
233 
234  if (numberPart > 0) {
235  G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
236  G4String partName;
237  ekinPDG.resize(numberPart, 0);
238  for (unsigned int i = 0; i < numberPart; ++i) {
239  ekinPDG[i] = theParticleTable->FindParticle(partName = ekinParticles[i])->GetPDGEncoding();
240  edm::LogVerbatim("SimG4CoreApplication") << "Particle " << ekinParticles[i] << " with PDG code " << ekinPDG[i]
241  << " and KE cut off " << ekinMins[i] / MeV << " MeV";
242  }
243  }
244 
245  const G4RegionStore* rs = G4RegionStore::GetInstance();
246  if (numberTimes > 0) {
247  maxTimeRegions.resize(numberTimes, nullptr);
248  std::vector<G4Region*>::const_iterator rcite;
249  for (rcite = rs->begin(); rcite != rs->end(); ++rcite) {
250  for (unsigned int i = 0; i < numberTimes; ++i) {
251  if ((*rcite)->GetName() == (G4String)(maxTimeNames[i])) {
252  maxTimeRegions[i] = (*rcite);
253  break;
254  }
255  }
256  }
257  }
258  if (ndeadRegions > 0) {
259  deadRegions.resize(ndeadRegions, nullptr);
260  std::vector<G4Region*>::const_iterator rcite;
261  for (rcite = rs->begin(); rcite != rs->end(); ++rcite) {
262  for (unsigned int i = 0; i < ndeadRegions; ++i) {
263  if ((*rcite)->GetName() == (G4String)(deadRegionNames[i])) {
264  deadRegions[i] = (*rcite);
265  break;
266  }
267  }
268  }
269  }
270  return true;
271 }
272 
273 void SteppingAction::PrintKilledTrack(const G4Track* aTrack, const TrackStatus& tst) const {
274  std::string vname = "";
275  std::string rname = "";
276  std::string typ = " ";
277  switch (tst) {
278  case sKilledByProcess:
279  typ = " G4Process ";
280  break;
281  case sDeadRegion:
282  typ = " in dead region ";
283  break;
284  case sOutOfTime:
285  typ = " out of time window ";
286  break;
287  case sLowEnergy:
288  typ = " low energy limit ";
289  break;
290  case sLowEnergyInVacuum:
291  typ = " low energy limit in vacuum ";
292  break;
293  case sEnergyDepNaN:
294  typ = " energy deposition is NaN ";
295  break;
296  case sVeryForward:
297  typ = " very forward track ";
298  break;
299  default:
300  break;
301  }
302  G4VPhysicalVolume* pv = aTrack->GetNextVolume();
303  if (pv) {
304  vname = pv->GetLogicalVolume()->GetName();
305  rname = pv->GetLogicalVolume()->GetRegion()->GetName();
306  }
307 
308  edm::LogVerbatim("SimG4CoreApplication")
309  << "Track #" << aTrack->GetTrackID() << " " << aTrack->GetDefinition()->GetParticleName()
310  << " E(MeV)= " << aTrack->GetKineticEnergy() / MeV << " T(ns)= " << aTrack->GetGlobalTime() / ns
311  << " is killed due to " << typ << " inside LV: " << vname << " (" << rname << ") at " << aTrack->GetPosition();
312 }
SteppingAction::maxTimeNames
std::vector< std::string > maxTimeNames
Definition: SteppingAction.h:59
DDAxes::y
SteppingAction::theCriticalDensity
double theCriticalDensity
Definition: SteppingAction.h:54
mps_fire.i
i
Definition: mps_fire.py:428
MessageLogger.h
SteppingAction.h
EventAction
Definition: EventAction.h:23
funct::false
false
Definition: Factorize.h:29
SteppingAction::tracker
const G4VPhysicalVolume * tracker
Definition: SteppingAction.h:51
SteppingAction::killBeamPipe
bool killBeamPipe
Definition: SteppingAction.h:72
edm::isNotFinite
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
SteppingAction::isLowEnergy
bool isLowEnergy(const G4Step *aStep) const
Definition: SteppingAction.cc:175
SteppingAction::isOutOfTimeWindow
bool isOutOfTimeWindow(const G4Track *theTrack, const G4Region *reg) const
Definition: SteppingAction.h:87
SteppingAction::maxZCentralCMS
double maxZCentralCMS
Definition: SteppingAction.h:57
CMSSteppingVerbose::NextStep
void NextStep(const G4Step *, const G4SteppingManager *ptr, bool isKilled) const
Definition: CMSSteppingVerbose.cc:156
AlCaHLTBitMon_ParallelJobs.p
p
Definition: AlCaHLTBitMon_ParallelJobs.py:153
math::XYZTLorentzVectorD
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzE4D< double > > XYZTLorentzVectorD
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:14
pos
Definition: PixelAliasList.h:18
SteppingAction::numberPart
unsigned int numberPart
Definition: SteppingAction.h:67
sAlive
Definition: SteppingAction.h:21
EventAction.h
MeV
const double MeV
SteppingAction::maxTrackTime
double maxTrackTime
Definition: SteppingAction.h:55
SteppingAction::deadRegionNames
std::vector< std::string > deadRegionNames
Definition: SteppingAction.h:60
CMSSteppingVerbose
Definition: CMSSteppingVerbose.h:25
sKilledByProcess
Definition: SteppingAction.h:22
DDAxes::x
sLowEnergyInVacuum
Definition: SteppingAction.h:26
SteppingAction::initPointer
bool initPointer()
Definition: SteppingAction.cc:194
edm::LogWarning
Log< level::Warning, false > LogWarning
Definition: MessageLogger.h:122
SteppingAction::ekinParticles
std::vector< std::string > ekinParticles
Definition: SteppingAction.h:59
TrackStatus
TrackStatus
Definition: SteppingAction.h:20
SteppingAction::maxTimeRegions
std::vector< const G4Region * > maxTimeRegions
Definition: SteppingAction.h:61
SteppingAction::ekinNames
std::vector< std::string > ekinNames
Definition: SteppingAction.h:59
SteppingAction::theCriticalEnergyForVacuum
double theCriticalEnergyForVacuum
Definition: SteppingAction.h:53
sOutOfTime
Definition: SteppingAction.h:24
visualization-live-secondInstance_cfg.m
m
Definition: visualization-live-secondInstance_cfg.py:72
SteppingAction::initialized
bool initialized
Definition: SteppingAction.h:71
pfDeepBoostedJetPreprocessParams_cfi.sv
sv
Definition: pfDeepBoostedJetPreprocessParams_cfi.py:352
DDAxes::z
SteppingAction::maxTrackTimeForward
double maxTrackTimeForward
Definition: SteppingAction.h:56
SteppingAction::PrintKilledTrack
void PrintKilledTrack(const G4Track *, const TrackStatus &) const
Definition: SteppingAction.cc:273
SteppingAction::isInsideDeadRegion
bool isInsideDeadRegion(const G4Region *reg) const
Definition: SteppingAction.h:76
SteppingAction::numberTimes
unsigned int numberTimes
Definition: SteppingAction.h:65
AlCaHLTBitMon_QueryRunRegistry.string
string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
SteppingAction::steppingVerbose
const CMSSteppingVerbose * steppingVerbose
Definition: SteppingAction.h:52
math::XYZVectorD
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > XYZVectorD
spatial vector with cartesian internal representation
Definition: Vector3D.h:8
sDeadRegion
Definition: SteppingAction.h:23
PbPb_ZMuSkimMuonDPG_cff.tracker
tracker
Definition: PbPb_ZMuSkimMuonDPG_cff.py:60
SteppingAction::maxTrackTimes
std::vector< double > maxTrackTimes
Definition: SteppingAction.h:58
LogDebug
#define LogDebug(id)
Definition: MessageLogger.h:223
edm::ParameterSet
Definition: ParameterSet.h:47
rname
const G4String rname[NREG]
Definition: ParametrisedEMPhysics.cc:48
SteppingAction::ndeadRegions
unsigned int ndeadRegions
Definition: SteppingAction.h:68
SteppingAction::calo
const G4VPhysicalVolume * calo
Definition: SteppingAction.h:51
MetAnalyzer.pv
def pv(vc)
Definition: MetAnalyzer.py:7
SteppingAction::UserSteppingAction
void UserSteppingAction(const G4Step *aStep) final
Definition: SteppingAction.cc:89
SteppingAction::ekinMins
std::vector< double > ekinMins
Definition: SteppingAction.h:58
SteppingAction::~SteppingAction
~SteppingAction() override
Definition: SteppingAction.cc:87
FSQDQM_cfi.pvs
pvs
Definition: FSQDQM_cfi.py:12
SteppingAction::isThisVolume
bool isThisVolume(const G4VTouchable *touch, const G4VPhysicalVolume *pv) const
Definition: SteppingAction.h:98
sEnergyDepNaN
Definition: SteppingAction.h:27
SteppingAction::ekinVolumes
std::vector< G4LogicalVolume * > ekinVolumes
Definition: SteppingAction.h:63
SteppingAction::m_g4StepSignal
SimActivityRegistry::G4StepSignal m_g4StepSignal
Definition: SteppingAction.h:38
SteppingAction::eventAction_
EventAction * eventAction_
Definition: SteppingAction.h:50
CMSSteppingVerbose.h
isFinite.h
EventAction::addTkCaloStateInfo
void addTkCaloStateInfo(uint32_t t, const std::pair< math::XYZVectorD, math::XYZTLorentzVectorD > &p)
Definition: EventAction.cc:72
edm::LogVerbatim
Log< level::Info, true > LogVerbatim
Definition: MessageLogger.h:128
sLowEnergy
Definition: SteppingAction.h:25
SteppingAction::ekinPDG
std::vector< int > ekinPDG
Definition: SteppingAction.h:64
funct::abs
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
SteppingAction::SteppingAction
SteppingAction(EventAction *ea, const edm::ParameterSet &ps, const CMSSteppingVerbose *, bool hasW)
Definition: SteppingAction.cc:18
calo
Definition: Common.h:9
SteppingAction::deadRegions
std::vector< const G4Region * > deadRegions
Definition: SteppingAction.h:62
sVeryForward
Definition: SteppingAction.h:28
SteppingAction::numberEkins
unsigned int numberEkins
Definition: SteppingAction.h:66
SteppingAction::nWarnings
unsigned int nWarnings
Definition: SteppingAction.h:69
g
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
MillePedeFileConverter_cfg.e
e
Definition: MillePedeFileConverter_cfg.py:37