GAN sources (Generative Adversarial Network)#

Description#

A Phase-Space (phsp) source typically uses a large file containing particle properties (e.g., energy, position, direction, time) to generate primary events in a simulation. This traditional phsp source can be replaced by a neural network-based particle generator that replicates similar distribution probabilities in a more compact form. GAN sources utilize Generative Adversarial Networks (GANs) trained to reproduce these particle properties based on an initial phsp. This approach, proposed in [Sarrut et al, PMB, 2019], can be applied across various applications:

Installation Requirements#

To use GAN sources, first install the required torch and gaga_phsp libraries with:

pip install torch gaga_phsp

The gaga_phsp library provides tools for training and using GAN models: OpenGATE/gaga-phsp.

Workflow Overview#

The workflow to use a GAN source involves three main steps:

  1. Generate the training dataset.

  2. Train the GAN model.

  3. Use the GAN model as a source in GATE.

For Linac applications, a conventional Linac phsp can serve as the training dataset. In SPECT or PET applications, a conditional GAN is used to generate particles exiting the patient, conditioned on the activity distribution within the patient. In this case, the training dataset must include not only the particle properties at the patient exit (e.g., position and direction in a spheroid or cylinder around the patient) but also the initial emission point inside the patient (using EventPosition and EventDirection). An example can be found in test038_gan_phsp_spect_training_dataset_mt.py.

Training the GAN#

Once the training data is generated, train the GAN model outside of GATE using gaga_phsp. Example command:

gaga_train my_phsp.root gaga_train_options.json -pi epoch 50 -o gan_source.pth

A sample JSON file for GAN options, train_gaga_v124.json, can be found in the tests/data/test038 folder. Training can be resource-intensive, typically requiring a GPU and several hours. The resulting generator model is saved as a compact .pth file, containing the neural network weights (generally a few tens of MB).

Using the GAN Source in GATE#

Once trained, the generator can be used as a source in GATE using the GANSource type, as in the example below:

gsource = sim.add_source("GANSource", "my_gan_source")
gsource.particle = "gamma"
gsource.activity = 1 * MBq
gsource.pth_filename = "gan_source.pth"

gsource.position_keys = ["PrePosition_X", "PrePosition_Y", "PrePosition_Z"]
gsource.direction_keys = ["PreDirection_X", "PreDirection_Y", "PreDirection_Z"]
gsource.energy_key = "KineticEnergy"
gsource.time_key = None
gsource.weight_key = None

gsource.energy_min_threshold = 10 * keV
gsource.backward_distance = 5 * cm
# Use ZeroEnergy policy to avoid altering event counts
gsource.skip_policy = "ZeroEnergy"

gsource.batch_size = 5e4
gsource.verbose_generator = True
gsource.gpu_mode = "auto"

cond_gen = gate.sources.gansources.VoxelizedSourceConditionGenerator("myactivity.mhd")
cond_gen.compute_directions = True
gen = gate.sources.gansources.GANSourceConditionalGenerator(gsource, cond_gen.generate_condition)
source.generator = gen

In this example, the GAN source emits 10 MBq of gamma particles with position and direction distributions learned by the GAN. Each attribute of the particles (e.g., position, direction, energy) corresponds to a key in the GAN file. The energy_min_threshold parameter defines a lower limit for energy; particles with energy below this threshold can either be skipped (skip_policy = “SkipEvents”) or assigned zero energy (skip_policy = “ZeroEnergy”), meaning they are not tracked.

The GAN operates in batches, with the size defined by batch_size. In this case, a conditional GAN is used to control the emitted particles based on an internal activity distribution provided by a voxelized source (myactivity.mhd file). This approach can efficiently replicate complex spatial dependencies in the particle emission process.

The GAN-based source is an experimental feature in GATE. While it offers promising advantages in terms of reduced file size and simulation speed, users are encouraged to approach it cautiously. We strongly recommend thoroughly reviewing the associated publications [Sarrut et al, PMB, 2019], [Sarrut et al, PMB, 2021], and [Saporta et al, PMB, 2022] to understand the method’s assumptions, limitations, and best practices. This method is best suited for research purposes and may not yet be appropriate for clinical or regulatory applications without extensive validation.

