Optional User Actions
There are five virtual classes whose methods the user may override
in order to gain control of the simulation at various stages. Each
method of each action class has an empty default implementation,
allowing the user to inherit and implement desired classes and
methods. Objects of user action classes must be registered with
G4RunManager.
Usage of User Actions
G4UserRunAction
This class has three virtual methods which are invoked by
G4RunManager for each run:
GenerateRun()
This method is invoked at the beginning of BeamOn.
Because the user can inherit the class G4Run and create
his/her own concrete class to store some information about the run,
the GenerateRun() method is the place to instantiate such
an object. It is also the ideal place to set variables which affect
the physics table (such as production thresholds) for a particular
run, because GenerateRun() is invoked before the
calculation of the physics table.
BeginOfRunAction()
This method is invoked before entering the event loop. A
typical use of this method would be to initialize and/or book
histograms for a particular run. This method is invoked after the
calculation of the physics tables.
EndOfRunAction()
This method is invoked at the very end of the run processing.
It is typically used for a simple analysis of the processed run.
G4UserRunAction
class G4UserRunAction
{
public:
G4UserRunAction();
virtual ~G4UserRunAction();
public:
virtual G4Run* GenerateRun();
virtual void BeginOfRunAction(const G4Run*);
virtual void EndOfRunAction(const G4Run*);
};
G4UserEventAction
This class has two virtual methods which are invoked by
G4EventManager for each event:
beginOfEventAction()
This method is invoked before converting the primary particles
to G4Track objects. A typical use of this method
would be to initialize and/or book histograms for a particular event.
endOfEventAction()
This method is invoked at the very end of event processing. It
is typically used for a simple analysis of the processed event.
If the user wants to keep the currently processing event until the
end of the current run, the user can invoke
fpEventManager->KeepTheCurrentEvent();
so that it is kept in G4Run object. This should
be quite useful if you simulate quite many events and want to
visualize only the most interest ones after the long execution.
Given the memory size of an event and its contents may be large,
it is the user's responsibility not to keep unnecessary events.
G4UserEventAction
class G4UserEventAction
{
public:
G4UserEventAction() {;}
virtual ~G4UserEventAction() {;}
virtual void BeginOfEventAction(const G4Event*);
virtual void EndOfEventAction(const G4Event*);
protected:
G4EventManager* fpEventManager;
};
G4UserStackingAction
This class has three virtual methods, ClassifyNewTrack,
NewStage and PrepareNewEvent which the
user may override in order to control the various track stacking mechanisms.
ExampleN04 could be a good example to understand the usage of this class.
ClassifyNewTrack() is invoked by
G4StackManager whenever a new G4Track
object is "pushed" onto a stack by G4EventManager.
ClassifyNewTrack() returns an enumerator,
G4ClassificationOfNewTrack, whose value indicates to which
stack, if any, the track will be sent. This value should be
determined by the user. G4ClassificationOfNewTrack has
four possible values:
fUrgent - track is placed in the
urgent stack
fWaiting - track is placed in the
waiting stack, and will not be simulated until
the urgent stack is empty
fPostpone - track is postponed to the next event
fKill - the track is deleted immediately and not
stored in any stack.
These assignments may be made based on the origin of the track
which is obtained as follows:
G4int parent_ID = aTrack->get_parentID();
where
parent_ID = 0 indicates a primary particle
parent_ID > 0 indicates a secondary particle
parent_ID < 0 indicates postponed particle from
previous event.
NewStage() is invoked when the urgent
stack is empty and the waiting stack contains at least one
G4Track object. Here the user may kill or re-assign to
different stacks all the tracks in the waiting stack by
calling the stackManager->ReClassify() method which, in
turn, calls the ClassifyNewTrack() method. If no user
action is taken, all tracks in the waiting stack are
transferred to the urgent stack. The user may also decide to
abort the current event even though some tracks may remain in the
waiting stack by calling stackManager->clear().
This method is valid and safe only if it is called from the
G4UserStackingAction class. A global method of event
abortion is
G4UImanager * UImanager = G4UImanager::GetUIpointer();
UImanager->ApplyCommand("/event/abort");
PrepareNewEvent() is invoked at the beginning of each
event. At this point no primary particles have been converted to
tracks, so the urgent and waiting
stacks are empty. However, there may be tracks in the
postponed-to-next-event stack;
for each of these the ClassifyNewTrack() method is
called and the track is assigned to the appropriate stack.
G4UserStackingAction
#include "G4ClassificationOfNewTrack.hh"
class G4UserStackingAction
{
public:
G4UserStackingAction();
virtual ~G4UserStackingAction();
protected:
G4StackManager * stackManager;
public:
//---------------------------------------------------------------
// virtual methods to be implemented by user
//---------------------------------------------------------------
//
virtual G4ClassificationOfNewTrack
ClassifyNewTrack(const G4Track*);
//
//---------------------------------------------------------------
//
virtual void NewStage();
//
//---------------------------------------------------------------
//
virtual void PrepareNewEvent();
//
//---------------------------------------------------------------
};
G4UserTrackingAction
G4UserTrackingAction
//---------------------------------------------------------------
//
// G4UserTrackingAction.hh
//
// Description:
// This class represents actions taken place by the user at each
// end of stepping.
//
//---------------------------------------------------------------
///////////////////////////
class G4UserTrackingAction
///////////////////////////
{
//--------
public:
//--------
// Constructor & Destructor
G4UserTrackingAction(){};
virtual ~G4UserTrackingAction(){}
// Member functions
virtual void PreUserTrackingAction(const G4Track*){}
virtual void PostUserTrackingAction(const G4Track*){}
//-----------
protected:
//-----------
// Member data
G4TrackingManager* fpTrackingManager;
};
G4UserSteppingAction
G4UserSteppingAction
//---------------------------------------------------------------
//
// G4UserSteppingAction.hh
//
// Description:
// This class represents actions taken place by the user at each
// end of stepping.
//
//---------------------------------------------------------------
///////////////////////////
class G4UserSteppingAction
///////////////////////////
{
//--------
public:
//--------
// Constructor and destructor
G4UserSteppingAction(){}
virtual ~G4UserSteppingAction(){}
// Member functions
virtual void UserSteppingAction(const G4Step*){}
//-----------
protected:
//-----------
// Member data
G4SteppingManager* fpSteppingManager;
};
Killing Tracks in User Actions and Energy Conservation
In either of user action classes described in the previous section,
the user can implement an unnatural/unphysical action. A typical
example is to kill a track, which is under the simulation, in the
user stepping action. In this case the user have to be cautious of
the total energy conservation. The user stepping action itself does
not take care the energy or any physics quantity associated with
the killed track. Therefore if the user want to keep the total
energy of an event in this case, the lost track energy need to be
recorded by the user.
The same is true for user stacking or tracking actions. If the
user has killed a track in these actions the all physics information
associated with it would be lost and, for example, the total energy
conservation be broken.
If the user wants the Geant4 kernel to take care the total energy
conservation automatically when he/she has killed artificially
a track, the user has to use a killer process. For example if the
user uses G4UserLimits and G4UserSpecialCuts process, energy of
the killed track is added to the total energy deposit.