Skip to content

Commit 09a261a

Browse files
committed
DOC: Add full Python example
Add a new Python example that illustrate the full reconstruction workflow, from the GATE simulation until the final FDK reconstruction.
1 parent a44b861 commit 09a261a

5 files changed

Lines changed: 91 additions & 0 deletions

File tree

documentation/docs/getting_started.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ The resulting image can be visualized by any MHD image viewer, such as [vv](http
136136

137137
Note that to keep the running times in this guide fast enough, not enough statistics are generated to yield a nice output image. This is just an illustration of the PCT reconstruction workflow.
138138

139+
PCT also provides Python functions that behave exactly like the applications described above. For illustration, the exact same simulation than the one described in this page is reimplemented in Python in the file [`examples/Reconstruction/Reconstruction.py`](https://github.com/RTKConsortium/PCT/tree/main/examples/Reconstruction/Reconstruction.py).
140+
139141
## Conclusion
140142

141143
This guide gives an overview of a complete workflow that uses GATE to generate proton CT data, and PCT to process the data all the way to image reconstruction. To further familiarize yourself with PCT, you can explore the other applications offered by PCT, customize the current workflow with additional parameters using the `--help` flag, or implement your own simulation in GATE and try to produce a reconstruction.

examples/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Python examples
2+
3+
This section provides a collection of Python code examples to demonstrate how to effectively use PCT in various applications.
4+
5+
```{toctree}
6+
:maxdepth: 1
7+
8+
./Reconstruction/README.md
9+
```

examples/Reconstruction/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Reconstruction
2+
3+
A simple but complete pCT reconstruction workflow, starting from GATE Monte Carlo data, illustrating how to:
4+
- pair protons between the two detectors;
5+
- create distance-driven projections from the paired protons;
6+
- reconstruct an image using distance-driven FDK.
7+
8+
## Code
9+
10+
```{literalinclude} ./Reconstruction.py
11+
:language: python
12+
```
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/usr/bin/env python
2+
3+
import os
4+
import sys
5+
import warnings
6+
from itk import PCT as pct
7+
from itk import RTK as rtk
8+
from opengate.contrib.protonct.protonct import protonct
9+
10+
if len(sys.argv) < 1:
11+
print("Usage: python Reconstruction.py <outputfolder>")
12+
sys.exit(1)
13+
14+
output_folder = sys.argv[1]
15+
16+
number_of_projections = 90
17+
18+
# Generate some data
19+
gate_folder = os.path.join(output_folder, "gate")
20+
protonct(gate_folder, projections=number_of_projections, verbose=False)
21+
22+
# TODO example on how to make data noisy
23+
24+
# Convert GATE data to PCT list-mode
25+
pairs_folder = os.path.join(output_folder, "pairs")
26+
os.makedirs(pairs_folder, exist_ok=True)
27+
pct.pctpairprotons(
28+
input_in=os.path.join(gate_folder, "PhaseSpaceIn.root"),
29+
input_out=os.path.join(gate_folder, "PhaseSpaceOut.root"),
30+
output=os.path.join(pairs_folder, "pairs.mhd"),
31+
psin="PhaseSpaceIn",
32+
psout="PhaseSpaceOut",
33+
plane_in=-110.0,
34+
plane_out=110.0,
35+
verbose=True,
36+
)
37+
38+
# TODO cut the pairs (pctpaircuts is not converted to Python yet)
39+
40+
# Bin the pairs into projections
41+
projections_folder = os.path.join(output_folder, "projections")
42+
os.makedirs(projections_folder, exist_ok=True)
43+
for p in range(number_of_projections):
44+
pct.pctbinning(
45+
input=os.path.join(pairs_folder, f"pairs{p:04d}.mhd"),
46+
output=os.path.join(projections_folder, f"projections{p}.mhd"),
47+
source=-1000.0,
48+
size=[200, 1, 200],
49+
spacing=[2.0, 1.0, 1.0],
50+
verbose=True,
51+
)
52+
53+
# Build geometry
54+
geometry = os.path.join(output_folder, "geometry.xml")
55+
rtk.rtksimulatedgeometry(
56+
nproj=number_of_projections, output=geometry, sdd=1000.0 + 110.0, sid=1000.0
57+
)
58+
59+
# Reconstruct
60+
pct.pctfdk(
61+
geometry=geometry,
62+
path=projections_folder,
63+
regexp=r"projections.*\.mhd",
64+
output=os.path.join(output_folder, "recon.mhd"),
65+
size=[210, 1, 210],
66+
verbose=True,
67+
)

index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ documentation/docs/installation.md
2222
documentation/docs/getting_started.md
2323
documentation/docs/pct_format.md
2424
documentation/docs/wepl_calibration.md
25+
examples/README.md
2526
```
2627

2728
```{toctree}

0 commit comments

Comments
 (0)