Skip to content

Commit 2e01d49

Browse files
committed
Reading of extra info.
1 parent 89203bb commit 2e01d49

File tree

2 files changed

+23
-45
lines changed

2 files changed

+23
-45
lines changed

nibabel/freesurfer/io.py

Lines changed: 19 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -45,35 +45,20 @@ def _fread3_many(fobj, n):
4545
return (b1 << 16) + (b2 << 8) + b3
4646

4747

48-
def _read_volume_info(extra):
48+
def _read_volume_info(fobj):
4949
volume_info = OrderedDict()
50-
51-
if extra is None:
52-
return volume_info
53-
54-
if extra[:4] != b'\x00\x00\x00\x14':
50+
head = np.fromfile(fobj, '>i4', 3)
51+
if any(head != [2, 0, 20]):
5552
warnings.warn("Unknown extension code.")
5653
else:
57-
try:
58-
for line in extra[4:].split(b'\n'):
59-
if len(line) == 0:
60-
continue
61-
key, val = map(bytes.strip, line.split(b'=', 1))
62-
key = key.decode('utf-8')
63-
if key in ('voxelsize', 'xras', 'yras', 'zras', 'cras'):
64-
val = np.fromstring(val, sep=' ')
65-
val = val.astype(np.float)
66-
elif key == 'volume':
67-
val = np.fromstring(val, sep=' ', dtype=np.uint)
68-
val = val.astype(np.int)
69-
volume_info[key] = val
70-
except ValueError:
71-
raise ValueError("Error parsing volume info")
72-
73-
if len(volume_info) == 0:
74-
warnings.warn("Volume geometry info is either "
75-
"not contained or not valid.")
76-
54+
volume_info['head'] = head
55+
for key in ['valid', 'filename', 'volume', 'voxelsize', 'xras', 'yras',
56+
'zras', 'cras']:
57+
pair = fobj.readline().split('=')
58+
if pair[0].strip() != key or len(pair) != 2:
59+
raise IOError('Error parsing volume info.')
60+
volume_info[pair[0]] = pair[1]
61+
# Ignore the rest
7762
return volume_info
7863

7964

@@ -105,7 +90,7 @@ def read_geometry(filepath, read_metadata=False, read_stamp=False):
10590

10691
with open(filepath, "rb") as fobj:
10792
magic = _fread3(fobj)
108-
if magic == 16777215: # Quad file
93+
if magic in (16777215, 16777213): # Quad file
10994
nvert = _fread3(fobj)
11095
nquad = _fread3(fobj)
11196
coords = np.fromfile(fobj, ">i2", nvert * 3).astype(np.float)
@@ -137,8 +122,7 @@ def read_geometry(filepath, read_metadata=False, read_stamp=False):
137122
coords = np.fromfile(fobj, ">f4", vnum * 3).reshape(vnum, 3)
138123
faces = np.fromfile(fobj, ">i4", fnum * 3).reshape(fnum, 3)
139124

140-
extra = fobj.read() if read_metadata else b''
141-
volume_info = _read_volume_info(extra)
125+
volume_info = _read_volume_info(fobj)
142126
else:
143127
raise ValueError("File does not appear to be a Freesurfer surface")
144128

@@ -176,18 +160,6 @@ def write_geometry(filepath, coords, faces, create_stamp=None,
176160
create_stamp = "created by %s on %s" % (getpass.getuser(),
177161
time.ctime())
178162

179-
postlude = b''
180-
if volume_info is not None and len(volume_info) > 0:
181-
postlude = [b'\x00\x00\x00\x14']
182-
for key, val in volume_info.items():
183-
if key in ('voxelsize', 'xras', 'yras', 'zras', 'cras'):
184-
val = '{0:.4f} {1:.4f} {2:.4f}'.format(*val)
185-
elif key == 'volume':
186-
val = '{0:d} {1:d} {2:d}'.format(*val)
187-
key = key.ljust(6)
188-
postlude.append('{0} = {1}'.format(key, val).encode('utf-8'))
189-
postlude = b'\n'.join(postlude)
190-
191163
with open(filepath, 'wb') as fobj:
192164
magic_bytes.tofile(fobj)
193165
fobj.write(("%s\n\n" % create_stamp).encode('utf-8'))
@@ -199,7 +171,12 @@ def write_geometry(filepath, coords, faces, create_stamp=None,
199171
faces.astype('>i4').reshape(-1).tofile(fobj)
200172

201173
# Add volume info, if given
202-
fobj.write(postlude)
174+
if volume_info is not None and len(volume_info) > 0:
175+
for key, val in volume_info.items():
176+
if key == 'head':
177+
val.tofile(fobj)
178+
continue
179+
fobj.write('{0}={1}'.format(key, val).encode('utf-8'))
203180

204181

205182
def read_morph_data(filepath):

nibabel/freesurfer/tests/test_io.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ def test_geometry():
6363
read_geometry(surf_path, read_metadata=True, read_stamp=True)
6464
assert_equal(0, faces.min())
6565
assert_equal(coords.shape[0], faces.max() + 1)
66-
assert_equal(0, len(volume_info))
66+
assert_equal(9, len(volume_info))
67+
assert_equal([2, 0, 20], volume_info['head'])
6768
assert_equal(u'created by greve on Thu Jun 8 19:17:51 2006',
6869
create_stamp)
6970

@@ -73,13 +74,13 @@ def test_geometry():
7374
surf_path = 'test'
7475
create_stamp = "created by %s on %s" % (getpass.getuser(),
7576
time.ctime())
76-
volume_info['cras'] = np.array([1., 2., 3.])
77+
volume_info['cras '] = '1. 2. 3.'
7778
write_geometry(surf_path, coords, faces, create_stamp, volume_info)
7879

7980
coords2, faces2, volume_info2 = \
8081
read_geometry(surf_path, read_metadata=True)
8182

82-
assert_equal(volume_info2['cras'], volume_info['cras'])
83+
assert_equal(volume_info2['cras '], volume_info['cras '])
8384
with open(surf_path, 'rb') as fobj:
8485
np.fromfile(fobj, ">u1", 3)
8586
read_create_stamp = fobj.readline().decode().rstrip('\n')

0 commit comments

Comments
 (0)