99import petsird
1010import matplotlib .pyplot as plt
1111import math
12+ import json
1213
14+ from pathlib import Path
1315
14- # %% c
16+
17+ # %%
1518def circular_distance (i_mod_1 : int , i_mod_2 : int , num_modules : int ) -> int :
1619 clockwise_distance = abs (i_mod_1 - i_mod_2 )
1720 counterclockwise_distance = num_modules - clockwise_distance
@@ -36,11 +39,12 @@ def module_pair_eff_from_sgd(i_sgd: int) -> float:
3639# parse the command line for the input parameters below
3740parser = argparse .ArgumentParser ()
3841
39- parser .add_argument ("--fname" , type = str , default = "sim_lm.bin" )
42+ parser .add_argument ("--fname" , type = str , default = "simulated_lm_file.bin" )
43+ parser .add_argument ("--output_dir" , type = str , default = "my_lm_sim" )
4044parser .add_argument ("--num_true_counts" , type = int , default = int (1e6 ))
4145parser .add_argument ("--show_plots" , default = False , action = "store_true" )
4246parser .add_argument ("--check_backprojection" , default = False , action = "store_true" )
43- parser .add_argument ("--run_recon " , default = False , action = "store_true" )
47+ parser .add_argument ("--run_histogram_mlem " , default = False , action = "store_true" )
4448parser .add_argument ("--num_iter" , type = int , default = 10 )
4549parser .add_argument ("--skip_writing" , default = False , action = "store_true" )
4650parser .add_argument ("--fwhm_mm" , type = float , default = 1.5 )
@@ -58,15 +62,24 @@ def module_pair_eff_from_sgd(i_sgd: int) -> float:
5862fname = args .fname
5963show_plots = args .show_plots
6064check_backprojection = args .check_backprojection
61- run_recon = args .run_recon
65+ run_histogram_mlem = args .run_histogram_mlem
6266num_true_counts = args .num_true_counts
6367skip_writing = args .skip_writing
6468num_iter = args .num_iter
6569fwhm_mm = args .fwhm_mm
6670tof_fwhm_mm = args .tof_fwhm_mm
6771seed = args .seed
6872phantom = args .phantom
73+ output_dir = Path (args .output_dir )
74+
75+ if not output_dir .exists ():
76+ output_dir .mkdir (parents = True )
6977
78+ # dump args into a json file output_dir / "args.json"
79+ with open (output_dir / "sim_parameters.json" , "w" ) as f :
80+ json .dump (vars (args ), f , indent = 4 )
81+
82+ # %%
7083dev = "cpu"
7184xp .random .seed (args .seed )
7285
@@ -262,8 +275,9 @@ def module_pair_eff_from_sgd(i_sgd: int) -> float:
262275# TOF backproject a "TOF histogram" full of ones ("sensitivity image" when attenuation
263276# and normalization are ignored)
264277
265- ones_back_tof = fwd_op .adjoint (xp .ones (fwd_op .out_shape , dtype = xp .float32 , device = dev ))
266- print (ones_back_tof .shape )
278+ sens_img = fwd_op .adjoint (xp .ones (fwd_op .out_shape , dtype = xp .float32 , device = dev ))
279+ xp .save (output_dir / "reference_sensitivity_image.npy" , sens_img )
280+ print (sens_img .shape )
267281
268282# %%
269283# put poisson noise on the forward projection
@@ -276,18 +290,19 @@ def module_pair_eff_from_sgd(i_sgd: int) -> float:
276290 emission_data = img_fwd_tof
277291
278292# %%
279- if run_recon :
293+ if run_histogram_mlem :
280294 recon = xp .ones (img_shape , dtype = xp .float32 , device = dev )
281295
282296 for i in range (num_iter ):
283297 print (f"{ (i + 1 ):03} /{ num_iter :03} " , end = "\r " )
284298
285299 exp = xp .clip (fwd_op (recon ), 1e-6 , None )
286300 grad = fwd_op .adjoint ((exp - emission_data ) / exp )
287- step = recon / ones_back_tof
301+ step = recon / sens_img
288302 recon -= step * grad
289303
290304 print ("" )
305+ xp .save (output_dir / f"reference_histogram_mlem_{ num_iter } .npy" , recon )
291306
292307# %%
293308# convert emission histogram to LM
@@ -382,13 +397,13 @@ def module_pair_eff_from_sgd(i_sgd: int) -> float:
382397
383398if show_plots :
384399 fig6 , ax6 = plt .subplots (1 , 4 , figsize = (12 , 3 ), tight_layout = True )
385- vmin = float (xp .min (ones_back_tof ))
386- vmax = float (xp .max (ones_back_tof ))
400+ vmin = float (xp .min (sens_img ))
401+ vmax = float (xp .max (sens_img ))
387402 for i , sl in enumerate (
388403 [img_shape [2 ] // 4 , img_shape [2 ] // 2 , 3 * img_shape [2 ] // 4 ]
389404 ):
390405 ax6 [i ].imshow (
391- parallelproj .to_numpy_array (ones_back_tof [:, :, sl ]),
406+ parallelproj .to_numpy_array (sens_img [:, :, sl ]),
392407 vmin = vmin ,
393408 vmax = vmax ,
394409 cmap = "Greys" ,
@@ -610,7 +625,7 @@ def module_pair_eff_from_sgd(i_sgd: int) -> float:
610625
611626 if not skip_writing :
612627 print ("Writing LM file" )
613- with petsird .BinaryPETSIRDWriter (fname ) as writer :
628+ with petsird .BinaryPETSIRDWriter (str ( output_dir / fname ) ) as writer :
614629 writer .write_header (header )
615630 for i_t in range (1 ):
616631 start = i_t * header .scanner .event_time_block_duration
0 commit comments