# emacs: -*- mode: python-mode; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## # # See COPYING file distributed along with the NiBabel package for the # copyright and license terms. # ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## from __future__ import division, print_function, absolute_import from os.path import join as pjoin import gzip import bz2 import warnings import types from io import BytesIO import numpy as np from .. import load, Nifti1Image from ..externals.netcdf import netcdf_file from ..deprecated import ModuleProxy from .. import minc1 from ..minc1 import Minc1File, Minc1Image, MincHeader from nose.tools import (assert_true, assert_equal, assert_false, assert_raises) from numpy.testing import assert_array_equal, assert_array_almost_equal from ..tmpdirs import InTemporaryDirectory from ..testing import data_path from . import test_spatialimages as tsi from .test_fileslice import slicer_samples from .test_helpers import assert_data_similar EG_FNAME = pjoin(data_path, 'tiny.mnc') # Example images in format expected for ``test_image_api``, adding ``zooms`` # item. EXAMPLE_IMAGES = [ dict( fname = pjoin(data_path, 'tiny.mnc'), shape = (10,20,20), dtype = np.uint8, affine = np.array([[0, 0, 2.0, -20], [0, 2.0, 0, -20], [2.0, 0, 0, -10], [0, 0, 0, 1]]), zooms = (2., 2., 2.), # These values from SPM2 data_summary = dict( min = 0.20784314, max = 0.74901961, mean = 0.60602819), is_proxy = True), dict( fname = pjoin(data_path, 'minc1_1_scale.mnc'), shape = (10,20,20), dtype = np.uint8, affine = np.array([[0, 0, 2.0, -20], [0, 2.0, 0, -20], [2.0, 0, 0, -10], [0, 0, 0, 1]]), zooms = (2., 2., 2.), # These values from mincstats data_summary = dict( min = 0.2082842439, max = 0.2094327615, mean = 0.2091292083), is_proxy = True), dict( fname = pjoin(data_path, 'minc1_4d.mnc'), shape = (2, 10,20,20), dtype = np.uint8, affine = np.array([[0, 0, 2.0, -20], [0, 2.0, 0, -20], [2.0, 0, 0, -10], [0, 0, 0, 1]]), zooms = (1., 2., 2., 2.), # These values from mincstats data_summary = dict( min = 0.2078431373, max = 1.498039216, mean = 0.9090422837), is_proxy = True), ] def test_old_namespace(): # Check old names are defined in minc1 module and top level # Check warnings raised arr = np.arange(24).reshape((2, 3, 4)) aff = np.diag([2, 3, 4, 1]) with warnings.catch_warnings(record=True) as warns: # Top level import. # This import does not trigger an import of the minc.py module, because # it's the proxy object. from .. import minc assert_equal(warns, []) # If there was a previous import it will be module, otherwise it will be # a proxy previous_import = isinstance(minc, types.ModuleType) if not previous_import: assert_true(isinstance(minc, ModuleProxy)) old_minc1image = minc.Minc1Image # just to check it works # There may or may not be a warning raised on accessing the proxy, # depending on whether the minc.py module is already imported in this # test run. if not previous_import: assert_equal(warns.pop(0).category, FutureWarning) from .. import Minc1Image, MincImage assert_equal(warns, []) # The import from old module is the same as that from new assert_true(old_minc1image is Minc1Image) # But the old named import, imported from new, is not the same assert_false(Minc1Image is MincImage) assert_equal(warns, []) # Create object using old name mimg = MincImage(arr, aff) assert_array_equal(mimg.get_data(), arr) # Call to create object created warning assert_equal(warns.pop(0).category, FutureWarning) # Another old name from ..minc1 import MincFile, Minc1File assert_false(MincFile is Minc1File) assert_equal(warns, []) mf = MincFile(netcdf_file(EG_FNAME)) assert_equal(mf.get_data_shape(), (10, 20 , 20)) # Call to create object created warning assert_equal(warns.pop(0).category, FutureWarning) class _TestMincFile(object): module = minc1 file_class = Minc1File fname = EG_FNAME opener = netcdf_file test_files = EXAMPLE_IMAGES def test_mincfile(self): for tp in self.test_files: mnc_obj = self.opener(tp['fname'], 'r') mnc = self.file_class(mnc_obj) assert_equal(mnc.get_data_dtype().type, tp['dtype']) assert_equal(mnc.get_data_shape(), tp['shape']) assert_equal(mnc.get_zooms(), tp['zooms']) assert_array_equal(mnc.get_affine(), tp['affine']) data = mnc.get_scaled_data() assert_equal(data.shape, tp['shape']) def test_mincfile_slicing(self): # Test slicing and scaling of mincfile data for tp in self.test_files: mnc_obj = self.opener(tp['fname'], 'r') mnc = self.file_class(mnc_obj) data = mnc.get_scaled_data() for slicedef in ((slice(None),), (1,), (slice(None), 1), (1, slice(None)), (slice(None), 1, 1), (1, slice(None), 1), (1, 1, slice(None)), ): sliced_data = mnc.get_scaled_data(slicedef) assert_array_equal(sliced_data, data[slicedef]) def test_load(self): # Check highest level load of minc works for tp in self.test_files: img = load(tp['fname']) data = img.get_data() assert_equal(data.shape, tp['shape']) # min, max, mean values from read in SPM2 / minctools assert_data_similar(data, tp) # check if mnc can be converted to nifti ni_img = Nifti1Image.from_image(img) assert_array_equal(ni_img.affine, tp['affine']) assert_array_equal(ni_img.get_data(), data) def test_array_proxy_slicing(self): # Test slicing of array proxy for tp in self.test_files: img = load(tp['fname']) arr = img.get_data() prox = img.dataobj assert_true(prox.is_proxy) for sliceobj in slicer_samples(img.shape): assert_array_equal(arr[sliceobj], prox[sliceobj]) class TestMinc1File(_TestMincFile): def test_compressed(self): # we can read minc compressed # Not so for MINC2; hence this small sub-class for tp in self.test_files: content = open(tp['fname'], 'rb').read() openers_exts = ((gzip.open, '.gz'), (bz2.BZ2File, '.bz2')) with InTemporaryDirectory(): for opener, ext in openers_exts: fname = 'test.mnc' + ext fobj = opener(fname, 'wb') fobj.write(content) fobj.close() img = self.module.load(fname) data = img.get_data() assert_data_similar(data, tp) del img # Test the Minc header def test_header_data_io(): bio = BytesIO() hdr = MincHeader() arr = np.arange(24).reshape((2, 3, 4)) assert_raises(NotImplementedError, hdr.data_to_fileobj, arr, bio) assert_raises(NotImplementedError, hdr.data_from_fileobj, bio) class TestMinc1Image(tsi.TestSpatialImage): image_class = Minc1Image eg_images = (pjoin(data_path, 'tiny.mnc'),) module = minc1 def test_data_to_from_fileobj(self): # Check data_from_fileobj of header raises an error for fpath in self.eg_images: img = self.module.load(fpath) bio = BytesIO() arr = np.arange(24).reshape((2, 3, 4)) assert_raises(NotImplementedError, img.header.data_to_fileobj, arr, bio) assert_raises(NotImplementedError, img.header.data_from_fileobj, bio)