22from scipy .io import loadmat
33import nibabel as nib
44import json
5+ import argparse
6+ import os
57from utilities .data_simulation .Download_data import download_data
68
79##########
1012# This code generates a 4D IVIM phantom as nifti file
1113
1214def phantom (bvalue , noise , TR = 3000 , TE = 40 , motion = False , rician = False , interleaved = False ):
13- download_data ()
1415 np .random .seed (42 )
1516 if motion :
1617 states = range (1 ,21 )
@@ -366,76 +367,124 @@ def XCAT_to_MR_DCE(XCAT, TR, TE, bvalue, D, f, Ds, b0=3, ivim_cont = True):
366367 return MR , Dim , fim , Dpim , legend
367368
368369if __name__ == '__main__' :
369- bvalue = np .array ([0. , 1 , 2 , 5 , 10 , 20 , 30 , 50 , 75 , 100 , 150 , 250 , 350 , 400 , 550 , 700 , 850 , 1000 ])
370- noise = 0.0005
371- motion = False
372- interleaved = False
373- sig , XCAT , Dim , fim , Dpim , legend = phantom (bvalue , noise , motion = motion , interleaved = interleaved )
374- # sig = np.flip(sig,axis=0)
375- # sig = np.flip(sig,axis=1)
376- res = np .eye (4 )
377- res [2 ]= 2
370+ parser = argparse .ArgumentParser (description = f"""
371+ A commandline for generating a 4D IVIM phantom as nifti file
372+ """ )
378373
379- voxel_selector_fraction = 0.5
380- D , f , Ds = contrast_curve_calc ()
381- ignore = np .isnan (D )
382- generic_data = {}
383- for level , name in legend .items ():
384- if len (ignore ) > level and ignore [level ]:
385- continue
386- selector = XCAT == level
387- voxels = sig [selector ]
388- if len (voxels ) < 1 :
389- continue
390- signals = np .squeeze (voxels [int (voxels .shape [0 ] * voxel_selector_fraction )]).tolist ()
391- generic_data [name ] = {
392- 'noise' : noise ,
393- 'D' : np .mean (Dim [selector ], axis = 0 ),
394- 'f' : np .mean (fim [selector ], axis = 0 ),
395- 'Dp' : np .mean (Dpim [selector ], axis = 0 ),
396- 'data' : signals
397- }
398- generic_data ['config' ] = {
399- 'bvalues' : bvalue .tolist ()
400- }
401- with open ('generic.json' , 'w' ) as f :
402- json .dump (generic_data , f , indent = 4 )
374+ def parse_bvalues_file (file_path ):
375+ """Used for passing the JSON file"""
376+ if not os .path .exists (file_path ):
377+ raise argparse .ArgumentTypeError (f"File '{ file_path } ' does not exist" )
403378
379+ try :
380+ with open (file_path , "r" ) as file :
381+ bvalues_dict = json .load (file )
382+ if not isinstance (bvalues_dict , dict ):
383+ raise argparse .ArgumentTypeError ("JSON file does not contain a dict of b-values" )
384+ for _ , bvalue in bvalues_dict .items ():
385+ if not isinstance (bvalue , list ):
386+ raise argparse .ArgumentTypeError ("bvalues in JSON file are not list" )
387+ for value in bvalue :
388+ if not isinstance (value , float ):
389+ raise argparse .ArgumentTypeError ("Values in lists are not float" )
390+ except json .JSONDecodeError as e :
391+ raise argparse .ArgumentTypeError (f"Invalid JSON file: { e } " )
404392
405- nifti_img = nib .Nifti1Image (sig , affine = res ) # Replace affine if necessary
406- # Save the NIfTI image to a file
407- nifti_img .header .set_data_dtype (np .float64 )
408- if not motion :
409- output_file = 'output.nii.gz' # Replace with your desired output file name
410- elif interleaved :
411- output_file = 'output_resp_int.nii.gz' # Replace with your desired output file name
393+ return bvalues_dict
394+
395+ parser .add_argument ("-b" , "--bvalue" , type = float ,
396+ nargs = "+" ,
397+ help = "B values (list of of numbers)" )
398+ parser .add_argument ("-f" , "--bvalues-file" , metavar = "FILE" , type = parse_bvalues_file ,
399+ help = 'JSON file containing the b-values' )
400+ parser .add_argument ("-n" , "--noise" , type = float , default = 0.0005 , help = "Noise" )
401+ parser .add_argument ("-m" , "--motion" , action = "store_true" , help = "Motion flag" )
402+ parser .add_argument ("-i" , "--interleaved" , action = "store_true" , help = "Interleaved flag" )
403+ args = parser .parse_args ()
404+
405+ if args .bvalues_file and args .bvalue :
406+ raise argparse .ArgumentError (None , "Arguments --bvalues-file and --bvalues are mutually exclusive" )
407+
408+ bvalues = None
409+ if args .bvalues_file :
410+ bvalues = args .bvalues_file
411+ elif args .bvalue :
412+ bvalues = {"cmd" : args .bvalue }
412413 else :
413- output_file = 'output_resp.nii.gz' # Replace with your desired output file name
414+ bvalues = parse_bvalues_file ("b_values.json" )
415+
416+
417+ noise = args .noise
418+ motion = args .motion
419+ interleaved = args .interleaved
420+ download_data ()
421+ for key , bvalue in bvalues .items ():
422+ bvalue = np .array (bvalue )
423+ sig , XCAT , Dim , fim , Dpim , legend = phantom (bvalue , noise , motion = motion , interleaved = interleaved )
424+ # sig = np.flip(sig,axis=0)
425+ # sig = np.flip(sig,axis=1)
426+ res = np .eye (4 )
427+ res [2 ]= 2
428+
429+ voxel_selector_fraction = 0.5
430+ D , f , Ds = contrast_curve_calc ()
431+ ignore = np .isnan (D )
432+ generic_data = {}
433+ for level , name in legend .items ():
434+ if len (ignore ) > level and ignore [level ]:
435+ continue
436+ selector = XCAT == level
437+ voxels = sig [selector ]
438+ if len (voxels ) < 1 :
439+ continue
440+ signals = np .squeeze (voxels [int (voxels .shape [0 ] * voxel_selector_fraction )]).tolist ()
441+ generic_data [name ] = {
442+ 'noise' : noise ,
443+ 'D' : np .mean (Dim [selector ], axis = 0 ),
444+ 'f' : np .mean (fim [selector ], axis = 0 ),
445+ 'Dp' : np .mean (Dpim [selector ], axis = 0 ),
446+ 'data' : signals
447+ }
448+ generic_data ['config' ] = {
449+ 'bvalues' : bvalue .tolist ()
450+ }
451+ with open (f'generic_{ key } .json' , 'w' ) as f :
452+ json .dump (generic_data , f , indent = 4 )
453+
454+ nifti_img = nib .Nifti1Image (sig , affine = res ) # Replace affine if necessary
455+ # Save the NIfTI image to a file
456+ nifti_img .header .set_data_dtype (np .float64 )
457+ if not motion :
458+ output_file = f'output_{ key } .nii.gz' # Replace with your desired output file name
459+ elif interleaved :
460+ output_file = f'output_resp_int_{ key } .nii.gz' # Replace with your desired output file name
461+ else :
462+ output_file = f'output_resp_{ key } .nii.gz' # Replace with your desired output file name
414463
415- nib .save (nifti_img , output_file )
464+ nib .save (nifti_img , output_file )
416465
417466
418- nifti_img = nib .Nifti1Image (XCAT , affine = res ) # Replace affine if necessary
419- # Save the NIfTI image to a file
420- output_file = 'output_xcat .nii.gz' # Replace with your desired output file name
421- nib .save (nifti_img , output_file )
467+ nifti_img = nib .Nifti1Image (XCAT , affine = res ) # Replace affine if necessary
468+ # Save the NIfTI image to a file
469+ output_file = f'output_xcat_ { key } .nii.gz' # Replace with your desired output file name
470+ nib .save (nifti_img , output_file )
422471
423- nifti_img = nib .Nifti1Image (Dim , affine = res ) # Replace affine if necessary
424- # Save the NIfTI image to a file
425- nifti_img .header .set_data_dtype (np .float64 )
426- output_file = 'D .nii.gz' # Replace with your desired output file name
427- nib .save (nifti_img , output_file )
472+ nifti_img = nib .Nifti1Image (Dim , affine = res ) # Replace affine if necessary
473+ # Save the NIfTI image to a file
474+ nifti_img .header .set_data_dtype (np .float64 )
475+ output_file = f'D_ { key } .nii.gz' # Replace with your desired output file name
476+ nib .save (nifti_img , output_file )
428477
429- nifti_img = nib .Nifti1Image (fim , affine = res ) # Replace affine if necessary
430- # Save the NIfTI image to a file
431- nifti_img .header .set_data_dtype (np .float64 )
432- output_file = 'f .nii.gz' # Replace with your desired output file name
433- nib .save (nifti_img , output_file )
478+ nifti_img = nib .Nifti1Image (fim , affine = res ) # Replace affine if necessary
479+ # Save the NIfTI image to a file
480+ nifti_img .header .set_data_dtype (np .float64 )
481+ output_file = f'f_ { key } .nii.gz' # Replace with your desired output file name
482+ nib .save (nifti_img , output_file )
434483
435- nifti_img = nib .Nifti1Image (Dpim , affine = res ) # Replace affine if necessary
436- # Save the NIfTI image to a file
437- nifti_img .header .set_data_dtype (np .float64 )
438- output_file = 'Dp .nii.gz' # Replace with your desired output file name
439- nib .save (nifti_img , output_file )
484+ nifti_img = nib .Nifti1Image (Dpim , affine = res ) # Replace affine if necessary
485+ # Save the NIfTI image to a file
486+ nifti_img .header .set_data_dtype (np .float64 )
487+ output_file = f'Dp_ { key } .nii.gz' # Replace with your desired output file name
488+ nib .save (nifti_img , output_file )
440489
441- np .savetxt ('bvals .txt' , bvalue )
490+ np .savetxt (f'bvals_ { key } .txt' , bvalue )
0 commit comments