Skip to content

Commit

Permalink
Merge pull request #568 from OpenGATE/doc_contrib
Browse files Browse the repository at this point in the history
Add user guide docs for new SPECT, PET, and Linac models
  • Loading branch information
dsarrut authored Nov 18, 2024
2 parents 8d8ccac + 77570f6 commit 737a600
Show file tree
Hide file tree
Showing 8 changed files with 252 additions and 178 deletions.
5 changes: 5 additions & 0 deletions docs/source/user_guide/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ User Guide
:maxdepth: 2

user_guide_contrib
user_guide_contrib_dose_rate
user_guide_contrib_phantom
user_guide_contrib_linac
user_guide_contrib_spect
user_guide_contrib_pet

.. toctree::
:caption: How to migrate from Gate 9 to 10
Expand Down
184 changes: 6 additions & 178 deletions docs/source/user_guide/user_guide_contrib.rst
Original file line number Diff line number Diff line change
@@ -1,185 +1,13 @@
Contributions
=============

The "contribution folder" contains additional useful functions that do not belong to the core of gate.
The `contrib folder <https://github.com/OpenGATE/opengate/tree/master/opengate/contrib>`_ contains additional utilities and functionalities that extend the core capabilities of OpenGATE. These contributions include commonly used tools and configurations, such as:

Dose rate computation
---------------------
- Standard imaging phantoms (e.g., NEMA, IEC)
- Linac models
- Predefined SPECT and PET imaging systems

Dose rate computations can be performed using Monte Carlo simulations, especially in the context of dosimetry for targeted radionuclide therapy. To run the simulations, you need to use the following command:
Several tests within OpenGATE make use of these contributions to facilitate specific applications.

.. code:: python
If you would like to propose a new contribution, please contact the development team. Your additions can help enhance the functionality of OpenGATE for the entire community.

python dose_rate dose_rate_test1.json -o outputFolder/
The `dose_rate_test1.json` file contains the input parameters for the simulation: SPECT image, CT image, activity to simulate, radionuclide used, number of threads, and visualization settings.

.. code:: json
{
"# Input CT image": "",
"ct_image": "./dose_rate_data/29_CT_5mm.mhd",
"table_mat": "./dose_rate_data/Schneider2000MaterialsTable.txt",
"table_density": "./dose_rate_data/Schneider2000DensitiesTable.txt",
"density_tolerance_gcm3": 0.2,
"# Input activity image": "",
"activity_image": "./dose_rate_data/385_NM_5mm.mhd",
"# Input radionuclide": "",
"radionuclide": "Lu177",
"# Input total simulated activity in the whole image, in Bq": "",
"activity_bq": 1e6,
"# Option: number of threads": "",
"number_of_threads": 1,
"# Option: visualisation (for debug)": "",
"visu": false,
"# verbosity": "",
"verbose": true
}
The SPECT and CT images provide information on the bio-distribution of the source as well as the density of the different materials. The simulated activity can be relatively low compared to the actual administered activity to reduce simulation times. For example, 10 MBq can be simulated, and then the dose rates can be scaled according to the actual injected activity. However, be aware that the choice of simulated activity affects the uncertainties, which may be acceptable at the organ level but not at the voxel level. In the latter case, the activity should be increased.
By default, the simulation times are set to 1 second. They can be modified by adding the time interval corresponding to the duration of the acquisition with the following line. More details in the section “Run and timing” of the page “Description of the simulation object”.

.. code:: python
sim.run_timing_intervals = [[0, 3600 * sec]] for a total duration of one hour.
An alternative option is to account for radioactive decay by providing the radionuclide’s half-life. If the simulation starts at t=4s, with 10 MBq simulated, and the half-life of 4s, the simulation will consider 5 MBq instead of 10. The half-life can be added with the following line. More details in the section “Half-life and Time Activity Curve (TAC)” of the page “Source”.
.. code:: python
source.half_life = 60 * sec
At present, only four radionuclides can be used in these simulations: 177Lu, 90Y, 111In, and 131I.
To speed up the calculations, it is possible to increase the number of threads used. More information in the section “Multithreading” in the page “Description of the simulation object”. However, you can look at the source code of this tool, the file `opengate/contrib/dose/doserate.py` to create your own simulation.

The simulation generates five files: the dose rate map (`dose_edep.mhd`), the energy deposition map (`edep.mhd`), the uncertainties (`edep_uncertainty.mhd`), the labels of the CT image to material correspondance (labels.mhd), and the statistics from the simulation (`stats.txt`, simulation time, number of tracks, number of events, etc.).



Phantoms
--------

### Phantom: IEC 6 spheres NEMA phantom

An analytical model of the 6 spheres IEC NEMA phantom is provided. It can be used as follows:

