31.3. Using Configuration Parameters
Table of Contents
Why Configuration Parameters Matter
Geant4 applications quickly become difficult to modify if key values are hard coded inside C++ source files. Detector dimensions, material choices, beam energies, and analysis options often need to change many times during development or for different studies.
Configuration parameters give you a central, flexible way to control such values. Instead of recompiling every time you change a number, you adjust a configuration source, rebuild less often, and keep your code more readable.
Configuration parameters should collect all important, frequently changed numbers and options in one place. Hard coded values scattered in the code are a major source of errors and maintenance problems.
Configuration also separates the physics or detector concept from the technical implementation. This makes it easier to reproduce a study, compare configurations, and share your code with others.
What To Treat As Configuration
Not every value needs to be configurable. The goal is to expose what a user or future you is likely to vary.
Typical configuration candidates in Geant4 applications include:
Detector geometry. Dimensions of volumes, positions and orientations of detectors, number of elements in arrays, and gaps between components are usually configuration options. For example, crystal length, number of layers, or ring radius in a PET scanner.
Materials. Choice of material for a given component and its parameters such as density or mixture composition are often configurable. You might want to compare lead, concrete, and water shielding without editing C++ each time.
Beam and source parameters. Particle type, energy, position distribution, direction distribution, and time structure are ideal configuration parameters. They are often varied in parameter scans and sensitivity studies.
Physics and cuts. Selection of a reference physics list, production cuts, step limits, and other physics settings are typically controlled by configuration so you can adapt your simulation to different use cases.
Run control and statistics. Number of events, random seeds, and multithreading parameters are natural configuration items.
Analysis and output. Which histograms to create, file names, which variables to record in ntuples, and output frequency should be configurable so you can change analysis without touching the core simulation.
By consciously deciding what belongs in configuration, you avoid both extremes: an opaque, rigid application and a tangled one where every small detail must be set externally.
Sources of Configuration in Geant4
Geant4 offers several common ways to provide configuration values. Most realistic applications use a combination of them.
Macro Commands as Configuration
Macro files are the most direct configuration tool provided by Geant4. They are human readable text files containing UI commands that your application already understands.
For many settings, you do not need custom C++ configuration code at all. You can use existing command trees to configure:
Geometry parameters exposed by messenger classes.
Physics lists and cut values if the physics code provides commands.
Primary particle sources through the particle gun or General Particle Source UI commands.
Visualization, run control, and output behavior that you hook to commands.
You can also create your own commands for your detectors and analysis, so that almost any aspect of the application is controlled through macros.
Macro based configuration has several advantages. It requires no recompilation to change values. It is easy to script parameter scans by generating or editing macros. It provides a built-in help system through the Geant4 UI.
Limitations appear when you need values before the UI is active or when you want to organize complex configurations into structured files. In those cases, you may combine macros with C++ configuration objects or external configuration files.
C++ Configuration Objects
A common pattern is to collect parameters in dedicated C++ classes that act as configuration containers. You might define, for example, a DetectorConfig class with members for dimensions, materials, and layout, a BeamConfig class with source settings, and an AnalysisConfig class for output options.
This approach keeps parameters strongly typed, lets you compute derived values in one place, and makes it easy to validate inputs. Your detector construction, physics list, primary generator, and analysis classes can all refer to these shared configuration objects.
The configuration values stored in such objects can be set in several ways. You can hard code default values in the class constructor. You can modify them using environment variables or command line arguments. You can connect them to UI commands through messenger classes so they are controllable from macros.
A configuration object is especially useful when several parts of the code must agree on a value. For instance, if the detector thickness is needed in both geometry and analysis, reading it from a single configuration object avoids duplication and risk of mismatch.
External Configuration Files
Besides macros, you may want separate configuration files in your own format, such as JSON, XML, or simple key value text files. These can describe, for example, a detector layout, a list of materials, or a large set of run parameters.
You load and parse these files in C++ at startup, then populate your configuration objects with the values. From there, the rest of your Geant4 code does not need to know where the numbers came from.
External configuration files are helpful when you share the simulation with non-programmers or you need to store many configurations for different studies. They also make it easier to place configuration under version control separately from code, so you can track which input set produced which result.
External configuration is not a replacement for macros. Macros remain useful for commands that must be executed at runtime, such as /run/beamOn or visualization commands. In practice, you use external files to define values, macros to trigger and control runs, and C++ configuration objects to bind everything to your classes.
Passing Configuration Through the Application
Configuration parameters are most useful when they reach all parts of the application that need them in a consistent way. For a small Geant4 program, it is tempting to read configuration values directly inside each class, but this quickly leads to duplication and inconsistent settings.
A better pattern is to create configuration objects in main() or in a central initialization class, set their values there, and then pass references or pointers to the relevant user initialization and user action classes.
For example, you might create a shared MyConfig object in main(). You pass it to your detector construction, which uses the geometry parameters. You pass the same object to your primary generator, which uses the beam parameters, and to your analysis manager, which uses output settings. This ensures that a single change in configuration is reflected everywhere.
You can also store pointers to configuration objects in singleton style manager classes if that fits your architecture, but for beginners, explicit passing of references is easier to understand and safer.
When you introduce configuration parameters, ensure that dependent classes do not silently make their own assumptions. For instance, if the geometry changes, confirm that any related cuts, histograms, or detector IDs still make sense in light of the new configuration.
Using Macro Commands as Configuration Interface
The Geant4 user interface system is the standard way to expose configuration parameters to macro files and interactive sessions. To connect your configuration objects to macro commands, you typically use messenger classes derived from G4UImessenger.
A messenger class defines UI commands and binds them to member variables or methods of your configuration or detector classes. When the user executes a command in a macro, for example /det/setSize 5 cm, the messenger receives it, parses the value, converts it to the appropriate units, and stores it in your configuration.
This approach has several key advantages. You can change run parameters, geometry parameters that are allowed to vary before /run/initialize, or analysis options in text macros without recompilation. You can add online control of output or visualization. You provide a discoverable set of commands through the UI help system.
You must, however, respect the Geant4 initialization order. Some parameters cannot be changed after certain initialization steps. When designing configuration commands, clearly document which values must be set before /run/initialize and which can be modified between runs or even during a run.
Any configuration value that affects the geometry or physics list must be set before the corresponding initialization step finishes. Changes after /run/initialize usually require reinitialization with /run/reinitializeGeometry or /run/reinitializePhysics or a new process.
When using macro commands as configuration, always provide reasonable defaults in C++ so that your application can run even if no macro is supplied. Then treat macros as overrides of those defaults.
Balancing Flexibility and Safety
Over-configurable applications can become as hard to use as under-configurable ones. Each new parameter is an axis where users can misconfigure the simulation, break assumptions in the code, or create combinations that were never tested.
There are several ways to keep configuration flexible but safe.
Provide meaningful default values that produce a valid run. Users should be able to run a standard configuration with no manual setup. Defaults also serve as a documented example.
Validate configuration at startup. Whenever possible, check ranges, relationships, and constraints, for example that layer thicknesses sum to the total detector length, that energies are positive, that material names are known, or that cut values are reasonable. Report clear error messages if something is inconsistent.
Keep parameters as high level as possible. Instead of exposing low level details like every individual layer position, consider higher level parameters like number of layers and overall length, then compute the rest internally. This reduces the chance of combinatorial errors.
Use consistent units. When reading values from macros or files, explicitly multiply by Geant4 units like cm or MeV at the point of parsing, and store them in SI based internal units consistently. This reduces the risk of accidental unit mistakes between configuration sources.
Group related parameters. Detector geometry settings belong together, as do beam settings or analysis options. Grouping them into configuration classes or namespaces keeps your code organized and makes it easier for users to understand what to change.
Finally, document which parameters are expected to change for typical studies and which should rarely be touched. This helps others use your simulation correctly, and it keeps the configuration surface manageable.
Reproducibility and Versioning of Configuration
Reproducible simulations depend not only on code and random seeds, but also on a complete, well defined set of configuration parameters. If you cannot reconstruct which geometry, source, and cuts were used, you cannot reliably repeat your results.
Good practices for configuration and reproducibility include:
Store the configuration that was used for each run. This might mean archiving the macro files, external configuration files, and a small text summary generated automatically at runtime. Including these files in your output directory makes it easy to revisit a run later.
Keep configuration under version control alongside the code. Tag both the code revision and the configuration files when you produce results. If you change default values, update the documentation and, where needed, keep backward compatible examples.
Record configuration values inside the output file when possible. For example, write key parameter values into a ROOT TTree or metadata structure. This provides an extra layer of traceability even if configuration files are lost.
Coordinate random seeds with configuration. A given seed only reproduces the same event sequence if the configuration is identical, including geometry and physics options. Whenever you change configuration, treat the simulation as a new scenario and pick new seeds.
By treating configuration as part of the scientific record rather than a temporary convenience, you make your Geant4 applications more reliable and suitable for long term use and publication.
Configuration for Parameter Scans and Studies
One of the main reasons to build flexible configuration is to run systematic studies, such as varying detector thickness, beam energy, or material composition, and observing the impact on observables.
With a well designed configuration system, you can perform such scans without changing C++ code. You can create multiple macro files or configuration files, each representing a point or set of points in parameter space, and loop over them with a script. Your application stays the same, while configuration defines each scenario.
This pattern is much easier when configuration values are centralized. A simple script can edit or generate macro commands that set only a few key parameters, then run the simulation for each case. Because parameters are named and documented, you know exactly which values changed.
During such studies, it becomes especially important to keep configuration, run logs, and results organized. Use clear naming conventions for configuration files and output directories, and ensure that your analysis picks up and records the parameter values along with the data.
If you plan large parameter scans, verify that your configuration system performs well where many runs may be launched automatically. For example, ensure that defaults are sensible, error messages are clear, and missing or malformed configuration values are caught early.
Summary
Configuration parameters are one of the main tools for writing better Geant4 applications. By centralizing geometry, materials, source, physics, run, and analysis settings, you avoid hard coded numbers scattered across your code, make your simulations easier to adapt, and improve reproducibility.
Geant4 provides macro commands and the UI system as a natural configuration interface. You can complement these with C++ configuration objects and external configuration files to organize more complex setups. The key is to pass configuration consistently through your application, validate it, and record it as part of your simulation outputs.
With thoughtful use of configuration parameters, you can support many studies with one well structured Geant4 codebase, instead of creating many almost identical programs that differ only in a few numbers.
Views: 8
KAHIBARO