66from scipy .ndimage import zoom
77from utilities .data_simulation .Download_data import download_data
88
9- if __name__ == "__main__" :
9+ DIFFUSIVE_REGIME = 'diffusive'
10+ BALLISTIC_REGIME = 'ballistic'
11+
12+ def simulate_brain_phantom (regime = DIFFUSIVE_REGIME , snr = 100 , sim_relaxation = True , TE = 60e-3 , TR = 5 , resolution = [3 ,3 ,3 ]):
13+ '''
14+ Simulation parameters can be set by changing the default values of the function arguments.
15+ The default values are chosen to be suitable for a diffusive regime phantom, but can be changed to simulate a ballistic regime phantom as well.
16+ The simulated image is saved in phantoms/brain/data with the name 'diffusive_sn{snr}.nii.gz' or 'ballistic_sn{snr}.nii.gz' depending on the regime.
17+ The corresponding bvals and cvals (if applicable) are also saved in the same folder.
18+
19+ regime: 'diffusive' or 'ballistic' to choose the type of phantom to simulate
20+ snr: signal-to-noise ratio of the simulated image
21+ sim_relaxation: whether to simulate T1 and T2 relaxation effects in the signal
22+ TE: echo time in seconds
23+ TR: repetition time in seconds
24+ resolution: voxel size in mm
25+ '''
1026 download_data ()
1127
12- DIFFUSIVE_REGIME = 'diffusive'
13- BALLISTIC_REGIME = 'ballistic'
1428
1529 folder = os .path .dirname (__file__ )
1630
17- ###########################
18- # Simulation parameters #
19- regime = DIFFUSIVE_REGIME
20- snr = 200
21- resolution = [3 ,3 ,3 ]
22- # #
23- ###########################
24-
25-
2631 # Ground truth
2732 nii = nib .load (os .path .join (os .path .split (os .path .split (folder )[0 ])[0 ],'download' ,'Phantoms' ,'brain' ,'ground_truth' ,'hrgt_icbm_2009a_nls_3t.nii.gz' ))
2833 segmentation = np .squeeze (nii .get_fdata ()[...,- 1 ])
4045
4146 # Calculate signal
4247 S = np .zeros (list (np .shape (segmentation ))+ [b .size ])
43-
48+ print ( ivim_pars )
4449 if regime == BALLISTIC_REGIME :
4550 Db = ivim_pars ["Db" ]
46- for i ,(D ,f ,vd ) in enumerate (zip (ivim_pars ["D" ],ivim_pars ["f" ],ivim_pars ["vd" ])):
51+ for i ,(D ,f ,vd , T1 , T2 ) in enumerate (zip (ivim_pars ["D" ],ivim_pars ["f" ],ivim_pars ["vd" ], ivim_pars [ "T1" ], ivim_pars [ "T2 " ])):
4752 S [segmentation == i + 1 ,:] = S0 * ((1 - f )* np .exp (- b * D )+ f * np .exp (- b * Db - c ** 2 * vd ** 2 ))
53+ if sim_relaxation :
54+ S [segmentation == i + 1 ,:] *= np .exp (- TE / T2 )* (1 - np .exp (- TR / T1 ))
4855 else :
49- for i ,(D ,f ,Dstar ) in enumerate (zip (ivim_pars ["D" ],ivim_pars ["f" ],ivim_pars ["Dstar" ])):
56+ for i ,(D ,f ,Dstar , T1 , T2 ) in enumerate (zip (ivim_pars ["D" ],ivim_pars ["f" ],ivim_pars ["Dstar" ], ivim_pars [ "T1" ], ivim_pars [ "T2 " ])):
5057 S [segmentation == i + 1 ,:] = S0 * ((1 - f )* np .exp (- b * D )+ f * np .exp (- b * Dstar ))
58+ if sim_relaxation :
59+ S [segmentation == i + 1 ,:] *= np .exp (- TE / T2 )* (1 - np .exp (- TR / T1 ))
5160
5261 # Resample to suitable resolution
5362 im = zoom (S ,np .append (np .diag (nii .affine )[:3 ]/ np .array (resolution ),1 ),order = 1 )
5463 sz = im .shape
5564
56- # Add noise
65+ # Save image without noise for reference
66+ nii_out = nib .Nifti1Image (im ,np .eye (4 ))
67+ base_name = os .path .join (folder ,'data' ,'{}_reference' .format (regime ,snr ))
68+ nib .save (nii_out ,base_name + '.nii.gz' )
69+ shutil .copyfile (bval_file ,base_name + '.bval' )
70+
71+ # Add Rician noise
5772 im_noise = np .abs (im + S0 / snr * (np .random .randn (sz [0 ],sz [1 ],sz [2 ],sz [3 ])+ 1j * np .random .randn (sz [0 ],sz [1 ],sz [2 ],sz [3 ])))
5873
5974 # Save as image and sequence parameters
6277 nib .save (nii_out ,base_name + '.nii.gz' )
6378 shutil .copyfile (bval_file ,base_name + '.bval' )
6479 if regime == BALLISTIC_REGIME :
65- shutil .copyfile (cval_file ,base_name + '.cval' )
80+ shutil .copyfile (cval_file ,base_name + '.cval' )
81+
82+ # Resample and save segmentation
83+ segmentation = zoom (segmentation ,np .diag (nii .affine )[:3 ]/ np .array (resolution ),order = 0 )
84+ nii_out = nib .Nifti1Image (segmentation ,np .eye (4 ))
85+ base_name = os .path .join (folder ,'data' ,'{}_snr{}_mask' .format (regime ,snr ))
86+ nib .save (nii_out ,base_name + '.nii.gz' )
87+
88+
89+ if __name__ == "__main__" :
90+ simulate_brain_phantom ()
0 commit comments