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
.
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 Section 4.4 and Section 4.5.
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*)
G4Run
base-class method for
must be invoked for recording data members in the base class.
void Merge(const G4Run*)
G4Run
base-class method for
must be invoked for merging data members in the base class.
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 Section 2.1, 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 Chapter 6.
G4RunManager
has several public methods, which are listed
below.
Initialize()
BeamOn(G4int numberOfEvent)
GetRunManager()
G4RunManager
singleton object.
GetCurrentEvent()
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)
G4RunManager
keeps nPrevious
G4Event
objects. This method must be invoked before proceeding
to BeamOn()
.
GetPreviousEvent(G4int i_thPrevious)
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()
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.
G4WorkerRunManager
of the local thread when
it is invoked from thread-local object.G4MTRunManager
when it is invoked
from shared object.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
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()
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()
BeamOn()
method but after confirmation of the conditions
of the Geant4 kernel. Likely uses of this method include:
EndOfRunAction()
BeamOn()
method. Typical use cases of this method are
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
stateG4State_Init
stateInitialize()
method of G4RunManager
is being invoked. Methods defined in any
user initialization classes
are invoked during this state.
G4State_Idle
stateG4State_GeomClosed
stateBeamOn()
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
stateGetCurrentEvent()
and
GetPreviousEvent()
methods of
G4RunManager
are
available only at this state.
G4State_Quit
stateG4RunManager
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
stateG4Exception
occurs, the application comes to this
"dead end" state and causes a core dump. The user still has a hook
to do some "safe" opperations, e.g. storing histograms, by
implementing a user concrete class of G4VStateDependent
. The
user also has a choice to suppress the occurence 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.
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 mabe in, for example main()
, by the user code.
This object will be automatically registered to
G4StateManager
at its construction.
Example 3.1. Header file of UserHookForAbortState
#ifndef UserHookForAbortState_H #define UserHookForAbortState_H 1 #include "G4VStateDependent.hh" class UserHookForAbortState : public G4VStateDependent { public: UserHookForAbortState(); // constructor ~UserHookForAbortState(); // destructor virtual G4bool Notify(G4ApplicationState requiredState); };
Example 3.2. Source file of UserHookForAbortState
#include "UserHookForAbortState.hh" UserHookForAbortState::UserHookForAbortState() {;} UserHookForAbortState::~UserHookForAbortState() {;} G4bool UserHookForAbortState::Notify(G4ApplicationState requiredState) { if(requiredState!=Abort) return true; // Do book keeping here return true; }
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();
protected: virtual void InitializeGeometry();
protected: virtual void InitializePhysics();
public: virtual void BeamOn(G4int n_event);
protected: virtual G4bool ConfirmBeamOnCondition();
protected: virtual void RunInitialization();
protected: virtual void DoEventLoop(G4int n_events);
protected: virtual G4Event* GenerateEvent(G4int i_event);
G4Event
object
protected: virtual void AnalyzeEvent(G4Event* anEvent);
protected: virtual void RunTermination();
public: virtual void DefineWorldVolume(G4VPhysicalVolume * worldVol);
G4Navigator
public: virtual void AbortRun();
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 virtual
GeneratePrimaryEvent()
method.
send the G4Event
object to G4EventManager
for the detector simulation. Hits and
trajectories will
be associated with the G4Event
object as a
consequence.
perform bookkeeping for the current G4Event
object.
This is done by the virtual AnalyzeEvent()
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.
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 yoursef,
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.
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
Section 2.4 and
Section 5.3 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 Section 2.5
and Section 5.2).
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.
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
G4WorkerRunManager
is instantiated.
virtual void WorkerStart() const
PreInit
" state in the sequential mode.
virtual void WorkerStartRun() const
Idle
" state in the sequential mode.
virtual void WorkerRunEnd() const
virtual void WorkerStop() const