diff --git a/nibabel/gifti/gifti.py b/nibabel/gifti/gifti.py index ed48de8a6b..e3f0e9039e 100644 --- a/nibabel/gifti/gifti.py +++ b/nibabel/gifti/gifti.py @@ -68,10 +68,10 @@ def print_summary(self): class GiftiNVPairs(object): - + """ name = str value = str - + """ def __init__(self, name='', value=''): self.name = name self.value = value @@ -104,6 +104,7 @@ def print_summary(self): class GiftiLabel(xml.XmlSerializable): + """ key = int label = str # rgba @@ -114,6 +115,7 @@ class GiftiLabel(xml.XmlSerializable): green = float blue = float alpha = float + """ def __init__(self, key=0, label='', red=None, green=None, blue=None, alpha=None): @@ -157,9 +159,11 @@ def _arr2txt(arr, elem_fmt): class GiftiCoordSystem(xml.XmlSerializable): + """ dataspace = int xformspace = int xform = np.ndarray # 4x4 numpy array + """ def __init__(self, dataspace=0, xformspace=0, xform=None): self.dataspace = dataspace @@ -224,12 +228,11 @@ def _data_tag_element(dataarray, encoding, datatype, ordering): class GiftiDataArray(xml.XmlSerializable): - + """ # These are for documentation only; we don't use these class variables intent = int datatype = int ind_ord = int - num_dim = int dims = list encoding = int endian = int @@ -238,19 +241,38 @@ class GiftiDataArray(xml.XmlSerializable): data = np.ndarray coordsys = GiftiCoordSystem meta = GiftiMetaData + """ - def __init__(self, data=None): + def __init__(self, data=None, + encoding="GIFTI_ENCODING_B64GZ", + endian=sys.byteorder, + coordsys=None, + ordering="C", + meta=None): + """ + Returns a shell object that cannot be saved. + """ self.data = data self.dims = [] - self.meta = GiftiMetaData() - self.coordsys = GiftiCoordSystem() + self.meta = meta or GiftiMetaData() + self.coordsys = coordsys or GiftiCoordSystem() self.ext_fname = '' self.ext_offset = '' + self.intent = 0 # required attribute, NIFTI_INTENT_NONE + self.datatype = 0 # required attribute, void/none + # python/numpy default: column major order + self.ind_ord = array_index_order_codes.code[ordering] + self.encoding = encoding + self.endian = endian + + @property + def num_dim(self): + return len(self.dims) @classmethod def from_array(klass, darray, - intent, + intent="NIFTI_INTENT_NONE", datatype=None, encoding="GIFTI_ENCODING_B64GZ", endian=sys.byteorder, @@ -289,7 +311,6 @@ def from_array(klass, if meta is None: meta = {} cda = klass(darray) - cda.num_dim = len(darray.shape) cda.dims = list(darray.shape) if datatype is None: cda.datatype = data_type_codes.code[darray.dtype] diff --git a/nibabel/gifti/parse_gifti_fast.py b/nibabel/gifti/parse_gifti_fast.py index 85973db40c..18096e178a 100644 --- a/nibabel/gifti/parse_gifti_fast.py +++ b/nibabel/gifti/parse_gifti_fast.py @@ -167,14 +167,14 @@ def StartElementHandler(self, name, attrs): if "ArrayIndexingOrder" in attrs: self.da.ind_ord = array_index_order_codes.code[ attrs["ArrayIndexingOrder"]] - if "Dimensionality" in attrs: - self.da.num_dim = int(attrs["Dimensionality"]) - for i in range(self.da.num_dim): + num_dim = int(attrs.get("Dimensionality", 0)) + for i in range(num_dim): di = "Dim%s" % str(i) if di in attrs: self.da.dims.append(int(attrs[di])) # dimensionality has to correspond to the number of DimX given - assert len(self.da.dims) == self.da.num_dim + # TODO (bcipolli): don't assert; raise parse warning, and recover. + assert len(self.da.dims) == num_dim if "Encoding" in attrs: self.da.encoding = gifti_encoding_codes.code[attrs["Encoding"]] if "Endian" in attrs: diff --git a/nibabel/gifti/tests/test_gifti.py b/nibabel/gifti/tests/test_gifti.py index b572db0c85..95eccf36e4 100644 --- a/nibabel/gifti/tests/test_gifti.py +++ b/nibabel/gifti/tests/test_gifti.py @@ -7,7 +7,7 @@ import nibabel as nib from nibabel.externals.six import string_types from nibabel.gifti import (GiftiImage, GiftiDataArray, GiftiLabel, - GiftiLabelTable, GiftiMetaData) + GiftiLabelTable, GiftiMetaData, GiftiNVPairs) from nibabel.gifti.gifti import data_tag from nibabel.nifti1 import data_type_codes @@ -34,14 +34,24 @@ def test_gifti_image(): gi = GiftiImage() assert_equal(gi.numDA, 0) - da = GiftiDataArray(data='data') + # Test from numpy numeric array + data = np.random.random((5,)) + da = GiftiDataArray.from_array(data) gi.add_gifti_data_array(da) assert_equal(gi.numDA, 1) - assert_equal(gi.darrays[0].data, 'data') + assert_array_equal(gi.darrays[0].data, data) + # Test removing gi.remove_gifti_data_array(0) assert_equal(gi.numDA, 0) + # Test from string + da = GiftiDataArray.from_array('zzzzz') + gi.add_gifti_data_array(da) + assert_equal(gi.numDA, 1) + assert_array_equal(gi.darrays[0].data, data) + + # Remove from empty gi = GiftiImage() gi.remove_gifti_data_array_by_intent(0) @@ -49,14 +59,13 @@ def test_gifti_image(): # Remove one gi = GiftiImage() - da = GiftiDataArray(data='data') + da = GiftiDataArray.from_array(np.zeros((5,)), intent=0) gi.add_gifti_data_array(da) - gi.remove_gifti_data_array_by_intent(0) - assert_equal(gi.numDA, 1) + gi.remove_gifti_data_array_by_intent(3) + assert_equal(gi.numDA, 1, "data array should exist on 'missed' remove") - gi.darrays[0].intent = 0 - gi.remove_gifti_data_array_by_intent(0) + gi.remove_gifti_data_array_by_intent(da.intent) assert_equal(gi.numDA, 0) @@ -97,13 +106,22 @@ def test_labeltable(): def test_metadata(): # Test deprecation with clear_and_catch_warnings() as w: - warnings.filterwarnings('once', category=DeprecationWarning) + warnings.filterwarnings('always', category=DeprecationWarning) assert_equal(len(GiftiDataArray().get_metadata()), 0) + assert_equal(len(w), 1) # Test deprecation with clear_and_catch_warnings() as w: warnings.filterwarnings('once', category=DeprecationWarning) assert_equal(len(GiftiMetaData().get_metadata()), 0) + assert_equal(len(w), 1) + + +def test_metadata(): + nvpair = GiftiNVPairs('key', 'value') + da = GiftiMetaData(nvpair=nvpair) + assert_equal(da.data[0].name, 'key') + assert_equal(da.data[0].value, 'value') def test_gifti_label_rgba(): @@ -133,6 +151,7 @@ def assign_rgba(gl, val): with clear_and_catch_warnings() as w: warnings.filterwarnings('once', category=DeprecationWarning) assert_equal(kwargs['red'], gl3.get_rgba()[0]) + assert_equal(len(w), 1) # Test default value gl4 = GiftiLabel() diff --git a/tox.ini b/tox.ini index ea90c56b79..8a00d1f7e7 100644 --- a/tox.ini +++ b/tox.ini @@ -20,6 +20,6 @@ deps = deps = [flake8] max-line-length=100 -ignore=D100,D101,D102,D103,D104,D105,D200,D201,D204,D205,D208,D210,D300,D301,D400,D401,D403,E266,E402,E731,F821,I100,I101,I201,N802,N803,N804,N806 +ignore=D100,D101,D102,D103,D104,D105,D200,D201,D202,D204,D205,D208,D209,D210,D300,D301,D400,D401,D403,E266,E402,E731,F821,I100,I101,I201,N802,N803,N804,N806 exclude=*test*,*sphinx*,nibabel/externals/*,*/__init__.py