Run¶
Basic concept of Run¶
In Geant4, Run is the largest unit of simulation. A run consists of a
sequence of events. Within a run, the detector geometry, the set up of
sensitive detectors, and the physics processes used in the simulation
should be kept unchanged. A run is represented by a G4Run
class
object. A run starts with BeamOn()
method of G4RunManager
.
Representation of a run¶
G4Run
represents a run. It has a run identification number, which
should be set by the user, and the number of events simulated during the
run. Please note that the run identification number is not used by the
Geant4 kernel, and thus can be arbitrarily assigned at the user’s
convenience.
G4Run
has pointers to the tables G4VHitsCollection
and
G4VDigiCollection
. These tables are associated in case sensitive
detectors and digitizer modules are simulated, respectively. The
usage of these tables will be mentioned in Hits and
Digitization.
G4Run
has two virtual methods, and thus you can extend G4Run
class. In particular if you use Geant4 in multi-threaded mode and need
to accumulate values, these two virtual method must be overwritten to
specify how such values should be collected firstly for a worker thread,
and then for the entire run. These virtual methods are the following.
virtual void RecordEvent(const G4Event*)
Method to be overwritten by the user for recording events in this (thread-local) run. At the end of the implementation, G4Run base-class method for must be invoked for recording data members in the base class.
void Merge(const G4Run*)
Method to be overwritten by the user for merging local Run object to the global Run object. At the end of the implementation, G4Run base-class method for must be invoked for merging data members in the base class.
Manage the run procedures¶
G4RunManager
manages the procedures of a run. In the constructor of
G4RunManager
, all of the manager classes in Geant4 kernel, except
for some static managers, are constructed. These managers are deleted in
the destructor of G4RunManager
. G4RunManager
must be a singleton
created in the user’s main()
program; the pointer to this singleton
object can be obtained by other code using the GetRunManager()
static method.
As already mentioned in How to Define the main() Program, all of the user
initialization classes defined by the user should be assigned to
G4RunManager
before starting initialization of the Geant4 kernel.
The assignments of these user classes are done by
SetUserInitialization()
methods. All user classes defined by the
Geant4 kernel will be summarized in User Actions.
G4RunManager
has several public methods, which are listed below.
Initialize()
All initializations required by the Geant4 kernel are triggered by this method. Initializations are:
construction of the detector geometry and set up of sensitive detectors and/or digitizer modules,
construction of particles and physics processes,
calculation of cross-section tables.
This method is thus mandatory before proceeding to the first run. This method will be invoked automatically for the second and later runs in case some of the initialized quantities need to be updated.
BeamOn(G4int numberOfEvent)
This method triggers the actual simulation of a run, that is, an event loop. It takes an integer argument which represents the number of events to be simulated.
GetRunManager()
This static method returns the pointer to the G4RunManager singleton object.
GetCurrentEvent()
This method returns the pointer to the G4Event object which is currently being simulated. This method is available only when an event is being processed. At this moment, the application state of Geant4, which is explained in the following sub-section, is “EventProc”. When Geant4 is in a state other than “EventProc”, this method returns null. Please note that the return value of this method is const G4Event * and thus you cannot modify the contents of the object.
SetNumberOfEventsToBeStored(G4int nPrevious)
When simulating the “pile up” of more than one event, it is essential to access more than one event at the same moment. By invoking this method, G4RunManager keeps nPrevious G4Event objects. This method must be invoked before proceeding to BeamOn().
GetPreviousEvent(G4int i_thPrevious)
The pointer to the i_thPrevious G4Event object can be obtained through this method. A pointer to a const object is returned. It is inevitable that i_thPrevious events must have already been simulated in the same run for getting the i_thPrevious event. Otherwise, this method returns null.
AbortRun()
This method should be invoked whenever the processing of a run must be stopped. It is valid for GeomClosed and EventProc states. Run processing will be safely aborted even in the midst of processing an event. However, the last event of the aborted run will be incomplete and should not be used for further analysis.
Run manager classes for multi-threading mode¶
G4MTRunManager
is the replacement of G4RunManager
for
multi-threading mode. At the very end of Initialize()
method,
G4MTRunManager
creates and starts worker threads. The event each
thread is tasked is in first-come-first-served basis, so that event
numbers each thread has are not sequential.
G4WorkerRunManager
is the local RunManager automatically
instantiated by G4MTRunManager
to take care of initialization and
event handling of a thread. Both G4MTRunManager
and
G4WorkerRunManager
are derived classes of G4RunManager
base
class.
The static method G4RunManager::GetRunManager()
returns the
following pointer.
It returns the pointer to the
G4WorkerRunManager
of the local thread when it is invoked from thread-local object.It returns the pointer to the
G4MTRunManager
when it is invoked from shared object.It returns the pointer to the base
G4RunManager
if it is used in the sequential mode.
G4RunManager
has a method GetRunManagerType()
that returns an
enum named RMType
to indicate what kind of RunManager
it is.
RMType
is defined as { sequentialRM, masterRM, workerRM }
. From
the thread-local object, a static method
G4MTRunManager::GetMasterRunManager()
is available to access to
G4MTRunManager
. From a worker thread, the user may access to, for
example, detector construction (it is a shared class) through this
GetMasterRunManager()
method.
G4UserRunAction
¶
G4UserRunAction
is one of the user action classes from which you
can derive your own concrete class. This base class has three virtual
methods as follows:
GenerateRun()
This method is invoked at the beginning of the BeamOn() method but after confirmation of the conditions of the Geant4 kernel. This method should be used to instantiate a user-specific run class object.
BeginOfRunAction()
This method is invoked at the beginning of the BeamOn() method but after confirmation of the conditions of the Geant4 kernel. Likely uses of this method include:
setting a run identification number,
booking histograms,
setting run specific conditions of the sensitive detectors and/or digitizer modules (e.g., dead channels).
EndOfRunAction()
This method is invoked at the very end of the BeamOn() method. Typical use cases of this method are
store/print histograms,
manipulate run summaries.
Geant4 as a state machine¶
Geant4 is designed as a state machine. Some methods in Geant4 are
available for only a certain state(s). G4RunManager
controls the
state changes of the Geant4 application. States of Geant4 are
represented by the enumeration G4ApplicationState
. It has six states
through the life cycle of a Geant4 application.
G4State_PreInit
stateA Geant4 application starts with this state. The application needs to be initialized when it is in this state. The application occasionally comes back to this state if geometry, physics processes, and/or cut-off have been changed after processing a run.
G4State_Init
stateThe application is in this state while the Initialize() method of G4RunManager is being invoked. Methods defined in any user initialization classes are invoked during this state.
G4State_Idle
stateThe application is ready for starting a run.
G4State_GeomClosed
stateWhen BeamOn() is invoked, the application proceeds to this state to process a run. Geometry, physics processes, and cut-off cannot be changed during run processing.
G4State_EventProc
stateA Geant4 application is in this state when a particular event is being processed. GetCurrentEvent() and GetPreviousEvent() methods of G4RunManager are available only at this state.
G4State_Quit
stateWhen the destructor of G4RunManager is invoked, the application comes to this “dead end” state. Managers of the Geant4 kernel are being deleted and thus the application cannot come back to any other state.
G4State_Abort
stateWhen a G4Exception occurs, the application comes to this “dead end” state and causes a core dump. The user still has a hook to do some “safe” operations, e.g. storing histograms, by implementing a user concrete class of G4VStateDependent. The user also has a choice to suppress the occurrence of G4Exception by a UI command /control/suppressAbortion. When abortion is suppressed, you will still get error messages issued by G4Exception, and there is NO guarantee of a correct result after the G4Exception error message.
G4StateManager
belongs to the intercoms category.
User’s hook for state change¶
In case the user wants to do something at the moment of state change of
Geant4, the user can create a concrete class of the
G4VStateDependent
base class. For example, the user can store
histograms when G4Exception occurs and Geant4 comes to the Abort
state, but before the actual core dump.
The following is an example user code which stores histograms when
Geant4 becomes to the Abort state. This class object should be made
in, for example main()
, by the user code. This object will be
automatically registered to G4StateManager
at its construction.
#ifndef UserHookForAbortState_H
#define UserHookForAbortState_H 1
#include "G4VStateDependent.hh"
class UserHookForAbortState : public G4VStateDependent
{
public:
UserHookForAbortState(); // constructor
~UserHookForAbortState(); // destructor
virtual G4bool Notify(G4ApplicationState requiredState);
};
#include "UserHookForAbortState.hh"
UserHookForAbortState::UserHookForAbortState() {;}
UserHookForAbortState::~UserHookForAbortState() {;}
G4bool UserHookForAbortState::Notify(G4ApplicationState requiredState)
{
if(requiredState!=Abort) return true;
// Do book keeping here
return true;
}
Customizing the Run Manager¶
Virtual Methods in the Run Manager¶
G4RunManager
is a concrete class with a complete set of
functionalities for managing the Geant4 kernel. It is the only manager
class in the Geant4 kernel which must be constructed in the main()
method of the user’s application. Thus, instead of constructing the
G4RunManager
provided by Geant4, you are free to construct your own
RunManager
. It is recommended, however, that your RunManager
inherit G4RunManager
. For this purpose, G4RunManager
has various
virtual methods which provide all the functionalities required to handle
the Geant4 kernel. Hence, your customized run manager need only override
the methods particular to your needs; the remaining methods in
G4RunManager
base class can still be used. A summary of the
available methods is presented here:
public: virtual void Initialize();
main entry point of Geant4 kernel initialization
protected: virtual void InitializeGeometry();
geometry construction
protected: virtual void InitializePhysics();
physics processes construction
public: virtual void BeamOn(G4int n_event);
main entry point of the event loop
protected: virtual G4bool ConfirmBeamOnCondition();
check the kernel conditions for the event loop
protected: virtual void RunInitialization();
prepare a run
protected: virtual void DoEventLoop(G4int n_events);
manage an event loop
protected: virtual G4Event* GenerateEvent(G4int i_event);
generation of G4Event object
protected: virtual void AnalyzeEvent(G4Event* anEvent);
storage/analysis of an event
protected: virtual void RunTermination();
terminate a run
public: virtual void DefineWorldVolume(G4VPhysicalVolume * worldVol);
set the world volume to G4Navigator
public: virtual void AbortRun();
abort the run
Customizing the Event Loop¶
In G4RunManager
the event loop is handled by the virtual method
DoEventLoop()
. This method is implemented by a for
loop
consisting of the following steps:
construct a
G4Event
object and assign to it primary vertex(es) and primary particles. This is done by the virtualGeneratePrimaryEvent()
method.send the
G4Event
object toG4EventManager
for the detector simulation. Hits and trajectories will be associated with theG4Event
object as a consequence.perform bookkeeping for the current
G4Event
object. This is done by the virtualAnalyzeEvent()
method.
DoEventLoop()
performs the entire simulation of an event. However,
it is often useful to split the above three steps into isolated
application programs. If, for example, you wish to examine the effects
of changing discriminator thresholds, ADC gate widths and/or trigger
conditions on simulated events, much time can be saved by performing
steps 1 and 2 in one program and step 3 in another. The first program
need only generate the hit/trajectory information once and store it,
perhaps in a database. The second program could then retrieve the stored
G4Event
objects and perform the digitization (analysis) using the
above threshold, gate and trigger settings. These settings could then be
changed and the digitization program re-run without re-generating the
G4Event
s.
Changing the Detector Geometry¶
The detector geometry defined in your G4VUserDetectorConstruction
concrete class can be changed during a run break (between two runs). Two
different cases are considered.
The first is the case in which you want to delete the entire structure
of your old geometry and build up a completely new set of volumes. For
this case, you need to delete them by yourself, and let RunManager
invokes Construct()
and ConstructSDandField()
methods of your
detector construction once again when RunManager
starts the next
run.
G4RunManager* runManager = G4RunManager::GetRunManager();
runManager->ReinitializeGeometry();
If this ReinitializeGeometry()
is invoked,
GeometryHasBeenModified()
(discussed next) is automatically invoked.
Presumably this case is rather rare. The second case is more frequent
for the user.
The second case is the following. Suppose you want to move and/or rotate
a particular piece of your detector component. This case can easily
happen for a beam test of your detector. It is obvious for this case
that you need not change the world volume. Rather, it should be said
that your world volume (experimental hall for your beam test) should be
big enough for moving/rotating your test detector. For this case, you
can still use all of your detector geometries, and just use a Set
method of a particular physical volume to update the transformation
vector as you want. Thus, you don’t need to re-set your world volume
pointer to RunManager.
If you want to change your geometry for every run, you can implement it
in the BeginOfRunAction()
method of G4UserRunAction
class, which
will be invoked at the beginning of each run, or, derive the
RunInitialization()
method. Please note that, for both of the above
mentioned cases, you need to let RunManager know “the geometry needs
to be closed again”. Thus, you need to invoke
runManager->GeometryHasBeenModified();
before proceeding to the next run. An example of changing geometry is given in a Geant4 tutorial in Geant4 Training kit #2.
Switch physics processes¶
In the InitializePhysics()
method, G4VUserPhysicsList::Construct
is invoked in order to define particles and physics processes in your
application. Basically, you can not add nor remove any particles during
execution, because particles are static objects in Geant4 (see
How to Specify Particles and Particles for details).
In addition, it is very difficult to add and/or remove physics processes
during execution, because registration procedures are very complex,
except for experts (see How to Specify Physics Processes and
Physics Processes). This is why the initializePhysics()
method is assumed to be invoked at once in Geant4 kernel initialization.
However, you can switch on/off physics processes defined in your
G4VUserPhysicsList
concrete class and also change parameters in
physics processes during the run break.
You can use ActivateProcess()
and InActivateProcess()
methods of
G4ProcessManager
anywhere outside the event loop to switch on/off
some process. You should be very careful to switch on/off processes
inside the event loop, though it is not prohibited to use these methods
even in the EventProc state.
It is a likely case to change cut-off values in a run. You can change
defaultCutValue
in G4VUserPhysicsList
during the Idle state.
In this case, all cross section tables need to be recalculated before
the event loop. You should use the CutOffHasBeenModified()
method
when you change cut-off values so that the SetCuts
method of your
PhysicsList concrete class will be invoked.
Managing worker thread¶
G4UserWorkerInitialization
is an additional user initialization
class to be used only for the multi-threaded mode. The object of this
class can be set to G4MTRunManager
, but not to G4RunManager
.
G4UserWorkerInitialization
class has five virtual methods as the
user hooks which are invoked at several occasions of the life cycle of
each thread.
virtual void WorkerInitialize() const
This method is called after the tread is created but before the G4WorkerRunManager is instantiated.
virtual void WorkerStart() const
This method is called once at the beginning of simulation job when kernel classes and user action classes have already instantiated but geometry and physics have not been yet initialized. This situation is identical to “PreInit” state in the sequential mode.
virtual void WorkerStartRun() const
This method is called before an event loop. Geometry and physics have already been set up for the thread. All threads are synchronized and ready to start the local event loop. This situation is identical to “Idle” state in the sequential mode.
virtual void WorkerRunEnd() const
This method is called for each thread when the local event loop is done, but before the synchronization over all worker threads.
virtual void WorkerStop() const
This method is called once at the end of simulation job.