@@ -182,155 +182,3 @@ def test_to_mask(self):
182
182
],
183
183
)
184
184
assert np .array_equal (mask_img .affine , np .eye (4 ))
185
-
186
-
187
- class H5ArrayProxy :
188
- def __init__ (self , file_like , dataset_name ):
189
- self .file_like = file_like
190
- self .dataset_name = dataset_name
191
- with h5 .File (file_like , 'r' ) as h5f :
192
- arr = h5f [dataset_name ]
193
- self ._shape = arr .shape
194
- self ._dtype = arr .dtype
195
-
196
- @property
197
- def is_proxy (self ):
198
- return True
199
-
200
- @property
201
- def shape (self ):
202
- return self ._shape
203
-
204
- @property
205
- def ndim (self ):
206
- return len (self .shape )
207
-
208
- @property
209
- def dtype (self ):
210
- return self ._dtype
211
-
212
- def __array__ (self , dtype = None ):
213
- with h5 .File (self .file_like , 'r' ) as h5f :
214
- return np .asanyarray (h5f [self .dataset_name ], dtype )
215
-
216
- def __getitem__ (self , slicer ):
217
- with h5 .File (self .file_like , 'r' ) as h5f :
218
- return h5f [self .dataset_name ][slicer ]
219
-
220
-
221
- class H5Geometry (ps .TriMeshFamily ):
222
- """Simple Geometry file structure that combines a single topology
223
- with one or more coordinate sets
224
- """
225
-
226
- @classmethod
227
- def from_filename (klass , pathlike ):
228
- meshes = {}
229
- with h5 .File (pathlike , 'r' ) as h5f :
230
- triangles = H5ArrayProxy (pathlike , '/topology' )
231
- for name in h5f ['coordinates' ]:
232
- meshes [name ] = (H5ArrayProxy (pathlike , f'/coordinates/{ name } ' ), triangles )
233
- return klass (meshes )
234
-
235
- def to_filename (self , pathlike ):
236
- with h5 .File (pathlike , 'w' ) as h5f :
237
- h5f .create_dataset ('/topology' , data = self .get_triangles ())
238
- for name , coord in self ._coords .items ():
239
- h5f .create_dataset (f'/coordinates/{ name } ' , data = coord )
240
-
241
-
242
- class FSGeometryProxy :
243
- def __init__ (self , pathlike ):
244
- self ._file_like = str (Path (pathlike ))
245
- self ._offset = None
246
- self ._vnum = None
247
- self ._fnum = None
248
-
249
- def _peek (self ):
250
- from nibabel .freesurfer .io import _fread3
251
-
252
- with open (self ._file_like , 'rb' ) as fobj :
253
- magic = _fread3 (fobj )
254
- if magic != 16777214 :
255
- raise NotImplementedError ('Triangle files only!' )
256
- fobj .readline ()
257
- fobj .readline ()
258
- self ._vnum = np .fromfile (fobj , '>i4' , 1 )[0 ]
259
- self ._fnum = np .fromfile (fobj , '>i4' , 1 )[0 ]
260
- self ._offset = fobj .tell ()
261
-
262
- @property
263
- def vnum (self ):
264
- if self ._vnum is None :
265
- self ._peek ()
266
- return self ._vnum
267
-
268
- @property
269
- def fnum (self ):
270
- if self ._fnum is None :
271
- self ._peek ()
272
- return self ._fnum
273
-
274
- @property
275
- def offset (self ):
276
- if self ._offset is None :
277
- self ._peek ()
278
- return self ._offset
279
-
280
- @auto_attr
281
- def coords (self ):
282
- ap = ArrayProxy (self ._file_like , ((self .vnum , 3 ), '>f4' , self .offset ))
283
- ap .order = 'C'
284
- return ap
285
-
286
- @auto_attr
287
- def triangles (self ):
288
- offset = self .offset + 12 * self .vnum
289
- ap = ArrayProxy (self ._file_like , ((self .fnum , 3 ), '>i4' , offset ))
290
- ap .order = 'C'
291
- return ap
292
-
293
-
294
- class FreeSurferHemisphere (ps .TriMeshFamily ):
295
- @classmethod
296
- def from_filename (klass , pathlike ):
297
- path = Path (pathlike )
298
- hemi , default = path .name .split ('.' )
299
- mesh_names = (
300
- 'orig' ,
301
- 'white' ,
302
- 'smoothwm' ,
303
- 'pial' ,
304
- 'inflated' ,
305
- 'sphere' ,
306
- 'midthickness' ,
307
- 'graymid' ,
308
- ) # Often created
309
- if default not in mesh_names :
310
- mesh_names .append (default )
311
- meshes = {}
312
- for mesh in mesh_names :
313
- fpath = path .parent / f'{ hemi } .{ mesh } '
314
- if fpath .exists ():
315
- meshes [mesh ] = FSGeometryProxy (fpath )
316
- hemi = klass (meshes )
317
- hemi ._default = default
318
- return hemi
319
-
320
-
321
- def test_FreeSurferHemisphere ():
322
- lh = FreeSurferHemisphere .from_filename (FS_DATA / 'fsaverage/surf/lh.white' )
323
- assert lh .n_coords == 163842
324
- assert lh .n_triangles == 327680
325
-
326
-
327
- @skipUnless (has_h5py , reason = 'Test requires h5py' )
328
- def test_make_H5Geometry (tmp_path ):
329
- lh = FreeSurferHemisphere .from_filename (FS_DATA / 'fsaverage/surf/lh.white' )
330
- h5geo = H5Geometry ({name : lh .get_mesh (name ) for name in ('white' , 'pial' )})
331
- h5geo .to_filename (tmp_path / 'geometry.h5' )
332
-
333
- rt_h5geo = H5Geometry .from_filename (tmp_path / 'geometry.h5' )
334
- assert set (h5geo ._coords ) == set (rt_h5geo ._coords )
335
- assert np .array_equal (lh .get_coords ('white' ), rt_h5geo .get_coords ('white' ))
336
- assert np .array_equal (lh .get_triangles (), rt_h5geo .get_triangles ())
0 commit comments