-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #568 from OpenGATE/doc_contrib
Add user guide docs for new SPECT, PET, and Linac models
- Loading branch information
Showing
8 changed files
with
252 additions
and
178 deletions.
There are no files selected for viewing
File renamed without changes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.). | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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>`_. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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). |
Oops, something went wrong.