26
26
"""
27
27
28
28
29
- def get_trt (in_meta , in_file = None ):
29
+ def get_trt (
30
+ in_meta ,
31
+ in_file = None ,
32
+ * ,
33
+ use_estimate = False ,
34
+ fallback = None ,
35
+ ):
30
36
r"""
31
37
Obtain the *total readout time* :math:`T_\text{ro}` from available metadata.
32
38
@@ -43,6 +49,26 @@ def get_trt(in_meta, in_file=None):
43
49
>>> nb.Nifti1Image(np.zeros((90, 90, 60)), None, None).to_filename(
44
50
... tmpdir.join('epi.nii.gz').strpath)
45
51
52
+ Parameters
53
+ ----------
54
+ in_meta: :class:`dict`
55
+ BIDS metadata dictionary.
56
+ in_file: :class:`str`, optional
57
+ Path to the EPI file. Used to determine the number of voxels along the
58
+ phase-encoding direction.
59
+ use_estimate: :class:`bool`, optional
60
+ Whether to use "Estimated*" fields to calculate the total readout time.
61
+ These are generated by dcm2niix when authoritative metadata is not available
62
+ but heuristic methods permit an estimation.
63
+ fallback: :class:`float`, optional
64
+ A fallback value, in seconds, to use when the total readout time cannot be
65
+ calculated. This should only be used in situations where the field is to be
66
+ determined from displacement fields, as in SyN-SDC.
67
+ A recommended "plausible" value would be 0.03125, to minimize the impact of
68
+ floating-point errors in the calculations.
69
+
70
+ Examples
71
+ --------
46
72
47
73
>>> meta = {'TotalReadoutTime': 0.05251}
48
74
>>> get_trt(meta)
@@ -159,6 +185,23 @@ def get_trt(in_meta, in_file=None):
159
185
Traceback (most recent call last):
160
186
ValueError:
161
187
188
+ dcm2niix may provide "EstimatedTotalReadoutTime" or "EstimatedEffectiveEchoSpacing"
189
+ fields when converting Philips data. In order to use these fields, pass
190
+ ``use_estimate=True``:
191
+
192
+ >>> get_trt({'EstimatedTotalReadoutTime': 0.05251}, use_estimate=True)
193
+ 0.05251
194
+ >>> meta = {'EstimatedEffectiveEchoSpacing': 0.00059,
195
+ ... 'PhaseEncodingDirection': 'j-'}
196
+ >>> f"{get_trt(meta, in_file='epi.nii.gz', use_estimate=True):g}"
197
+ '0.05251'
198
+
199
+ Finally, if a fallback value is provided, it will be used when the total readout
200
+ time cannot be calculated by any method:
201
+
202
+ >>> get_trt({}, fallback=0.03125)
203
+ 0.03125
204
+
162
205
.. testcleanup::
163
206
164
207
>>> os.chdir(cwd)
@@ -194,6 +237,12 @@ def get_trt(in_meta, in_file=None):
194
237
raise ValueError (f"'{ trt } '" )
195
238
196
239
return trt
240
+ elif use_estimate and "EstimatedTotalReadoutTime" in in_meta :
241
+ trt = in_meta .get ("EstimatedTotalReadoutTime" )
242
+ if not trt :
243
+ raise ValueError (f"'{ trt } '" )
244
+
245
+ return trt
197
246
198
247
# npe = N voxels PE direction
199
248
pe_index = "ijk" .index (in_meta ["PhaseEncodingDirection" ][0 ])
@@ -204,6 +253,8 @@ def get_trt(in_meta, in_file=None):
204
253
if ees :
205
254
# Effective echo spacing means that acceleration factors have been accounted for.
206
255
return ees * (npe - 1 )
256
+ elif use_estimate and "EstimatedEffectiveEchoSpacing" in in_meta :
257
+ return in_meta .get ("EstimatedEffectiveEchoSpacing" ) * (npe - 1 )
207
258
208
259
try :
209
260
echospacing = in_meta ["EchoSpacing" ]
@@ -231,6 +282,9 @@ def get_trt(in_meta, in_file=None):
231
282
ees = wfs / (wfs_hz * (epifactor + 1 ))
232
283
return ees * (npe - 1 )
233
284
285
+ if fallback :
286
+ return fallback
287
+
234
288
raise ValueError ("Unknown total-readout time specification" )
235
289
236
290
0 commit comments