20.5. Controlling Simulations Without Recompiling
Table of Contents
Changing parameters
In a typical Geant4 application, the C++ code defines the detector geometry, physics list, primary generator, and user actions. Once the executable is compiled, you often want to adjust many details without editing C++ and recompiling. Geant4 macro commands provide this flexibility. By exposing settings through UI commands and reading them from .mac files, you can control a large part of your simulation configuration at run time.
Most Geant4 features that you can change from a macro correspond to messengers attached to classes. Many built-in classes already have messengers, for example for visualization, physics options, and the General Particle Source. For your own user classes you can add messengers to expose custom parameters, but that topic is covered elsewhere. Here the focus is how to use these commands once they exist.
A macro file is a plain text file, for example run1.mac, containing one command per line. Commands are the same ones you can type interactively in the Geant4 terminal. To execute a macro from another macro or from an interactive session, use
/control/execute filename.mac. You normally execute at least one macro at the very beginning of the session to set global options, and another before each run to configure the current scenario.
A common pattern is to separate geometry, physics, and run configuration into different macros and execute them in order. For example, you may have init.mac to call /run/initialize and some static configuration, and separate macros like source_gamma_1MeV.mac to define the particle source for a particular run. This avoids mixing unrelated settings in one large file, and lets you reuse pieces across different studies.
You should also decide which parameters are allowed to change after /run/initialize and which are fixed. Geometry and physics changes usually require reinitialization, often by calling /run/reinitializeGeometry or /run/reinitializePhysics. Source settings, cuts, visualization, and analysis options can often be changed between runs without reinitialization. Whenever you change something fundamental, you should check the Geant4 documentation for the corresponding command to see whether reinitialization is required.
Important rule: Do not change geometry or physics-related settings between events of the same run unless the corresponding Geant4 commands explicitly allow it. To change such parameters safely, adjust them, then call /run/initialize or the appropriate reinitialization command, and only then start a new run.
Within a macro, you can change particle type, energy, position, direction, production cuts, visualization styles, run length, and much more. For example, a macro for a simple run might look like:
/control/verbose 1
/run/verbose 1
/event/verbose 0
/tracking/verbose 0
# Initialize geometry and physics
/run/initialize
# Configure source (for example GPS)
/gps/particle gamma
/gps/energy 1 MeV
/gps/position 0 0 -10 cm
/gps/direction 0 0 1
# Configure analysis (histograms, ntuples) if your code defines commands
/myAnalysis/setOutputFile gamma_1MeV.root
# Start the run
/run/beamOn 100000If you want to do the same run with a different energy, you only need to change the energy line or the output file name and rerun the macro. The C++ executable stays identical. This is the key idea behind controlling simulations without recompilation: move as many configurable pieces as possible into macro-accessible parameters.
A useful habit is to make the macro content self-documenting by including comments with the run purpose, date, and key parameters. Comments start with # and extend to the end of the line. Macros then become a record of how a particular simulation was configured, which helps reproducibility.
In interactive sessions, you can first experiment by typing commands, and once you are satisfied, copy those commands into a macro file. This allows you to refine your configuration interactively and then formalize it for batch use.
From the C++ side, you can also start with a default macro that runs at startup by passing it as a command line argument, for example ./MyApp init.mac. Inside init.mac, you can then execute more specialized macros. This structure keeps your executable generic and all scenario-specific details in macros.
Running parameter scans
Parameter scans are a systematic way to repeat the same simulation while varying one or more parameters, for example primary energy, source position, angle, detector thickness, or material. Using macros, you can automate such scans so that no recompilation and no manual retyping is needed.
The essential idea is:
- Decide which parameter is scanned.
- Ensure that parameter is controllable via a macro command.
- Structure your macros and possibly your shell scripts so that each run corresponds to a specific parameter value.
- Record the parameter value in the output file name or in the data itself, so you can identify it later.
You can perform simple scans purely inside Geant4 macros using looping commands from the user interface. Geant4 provides commands such as /control/loop and /control/foreach that repeat a block of commands with changing variables. Alternatively, you can use an external script, for example a shell script or Python, that calls your Geant4 executable multiple times with different macro files or with macro arguments.
For example, suppose your primary source energy is set using GPS with the command /gps/energy. You might want to simulate energies from 0.5 MeV to 5 MeV in steps of 0.5 MeV. One approach is to write a macro template that uses a variable for energy and then use /control/loop:
/control/verbose 1
/run/verbose 1
/run/initialize
# Scan from 0.5 MeV to 5.0 MeV in steps of 0.5 MeV
/control/loop /myLoop/energy 0.5 5.0 0.5 MeVInside that loop, you would define the body, something like:
/control/loop myEnergy 0.5 5.0 0.5
/gps/energy {myEnergy} MeV
/myAnalysis/setOutputFile spectrum_{myEnergy}MeV.root
/run/beamOn 100000
/control/endloop
The exact syntax can differ depending on Geant4 version and UI system, so you should check the current Geant4 user interface documentation for the full details. The principle is that a macro variable is given different values inside a loop, and you use it to set commands before /run/beamOn.
If you find the macro looping syntax unfamiliar, another practical approach is to generate small per-run macros from an external script. For example, a shell script on Linux could write macros like:
# Template macro: base_scan.mac
/run/initialize
/gps/particle gamma
#gps/energy will be set per run
/run/beamOn 100000Then a script could create a specific macro for each energy:
for E in 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0
do
MACRO="run_${E}MeV.mac"
echo "/gps/energy ${E} MeV" > $MACRO
echo "/myAnalysis/setOutputFile spectrum_${E}MeV.root" >> $MACRO
cat base_scan.mac >> $MACRO
./MyApp $MACRO
doneThis technique keeps all the variation in the script and the generated macros, and the executable is unchanged. It also makes it easy to run the scans on a cluster, because each macro corresponds to one independent job.
You should also consider initialization costs when designing scans. If you have to reinitialize geometry or physics for every parameter value, each scan point will take extra time before starting the run. Whenever possible, separate parameters that demand reinitialization, such as detector dimensions, from those that do not, such as source energy. Perhaps you can perform one scan where geometry is fixed and only source parameters change, then another where geometry changes and you accept the reinitialization overhead.
For multi dimensional scans, for example energy and angle together, you can nest loops, either inside a macro or in an external script. A table of typical scan parameters might look like this:
| Parameter type | Typical examples | Often changeable without reinit |
|---|---|---|
| Source | Energy, particle, direction | Yes |
| Detector | Thickness, material, position | No, usually requires reinit |
| Physics | Cuts, models, step limits | Sometimes, check documentation |
| Analysis | Histograms, file names | Yes |
Important rule: When running parameter scans, always make sure that each run is fully independent and that any modified parameter is correctly recorded for that run. Use distinct output file names or include parameter values inside the data to avoid mixing results from different settings.
Finally, parameter scans become especially powerful when combined with batch execution. You can submit many runs to a batch system, each with its own macro file, run them in parallel, and later combine their outputs in an analysis tool such as ROOT. All of this is possible without rebuilding the Geant4 executable, as long as your code exposes the right configuration options through macro commands.
Views: 7
KAHIBARO