Reference#

class GANSource(*args, **kwargs)[source]#

GAN source: the Generator produces particles Input is a neural network Generator trained with a GAN

User input parameters and default values:

  • activity:

    • Default value: 0

    • Description: Activity of the source in Bq (exclusive with ‘n’)

  • attached_to:

    • Default value: world

    • Description: Name of the volume to which the source is attached.

  • backward_distance:

    • Default value: None

    • Description: Change position of the generated particle according to this distance in backward direction (-direction)

  • backward_force:

    • Default value: None

    • Description: if backward is enabled and the time is not managed by the GAN the time cannot be changed (yet). Use ‘force’ to enable backward if you know what your are doing

  • batch_size:

    • Default value: 10000

    • Description: Batch size of the GAN generated particles.

  • compute_directions:

    • Default value: False

    • Description: FIXME

  • cond_debug:

    • Default value: False

    • Description: Print debug information for conditional GAN

  • cond_image:

    • Default value: None

    • Description: Filename of the activity distribution (provided as image) to use for the conditional GAN

  • direction:

    • Default value: {‘type’: ‘iso’, ‘theta’: [0, 3.141592653589793], ‘phi’: [0, 6.283185307179586], ‘momentum’: [0, 0, 1], ‘focus_point’: [0, 0, 0], ‘sigma’: [0, 0], ‘acceptance_angle’: {‘skip_policy’: ‘SkipEvents’, ‘volumes’: [], ‘intersection_flag’: False, ‘normal_flag’: False, ‘normal_vector’: [0, 0, 1], ‘normal_tolerance’: 0.05235987755982989}, ‘accolinearity_flag’: False, ‘accolinearity_fwhm’: 0.008726646259971648, ‘histogram_theta_weights’: [], ‘histogram_theta_angles’: [], ‘histogram_phi_weights’: [], ‘histogram_phi_angles’: []}

    • Description: Define the direction of the primary particles

  • direction_keys:

    • Default value: None

    • Description: FIXME

  • direction_relative_to_attached_volume:

    • Default value: False

    • Description: Should we update the direction of the particle when the volume is moved (with dynamic parametrisation)?

  • end_time:

    • Default value: None

    • Description: End time of the source

  • energy:

    • Default value: {‘type’: ‘mono’, ‘mono’: 0, ‘sigma_gauss’: 0, ‘is_cdf’: False, ‘min_energy’: None, ‘max_energy’: None, ‘spectrum_type’: None, ‘spectrum_weights’: [], ‘spectrum_energies’: [], ‘spectrum_energy_bin_edges’: [], ‘spectrum_histogram_interpolation’: None}

    • Description: Define the energy of the primary particles

  • energy_key:

    • Default value: None

    • Description: FIXME

  • energy_max_threshold:

    • Default value: 1.7976931348623157e+308

    • Description: Maximum energy threshold. If the generator creates particles with a higher energy, the particle is skipped

  • energy_min_threshold:

    • Default value: -1

    • Description: Minimum energy threshold. If the generator creates particles with less than this energy, the particle is skipped

  • generator:

    • Default value: None

    • Description: FIXME

  • gpu_mode:

    • Default value: gpu

    • Allowed values: (‘auto’, ‘cpu’, ‘gpu’)

    • Description: Use the GPU or CPU for the GAN, or let GATE decide.

  • half_life:

    • Default value: -1

    • Description: Half-life decay (-1 if no decay). Only when used with ‘activity’

  • ion:

    • Default value: {‘Z’: 0, ‘A’: 0, ‘E’: 0}

    • Description: If the particle is an ion, you must set Z: Atomic Number, A: Atomic Mass (nn + np +nlambda), E: Excitation energy (i.e. for metastable)

  • mother:

    • Deprecated: The user input parameter ‘mother’ is deprecated. Use ‘attached_to’ instead.

  • n:

    • Default value: 0

    • Description: Number of particle to generate (exclusive with ‘activity’)

  • name (must be provided):

    • Default value: None

  • particle:

    • Default value: gamma

    • Description: Name of the particle generated by the source (gamma, e+ … or an ion such as ‘ion 9 18’)

  • position:

    • Default value: {‘type’: ‘point’, ‘radius’: 0, ‘sigma_x’: 0, ‘sigma_y’: 0, ‘size’: [0, 0, 0], ‘translation’: [0, 0, 0], ‘rotation’: array([[1., 0., 0.],, [0., 1., 0.],, [0., 0., 1.]]), ‘confine’: None}

    • Description: Define the position of the primary particles

  • position_keys:

    • Default value: None

    • Description: FIXME

  • pth_filename:

    • Default value: None

    • Description: Filename of the Generator (.pth), train with gaga_train

  • relative_timing:

    • Default value: True

    • Description: FIXME

  • skip_policy:

    • Default value: SkipEvents

    • Allowed values: (‘SkipEvents’, ‘ZeroEnergy’)

    • Description: When some generated events are skipped (e.g. with the energy threshold), they could be either ‘skipped’ (SkippedEvents) or generated with energy=zero (ZeroEnergy) to preserve the correct number of events

  • start_time:

    • Default value: None

    • Description: Starting time of the source

  • tac_activities:

    • Default value: None

    • Description: TAC: Time Activity Curve, this set the vector for the activities. Must be used with tac_times.

  • tac_times:

    • Default value: None

    • Description: TAC: Time Activity Curve, this set the vector for the times. Must be used with tac_activities.

  • time_key:

    • Default value: None

    • Description: FIXME

  • use_time:

    • Default value: False

    • Description: Consider the particle time given by the generator.

  • use_weight:

    • Default value: False

    • Description: Consider the particle weight given by the generator.

  • user_particle_life_time:

    • Default value: -1

    • Description: FIXME

  • verbose_generator:

    • Default value: False

    • Description: Print information every time the generator generates a batch of particles.

  • weight:

    • Default value: -1

    • Description: Particle initial weight (for variance reduction technique)

  • weight_key:

    • Default value: None

    • Description: FIXME

  • weight_sigma:

    • Default value: -1

    • Description: if not negative, the weights of the particle are a Gaussian distribution with this sigma

