44.7 Version Control
Table of Contents
Git
For GATE projects, version control is as important as correct physics lists or geometry. Git is the standard tool you will meet in almost all research and development environments, and using it early will keep your simulations organized and traceable.
At its core, Git records snapshots of your project directory over time. Each snapshot is a commit, identified by a hash. When you change a simulation, Git lets you see exactly what changed, when, and why.
You typically start by creating a repository in the directory that contains your simulation scripts, configuration files, and possibly analysis notebooks. From that point, every meaningful change is committed with a short message that explains the purpose of the change. This message should describe the intent, not the mechanics. For example, “Adjust PET energy window to 350–650 keV” is more useful than “Update script.”
Git allows you to create branches, which are separate lines of development. For GATE work, branches are very useful when you want to test an alternative geometry, a new physics configuration, or a different source model without disturbing a stable baseline. You can, for example, keep a main branch that contains a validated scanner model and create feature branches for new ideas, such as a different detector material or a modified collimator design.
When you are satisfied with an experimental branch, you merge it back into the main branch. This keeps the history clear: the main branch remains close to what you would use for production runs or publications, and branches embody specific experiments and developments.
Using Git remotes, such as GitHub, GitLab, or an institutional server, allows you to back up your repository and collaborate with others. Pushing your commits to a remote server ensures that your simulation history is not lost if your local machine fails. It also allows collaborators to clone the repository, run the same simulations, and propose improvements through branches and merge requests.
It is important to decide what you track with Git. Source files, configuration files, and documentation belong in the repository. Large generated files such as ROOT outputs, dose images, and temporary logs usually do not. Instead, you keep small text files that describe how to regenerate those outputs. You can instruct Git to ignore certain files using a dedicated ignore file so that your repository remains focused on code and configuration, not massive datasets.
Git history becomes valuable when you need to understand past decisions. If a later result looks suspicious, you can examine older commits to see which geometry or physics settings were used. You can also check out an older commit and re-run the simulation exactly as it was at that time, provided that the environment and external conditions are preserved, which ties directly into reproducible simulations.
Treat Git commits as scientific records: commit small, logical changes with clear messages, keep large output files out of the repository, and use branches to isolate new ideas from validated baselines.
Reproducible simulations
Reproducibility means that you, or someone else, can rerun a GATE simulation at a later time and obtain statistically consistent results, given the same configuration. Version control is a key part of this, but it is not sufficient by itself. You must also capture all elements that influence the simulation outcome.
First, the exact version of your simulation code must be identifiable. Using Git, you can refer to a specific commit hash. In your simulation logs, you can record this hash, either manually or by having your Python script query Git when the simulation starts. This directly links each run to a precise state of the code.
Second, the software environment must be known. This includes the GATE version, the Geant4 version, the compiler used to build them, and the Python library versions that you use for pre and post processing. One common approach is to keep environment description files under version control, such as a list of Python dependencies. This allows others to reconstruct a compatible environment. For more controlled setups, you may also use containerization, but the technical details of that are covered elsewhere.
Third, random number seeds must be controlled and recorded. Monte Carlo simulations rely on random sampling, so even with identical code, different seeds will produce different random histories. If you set the random seed explicitly in your configuration and log its value, you can reproduce the exact sequence of events. If you want runs to be independent but still reproducible, you can base seeds on a simple rule, for example, different integer seeds per job, and record those in your metadata.
Fourth, all input data must be versioned or at least clearly referenced. This includes CT images, voxelized activity maps, material maps, and any external parameter files. Ideally, small inputs are stored in the repository. For large clinical datasets, you may not store them in Git, but you should record unambiguous identifiers, such as patient IDs, acquisition dates, or dataset checksums, so that the same data can be located later.
Fifth, simulation parameters that are not in code should be documented. This includes things like the intended number of primary events, acquisition time, dose actor resolution, energy windows, and coincidence settings. Using configuration files instead of hard coded parameters helps keep these settings explicit and readable. These configuration files are then tracked with Git so their evolution over time is known.
Finally, link simulation runs to outputs through metadata. For every run, you can create a small text or JSON file that records the Git commit hash, random seeds, key parameters, environment description, date and time, and paths to main output files. This file should be stored alongside the output, and ideally the template for it belongs in the repository. This way, when you inspect a ROOT file or a dose image months later, you can find out exactly how it was produced.
A simulation is reproducible only if you can reconstruct the code version, environment, random seeds, input data, and configuration parameters. Use Git to track the first two, configuration files for the third and fourth, and small metadata files to connect each simulation run to its outputs.
Views: 13
KAHIBARO