From 98a8d42ca3a94f97d3bb5e39ed8fab418ea43a9d Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauldmccarthy@gmail.com>
Date: Tue, 22 Sep 2020 12:58:43 +0100
Subject: [PATCH] RF: readFnirt function allows field type to be specified in
 case file has no intent code set

---
 fsl/transform/fnirt.py | 44 ++++++++++++++++++++++++++----------------
 1 file changed, 27 insertions(+), 17 deletions(-)

diff --git a/fsl/transform/fnirt.py b/fsl/transform/fnirt.py
index 6357fb9ec..36dbda8c6 100644
--- a/fsl/transform/fnirt.py
+++ b/fsl/transform/fnirt.py
@@ -257,7 +257,7 @@ def _readFnirtCoefficientField(fname, img, src, ref):
                                       fieldToRefMat=fieldToRefMat)
 
 
-def readFnirt(fname, src, ref, defType=None):
+def readFnirt(fname, src, ref, defType=None, intent=None):
     """Reads a non-linear FNIRT transformation image, returning
     a :class:`.DeformationField` or :class:`.CoefficientField` depending
     on the file type.
@@ -268,28 +268,38 @@ def readFnirt(fname, src, ref, defType=None):
     :arg defType:  Deformation type - either ``'absolute'`` or ``'relative'``.
                    Only used if the file is a deformation field. If not
                    provided, is automatically inferred from the data.
+    :arg intent:   NIFTI intent code of ``fname``. e.g.
+                   :attr:`.constants.FSL_FNIRT_DISPLACEMENT_FIELD`. If not
+                   provided, the intent is read from the image header.
     """
 
-    # Figure out whether the file
-    # is a deformation field or
-    # a coefficient field
-
-    img   = fslimage.Image(fname, loadData=False)
-    disps = (constants.FSL_FNIRT_DISPLACEMENT_FIELD,
-             constants.FSL_TOPUP_FIELD)
-    coefs = (constants.FSL_CUBIC_SPLINE_COEFFICIENTS,
-             constants.FSL_DCT_COEFFICIENTS,
-             constants.FSL_QUADRATIC_SPLINE_COEFFICIENTS,
-             constants.FSL_TOPUP_CUBIC_SPLINE_COEFFICIENTS,
-             constants.FSL_TOPUP_QUADRATIC_SPLINE_COEFFICIENTS)
+    if defType not in (None, 'absolute', 'relative'):
+        raise ValueError('defType must be None, "absolute" or "relative" '
+                         '(passed in as {})'.format(defType))
+
+    # Figure out whether the file is a
+    # deformation field or a coefficient
+    # field by checking the intent code.
+    # If the intent is provided, assume
+    # that the caller knows the type of
+    # the field.
+    img    = fslimage.Image(fname, loadData=False)
+    intent = intent or img.intent
+    disps  = (constants.FSL_FNIRT_DISPLACEMENT_FIELD,
+              constants.FSL_TOPUP_FIELD)
+    coefs  = (constants.FSL_CUBIC_SPLINE_COEFFICIENTS,
+              constants.FSL_DCT_COEFFICIENTS,
+              constants.FSL_QUADRATIC_SPLINE_COEFFICIENTS,
+              constants.FSL_TOPUP_CUBIC_SPLINE_COEFFICIENTS,
+              constants.FSL_TOPUP_QUADRATIC_SPLINE_COEFFICIENTS)
 
-    if img.intent in disps:
+    if intent in disps:
         return _readFnirtDeformationField(fname, img, src, ref, defType)
-    elif img.intent in coefs:
+    elif intent in coefs:
         return _readFnirtCoefficientField(fname, img, src, ref)
     else:
-        raise ValueError('Cannot determine type of nonlinear '
-                         'file {}'.format(fname))
+        raise ValueError('Cannot determine type of nonlinear warp field '
+                         '{} (intent code: {})'.format(fname, intent))
 
 
 def toFnirt(field):
-- 
GitLab