@@ -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
205182def read_morph_data (filepath ):
0 commit comments