2626"""
2727
2828
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+ ):
3036 r"""
3137 Obtain the *total readout time* :math:`T_\text{ro}` from available metadata.
3238
@@ -43,6 +49,26 @@ def get_trt(in_meta, in_file=None):
4349 >>> nb.Nifti1Image(np.zeros((90, 90, 60)), None, None).to_filename(
4450 ... tmpdir.join('epi.nii.gz').strpath)
4551
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+ --------
4672
4773 >>> meta = {'TotalReadoutTime': 0.05251}
4874 >>> get_trt(meta)
@@ -159,6 +185,23 @@ def get_trt(in_meta, in_file=None):
159185 Traceback (most recent call last):
160186 ValueError:
161187
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'):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+
162205 .. testcleanup::
163206
164207 >>> os.chdir(cwd)
@@ -194,6 +237,13 @@ def get_trt(in_meta, in_file=None):
194237 raise ValueError (f"'{ trt } '" )
195238
196239 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
246+
197247
198248 # npe = N voxels PE direction
199249 pe_index = "ijk" .index (in_meta ["PhaseEncodingDirection" ][0 ])
@@ -204,6 +254,8 @@ def get_trt(in_meta, in_file=None):
204254 if ees :
205255 # Effective echo spacing means that acceleration factors have been accounted for.
206256 return ees * (npe - 1 )
257+ elif use_estimate and "EstimatedEffectiveEchoSpacing" in in_meta :
258+ return in_meta .get ("EstimatedEffectiveEchoSpacing" ) * (npe - 1 )
207259
208260 try :
209261 echospacing = in_meta ["EchoSpacing" ]
@@ -231,6 +283,9 @@ def get_trt(in_meta, in_file=None):
231283 ees = wfs / (wfs_hz * (epifactor + 1 ))
232284 return ees * (npe - 1 )
233285
286+ if fallback :
287+ return fallback
288+
234289 raise ValueError ("Unknown total-readout time specification" )
235290
236291
0 commit comments