KAHIBARO
Discord Login Register

47.15. Saving PET Data

Choosing What to Save

In a PET simulation you can easily generate more data than you can conveniently store or analyze. Before you write any code for saving PET data, decide what information you actually need for your study. In earlier sections of this example you created and processed several data levels: hits in crystals, singles after digitization, and coincidence events paired in time and space. For most PET performance and image reconstruction studies, coincidences are the primary data product. Hits and singles are useful for detector studies and debugging, but they increase file size and processing time.

A practical strategy is to record all three levels during development, then restrict output to coincidences, plus a minimal set of singles, for production runs. Think of coincidences as your “main dataset” and everything else as temporary diagnostic data.

Output Formats and File Types

GATE can write several output formats through actors or digitizers. For PET data, two types are most common: ROOT files for event data and voxel images for dose or occupancy maps. In this PET example you are primarily concerned with event data generated by the digitizer, so the main focus is ROOT output.

The typical PET outputs are summarized in the following table.

Data levelTypical contentCommon format
HitsRaw energy deposits in crystalsROOT
SinglesDigitized detector events per channelROOT
CoincidencesPaired detector events along lines of responseROOT
Auxiliary mapsDose, sensitivity, or occupancy images if neededMHD, NIfTI

ROOT is a high energy physics data format that stores trees with branches. Each event in a tree corresponds to one hit, one single, or one coincidence, depending on the tree type. You will typically open these ROOT files later using ROOT itself or with Python libraries such as uproot.

Image formats like MHD or NIfTI are used mainly when you record 3D images such as dose distributions or sensitivity maps with actors. For a PET coincidence study you can add such images as side products, but they are not mandatory.

Configuring Output Actors and Digitizers

In this PET example the output is usually controlled at two points: by actors attached to detector volumes or to the world, and by digitizer outputs attached to singles and coincidence processing. The configuration lives in your Python simulation script in the same way as geometry or sources.

For ROOT event data you will use a ROOT output actor or the output settings inside the digitizer. The PET digitizer collects hits into singles and then into coincidences. At each stage it can write a ROOT file with a specific tree name. PET tutorials usually follow a pattern where hits, singles, and coincidences each have their own tree and possibly their own file.

The most important configuration choices when setting up output are:

  1. What trees to write. Decide whether you need hits, singles, coincidences, or any combination.
  2. Which attributes to store. You can often choose a subset of variables, such as energy, detector IDs, positions, and times.
  3. Where to write files. Set output directories and filenames that reflect the simulation and parameter settings.

Once you have created the digitizer and coincidence sorter in earlier sections, you connect them with an output definition. This can be as simple as specifying a filename and enabling the desired data levels. If you use actors to collect additional information such as dose or phase space, you configure their output files directly when you create each actor.

Defining Which Variables to Store

PET data can quickly become huge if you write every possible variable for every event. For coincidences, a long list of attributes might be available, including energies, times, positions, detector IDs, event IDs, and internal bookkeeping variables. Not all of them are equally useful.

For image reconstruction and basic performance metrics you usually need, per coincidence:

Position information for both detectors, typically as $x, y, z$ or as crystal IDs and ring/module indices.

Energy of each photon, and sometimes the summed energy.

Time of each detection, or at least the time difference for time of flight studies.

Event classification labels such as true, scattered, or random, if you enabled truth tagging.

Additionally, you may want event or run identifiers to merge data from multiple jobs later.

By restricting output to these key variables, you get smaller ROOT files that are faster to analyze. Some GATE PET examples use default coincidence trees that already contain a reasonable subset of attributes. You can modify the configuration to remove rarely used branches, such as intermediate internal variables that are useful only for debugging.

For singles, a minimal set is usually energy, time, and detector identifiers. If you are working on energy resolution, non proportionality, or dead time effects, you might keep some additional timing flags or channel-level fields. For most standard PET simulations, however, singles are mostly an intermediate step toward coincidences.

For hits, a minimal set includes deposited energy, step position, and time. Since hits are the rawest and most numerous events, they are often written only in short runs intended for detector development or physics debugging.

