Skip to content

Commit

Permalink
Merge 675808b into 4c08d99
Browse files Browse the repository at this point in the history
  • Loading branch information
soazig committed Dec 13, 2015
2 parents 4c08d99 + 675808b commit 50ac083
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 0 deletions.
126 changes: 126 additions & 0 deletions code/utils/functions/mask_functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
"""mask_functions.py
A collection of functions to make masks on data.
See test_* functions in this directory for nose tests
"""
from __future__ import print_function, division

import sys, os, pdb
import numpy as np
import nibabel as nib
import numpy.linalg as npl

from os.path import splitext
from numpy.testing import assert_array_equal
from scipy.ndimage import affine_transform


def make_mask_filtered_data(func_path, mask_path):
"""Return the masked filtered data
Parameters
----------
func_path: string
path to the 4D data
mask_path: string
path to the mask function
Return
------
masked_func: 4D array
masked filtered data
"""
func_img = nib.load(func_path)
mask_img = nib.load(mask_path)
mask = mask_img.get_data()
func_data = func_img.get_data()
# Make data 4D to prepare for "broadcasting"
mask = np.reshape(mask, mask.shape + (1,))
# "Broadcasting" expands the final length 1 dimension to match the func data
masked_func = nib.Nifti1Image(func_data, func_img.affine, func_img.header)
# nib.save(masked_func, 'masked_' + img_name )
return masked_func

def make_binary_mask(data, mask_bool):
"""Return a numpy array with 0 and 1
Parameters
----------
Return
------
"""
data = np.asarray(data)
mask_bool = np.asarray(mask_bool)
assert(len(data.shape) == len(mask_bool.shape)),\
"Data and mask shape differ \n" \
+ "Data dim is: %s\nMask dim is: %s" \
%(len(data.shape), len(mask_bool.shape))
assert(all(data.shape[i] >= mask_bool.shape[i] \
for i in range(len(data.shape)))),\
"Data and mask shape are not compatible"\
+"Data shape is: %s\nMask shape is: %s"\
%(data.shape, mask_bool.shape)
new_mask = np.zeros(data.shape)
new_mask[mask_bool] = 1
return new_mask


def resample_filtered_data(func_path, template_path):
"""Resample template to filtered functional dataset
Parameters
----------
func_path: string
path of the 4D filtered data to resample
template_path: string
path to the template to apply on the data
"""
filtered_func = nib.load(func_path)
filtered_shape = filtered_func.shape[:3]
template_img = nib.load(mni_fname)
template_data = template_img.get_data()
vox2vox = npl.inv(template_img.affine).dot(filtered_func.affine)
M, trans = nib.affines.to_matvec(vox2vox)
resampled = affine_transform(template_data, M, trans,
output_shape=filtered_shape)
froot, ext = splitext(mni_fname)
new_name = froot + '_2mm' + ext
new_img = nib.Nifti1Image(resampled, filtered_func.affine,
template_img.header)
#nib.save(new_img, new_name)
return new_img

def apply_mask(data, mask):
"""Apply mask on an image and return the masked data
Parameters
----------
data: numpy array
The subject's run image data
mask: numpy array same shape as data
The mask for the corresponding data_3d
has 1 for the positions to select and
0 for the positions to filter out.
Return
------
masked_data: numpy array
Array with the values of the data at the selected positions
and 0 for the position filtered out by the mask.
"""
assert(data.shape == mask.shape), "Data and mask shape differ \n" \
+ "Data shape i: %s\nMask shape is: %s" %(data.shape, mask.shape)
return data * mask

if __name__=='__main__':
slab0 = np.reshape(np.arange(9), (3, 3))
slab1 = np.reshape(np.arange(100, 109), (3, 3))
arr_3d = np.zeros((2, 3, 3))
arr_3d[0, :, :] = slab0
arr_3d[1, :, :] = slab1
arr_2d = np.arange(9).reshape((3,3))
mask_bool2d = arr_2d < 10
make_binary_mask(arr_3d,mask_bool2d)
pdb.set_trace()
51 changes: 51 additions & 0 deletions code/utils/tests/test_mask.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"""test_mask.py
Tests for the functions in the mask_functions.py
Run with:
nosetests test_mask.py
"""
from __future__ import print_function
import os, sys
import numpy as np
from numpy.testing import assert_array_equal

#Append path to functions
sys.path.append(os.path.join(os.path.dirname(__file__), "../functions/"))
from mask_functions import *


def test_apply_mask():
# We make a 3D array of shape (3,3,2)
slab0 = np.reshape(np.arange(9), (3, 3))
slab1 = np.reshape(np.arange(100, 109), (3, 3))
arr_3d = np.zeros((2, 3, 3))
arr_3d[0, :, :] = slab0
arr_3d[1, :, :] = slab1
# We make a mask as a 3D array of shape (2,3,3)
# with zeros on the 2nd component of the 1st dimension
mask_3d = np.zeros((2, 3, 3))
mask_3d[0] = np.ones((3,3))
# Defined the resulting masked array
masked_arr = np.zeros((2,3,3))
masked_arr[0, :, :] = slab0
assert_array_equal(apply_mask(arr_3d, mask_3d),masked_arr)


def test_make_binary_mask():
# We make a 3D array of shape (3,3,2)
slab0 = np.reshape(np.arange(9), (3, 3))
slab1 = np.reshape(np.arange(100, 109), (3, 3))
arr_3d = np.zeros((2, 3, 3))
arr_3d[0, :, :] = slab0
arr_3d[1, :, :] = slab1
# We make a mask boolean as a 3D array of shape (2,3,3)
# that filtered the values below 100
mask_bool = arr_3d < 100
mask_3d = np.zeros((2, 3, 3))
mask_3d[0] = np.ones((3,3))
assert_array_equal(make_binary_mask(arr_3d,mask_bool), mask_3d)
arr_2d = np.arange(9).reshape((3,3))
mask_bool2d = arr_2d < 10
# make_binary_mask(arr_3d,mask_bool2d)


0 comments on commit 50ac083

Please sign in to comment.