Low-level TOF listmode projection example

A minimal example that shows how to use the joseph3d TOF forward and back projector in sinogram mode.

Tip

parallelproj is python array API compatible meaning it supports different array backends (e.g. numpy, cupy, torch, …) and devices (CPU or GPU). Choose your preferred array API xp and device dev below.

https://mybinder.org/badge_logo.svg
17 import array_api_compat.numpy as xp
18
19 # import array_api_compat.cupy as xp
20 # import array_api_compat.torch as xp
21
22 import parallelproj
23 from array_api_compat import to_device, device
24
25 # choose a device (CPU or CUDA GPU)
26 if "numpy" in xp.__name__:
27     # using numpy, device must be cpu
28     dev = "cpu"
29 elif "cupy" in xp.__name__:
30     # using cupy, only cuda devices are possible
31     dev = xp.cuda.Device(0)
32 elif "torch" in xp.__name__:
33     # using torch valid choices are 'cpu' or 'cuda'
34     dev = "cuda"

Setup a simple test image

40 # setup the image dimensions
41 n0, n1, n2 = (7, 7, 7)
42 img_dim = (n0, n1, n2)
43
44 # define the voxel sizes (in physical units)
45 voxel_size = to_device(xp.asarray([2.0, 2.0, 2.0], dtype=xp.float32), dev)
46 # define the origin of the image (location of voxel (0,0,0) in physical units)
47 img_origin = (
48     -to_device(xp.asarray(img_dim, dtype=xp.float32), dev) / 2 + 0.5
49 ) * voxel_size
50
51 # create a simple test image
52 img = to_device(xp.zeros((n0, n1, n2), dtype=xp.float32), dev)
53 img[n0 // 2, n1 // 2, n2 // 2] = 1

Setup the LOR start and end points

59 # Every line of response (LOR) along which we want to project is
60 # defined by its start point (3 element array) and end point (3 element array).
61 # Here we define 2 LORs and group all start and end points in two
62 # 2D arrays of shape (2,3).
63
64 # We first define the LORs start/end points in voxel coordinates (for convenience)
65 # and convert them later to physical units (as required for the projectors)
66
67 # define start/end points in voxel coordinates
68 vstart = to_device(
69     xp.asarray(
70         [
71             [n0 // 2, -1, n2 // 2],  #
72             [n0 // 2, n1 // 2, -1],  #
73         ],
74         dtype=xp.float32,
75     ),
76     dev,
77 )
78
79 vend = to_device(
80     xp.asarray(
81         [
82             [n0 // 2, n1, n2 // 2],
83             [n0 // 2, n1 // 2, n2],  #
84         ],
85         dtype=xp.float32,
86     ),
87     dev,
88 )
89
90 # convert the LOR coordinates to world coordinates (physical units)
91 xstart = vstart * voxel_size + img_origin
92 xend = vend * voxel_size + img_origin

Call the forward projector

129 img_fwd = parallelproj.joseph3d_fwd_tof_lm(
130     xstart,
131     xend,
132     img,
133     img_origin,
134     voxel_size,
135     tofbin_width,
136     sigma_tof,
137     tofcenter_offset,
138     nsigmas,
139     tof_bin,
140 )
141
142 print(img_fwd)
143 print(type(img_fwd))
144 print(device(img_fwd))
145 print("")
[0.46335313 0.3918243 ]
<class 'numpy.ndarray'>
cpu

Call the adjoint of the forward projector

151 # setup a list of ones to be back projected
152 lst = to_device(xp.ones(img_fwd.shape, dtype=xp.float32), dev)
153
154 back_img = parallelproj.joseph3d_back_tof_lm(
155     xstart,
156     xend,
157     img_dim,
158     img_origin,
159     voxel_size,
160     lst,
161     tofbin_width,
162     sigma_tof,
163     tofcenter_offset,
164     nsigmas,
165     tof_bin,
166 )
167
168 print(back_img[:, :, 3])
169 print(type(back_img))
170 print(device(back_img))
[[0.         0.         0.         0.         0.         0.
  0.        ]
 [0.         0.         0.         0.         0.         0.
  0.        ]
 [0.         0.         0.         0.         0.         0.
  0.        ]
 [0.03164449 0.14060059 0.34391424 0.8551774  0.34391424 0.14060059
  0.03164449]
 [0.         0.         0.         0.         0.         0.
  0.        ]
 [0.         0.         0.         0.         0.         0.
  0.        ]
 [0.         0.         0.         0.         0.         0.
  0.        ]]
<class 'numpy.ndarray'>
cpu

Total running time of the script: (0 minutes 0.003 seconds)

Related examples

Low-level TOF sinogram projection example

Low-level TOF sinogram projection example

Low-level non-TOF projection example

Low-level non-TOF projection example

PET non-TOF sinogram projector

PET non-TOF sinogram projector

TOF listmode MLEM with projection data

TOF listmode MLEM with projection data

Gallery generated by Sphinx-Gallery