From 69c108ea4e1aabd4dbc17e201523b64b70452387 Mon Sep 17 00:00:00 2001 From: Paul McCarthy <pauldmccarthy@gmail.com> Date: Thu, 11 Apr 2019 12:39:02 +0100 Subject: [PATCH] RF: VoxelwiseEVMixin has a new getData method which takes into account compressed voxelwise EVs --- fsl/data/featdesign.py | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/fsl/data/featdesign.py b/fsl/data/featdesign.py index 633b712b4..ce5b41f59 100644 --- a/fsl/data/featdesign.py +++ b/fsl/data/featdesign.py @@ -214,7 +214,7 @@ class FEATFSFDesign(object): 'for ev {}'.format(ev.index)) continue - design[:, ev.index] = ev.image[x, y, z, :] + design[:, ev.index] = ev.getData(x, y, z) return design @@ -228,6 +228,17 @@ class VoxelwiseEVMixin(object): ``filename`` Path to the image file containing the data for this EV ``image`` Reference to the :class:`.Image` object ============ ====================================================== + + Some FSL tools (e.g. `PNM + <https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/PNM>`_) generate *compressed* + voxelwise EVs, where there is only one voxel per slice. For example, + if the input data has shape ``(x, y, z, t)``, and slices are acquired + along the Z plane, voxelwise EV files generated by PNM will have shape + ``(1, 1, z, t)``. + + Therefore, using the :meth:`getData` method is preferable to accessing + the :meth:`image` directly, as ``getData`` will check for compressed + images, and adjust the voxel coordinates accordingly. """ def __init__(self, filename): @@ -272,6 +283,29 @@ class VoxelwiseEVMixin(object): return self.__image + def getData(self, x, y, z): + """Returns the data at the specified voxel, taking into account + compressed voxelwise EVs. + """ + image = self.image + + if image is None: + return None + + dx, dy, dz = image.shape[:3] + + # "Compressed" images have one voxel + # per slice, i.e. they have shape + # [1, 1, nslices, ntimepoints] (if + # Z is the slice plane). + if sum((dx == 1, dy == 1, dz == 1)) == 2: + if dx == 1: x = 0 + if dy == 1: y = 0 + if dz == 1: z = 0 + + return image[x, y, z, :] + + class EV(object): """Class representing an explanatory variable in a FEAT design matrix. -- GitLab