1111# code adapted from MAtlab code by Eric Schrauben: https://github.com/schrau24/XCAT-ERIC
1212# This code generates a 4D IVIM phantom as nifti file
1313
14- def phantom (bvalue , noise , TR = 3000 , TE = 40 , motion = False , rician = False , interleaved = False ):
14+ def phantom (bvalue , noise , TR = 3000 , TE = 40 , motion = False , rician = False , interleaved = False , T1T2 = True ):
1515 np .random .seed (42 )
1616 if motion :
1717 states = range (1 ,21 )
@@ -23,10 +23,10 @@ def phantom(bvalue, noise, TR=3000, TE=40, motion=False, rician=False, interleav
2323
2424 # Access the variables in the loaded .mat file
2525 XCAT = mat_data ['IMG' ]
26- XCAT = XCAT [0 : - 1 :2 , 0 :- 1 : 2 ,10 :160 :4 ]
26+ XCAT = XCAT [- 1 :0 :- 2 , - 1 : 0 : - 2 ,10 :160 :4 ]
2727
2828 D , f , Ds = contrast_curve_calc ()
29- S , Dim , fim , Dpim , legend = XCAT_to_MR_DCE (XCAT , TR , TE , bvalue , D , f , Ds )
29+ S , Dim , fim , Dpim , legend = XCAT_to_MR_DCE (XCAT , TR , TE , bvalue , D , f , Ds , T1T2 = T1T2 )
3030 if state == 1 :
3131 Dim_out = Dim
3232 fim_out = fim
@@ -95,15 +95,19 @@ def contrast_curve_calc():
9595 D [8 ] = 3e-3 # 8 Blood ra
9696 D [10 ] = 1.37e-3 # 8 Muscle: 10.3389/fresc.2022.910068
9797 D [13 ] = 1.5e-3 # 13 liver: Delattre et al. doi: 10.1097/RLI.0b013e31826ef901
98+ D [14 ] = 3.0e-3 # 13 Galbladder
9899 D [17 ] = 1.67e-3 # 17 esophagus : Huang et al. doi: 10.1259/bjr.20170421
99100 D [18 ] = 1.67e-3 # 18 esophagus cont : Huang et al. doi: 10.1259/bjr.20170421
100101 D [20 ] = 1.5e-3 # 20 stomach wall: Li et al. doi: 10.3389/fonc.2022.821586
102+ D [21 ] = 3.0e-3 # 21 stomach content
101103 D [22 ] = 1.3e-3 # 22 Pancreas (from literature)
102104 D [23 ] = 2.12e-3 # 23 right kydney cortex : van Baalen et al. Doi: jmri.25519
103105 D [24 ] = 2.09e-3 # 23 right kydney medulla : van Baalen et al. Doi: jmri.25519
104106 D [25 ] = 2.12e-3 # 23 left kydney cortex : van Baalen et al. Doi: jmri.25519
105107 D [26 ] = 2.09e-3 # 23 left kydney medulla : van Baalen et al. Doi: jmri.25519
106108 D [30 ] = 1.3e-3 # 30 spleen : Taimouri et al. Doi: 10.1118/1.4915495
109+ D [34 ] = 4.1e-4 # 34 spinal cord :doi: 10.3389/fonc.2022.961473
110+ D [35 ] = 0.43e-3 # 35 Bone marrow : https://pubmed.ncbi.nlm.nih.gov/30194746/
107111 D [36 ] = 3e-3 # 36 artery
108112 D [37 ] = 3e-3 # 37 vein
109113 D [40 ] = 1.31e-3 # 40 asc lower intestine : Hai-Jing et al. doi: 10.1097/RCT.0000000000000926
@@ -124,15 +128,19 @@ def contrast_curve_calc():
124128 f [8 ] = 1.00 # 8 Blood ra
125129 f [10 ] = 0.10 # 8 Muscle: 10.3389/fresc.2022.910068
126130 f [13 ] = 0.11 # 13 liver : Delattre et al. doi: 10.1097/RLI.0b013e31826ef901
131+ f [14 ] = 0 # 13 Gal
127132 f [17 ] = 0.32 # 17 esophagus : Huang et al. doi: 10.1259/bjr.20170421
128133 f [18 ] = 0.32 # 18 esophagus cont : Huang et al. doi: 10.1259/bjr.20170421
129134 f [20 ] = 0.3 # 20 stomach wall: Li et al. doi: 10.3389/fonc.2022.821586
135+ f [21 ] = 0.0 # 20 stomach content
130136 f [22 ] = 0.15 # 22 Pancreas (from literature)
131137 f [23 ] = 0.097 # 23 right kydney cortex : van Baalen et al. Doi: jmri.25519
132138 f [24 ] = 0.158 # 23 right kydney medulla : van Baalen et al. Doi: jmri.25519
133139 f [25 ] = 0.097 # 23 left kydney cortex : van Baalen et al. Doi: jmri.25519
134140 f [26 ] = 0.158 # 23 left kydney medulla : van Baalen et al. Doi: jmri.25519
135141 f [30 ] = 0.2 # 30 spleen : Taimouri et al. Doi: 10.1118/1.4915495
142+ f [34 ] = 0.178 # 34 spinal cord :doi: 10.3389/fonc.2022.961473
143+ f [35 ] = 0.145 # 35 Bone marrow : https://pubmed.ncbi.nlm.nih.gov/30194746/
136144 f [36 ] = 1.0 # 36 artery
137145 f [37 ] = 1.0 # 37 vein
138146 f [40 ] = 0.69 # 40 asc lower intestine : Hai-Jing et al. doi: 10.1097/RCT.0000000000000926
@@ -153,15 +161,19 @@ def contrast_curve_calc():
153161 Ds [8 ] = 0.1 # 8 Blood ra
154162 Ds [10 ] = 0.0263 # 8 Muscle: 10.3389/fresc.2022.910068
155163 Ds [13 ] = 0.1 # 13 liver: Delattre et al. doi: 10.1097/RLI.0b013e31826ef901
164+ Ds [14 ] = 0.1 # 14 Gal
156165 Ds [17 ] = 0.03 # 17 esophagus : Huang et al. doi: 10.1259/bjr.20170421
157166 Ds [18 ] = 0.03 # 18 esophagus cont : Huang et al. doi: 10.1259/bjr.20170421
158167 Ds [20 ] = 0.012 # 20 stomach wall: Li et al. doi: 10.3389/fonc.2022.821586
168+ Ds [21 ] = 0.0 # 20 stomach content
159169 Ds [22 ] = 0.01 # 22 Pancreas (from literature)
160170 Ds [23 ] = 0.02 # 23 right kydney cortex : van Baalen et al. Doi: jmri.25519
161171 Ds [24 ] = 0.019 # 23 right kydney medulla : van Baalen et al. Doi: jmri.25519
162172 Ds [25 ] = 0.02 # 23 left kydney cortex : van Baalen et al. Doi: jmri.25519
163173 Ds [26 ] = 0.019 # 23 left kydney medulla : van Baalen et al. Doi: jmri.25519
164174 Ds [30 ] = 0.03 # 30 spleen : Taimouri et al. Doi: 10.1118/1.4915495
175+ Ds [34 ] = 0.0289 # 34 spinal cord :doi: 10.3389/fonc.2022.961473
176+ Ds [35 ] = 0.05 # 35 Bone marrow :
165177 Ds [36 ] = 0.1 # 36 artery
166178 Ds [37 ] = 0.1 # 37 vein
167179 Ds [40 ] = 0.029 # 40 asc lower intestine : Hai-Jing et al. doi: 10.1097/RCT.0000000000000926
@@ -175,7 +187,7 @@ def contrast_curve_calc():
175187 return D , f , Ds
176188
177189
178- def XCAT_to_MR_DCE (XCAT , TR , TE , bvalue , D , f , Ds , b0 = 3 , ivim_cont = True ):
190+ def XCAT_to_MR_DCE (XCAT , TR , TE , bvalue , D , f , Ds , b0 = 3 , ivim_cont = True , T1T2 = True ):
179191 ###########################################################################################
180192 # This script converts XCAT tissue values to MR contrast based on the SSFP signal equation.
181193 # Christopher W. Roy 2018-12-04 # fetal.xcmr@gmail.com
@@ -285,7 +297,7 @@ def XCAT_to_MR_DCE(XCAT, TR, TE, bvalue, D, f, Ds, b0=3, ivim_cont = True):
285297 Tissue [19 ] = [1045.5 , 37.3 , 1201 , 44 ]
286298 Tissue [20 ] = [981.5 , 36 , 1232.9 , 37.20 ]
287299 #Tissue[20] = [981.5, 36, 1232.9, 37.20]
288- Tissue [21 ] = [0 , 0 , 0 , 0 ]
300+ Tissue [21 ] = [2500 , 1250 , 4000 , 2000 ]
289301 Tissue [22 ] = [584 , 46 , 725 , 43 ]
290302 Tissue [23 ] = [828 , 71 , 1168 , 66 ]
291303 Tissue [24 ] = [1412 , 85 , 1545 , 81 ]
@@ -351,7 +363,6 @@ def XCAT_to_MR_DCE(XCAT, TR, TE, bvalue, D, f, Ds, b0=3, ivim_cont = True):
351363 else :
352364 T1 = Tissue [iTissue , 2 ]
353365 T2 = Tissue [iTissue , 3 ]
354-
355366 if ivim_cont and not np .isnan ([D [iTissue ], f [iTissue ], Ds [iTissue ]]).any ():
356367 # note we are assuming blood fraction has the same T1 as tissue fraction here for simplicity. Can be changed in future.
357368 Dtemp = D [iTissue ]
@@ -362,8 +373,11 @@ def XCAT_to_MR_DCE(XCAT, TR, TE, bvalue, D, f, Ds, b0=3, ivim_cont = True):
362373 ftemp = np .random .rand (1 )* 0.5
363374 Dstemp = 5e-3 + np .random .rand (1 )* 1e-1
364375 S0 = ivim (bvalue ,Dtemp ,ftemp ,Dstemp )
365- if T1 > 0 or T2 > 0 :
366- MR = MR + np .tile (np .expand_dims (XCAT == iTissue ,3 ),len (S0 )) * S0 * (1 - 2 * np .exp (- (TR - TE / 2 ) / T1 ) + np .exp (- TR / T1 )) * np .exp (- TE / T2 )
376+ if T1T2 :
377+ if T1 > 0 or T2 > 0 :
378+ MR = MR + np .tile (np .expand_dims (XCAT == iTissue ,3 ),len (S0 )) * S0 * (1 - 2 * np .exp (- (TR - TE / 2 ) / T1 ) + np .exp (- TR / T1 )) * np .exp (- TE / T2 )
379+ else :
380+ MR = MR + np .tile (np .expand_dims (XCAT == iTissue ,3 ),len (S0 )) * S0
367381 Dim = Dim + (XCAT == iTissue ) * Dtemp
368382 fim = fim + (XCAT == iTissue ) * ftemp
369383 Dpim = Dpim + (XCAT == iTissue ) * Dstemp
@@ -403,6 +417,7 @@ def parse_bvalues_file(file_path):
403417 parser .add_argument ("-n" , "--noise" , type = float , default = 0.0005 , help = "Noise" )
404418 parser .add_argument ("-m" , "--motion" , action = "store_true" , help = "Motion flag" )
405419 parser .add_argument ("-i" , "--interleaved" , action = "store_true" , help = "Interleaved flag" )
420+ parser .add_argument ("-u" , "--T1T2" , action = "store_true" , help = "weight signal with T1T2" ) # note, set this to zero when generating test data for unit testing!
406421 args = parser .parse_args ()
407422
408423 if args .bvalues_file and args .bvalue :
@@ -420,14 +435,15 @@ def parse_bvalues_file(file_path):
420435 noise = args .noise
421436 motion = args .motion
422437 interleaved = args .interleaved
438+ T1T2 = args .T1T2
423439 download_data ()
424440 for key , bvalue in bvalues .items ():
425441 bvalue = np .array (bvalue )
426- sig , XCAT , Dim , fim , Dpim , legend = phantom (bvalue , noise , motion = motion , interleaved = interleaved )
442+ sig , XCAT , Dim , fim , Dpim , legend = phantom (bvalue , noise , motion = motion , interleaved = interleaved , T1T2 = T1T2 )
427443 # sig = np.flip(sig,axis=0)
428444 # sig = np.flip(sig,axis=1)
429445 res = np .eye (4 )
430- res [2 ]= 2
446+ res [2 , 2 ]= 2
431447
432448 voxel_selector_fraction = 0.5
433449 D , f , Ds = contrast_curve_calc ()
0 commit comments