2
2
from scipy .io import loadmat
3
3
import nibabel as nib
4
4
import json
5
+ import argparse
6
+ import os
5
7
from utilities .data_simulation .Download_data import download_data
6
8
7
9
##########
10
12
# This code generates a 4D IVIM phantom as nifti file
11
13
12
14
def phantom (bvalue , noise , TR = 3000 , TE = 40 , motion = False , rician = False , interleaved = False ):
13
- download_data ()
14
15
np .random .seed (42 )
15
16
if motion :
16
17
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):
366
367
return MR , Dim , fim , Dpim , legend
367
368
368
369
if __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
+ """ )
378
373
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" )
403
378
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 } " )
404
392
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 }
412
413
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
414
463
415
- nib .save (nifti_img , output_file )
464
+ nib .save (nifti_img , output_file )
416
465
417
466
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 )
422
471
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 )
428
477
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 )
434
483
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 )
440
489
441
- np .savetxt ('bvals .txt' , bvalue )
490
+ np .savetxt (f'bvals_ { key } .txt' , bvalue )
0 commit comments