Geant4 VMC Version 6.6
Loading...
Searching...
No Matches
TG4SteppingAction.cxx
Go to the documentation of this file.
1//------------------------------------------------
2// The Geant4 Virtual Monte Carlo package
3// Copyright (C) 2007 - 2014 Ivana Hrivnacova
4// All rights reserved.
5//
6// For the licensing terms see geant4_vmc/LICENSE.
7// Contact: root-vmc@cern.ch
8//-------------------------------------------------
9
14
15#include "TG4SteppingAction.h"
16#include "TG4G3Units.h"
17#include "TG4Globals.h"
18#include "TG4Limits.h"
19#include "TG4SDServices.h"
22#include "TG4StackPopper.h"
23#include "TG4StepManager.h"
24#include "TG4TrackInformation.h"
25#include "TG4TrackManager.h"
26#include "TG4TrackingAction.h"
27
28#include <G4EmParameters.hh>
29#include <G4Gamma.hh>
30#include <G4HadronicParameters.hh>
31#include <G4Neutron.hh>
32#include <G4SteppingManager.hh>
33#include <G4Track.hh>
34
35#include <TVirtualMCApplication.h>
36
37// static data members
39
40//_____________________________________________________________________________
43 fMessenger(this),
44 fGeoTrackManager(),
45 fSpecialControls(0),
46 fMCApplication(0),
47 fTrackManager(0),
48 fStepManager(0),
49 fStackPopper(0),
50 fMaxNofSteps(kMaxNofSteps),
51 fStandardVerboseLevel(-1),
52 fLoopVerboseLevel(1),
53 fLoopStepCounter(0),
54 fIsPairCut(false),
55 fCollectTracks(false)
56{
58
59 if (fgInstance) {
60 TG4Globals::Exception("TG4SteppingAction", "TG4SteppingAction",
61 "Cannot create two instances of singleton.");
62 }
63
64 fgInstance = this;
65}
66
67//_____________________________________________________________________________
74
75//
76// private methods
77//
78
79//_____________________________________________________________________________
81{
83
84 G4Track* track = step->GetTrack();
85 G4int stepNumber = track->GetCurrentStepNumber();
86
87 if (fLoopStepCounter) {
88 if (stepNumber == 1) {
89 // reset parameters at beginning of tracking
90 fpSteppingManager->SetVerboseLevel(fStandardVerboseLevel);
92 // necessary in case particle has reached fMaxNofSteps
93 // but has stopped before processing kMaxNofLoopSteps
94 }
95 else {
96 // count steps after detecting looping track
99
100 // stop the looping track
101 track->SetTrackStatus(fStopAndKill);
102
103 // reset parameters back
104 fpSteppingManager->SetVerboseLevel(fStandardVerboseLevel);
106 }
107 }
108 }
109 else if (stepNumber > fMaxNofSteps) {
110
111 // print looping info
112 if (fLoopVerboseLevel > 0) {
113 G4cout << "*** Particle reached max step number (" << fMaxNofSteps
114 << "). ***" << G4endl;
115 if (fStandardVerboseLevel == 0) PrintTrackInfo(track);
116 }
117
118 // keep standard verbose level
119 if (fStandardVerboseLevel < 0)
120 fStandardVerboseLevel = fpSteppingManager->GetverboseLevel();
121
122 // set loop verbose level
123 fpSteppingManager->SetVerboseLevel(fLoopVerboseLevel);
124
125 // start looping counter
127 }
128}
129
130//_____________________________________________________________________________
132{
134
135 G4ThreeVector position = step->GetPostStepPoint()->GetPosition();
136 position /= TG4G3Units::Length();
137
138 if (position.perp() > fMCApplication->TrackingRmax() ||
139 std::abs(position.z()) > fMCApplication->TrackingZmax()) {
140
141 // print looping info
142 if (fLoopVerboseLevel > 0) {
143 G4cout << "*** Particle has reached user defined tracking region. ***"
144 << G4endl;
145 if (fStandardVerboseLevel == 0) PrintTrackInfo(step->GetTrack());
146 }
147
148 // stop the track
149 step->GetTrack()->SetTrackStatus(fStopAndKill);
150 }
151}
152
153//_____________________________________________________________________________
155{
158
159 if (step->GetSecondaryInCurrentStep()->size() == 2 &&
160 ((*step->GetSecondaryInCurrentStep())[0]->GetCreatorProcess()->GetProcessName() ==
161 "muPairProd")) {
162 // Process sub type fPairProdByCharged does distinguish the creator
163 // particle type
164
165 G4double minEtotPair =
167
168 // G4cout << "minEtotPair[GeV]= " << minEtotPair << G4endl;
169
170 if (minEtotPair > 0. && (*step->GetSecondary())[0]->GetTotalEnergy() +
171 (*step->GetSecondary())[1]->GetTotalEnergy() <
172 minEtotPair) {
173 // G4cout << "In stepping action: going to flag pair to stop" << G4endl;
175 fTrackManager->GetTrackInformation((*step->GetSecondary())[0])
176 ->SetStop(true);
177 fTrackManager->GetTrackInformation((*step->GetSecondary())[1])
178 ->SetStop(true);
179 }
180 }
181}
182
183//_____________________________________________________________________________
185{
187
188 // let sensitive detector process boundary step
189 // if crossing geometry border
190 // (this ensures compatibility with G3 that
191 // makes boundary step of zero length)
192 if (step->GetTrack()->GetNextVolume() != 0) {
193
194 // set back max step limit if it has been modified on fly by user
196
197 if (modifiedLimits) {
198 G4UserLimits* nextLimits = step->GetPostStepPoint()
199 ->GetPhysicalVolume()
200 ->GetLogicalVolume()
201 ->GetUserLimits();
202
203 if (nextLimits != modifiedLimits) fStepManager->SetMaxStepBack();
204 }
205
206 if (step->GetTrack()->GetTrackStatus() == fAlive) {
207#ifdef MCDEBUG
210 step->GetPostStepPoint()
211 ->GetPhysicalVolume()
212 ->GetLogicalVolume()
213 ->GetSensitiveDetector());
214
215 if (tsd) tsd->ProcessHitsOnBoundary((G4Step*)step);
216#else
218 (TG4SensitiveDetector*)step->GetPostStepPoint()
219 ->GetPhysicalVolume()
220 ->GetLogicalVolume()
221 ->GetSensitiveDetector();
222
223 if (tsd) tsd->ProcessHitsOnBoundary((G4Step*)step);
224#endif
225 }
226 }
227}
228
229//
230// protected methods
231//
232
233//_____________________________________________________________________________
234void TG4SteppingAction::PrintTrackInfo(const G4Track* track) const
235{
240
241 // print track info
242 G4cout << G4endl;
243 G4cout << "*******************************************************"
244 << "**************************************************" << G4endl;
245 G4cout << "* G4Track Information: "
246 << " Particle = " << track->GetDefinition()->GetParticleName() << ","
247 << " Track ID = " << track->GetTrackID() << ","
248 << " Parent ID = " << track->GetParentID() << G4endl;
249 G4cout << "*******************************************************"
250 << "**************************************************" << G4endl;
251 G4cout << G4endl;
252
253 // print header
254#ifdef G4_USE_G4BESTUNIT_FOR_VERBOSE
255 G4cout << std::setw(5) << "Step#"
256 << " " << std::setw(8) << "X"
257 << " " << std::setw(8) << "Y"
258 << " " << std::setw(8) << "Z"
259 << " " << std::setw(9) << "KineE"
260 << " " << std::setw(8) << "dE"
261 << " " << std::setw(12) << "StepLeng"
262 << " " << std::setw(12) << "TrackLeng"
263 << " " << std::setw(12) << "NextVolume"
264 << " " << std::setw(8) << "ProcName" << G4endl;
265#else
266 G4cout << std::setw(5) << "Step#"
267 << " " << std::setw(8) << "X(mm)"
268 << " " << std::setw(8) << "Y(mm)"
269 << " " << std::setw(8) << "Z(mm)"
270 << " " << std::setw(9) << "KinE(MeV)"
271 << " " << std::setw(8) << "dE(MeV)"
272 << " " << std::setw(8) << "StepLeng"
273 << " " << std::setw(9) << "TrackLeng"
274 << " " << std::setw(11) << "NextVolume"
275 << " " << std::setw(8) << "ProcName" << G4endl;
276#endif
277}
278
279//
280// public methods
281//
282
283//_____________________________________________________________________________
285{
290
291 auto gammaGeneral = G4EmParameters::Instance()->GeneralProcessActive();
292 auto neutronGeneral = G4HadronicParameters::Instance()->EnableNeutronGeneralProcess();
293
294 if ((! gammaGeneral) && (! neutronGeneral)) return;
295
296 auto particle = step->GetTrack()->GetParticleDefinition();
297 auto nofSecondaries = step->GetNumberOfSecondariesInCurrentStep();
298 if (((particle==G4Gamma::GammaDefinition() && gammaGeneral) ||
299 (particle==G4Neutron::NeutronDefinition() && neutronGeneral)) && nofSecondaries>0) {
300 // Get the pointer to the process that limited the step: i.e. the one that
301 // created the secondaries of the current step
302 const G4VProcess* limiterProcess =
303 step->GetPostStepPoint()->GetProcessDefinedStep();
304 // note: this is a vector of secondaries containing all secondaries created
305 // along the tracking of the current `primary` track (i.e. not only
306 // secondaries created in this step)
307 auto secondaries = step->GetSecondary();
308 auto nofAllSecondaries = secondaries ->size();
309 for (auto it = nofAllSecondaries - nofSecondaries; it < nofAllSecondaries; ++it) {
310 auto secTrack = (*secondaries )[it];
311 if (secTrack->GetCreatorProcess() != limiterProcess) {
312 secTrack->SetCreatorProcess(limiterProcess);
313 }
314 }
315 }
316}
317
318//_____________________________________________________________________________
326
327#include "TGeoManager.h"
328#include "TGeoVolume.h"
329
330//_____________________________________________________________________________
332{
337
338 // Fix creator process for secondaries if using gamma or neutron general process
340
341 // stop track if maximum number of steps has been reached
343
344 /*
345 // TO BE REMOVED
346 G4LogicalVolume* currLV
347 = step->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume();
348
349 G4UserLimits* limits
350 = currLV->GetUserLimits();
351
352 if ( ! limits ) {
353 TGeoVolume* tgeoLV = gGeoManager->FindVolumeFast(currLV->GetName());
354
355 G4cout << "No limits in " << currLV->GetName()
356 << " TGeo volume " << tgeoLV << " with medium ";
357 if ( tgeoLV )
358 G4cout << tgeoLV->GetMedium() << G4endl;
359 else
360 G4cout << "-" << G4endl;
361 }
362 // END TO BE REMOVED
363 */
364
365 // stop track if a user defined tracking region has been reached
367
368 // flag e+e- secondary pair for stop if its energy is below user cut
370
371 // update Root track if collecting tracks is activated
373
374 // save secondaries
376 fTrackManager->SaveSecondaries(step->GetTrack(), step->GetSecondary());
377 }
378
379 // apply special controls if init step or if crossing geometry border
380 if (step->GetPostStepPoint()->GetStepStatus() == fGeomBoundary &&
382
384 }
385
386 // call stepping action of derived class
387 SteppingAction(step);
388
389 // actions on the boundary
390 if (step->GetPostStepPoint()->GetStepStatus() == fGeomBoundary) {
392 }
393
394 // Force an exclusive stackPopper step if track is not alive and
395 // there are user tracks popped in the VMC stack
396 if (fStackPopper && step->GetTrack()->GetTrackStatus() != fAlive &&
397 step->GetTrack()->GetTrackStatus() != fSuspend &&
399
400 // G4cout << "!!! Modifying track status to get processed user tracks."
401 // << G4endl;
402 fStackPopper->SetDoExclusiveStep(step->GetTrack()->GetTrackStatus());
403 G4Track* track = const_cast<G4Track*>(step->GetTrack());
404 // track->SetTrackStatus(fStopButAlive);
405 track->SetTrackStatus(fAlive);
406 }
407}
Definition of the TG4G3Units class.
Definition of the TG4Globals class and basic container types.
Definition of the TG4Limits class.
Definition of the TG4SDServices class.
Definition of the TG4SensitiveDetector class.
Definition of the TG4SpecialControlsV2 class.
Definition of the TG4StackPopper class.
Definition of the TG4StepManager class.
Definition of the TG4SteppingAction class.
Definition of the TG4TrackInformation class.
Definition of the TG4TrackManager class.
Definition of the TG4TrackingAction class.
G4double GetMinEtotPair() const
static G4double Length()
Definition TG4G3Units.h:81
void UpdateRootTrack(const G4Step *step)
static void Exception(const TString &className, const TString &methodName, const TString &text)
const TG4G3CutVector * GetCutVector() const
Definition TG4Limits.h:141
TG4SensitiveDetector * GetSensitiveDetector(G4VSensitiveDetector *sd) const
static TG4SDServices * Instance()
Sensitive detector class for calling a user defined stepping function.
virtual G4bool ProcessHitsOnBoundary(G4Step *step)
G4bool HasPoppedTracks() const
void SetDoExclusiveStep(G4TrackStatus trackStatus)
static TG4StackPopper * Instance()
TG4Limits * GetCurrentLimits() const
static TG4StepManager * Instance()
TG4Limits * GetLimitsModifiedOnFly() const
Actions at each step.
void ProcessTrackIfOutOfRegion(const G4Step *step)
static G4ThreadLocal TG4SteppingAction * fgInstance
this instance
G4int fStandardVerboseLevel
standard tracking verbose level
TG4SpecialControlsV2 * fSpecialControls
the special controls manager
void ProcessTrackIfBelowCut(const G4Step *step)
G4bool fIsPairCut
control of cut on e+e- pair
G4int fLoopStepCounter
counter of step in looping
virtual void UserSteppingAction(const G4Step *step)
TG4StepManager * fStepManager
Cached pointer to thread-local step manager.
virtual void SteppingAction(const G4Step *step)
void PrintTrackInfo(const G4Track *track) const
G4int fMaxNofSteps
max number of allowed steps
void ProcessTrackIfLooping(const G4Step *step)
void ProcessTrackIfGeneralProcess(const G4Step *step)
TG4StackPopper * fStackPopper
Cached pointer to thread-local stack popper.
TG4GeoTrackManager fGeoTrackManager
manager for collecting TGeo tracks
G4bool fCollectTracks
control to collect Root tracks
TVirtualMCApplication * fMCApplication
Cached pointer to thread-local VMC application.
void ProcessTrackOnBoundary(const G4Step *step)
G4int fLoopVerboseLevel
tracking verbose level for looping particles
TG4TrackManager * fTrackManager
Cached pointer to thread-local track manager.
void SetStop(G4bool stop)
void SaveSecondaries(const G4Track *track, const G4TrackVector *secondaries)
TG4TrackSaveControl GetTrackSaveControl() const
static TG4TrackManager * Instance()
TG4TrackInformation * GetTrackInformation(const G4Track *track) const
void SetParentToTrackInformation(const G4Track *aTrack)
@ kSaveInStep
save in step
@ fStackPopper