Skip to content

Commit 289175e

Browse files
committed
TEST: Read FreeSurfer subject, save/read H5 subject
1 parent 5b6fa16 commit 289175e

File tree

1 file changed

+37
-9
lines changed

1 file changed

+37
-9
lines changed

nibabel/tests/test_pointset.py

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
from pathlib import Path
2+
from unittest import skipUnless
23

34
import numpy as np
45

56
from nibabel import pointset as ps
67
from nibabel.arrayproxy import ArrayProxy
78
from nibabel.optpkg import optional_package
9+
from nibabel.tests.nibabel_data import get_nibabel_data
810

911
h5, has_h5py, _ = optional_package('h5py')
1012

13+
FS_DATA = Path(get_nibabel_data()) / 'nitest-freesurfer'
14+
1115

1216
class H5ArrayProxy:
1317
def __init__(self, file_like, dataset_name):
@@ -38,7 +42,7 @@ def __array__(self, dtype=None):
3842
with h5.File(self.file_like, "r") as h5f:
3943
return np.asanyarray(h5f[self.dataset_name], dtype)
4044

41-
def __slicer__(self, slicer):
45+
def __getitem__(self, slicer):
4246
with h5.File(self.file_like, "r") as h5f:
4347
return h5f[self.dataset_name][slicer]
4448

@@ -47,19 +51,22 @@ class H5Geometry(ps.TriangularMesh):
4751
"""Simple Geometry file structure that combines a single topology
4852
with one or more coordinate sets
4953
"""
54+
def __init__(self, meshes):
55+
self._meshes = meshes
56+
5057
@classmethod
5158
def from_filename(klass, pathlike):
5259
meshes = {}
5360
with h5.File(pathlike, "r") as h5f:
54-
triangles = h5f['topology']
55-
for name, coords in h5f['coordinates'].items():
56-
meshes[name] = (coords, triangles)
61+
triangles = H5ArrayProxy(pathlike, '/topology')
62+
for name in h5f['coordinates']:
63+
meshes[name] = (H5ArrayProxy(pathlike, f'/coordinates/{name}'), triangles)
5764
return klass(meshes)
5865

5966
def to_filename(self, pathlike):
6067
topology = None
6168
coordinates = {}
62-
for name, mesh in self.meshes.items():
69+
for name, mesh in self._meshes.items():
6370
coords, faces = mesh
6471
if topology is None:
6572
topology = faces
@@ -68,9 +75,9 @@ def to_filename(self, pathlike):
6875
coordinates[name] = coords
6976

7077
with h5.File(pathlike, "w") as h5f:
71-
h5f.create_dataset("/topology", topology)
78+
h5f.create_dataset("/topology", data=topology)
7279
for name, coord in coordinates.items():
73-
h5f.create_dataset(f"/coordinates/{name}", coord)
80+
h5f.create_dataset(f"/coordinates/{name}", data=coord)
7481

7582
def get_coords(self, name=None):
7683
if name is None:
@@ -137,6 +144,9 @@ def triangles(self):
137144

138145

139146
class FreeSurferHemisphere(ps.TriangularMesh):
147+
def __init__(self, meshes):
148+
self._meshes = meshes
149+
140150
@classmethod
141151
def from_filename(klass, pathlike):
142152
path = Path(pathlike)
@@ -167,8 +177,26 @@ def get_triangles(self, name=None):
167177

168178
@property
169179
def n_coords(self):
170-
return self.meshes[self._default].vnum
180+
return self._meshes[self._default].vnum
171181

172182
@property
173183
def n_triangles(self):
174-
return self.meshes[self._default].fnum
184+
return self._meshes[self._default].fnum
185+
186+
187+
def test_FreeSurferHemisphere():
188+
lh = FreeSurferHemisphere.from_filename(FS_DATA / 'fsaverage/surf/lh.white')
189+
assert lh.n_coords == 163842
190+
assert lh.n_triangles == 327680
191+
192+
193+
@skipUnless(has_h5py, reason="Test requires h5py")
194+
def test_make_H5Geometry(tmp_path):
195+
lh = FreeSurferHemisphere.from_filename(FS_DATA / 'fsaverage/surf/lh.white')
196+
h5geo = H5Geometry({name: lh.get_mesh(name) for name in ('white', 'pial')})
197+
h5geo.to_filename(tmp_path / "geometry.h5")
198+
199+
rt_h5geo = H5Geometry.from_filename(tmp_path / "geometry.h5")
200+
assert set(h5geo._meshes) == set(rt_h5geo._meshes)
201+
assert np.array_equal(lh.get_coords('white'), rt_h5geo.get_coords('white'))
202+
assert np.array_equal(lh.get_triangles(), rt_h5geo.get_triangles())

0 commit comments

Comments
 (0)