Skip to content

Commit 350ba5a

Browse files
Georg SchrammGeorg Schramm
authored andcommitted
finish first implementation of sens. image calculation
1 parent 8b2d817 commit 350ba5a

File tree

1 file changed

+30
-4
lines changed

1 file changed

+30
-4
lines changed

python/recon_block_scanner_listmode_data.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,6 @@ def transform_BoxShape(
144144
)
145145
det_element_center_list.append(det_element_centers)
146146

147-
# %%
148-
# calculate the sensitivity image
149-
150147
# create a list of the element detection efficiencies per module
151148
# this is a simple re-ordering of the detection efficiencies array which
152149
# makes the access easier
@@ -158,12 +155,29 @@ def transform_BoxShape(
158155
for i in range(num_modules)
159156
]
160157

158+
num_tofbins = len(header.scanner.tof_bin_edges) - 1
159+
tofbin_width = header.scanner.tof_bin_edges[1] - header.scanner.tof_bin_edges[0]
160+
sigma_tof = header.scanner.tof_resolution / 2.35
161+
162+
tof_params = parallelproj.TOFParameters(
163+
num_tofbins=num_tofbins, tofbin_width=tofbin_width, sigma_tof=sigma_tof
164+
)
165+
166+
assert num_tofbins % 2 == 1, "Number of TOF bins must be odd"
167+
# %%
168+
# calculate the sensitivity image
169+
170+
161171
# we loop through the symmetric group ID look up table to see which module pairs
162172
# are in coincidence
163173

164174
img_shape = (100, 100, 11)
165175
voxel_size = (1.0, 1.0, 1.0)
166176

177+
fwhm_mm = 1.5
178+
sig = fwhm_mm / (2.35 * xp.asarray(voxel_size, device=dev))
179+
res_model = parallelproj.GaussianFilterOperator(img_shape, sigma=sig)
180+
167181
sens_img = xp.zeros(img_shape, dtype="float32")
168182

169183
for i in range(num_modules):
@@ -184,6 +198,8 @@ def transform_BoxShape(
184198
proj = parallelproj.ListmodePETProjector(
185199
start_coords, end_coords, img_shape, voxel_size
186200
)
201+
proj.tof_parameters = tof_params
202+
187203
# TODO: add TOF parameters
188204

189205
# get the module pair efficiencies - asumming that we only use 1 energy bin
@@ -197,7 +213,17 @@ def transform_BoxShape(
197213
end_el_eff = xp.tile(det_el_efficiencies[j], (len(start_det_el)))
198214

199215
# TODO loop over TOF!
200-
sens_img += proj.adjoint(start_el_eff * end_el_eff * module_pair_eff)
216+
for tofbin in xp.arange(-(num_tofbins // 2), num_tofbins // 2 + 1):
217+
# print(tofbin)
218+
proj.event_tofbins = xp.full(
219+
start_coords.shape[0], tofbin, dtype="int32"
220+
)
221+
sens_img += proj.adjoint(start_el_eff * end_el_eff * module_pair_eff)
222+
223+
# for some reason we have to divide the sens image by the number of TOF bins
224+
# right now unclear why that is
225+
sens_img /= num_tofbins
226+
sens_img = res_model.adjoint(sens_img)
201227

202228
# %%
203229
# read all coincidence events

0 commit comments

Comments
 (0)