.. code-block:: python
import opengate as gate
import opengate.contrib.phantoms.nemaiec as gate_iec
sim = gate.Simulation()
iec_phantom = gate_iec.add_iec_phantom(sim, 'iec_phantom')
activities = [3 * BqmL, 4 * BqmL, 5 * BqmL, 6 * BqmL, 9 * BqmL, 12 * BqmL]
iec_source = gate_iec.add_spheres_sources(sim, 'iec_phantom', 'iec_source', 'all', activities)
iec_bg_source = gate_iec.add_background_source(sim, 'iec_phantom', 'iec_bg_source', 0.1 * BqmL)
The rotation should be adapted according to your need. The order of the 6 spheres can be changed with the parameter `sphere_starting_angle` of the `add_iec_phantom` command.

.. image:: ../figures/iec_6spheres.png

Examples can be found in `test015 <https://github.com/OpenGATE/opengate/blob/master/opengate/tests/src/test015_iec_phantom_1.py>`_ (and others).

### Phantom: cylinder phantom for PET NECR

An analytical model of the simple NECR phantom (cylinder and linear source) is provided. It can be used as follows:

.. code-block:: python
import opengate as gate
import opengate.contrib.phantoms.necr as gate_necr
sim = gate.Simulation()
necr_phantom = gate_necr.add_necr_phantom(sim, 'necr_phantom')
necr_source = gate_necr.add_necr_source(sim, 'necr_phantom')
necr_source.activity = 1000 * Bq
Example can be found in `test049 <https://github.com/OpenGATE/opengate/blob/master/opengate/tests/src/test049_pet_digit_blurring_v1.py>`_ (and others).

Radiation therapy linac
-----------------------

**Important Notice**: Please be aware that the models provided within the OpenGate toolkit are based on approximate simulations. Users are strongly encouraged to independently verify these models against empirical data to ensure their applicability and accuracy for specific use cases.

The following models are available:

- Elekta Synergy, without patient-specific collimation systems
- Elekta Versa HD, with Agility multileaf collimator (160 leaves) and back-up jaws.

.. code-block:: python
import opengate as gate
import opengate.contrib.linacs.elektasynergy as synergy
import opengate.contrib.linacs.elektaversa as versa
sim = gate.Simulation()
linac1 = synergy.add_linac(sim)
linac2 = versa.add_linac(sim)
### LINACs reference systems

Each LINAC head is simulated with a z-axis translation relative to the world center. This translation aligns the machine's isocenter with the world center, with a user-defined Source-Axis Distance (SAD). The "translation_from_sad" function (example in `test019_linac_elekta_versa.py <https://github.com/OpenGATE/opengate/blob/master/opengate/tests/src/test019_linac_elekta_versa.py>`_) can be used to move the LINAC head with a translation relative to the SAD.

.. image:: ../figures/explicaton_linac_reference.png

The "rotation_around_user_point" function enables LINAC head rotation around either the world center (i.e., the isocenter) or a user-defined point. Axis and angle lists for each axis must be defined in a way consistent with `Rotation.from_euler <https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.transform.Rotation.from_euler.html>`_. An example illustrating how to use this function is available in `test019_elekta_versa.py <https://github.com/OpenGATE/opengate/blob/master/opengate/tests/src/test019_linac_elekta_versa.py>`_.

...

(Full details of LINACs sources, fields, collimators, and more continue here in a similar structured format, depending on the sections and sub-sections required.)

...

SPECT imaging systems
---------------------

**Important Notice**: Please be aware that the models provided within the OpenGate toolkit are based on approximate simulations. Users are strongly encouraged to independently verify these models against empirical data to ensure their applicability and accuracy for specific use cases.

The following models are available:

- GE Discovery 670 SPECT
- Siemens Symbia Intevo Bold SPECT

.. code-block:: python
import opengate as gate
import opengate.contrib.spect.ge_discovery_nm670 as discovery
import opengate.contrib.spect.siemens_intevo as intevo
sim = gate.Simulation()
spect = discovery.add_spect_head(sim, "discovery1", collimator_type="melp")
crystal = sim.volume_manager.get_volume(f"{spect.name}_crystal")
discovery.add_digitizer_tc99m(sim, crystal.name, "digit_tc99m")
spect = discovery.add_spect_head(sim, "discovery12", collimator_type="lehr")
crystal = sim.volume_manager.get_volume(f"{spect.name}_crystal")
discovery.add_digitizer_lu177(sim, crystal.name, "digit_lu177")
spect = intevo.add_spect_head(sim, "intevo1", collimator_type="melp")
crystal = sim.volume_manager.get_volume(f"{spect.name}_crystal")
intevo.add_digitizer_tc99m(sim, crystal.name, "digit_tc99m")
spect = discovery.add_spect_head(sim, "intevo2", collimator_type="lehr")
crystal = sim.volume_manager.get_volume(f"{spect.name}_crystal")
intevo.add_digitizer_lu177(sim, crystal.name, "digit_lu177")
test028