Organizing Output Files and Directories

As your PET project grows, you will run many simulations with different configurations, such as varying activity, acquisition time, geometry, and physics models. If you keep all output in one folder with generic names, it will quickly become impossible to know which file corresponds to which settings.

It is essential to design an output structure from the start. A simple strategy is to create a base output directory and then create one subdirectory per simulation run, named with a unique run identifier that may include the date, scanner name, and a short description of important parameters. Inside each run directory you can place the main event ROOT files and any additional image outputs.

For example, you might use a hierarchy such as:

base_output_directory / scannerName_runID / hits.root, singles.root, coincidences.root, dose.mhd

You can generate the run ID automatically in Python, for instance by using a timestamp or a counter. You can also include key parameters such as energy window, acquisition duration, or activity in the filename or directory name. This helps you and your collaborators track which files belong to which scenario without opening the files.

Keep your analysis scripts synchronized with this structure. Analysis code that expects to find coincidences in a standard filename at a standard path is easier to maintain. You can centralize the path definition in one configuration block so that changing the output directory does not require editing multiple scripts.

Recording Simulation Metadata

Raw events are only part of what you need to interpret your PET data. To reproduce and understand results you must also know which simulation configuration was used. This includes geometry settings, physics lists, random seeds, source definitions, and acquisition time.

Some metadata get stored automatically inside ROOT trees, for instance run numbers and sometimes global parameters. However, it is safer to record your own metadata alongside the event data. You can do this by writing small text or JSON files that summarize the configuration, or by embedding metadata in a separate tree or branch.

Useful metadata include:

Scanner geometry parameters such as ring diameter, number of crystals per ring, and crystal sizes.

Source description such as radionuclide, activity, activity distribution, and simulation duration.

Physics configuration including the physics list name and any custom options.

Digitizer configuration such as energy resolution parameters, energy window limits, timing resolution, and coincidence time window.

Random seed information so that you can repeat the simulation if needed.

You can create a Python dictionary containing all these values and then write it as a JSON file into the same directory as your ROOT data. Later, analysis scripts can read the metadata to automatically configure histograms and selection cuts, for example by retrieving the energy window from the metadata instead of hard coding it.

Always save simulation metadata alongside PET event data. Without geometry, source, physics, and digitizer settings your ROOT files can become scientifically meaningless and impossible to reproduce.

Preparing Data for Analysis with ROOT and Python

Once you have saved PET data from your simulation, the next step is analysis. The design of your output directly affects how easy that analysis will be. For ROOT-based workflows you will typically open the coincidence tree in a ROOT session or C++ macro, draw histograms, and compute performance metrics. For Python workflows you will read the same ROOT files using uproot and then process them with NumPy, Pandas, and Matplotlib.

To make this process smooth, you should consider analysis needs already when you define your saved variables and file structure. If you plan to use time of flight reconstruction, you must ensure that both detection times or at least their difference are present. If you are interested in scatter fraction, you must have scatter labels or sufficient information to derive them. If you plan to reconstruct images, storing exact detector positions for each event is often more convenient than only crystal IDs.

A practical approach is to write a small test analysis script early on. After configuring saving of coincidences, run a short simulation with a small number of events, open the output with your analysis tool of choice, and verify that all necessary branches are present and correctly filled. This quick loop helps you adjust the output content before running long simulations.

You can also pre organize variables inside the ROOT trees. For example, you might group position components under clear names or ensure that branch names are short but descriptive. Consistent naming conventions will greatly reduce confusion later. For Python users, avoid branch names that contain characters which are inconvenient to reference in code.

Finally, if your simulation produces multiple ROOT files, such as one per batch job in a high performance computing environment, plan for how to combine them. Having a common tree structure and identical branch names across all files is essential. Your analysis scripts can then loop across files, concatenate arrays, and treat the combined dataset as one large virtual tree.

Design PET output with analysis in mind. Confirm early that coincidences contain all variables needed for your planned ROOT or Python workflow, including energies, detector positions, times, and any classification labels.

Views: 10

Comments

Please login to add a comment.

Don't have an account? Register now!