From 2f1e421b0b3cc9465891aef7645d2875ea5dc302 Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauldmccarthy@gmail.com>
Date: Mon, 3 Jun 2019 12:18:37 +0100
Subject: [PATCH] BF: Only FNIRT coefficient fields clobber NIFTI headers -
 displacement fields are fine. Generating a slightly less incorrect (but still
 incorrect) v2w affine for the former. Bug in test script

---
 fsl/data/image.py                             | 23 +++++++++++++++----
 .../{ => test_scripts}/test_fsl_convert_x5.py |  2 +-
 2 files changed, 20 insertions(+), 5 deletions(-)
 rename tests/{ => test_scripts}/test_fsl_convert_x5.py (95%)

diff --git a/fsl/data/image.py b/fsl/data/image.py
index 637e745af..b2f07648e 100644
--- a/fsl/data/image.py
+++ b/fsl/data/image.py
@@ -312,12 +312,27 @@ class Nifti(notifier.Notifier, meta.Meta):
         qform  = header.get('qform_code',  -1)
         sform  = header.get('sform_code',  -1)
 
-        if intent in (constants.FSL_FNIRT_DISPLACEMENT_FIELD,
-                      constants.FSL_CUBIC_SPLINE_COEFFICIENTS,
+        # FNIRT non-linear coefficient files
+        # clobber the sform/qform/intent
+        # and pixdims of the nifti header,
+        # so we can't correctly place it in
+        # the world coordinate system. See
+        # $FSLDIR/src/fnirt/fnirt_file_writer.cpp
+        # and fsl.transform.nonlinear for more
+        # details.
+        if intent in (constants.FSL_CUBIC_SPLINE_COEFFICIENTS,
                       constants.FSL_DCT_COEFFICIENTS,
                       constants.FSL_QUADRATIC_SPLINE_COEFFICIENTS):
-            log.debug('FNIRT output image detected - using qform matrix')
-            voxToWorldMat = np.array(header.get_qform())
+
+            log.debug('FNIRT coefficient field detected - generating affine')
+
+            knotpix       =  header.get_zooms()[:3]
+            refpix        = (header.get('intent_p1', 1),
+                             header.get('intent_p2', 1),
+                             header.get('intent_p3', 1))
+            voxToWorldMat = transform.concat(
+                transform.scaleOffsetXform(refpix,  0),
+                transform.scaleOffsetXform(knotpix, 0))
 
         # If the qform or sform codes are unknown,
         # then we can't assume that the transform
diff --git a/tests/test_fsl_convert_x5.py b/tests/test_scripts/test_fsl_convert_x5.py
similarity index 95%
rename from tests/test_fsl_convert_x5.py
rename to tests/test_scripts/test_fsl_convert_x5.py
index 0dab1ec52..e14b3c259 100644
--- a/tests/test_fsl_convert_x5.py
+++ b/tests/test_scripts/test_fsl_convert_x5.py
@@ -43,7 +43,7 @@ def test_convert_flirt():
             ref.getAffine('fsl', 'world'),
             xform,
             src.getAffine('world', 'fsl'))
-        gotxform, gotsrc, gotref = transform.readFlirtX5('src2ref.x5')
+        gotxform, gotsrc, gotref = transform.readLinearX5('src2ref.x5')
         assert np.all(np.isclose(gotxform, expxform))
         assert src.sameSpace(gotsrc)
         assert ref.sameSpace(gotref)
-- 
GitLab