class GANPairsSource(*args, **kwargs)[source]#

GAN source: the Generator produces pairs of particles (for PET) Input is a neural network Generator trained with a GAN

User input parameters and default values:

  • activity:

    • Default value: 0

    • Description: Activity of the source in Bq (exclusive with ‘n’)

  • attached_to:

    • Default value: world

    • Description: Name of the volume to which the source is attached.

  • backward_distance:

    • Default value: None

    • Description: Change position of the generated particle according to this distance in backward direction (-direction)

  • backward_force:

    • Default value: None

    • Description: if backward is enabled and the time is not managed by the GAN the time cannot be changed (yet). Use ‘force’ to enable backward if you know what your are doing

  • batch_size:

    • Default value: 10000

    • Description: Batch size of the GAN generated particles.

  • compute_directions:

    • Default value: False

    • Description: FIXME

  • cond_debug:

    • Default value: False

    • Description: Print debug information for conditional GAN

  • cond_image:

    • Default value: None

    • Description: Filename of the activity distribution (provided as image) to use for the conditional GAN

  • direction:

    • Default value: {‘type’: ‘iso’, ‘theta’: [0, 3.141592653589793], ‘phi’: [0, 6.283185307179586], ‘momentum’: [0, 0, 1], ‘focus_point’: [0, 0, 0], ‘sigma’: [0, 0], ‘acceptance_angle’: {‘skip_policy’: ‘SkipEvents’, ‘volumes’: [], ‘intersection_flag’: False, ‘normal_flag’: False, ‘normal_vector’: [0, 0, 1], ‘normal_tolerance’: 0.05235987755982989}, ‘accolinearity_flag’: False, ‘accolinearity_fwhm’: 0.008726646259971648, ‘histogram_theta_weights’: [], ‘histogram_theta_angles’: [], ‘histogram_phi_weights’: [], ‘histogram_phi_angles’: []}

    • Description: Define the direction of the primary particles

  • direction_keys:

    • Default value: None

    • Description: FIXME

  • direction_relative_to_attached_volume:

    • Default value: False

    • Description: Should we update the direction of the particle when the volume is moved (with dynamic parametrisation)?

  • end_time:

    • Default value: None

    • Description: End time of the source

  • energy:

    • Default value: {‘type’: ‘mono’, ‘mono’: 0, ‘sigma_gauss’: 0, ‘is_cdf’: False, ‘min_energy’: None, ‘max_energy’: None, ‘spectrum_type’: None, ‘spectrum_weights’: [], ‘spectrum_energies’: [], ‘spectrum_energy_bin_edges’: [], ‘spectrum_histogram_interpolation’: None}

    • Description: Define the energy of the primary particles

  • energy_key:

    • Default value: None

    • Description: FIXME

  • energy_max_threshold:

    • Default value: 1.7976931348623157e+308

    • Description: Maximum energy threshold. If the generator creates particles with a higher energy, the particle is skipped

  • energy_min_threshold:

    • Default value: -1

    • Description: Minimum energy threshold. If the generator creates particles with less than this energy, the particle is skipped

  • generator:

    • Default value: None

    • Description: FIXME

  • gpu_mode:

    • Default value: gpu

    • Allowed values: (‘auto’, ‘cpu’, ‘gpu’)

    • Description: Use the GPU or CPU for the GAN, or let GATE decide.

  • half_life:

    • Default value: -1

    • Description: Half-life decay (-1 if no decay). Only when used with ‘activity’

  • ion:

    • Default value: {‘Z’: 0, ‘A’: 0, ‘E’: 0}

    • Description: If the particle is an ion, you must set Z: Atomic Number, A: Atomic Mass (nn + np +nlambda), E: Excitation energy (i.e. for metastable)

  • mother:

    • Deprecated: The user input parameter ‘mother’ is deprecated. Use ‘attached_to’ instead.

  • n:

    • Default value: 0

    • Description: Number of particle to generate (exclusive with ‘activity’)

  • name (must be provided):

    • Default value: None

  • particle:

    • Default value: gamma

    • Description: Name of the particle generated by the source (gamma, e+ … or an ion such as ‘ion 9 18’)

  • position:

    • Default value: {‘type’: ‘point’, ‘radius’: 0, ‘sigma_x’: 0, ‘sigma_y’: 0, ‘size’: [0, 0, 0], ‘translation’: [0, 0, 0], ‘rotation’: array([[1., 0., 0.],, [0., 1., 0.],, [0., 0., 1.]]), ‘confine’: None}

    • Description: Define the position of the primary particles

  • position_keys:

    • Default value: None

    • Description: FIXME

  • pth_filename:

    • Default value: None

    • Description: Filename of the Generator (.pth), train with gaga_train

  • relative_timing:

    • Default value: True

    • Description: FIXME

  • skip_policy:

    • Default value: SkipEvents

    • Allowed values: (‘SkipEvents’, ‘ZeroEnergy’)

    • Description: When some generated events are skipped (e.g. with the energy threshold), they could be either ‘skipped’ (SkippedEvents) or generated with energy=zero (ZeroEnergy) to preserve the correct number of events

  • start_time:

    • Default value: None

    • Description: Starting time of the source

  • tac_activities:

    • Default value: None

    • Description: TAC: Time Activity Curve, this set the vector for the activities. Must be used with tac_times.

  • tac_times:

    • Default value: None

    • Description: TAC: Time Activity Curve, this set the vector for the times. Must be used with tac_activities.

  • time_key:

    • Default value: None

    • Description: FIXME

  • use_time:

    • Default value: False

    • Description: Consider the particle time given by the generator.

  • use_weight:

    • Default value: False

    • Description: Consider the particle weight given by the generator.

  • user_particle_life_time:

    • Default value: -1

    • Description: FIXME

  • verbose_generator:

    • Default value: False

    • Description: Print information every time the generator generates a batch of particles.

  • weight:

    • Default value: -1

    • Description: Particle initial weight (for variance reduction technique)

  • weight_key:

    • Default value: None

    • Description: FIXME

  • weight_sigma:

    • Default value: -1

    • Description: if not negative, the weights of the particle are a Gaussian distribution with this sigma