@@ -45,35 +45,20 @@ def _fread3_many(fobj, n):
45
45
return (b1 << 16 ) + (b2 << 8 ) + b3
46
46
47
47
48
- def _read_volume_info (extra ):
48
+ def _read_volume_info (fobj ):
49
49
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 ]):
55
52
warnings .warn ("Unknown extension code." )
56
53
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
77
62
return volume_info
78
63
79
64
@@ -105,7 +90,7 @@ def read_geometry(filepath, read_metadata=False, read_stamp=False):
105
90
106
91
with open (filepath , "rb" ) as fobj :
107
92
magic = _fread3 (fobj )
108
- if magic == 16777215 : # Quad file
93
+ if magic in ( 16777215 , 16777213 ) : # Quad file
109
94
nvert = _fread3 (fobj )
110
95
nquad = _fread3 (fobj )
111
96
coords = np .fromfile (fobj , ">i2" , nvert * 3 ).astype (np .float )
@@ -137,8 +122,7 @@ def read_geometry(filepath, read_metadata=False, read_stamp=False):
137
122
coords = np .fromfile (fobj , ">f4" , vnum * 3 ).reshape (vnum , 3 )
138
123
faces = np .fromfile (fobj , ">i4" , fnum * 3 ).reshape (fnum , 3 )
139
124
140
- extra = fobj .read () if read_metadata else b''
141
- volume_info = _read_volume_info (extra )
125
+ volume_info = _read_volume_info (fobj )
142
126
else :
143
127
raise ValueError ("File does not appear to be a Freesurfer surface" )
144
128
@@ -176,18 +160,6 @@ def write_geometry(filepath, coords, faces, create_stamp=None,
176
160
create_stamp = "created by %s on %s" % (getpass .getuser (),
177
161
time .ctime ())
178
162
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
-
191
163
with open (filepath , 'wb' ) as fobj :
192
164
magic_bytes .tofile (fobj )
193
165
fobj .write (("%s\n \n " % create_stamp ).encode ('utf-8' ))
@@ -199,7 +171,12 @@ def write_geometry(filepath, coords, faces, create_stamp=None,
199
171
faces .astype ('>i4' ).reshape (- 1 ).tofile (fobj )
200
172
201
173
# 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' ))
203
180
204
181
205
182
def read_morph_data (filepath ):
0 commit comments