Geant4 User's Guide
For Application Developers Toolkit Fundamentals |
3.4 Run
3.4.1 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 Sections 4.4 and 4.5.
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, and the pointer to this singleton object can be obtained by the getRunManager() static method.
As already mentioned in Section 2.1, all of the user initialization classes and user action 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() and SetUserAction() methods. All user classes defined by the Geant4 kernel will be summarized in Section 6.
G4RunManager has several public methods, which are listed below.
G4UserRunAction
G4UserRunAction is one of the user action classes from which you can derive your own concrete class. This base class has two virtual methods, as follows:
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.
#ifndef UserHookForAbortState_H #define UserHookForAbortState_H 1 #include "G4VStateDependent.hh" class UserHookForAbortState : public G4VStateDependent { public: UserHookForAbortState(); // constructor ~UserHookForAbortState(); // destructor virtual G4bool Notify(G4ApplicationState requiredState); }; #endif |
Source listing 3.4.3.1 Header 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; } |
Source listing 3.4.3.2 Source file of UserHookForAbortState |
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:
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:
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 G4Events.
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 set the new world physical volume pointer to the RunManager. Thus, you should proceed in the following way.
G4RunManager* runManager = G4RunManager::GetRunManager(); runManager->DefineWorldVolume( newWorldPhys );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 Sections 2.4 and 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 Sections 2.5 and 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.