Skip to content

Commit 8b0feb6

Browse files
committed
tst: added basic io tests
1 parent e1ab596 commit 8b0feb6

File tree

5 files changed

+126
-20
lines changed

5 files changed

+126
-20
lines changed

nibabel/cifti/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"""
1919

2020
from .parse_cifti_fast import create_cifti_image
21-
from .cifti import (CiftiMetaData, CiftiHeader, CiftiLabel,
21+
from .cifti import (CiftiMetaData, CiftiHeader, CiftiImage, CiftiLabel,
2222
CiftiLabelTable, CiftiNVPair, CiftiVertexIndices,
2323
CiftiVoxelIndicesIJK, CiftiBrainModel, CiftiMatrix,
2424
CiftiMatrixIndicesMap, CiftiNamedMap, CiftiParcel,

nibabel/cifti/cifti.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -263,10 +263,9 @@ def __init__(self, brainStructure=None, surfaceNumberOfVertices=None):
263263
def to_xml(self, prefix='', indent=' '):
264264
if self.brainStructure is None:
265265
return ''
266-
res = ('%s<Surface BrainStructure="%s" '
267-
'SurfaceNumberOfVertices"%s" />\n') % (prefix,
268-
self.brainStructure,
269-
self.surfaceNumberOfVertices)
266+
res = ('%s<Surface BrainStructure="%s" SurfaceNumberOfVertices="%s" '
267+
'/>\n') % (prefix, self.brainStructure,
268+
self.surfaceNumberOfVertices)
270269
return res
271270

272271
class CiftiVoxelIndicesIJK(object):
@@ -740,8 +739,10 @@ def from_header(klass, header=None):
740739
class CiftiImage(object):
741740
header_class = CiftiHeader
742741

743-
def __init__(self, data, header, nifti_header):
744-
self.header = header
742+
def __init__(self, data=None, header=None, nifti_header=None):
743+
self.header = CiftiHeader()
744+
if header is not None:
745+
self.header = header
745746
self.data = data
746747
self.extra = nifti_header
747748

nibabel/cifti/parse_cifti_fast.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,10 +361,7 @@ def parse_cifti_string(cifti_string):
361361
out = Outputter()
362362
for name in HANDLER_NAMES:
363363
setattr(parser, name, getattr(out, name))
364-
try:
365-
parser.Parse(cifti_string, True)
366-
except ExpatError:
367-
print('An expat error occured while parsing the Cifti file.')
364+
parser.Parse(cifti_string, True)
368365
return out.header
369366

370367
def create_cifti_image(nifti2_image, cifti_header, intent_code):
@@ -374,6 +371,8 @@ def create_cifti_image(nifti2_image, cifti_header, intent_code):
374371
if ext.get_code() == 32:
375372
nifti_header.extensions.remove(ext)
376373
break
374+
with open('test.xml', 'wt') as fp:
375+
fp.writelines(cifti_header)
377376
header = parse_cifti_string(cifti_header)
378377
img = CiftiImage(data, header, nifti_header)
379378
return img

nibabel/cifti/tests/test_ciftiio.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# emacs: -*- mode: python-mode; py-indent-offset: 4; indent-tabs-mode: nil -*-
2+
# vi: set ft=python sts=4 ts=4 sw=4 et:
3+
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
4+
#
5+
# See COPYING file distributed along with the NiBabel package for the
6+
# copyright and license terms.
7+
#
8+
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
9+
from __future__ import division, print_function, absolute_import
10+
11+
from os.path import join as pjoin, dirname
12+
import sys
13+
14+
import numpy as np
15+
16+
from ... import cifti as ci
17+
18+
from ...tmpdirs import InTemporaryDirectory
19+
20+
from numpy.testing import assert_array_equal, assert_array_almost_equal
21+
22+
from nose.tools import (assert_true, assert_false, assert_equal,
23+
assert_raises)
24+
25+
26+
IO_DATA_PATH = pjoin(dirname(__file__), 'data')
27+
28+
DATA_FILE1 = pjoin(IO_DATA_PATH, '')
29+
DATA_FILE2 = pjoin(IO_DATA_PATH,
30+
'Conte69.MyelinAndCorrThickness.32k_fs_LR.dscalar.nii')
31+
DATA_FILE3 = pjoin(IO_DATA_PATH,
32+
'Conte69.MyelinAndCorrThickness.32k_fs_LR.dtseries.nii')
33+
DATA_FILE4 = pjoin(IO_DATA_PATH,
34+
'Conte69.MyelinAndCorrThickness.32k_fs_LR.ptseries.nii')
35+
DATA_FILE5 = pjoin(IO_DATA_PATH,
36+
'Conte69.parcellations_VGD11b.32k_fs_LR.dlabel.nii')
37+
DATA_FILE6 = pjoin(IO_DATA_PATH, 'ones.dscalar.nii')
38+
39+
datafiles = [DATA_FILE2, DATA_FILE3, DATA_FILE4, DATA_FILE5, DATA_FILE6]
40+
41+
def test_read_ordering():
42+
# DATA_FILE1 has an expected darray[0].data shape of (3,3). However if we
43+
# read another image first (DATA_FILE2) then the shape is wrong
44+
# Read an image
45+
img2 = ci.load(DATA_FILE6)
46+
assert_equal(img2.data.shape, (91282,))
47+
48+
49+
def test_version():
50+
for i, dat in enumerate(datafiles):
51+
img = ci.load(dat)
52+
assert_equal(img.header.version, '2')
53+
54+
'''
55+
def test_dataarray1():
56+
img1 = gi.read(DATA_FILE1)
57+
# Round trip
58+
with InTemporaryDirectory():
59+
gi.write(img1, 'test.gii')
60+
bimg = gi.read('test.gii')
61+
for img in (img1, bimg):
62+
assert_array_almost_equal(img.darrays[0].data, DATA_FILE1_darr1)
63+
assert_array_almost_equal(img.darrays[1].data, DATA_FILE1_darr2)
64+
me=img.darrays[0].meta.get_metadata()
65+
assert_true('AnatomicalStructurePrimary' in me)
66+
assert_true('AnatomicalStructureSecondary' in me)
67+
assert_equal(me['AnatomicalStructurePrimary'], 'CortexLeft')
68+
assert_array_almost_equal(img.darrays[0].coordsys.xform, np.eye(4,4))
69+
assert_equal(xform_codes.niistring[img.darrays[0].coordsys.dataspace],'NIFTI_XFORM_TALAIRACH')
70+
assert_equal(xform_codes.niistring[img.darrays[0].coordsys.xformspace],'NIFTI_XFORM_TALAIRACH')
71+
'''
72+
73+
74+
def test_readwritedata():
75+
with InTemporaryDirectory():
76+
for name in datafiles:
77+
img = ci.load(name)
78+
img.to_filename('test.nii')
79+
img2 = ci.load('test.nii')
80+
assert_equal(img.header.matrix.numMIM,img2.header.matrix.numMIM)
81+
assert_array_almost_equal(img.data,
82+
img2.data)
83+
84+
85+
def test_newmetadata():
86+
img = ci.CiftiImage()
87+
attr = ci.CiftiNVPair(name = 'mykey', value = 'val1')
88+
newmeta = ci.CiftiMetaData(attr)
89+
img.header.matrix.meta = newmeta
90+
myme = img.header.matrix.meta.get_metadata()
91+
assert_true('mykey' in myme)
92+
newmeta = ci.CiftiMetaData.from_dict( {'mykey1' : 'val2'} )
93+
img.header.matrix.meta = newmeta
94+
myme = img.header.matrix.meta.get_metadata()
95+
assert_true('mykey1' in myme)
96+
assert_false('mykey' in myme)

nibabel/nifti2.py

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -237,16 +237,26 @@ def from_file_map(klass, file_map):
237237
img = super(Nifti2Image, klass).from_file_map(file_map)
238238
hdr = img.get_header()
239239
intent_code = hdr.get_intent('code')[0]
240+
img.is_cifti = False
240241
if intent_code >= 3000 and intent_code < 3100:
241-
cifti_header = None
242-
if hdr.extensions is not None:
243-
for extension in hdr.extensions:
244-
if extension.get_code() == 32:
245-
cifti_header = extension.get_content()
246-
if cifti_header is None:
247-
raise ValueError(('Nifti2 header does not contain a CIFTI '
248-
'extension'))
249-
img = create_cifti_image(img, cifti_header, intent_code)
242+
img.is_cifti = True
243+
img = img.to_cifti()
244+
return img
245+
246+
def to_cifti(self):
247+
if not self.is_cifti:
248+
TypeError('Nifti2 image is not a CIFTI file')
249+
hdr = self.get_header()
250+
intent_code = hdr.get_intent('code')[0]
251+
cifti_header = None
252+
if hdr.extensions is not None:
253+
for extension in hdr.extensions:
254+
if extension.get_code() == 32:
255+
cifti_header = extension.get_content()
256+
if cifti_header is None:
257+
raise ValueError(('Nifti2 header does not contain a CIFTI '
258+
'extension'))
259+
img = create_cifti_image(self, cifti_header, intent_code)
250260
return img
251261

252262
def load(filename):

0 commit comments

Comments
 (0)