You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Free Flight is a variance reduction technique designed to accelerate simulations, particularly in SPECT imaging, by replacing stochastic particle transport with analytical probability calculations[cite: 248]. Instead of tracking a photon step-by-step through a collimator or SPECT head, these actors analytically "project" the probability of a photon reaching a target volume (like a detector plane) without interaction. See paper [Sarrut et al, PMB, 2026, to appear].
1037
+
1038
+
1039
+
OpenGATE provides two main actors for this purpose:
1040
+
1041
+
* **GammaFreeFlightActor**: Primarily used for "primary" photons (unscattered) or those originating directly from the source.
1042
+
* **ScatterSplittingFreeFlightActor**: Used to handle photons that undergo Compton or Rayleigh scattering within a volume, such as a patient phantom.
1043
+
1044
+
GammaFreeFlightActor
1045
+
~~~~~~~~~~~~~~~~~~~~
1046
+
1047
+
This actor is typically attached to the world or a specific phantom volume. It ensures that photons directed towards the detector are accounted for analytically[cite: 249]. It is often used in conjunction with **Forced Direction** or **Angular Acceptance** source settings to focus the simulation on the detector's field of view.
1048
+
1049
+
.. code-block:: python
1050
+
1051
+
# Add the actor to the simulation
1052
+
ff = sim.add_actor("GammaFreeFlightActor", "ff")
1053
+
ff.attached_to ="world"
1054
+
1055
+
# Optionally exclude specific volumes like the detector crystal
1056
+
# to let standard Geant4 tracking take over once the particle reaches the detector.
1057
+
ff.exclude_volumes = ["spect_1_crystal"]
1058
+
1059
+
1060
+
1061
+
ScatterSplittingFreeFlightActor
1062
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1063
+
1064
+
The ``ScatterSplittingFreeFlightActor`` handles the calculation of scattered radiation contributions. When a photon interacts, this actor "splits" the interaction into multiple analytical paths directed toward the detector, weighted by the physics of the interaction (e.g., Klein-Nishina cross-section).
1065
+
1066
+
* **compton_splitting_factor / rayleigh_splitting_factor**: Defines how many analytical photons are generated per interaction.
1067
+
* **kill_interacting_in_volumes**: Volumes where the original interacting particle should be stopped to avoid double counting.
1068
+
* **angular_acceptance**: Filters the analytical scattered photons to only those heading toward the detector.
Because Free Flight separates simulations into primary and scatter components, results must be merged offline. To obtain a statistically sound result, one must sum the mean counts per event from each step and propagate the variance.
1092
+
1093
+
The helper function ``merge_freeflight_uncertainty`` automates this by processing the ``counts.mhd`` and ``squared_counts.mhd`` files from each subfolder (e.g., primary, scatter).
1094
+
1095
+
**Statistical Equations:**
1096
+
1097
+
* Let $C_i$ be the raw counts and $C2_i$ the squared counts for step $i$ with $N_i$ events.
1098
+
* Mean per event: $E[X_i] = C_i / N_i$.
1099
+
* Variance of the mean: $Var(E[X_i]) = (E[X_i^2] - (E[X_i])^2) / (N_i - 1)$.
1100
+
* Total Mean: $E[X_{total}] = \sum E[X_i]$.
1101
+
* Final Relative Uncertainty: $R = \frac{\sqrt{\sum Var(E[X_i])}}{E[X_{total}]}$.
1102
+
1103
+
**Usage of Helpers:**
1104
+
1105
+
.. code-block:: python
1106
+
1107
+
from opengate.contrib.spect.spect_freeflight_helpers import merge_freeflight_uncertainty
1108
+
from pathlib import Path
1109
+
1110
+
# Define parameters
1111
+
folder = Path("./output_simu")
1112
+
ref_n =1e8# Target reference number of events
1113
+
subfolders = ["primary", "scatter"]
1114
+
num_events = [1e6, 2e5] # Number of simulated events in each subfolder
1115
+
1116
+
# Merge images and calculate uncertainty for head 0
0 commit comments