PET imaging systems
-------------------

**Important Notice**: Please be aware that the models provided within the OpenGate toolkit are based on approximate simulations. Users are strongly encouraged to independently verify these models against empirical data to ensure their applicability and accuracy for specific use cases.

The following models are available:

- Philips Vereos Digital PET
- Siemens Biograph Vision PET

test037
57 changes: 57 additions & 0 deletions docs/source/user_guide/user_guide_contrib_dose_rate.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
Dose rate computation
=====================

Dose rate computations can be performed using Monte Carlo simulations, especially in the context of dosimetry for targeted radionuclide therapy. To run the simulations, you need to use the following command:

.. code:: python
python dose_rate dose_rate_test1.json -o outputFolder/
The `dose_rate_test1.json` file contains the input parameters for the simulation: SPECT image, CT image, activity to simulate, radionuclide used, number of threads, and visualization settings.

.. code:: json
{
"# Input CT image": "",
"ct_image": "./dose_rate_data/29_CT_5mm.mhd",
"table_mat": "./dose_rate_data/Schneider2000MaterialsTable.txt",
"table_density": "./dose_rate_data/Schneider2000DensitiesTable.txt",
"density_tolerance_gcm3": 0.2,
"# Input activity image": "",
"activity_image": "./dose_rate_data/385_NM_5mm.mhd",
"# Input radionuclide": "",
"radionuclide": "Lu177",
"# Input total simulated activity in the whole image, in Bq": "",
"activity_bq": 1e6,
"# Option: number of threads": "",
"number_of_threads": 1,
"# Option: visualisation (for debug)": "",
"visu": false,
"# verbosity": "",
"verbose": true
}
The SPECT and CT images provide information on the bio-distribution of the source as well as the density of the different materials. The simulated activity can be relatively low compared to the actual administered activity to reduce simulation times. For example, 10 MBq can be simulated, and then the dose rates can be scaled according to the actual injected activity. However, be aware that the choice of simulated activity affects the uncertainties, which may be acceptable at the organ level but not at the voxel level. In the latter case, the activity should be increased.
By default, the simulation times are set to 1 second. They can be modified by adding the time interval corresponding to the duration of the acquisition with the following line. More details in the section “Run and timing” of the page “Description of the simulation object”.

.. code:: python
sim.run_timing_intervals = [[0, 3600 * sec]] for a total duration of one hour.
An alternative option is to account for radioactive decay by providing the radionuclide’s half-life. If the simulation starts at t=4s, with 10 MBq simulated, and the half-life of 4s, the simulation will consider 5 MBq instead of 10. The half-life can be added with the following line. More details in the section “Half-life and Time Activity Curve (TAC)” of the page “Source”.
.. code:: python
source.half_life = 60 * sec
At present, only four radionuclides can be used in these simulations: 177Lu, 90Y, 111In, and 131I.
To speed up the calculations, it is possible to increase the number of threads used. More information in the section “Multithreading” in the page “Description of the simulation object”. However, you can look at the source code of this tool, the file `doserate.py <https://github.com/OpenGATE/opengate/blob/master/opengate/contrib/dose/doserate.py>`_ to create your own simulation.

The simulation generates five files: the dose rate map (`dose_edep.mhd`), the energy deposition map (`edep.mhd`), the uncertainties (`edep_uncertainty.mhd`), the labels of the CT image to material correspondance (labels.mhd), and the statistics from the simulation (`stats.txt`, simulation time, number of tracks, number of events, etc.).

38 changes: 38 additions & 0 deletions docs/source/user_guide/user_guide_contrib_linac.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
Radiation therapy linac
=======================

**Important Notice**: Please be aware that the models provided within the OpenGate toolkit are based on approximate simulations. Users are strongly encouraged to independently verify these models against empirical data to ensure their applicability and accuracy for specific use cases.

Elekta Synergy (no collimator)
------------------------------

This example comes without a patient-specific collimation system.

.. code-block:: python
import opengate as gate
import opengate.contrib.linacs.elektasynergy as synergy
sim = gate.Simulation()
linac = synergy.add_linac(sim)
Elekta Versa HD
---------------

This linac is with the Agility multileaf collimator (160 leaves) and back-up jaws.

.. code-block:: python
import opengate as gate
import opengate.contrib.linacs.elektaversa as versa
sim = gate.Simulation()
linac = versa.add_linac(sim)
Each LINAC head is simulated with a z-axis translation relative to the world center. This translation aligns the machine's isocenter with the world center, with a user-defined Source-Axis Distance (SAD). The "translation_from_sad" function (example in `test019_linac_elekta_versa.py <https://github.com/OpenGATE/opengate/blob/master/opengate/tests/src/test019_linac_elekta_versa.py>`_) can be used to move the LINAC head with a translation relative to the SAD.

