From 72da9475f6b4f8c1e9b0fb906e6482e98fae9dec Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauldmccarthy@gmail.com>
Date: Wed, 1 Nov 2017 09:44:22 +0000
Subject: [PATCH] Resample methods explicitly raises an error when num dims is
 wrong. Cleaned up related code in atlas classes

---
 fsl/data/atlases.py | 59 +++++++++++++++++++++++++++++----------------
 fsl/data/image.py   |  6 ++++-
 2 files changed, 43 insertions(+), 22 deletions(-)

diff --git a/fsl/data/atlases.py b/fsl/data/atlases.py
index 59122134f..6ed038f1a 100644
--- a/fsl/data/atlases.py
+++ b/fsl/data/atlases.py
@@ -675,6 +675,42 @@ class Atlas(fslimage.Image):
         return self.desc.find(*args, **kwargs)
 
 
+    def prepareMask(self, mask):
+        """Makes sure that the given mask has the same resolution as this
+        atlas, so it can be used for querying. Used by the
+        :meth:`.LabelAtlas.maskLabels` and
+        :meth:`.ProbabilisticAtlas.maskProportions` methods.
+
+        :arg mask: A :class:`.Image`
+
+        :returns:  A ``numpy`` array containing the resampled mask data.
+
+        :raises:   A :exc:`MaskError` if the mask is not in the same space as
+                   this atlas, or does not have three dimensions.
+        """
+
+        # Make sure that the mask has the same
+        # number of voxels as the atlas image.
+        # Use nearest neighbour interpolation
+        # for resampling, as it is most likely
+        # that the mask is binary.
+        try:
+            mask, xform = mask.resample(self.shape[:3],
+                                        dtype=np.float32,
+                                        order=0)
+
+        except ValueError:
+            raise MaskError('Mask has wrong number of dimensions')
+
+        # TODO allow non-aligned mask - as long as it overlaps
+        #      in world coordinates, it should be allowed
+        if not fslimage.Image(mask, xform=xform).sameSpace(self):
+            raise MaskError('Mask is not in the same space as atlas')
+
+        return mask
+
+
+
 class MaskError(Exception):
     """Exception raised by the :meth:`LabelAtlas.maskLabel` and
     :meth:`ProbabilisticAtlas.maskProportions` when a mask is provided which
@@ -781,23 +817,10 @@ class LabelAtlas(Atlas):
                   associated with each returned value.
         """
 
-        # Make sure that the mask has the same
-        # number of voxels as the atlas image.
-        # Use nearest neighbour interpolation
-        # for resampling, as it is most likely
-        # that the mask is binary.
-        mask, xform = mask.resample(self.shape[:3], dtype=np.float32, order=0)
-
-        if not fslimage.Image(mask, xform=xform).sameSpace(self):
-            raise MaskError('Mask is not in the same space as atlas')
-
-        # TODO allow non-aligned mask - as long as it overlaps
-        #      in world coordinates, it should be allowed
-
-
         # Extract the values that are in
         # the mask, and their corresponding
         # mask weights
+        mask      = self.prepareMask(mask)
         boolmask  = mask > 0
         vals      = self[boolmask]
         weights   = mask[boolmask]
@@ -924,13 +947,7 @@ class ProbabilisticAtlas(Atlas):
 
         props = []
 
-        # Make sure that the mask has the same
-        # number of voxels as the atlas image
-        mask, xform = mask.resample(self.shape[:3], dtype=np.float32, order=0)
-
-        if not fslimage.Image(mask, xform=xform).sameSpace(self):
-            raise MaskError('Mask is not in the same space as atlas')
-
+        mask      = self.prepareMask(mask)
         boolmask  = mask > 0
         weights   = mask[boolmask]
         weightsum = weights.sum()
diff --git a/fsl/data/image.py b/fsl/data/image.py
index b1c93c087..3b3e87041 100644
--- a/fsl/data/image.py
+++ b/fsl/data/image.py
@@ -1149,7 +1149,8 @@ class Image(Nifti):
 
         :arg sliceobj: Slice into this ``Image``. If ``None``, the whole
                        image is resampled, and it is assumed that it has the
-                       same number of dimensions as  ``shape``.
+                       same number of dimensions as  ``shape``. A
+                       :exc:`ValueError` is raised if this is not the case.
 
         :arg dtype:    ``numpy`` data type of the resampled data. If ``None``,
                        the :meth:`dtype` of this ``Image`` is used.
@@ -1184,6 +1185,9 @@ class Image(Nifti):
         oldShape = np.array(data.shape, dtype=np.float)
         newShape = np.array(newShape,   dtype=np.float)
 
+        if len(oldShape) != len(newShape):
+            raise ValueError('Shapes don\'t match')
+
         if not np.all(np.isclose(oldShape, newShape)):
 
             ratio    = oldShape / newShape
-- 
GitLab