.. image:: ../figures/linac_versa_reference.png

The "rotation_around_user_point" function enables LINAC head rotation around either the world center (i.e., the isocenter) or a user-defined point. Axis and angle lists for each axis must be defined in a way consistent with `Rotation.from_euler <https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.transform.Rotation.from_euler.html>`_. An example illustrating how to use this function is available in `test019_elekta_versa.py <https://github.com/OpenGATE/opengate/blob/master/opengate/tests/src/test019_linac_elekta_versa.py>`_.

42 changes: 42 additions & 0 deletions docs/source/user_guide/user_guide_contrib_pet.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
PET imaging systems
===================

**Important Notice**: Please be aware that the models provided within the OpenGate toolkit are based on approximate simulations. Users are strongly encouraged to independently verify these models against empirical data to ensure their applicability and accuracy for specific use cases.


Philips Vereos Digital PET
--------------------------

The Philips Vereos Digital PET model can be included in your simulation using the following command:


.. code-block:: python
import opengate.contrib.pet.philipsvereos as pet_vereos
pet = pet_vereos.add_pet(sim, "my_pet")
This command will include the whole PET head as described in `[Salvadori2020, EJNMMI] <http://doi.org/10.1186/s40658-020-00288-w>`_. It comprises 18 modules, each containing 4x5 stacks of 4x4 die, with each die consisting of 2x2 crystals.

Detail of the head description is `available here <https://github.com/OpenGATE/opengate/blob/master/opengate/contrib/pet/philipsvereos.py#L39>`_

**Note**: A validated digitizer for this PET model is not yet available. Development is ongoing. For examples, refer to the test037 test case.

Siemens Biograph Vision PET
---------------------------

To include the Siemens Biograph Vision PET model in your simulation, use the following commands:


.. code-block:: python
import opengate.contrib.pet.siemensbiograph as pet_biograph
pet = pet_biograph.add_pet(sim, "my_pet")
singles = pet_biograph.add_digitizer(sim, pet.name, "singles.root", "Singles")
This command will include the whole PET head as described in `[Salvadori2024, PMB] <http://doi.org/10.1088/1361-6560/ad638c>`_ or `[O'Briain 2022 MedPhys] <http://doi.org/10.1002/mp.16032>`_.

Detail of the head description is `available here <https://github.com/OpenGATE/opengate/blob/master/opengate/contrib/pet/siemensbiograph.py#L15>`_

**Note**: The provided digitizer is an illustrative example and has not yet been validated. For additional context, refer to the test049 test case.
41 changes: 41 additions & 0 deletions docs/source/user_guide/user_guide_contrib_phantom.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
Phantoms
========

Phantom: IEC 6 spheres NEMA phantom
-----------------------------------

An analytical model of the 6 spheres IEC NEMA phantom is provided. It can be used as follows:

.. code-block:: python
import opengate as gate
import opengate.contrib.phantoms.nemaiec as gate_iec
sim = gate.Simulation()
iec_phantom = gate_iec.add_iec_phantom(sim, 'iec_phantom')
activities = [3 * BqmL, 4 * BqmL, 5 * BqmL, 6 * BqmL, 9 * BqmL, 12 * BqmL]
iec_source = gate_iec.add_spheres_sources(sim, 'iec_phantom', 'iec_source', 'all', activities)
iec_bg_source = gate_iec.add_background_source(sim, 'iec_phantom', 'iec_bg_source', 0.1 * BqmL)
The rotation should be adapted according to your need. The order of the 6 spheres can be changed with the parameter `sphere_starting_angle` of the `add_iec_phantom` command.

.. image:: ../figures/iec_6spheres.png

Examples can be found in `test015 <https://github.com/OpenGATE/opengate/blob/master/opengate/tests/src/test015_iec_phantom_1.py>`_ (and others).

Phantom: cylinder phantom for PET NECR
--------------------------------------

An analytical model of the simple NECR phantom (cylinder and linear source) is provided. It can be used as follows:

.. code-block:: python
import opengate as gate
import opengate.contrib.phantoms.necr as gate_necr
sim = gate.Simulation()
necr_phantom = gate_necr.add_necr_phantom(sim, 'necr_phantom')
necr_source = gate_necr.add_necr_source(sim, 'necr_phantom')
necr_source.activity = 1000 * Bq
Example can be found in `test049 <https://github.com/OpenGATE/opengate/blob/master/opengate/tests/src/test049_pet_digit_blurring_v1.py>`_ (and others).
Loading

0 comments on commit 737a600

Please sign in to comment.