Skip to content

Commit af4e08a

Browse files
committed
TEST: Test Pointset and GridIndices classes
1 parent 25bbd12 commit af4e08a

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed

nibabel/tests/test_pointset.py

+122
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
from unittest import skipUnless
33

44
import numpy as np
5+
import pytest
56

67
from nibabel import pointset as ps
8+
from nibabel.affines import apply_affine
79
from nibabel.arrayproxy import ArrayProxy
810
from nibabel.onetime import auto_attr
911
from nibabel.optpkg import optional_package
@@ -14,6 +16,126 @@
1416
FS_DATA = Path(get_nibabel_data()) / 'nitest-freesurfer'
1517

1618

19+
class TestPointsets:
20+
rng = np.random.default_rng()
21+
22+
@pytest.mark.parametrize('shape', [(5, 2), (5, 3), (5, 4)])
23+
@pytest.mark.parametrize('homogeneous', [True, False])
24+
def test_init(self, shape, homogeneous):
25+
coords = self.rng.random(shape)
26+
27+
if homogeneous:
28+
coords = np.column_stack([coords, np.ones(shape[0])])
29+
30+
expected_shape = (shape[0], shape[1] + homogeneous)
31+
32+
points = ps.Pointset(coords, homogeneous=homogeneous)
33+
assert points.shape == expected_shape
34+
assert np.allclose(points.affine, np.eye(shape[1] + 1))
35+
assert points.homogeneous is homogeneous
36+
assert points.ndim == 2
37+
assert points.n_coords == shape[0]
38+
assert points.dim == shape[1]
39+
40+
points = ps.Pointset(coords, affine=np.diag([2] * shape[1] + [1]), homogeneous=homogeneous)
41+
assert points.shape == expected_shape
42+
assert np.allclose(points.affine, np.diag([2] * shape[1] + [1]))
43+
assert points.homogeneous is homogeneous
44+
assert points.ndim == 2
45+
assert points.n_coords == shape[0]
46+
assert points.dim == shape[1]
47+
48+
# Badly shaped affine
49+
with pytest.raises(ValueError):
50+
ps.Pointset(coords, affine=[0, 1])
51+
52+
# Badly valued affine
53+
with pytest.raises(ValueError):
54+
ps.Pointset(coords, affine=np.ones((shape[1] + 1, shape[1] + 1)))
55+
56+
@pytest.mark.parametrize('shape', [(5, 2), (5, 3), (5, 4)])
57+
@pytest.mark.parametrize('homogeneous', [True, False])
58+
def test_affines(self, shape, homogeneous):
59+
orig_coords = coords = self.rng.random(shape)
60+
61+
if homogeneous:
62+
coords = np.column_stack([coords, np.ones(shape[0])])
63+
64+
points = ps.Pointset(coords, homogeneous=homogeneous)
65+
assert np.allclose(points.get_coords(), orig_coords)
66+
67+
# Apply affines
68+
scaler = np.diag([2] * shape[1] + [1])
69+
scaled = scaler @ points
70+
assert np.array_equal(scaled.coordinates, points.coordinates)
71+
assert np.array_equal(scaled.affine, scaler)
72+
assert np.allclose(scaled.get_coords(), 2 * orig_coords)
73+
74+
flipper = np.eye(shape[1] + 1)
75+
# [[1, 0, 0], [0, 1, 0], [0, 0, 1]] becomes [[0, 1, 0], [1, 0, 0], [0, 0, 1]]
76+
flipper[:-1] = flipper[-2::-1]
77+
flipped = flipper @ points
78+
assert np.array_equal(flipped.coordinates, points.coordinates)
79+
assert np.array_equal(flipped.affine, flipper)
80+
assert np.allclose(flipped.get_coords(), orig_coords[:, ::-1])
81+
82+
# Concatenate affines, with any associativity
83+
for doubledup in [(scaler @ flipper) @ points, scaler @ (flipper @ points)]:
84+
assert np.array_equal(doubledup.coordinates, points.coordinates)
85+
assert np.allclose(doubledup.affine, scaler @ flipper)
86+
assert np.allclose(doubledup.get_coords(), 2 * orig_coords[:, ::-1])
87+
88+
def test_homogeneous_coordinates(self):
89+
ccoords = self.rng.random((5, 3))
90+
hcoords = np.column_stack([ccoords, np.ones(5)])
91+
92+
cartesian = ps.Pointset(ccoords)
93+
homogeneous = ps.Pointset(hcoords, homogeneous=True)
94+
95+
for points in (cartesian, homogeneous):
96+
assert np.array_equal(points.get_coords(), ccoords)
97+
assert np.array_equal(points.get_coords(as_homogeneous=True), hcoords)
98+
99+
affine = np.diag([2, 3, 4, 1])
100+
cart2 = affine @ cartesian
101+
homo2 = affine @ homogeneous
102+
103+
exp_c = apply_affine(affine, ccoords)
104+
exp_h = (affine @ hcoords.T).T
105+
for points in (cart2, homo2):
106+
assert np.array_equal(points.get_coords(), exp_c)
107+
assert np.array_equal(points.get_coords(as_homogeneous=True), exp_h)
108+
109+
110+
def test_GridIndices():
111+
# 2D case
112+
shape = (2, 3)
113+
gi = ps.GridIndices(shape)
114+
115+
assert gi.dtype == np.dtype('u1')
116+
assert gi.shape == (6, 2)
117+
assert repr(gi) == '<GridIndices(2, 3)>'
118+
119+
gi_arr = np.asanyarray(gi)
120+
assert gi_arr.dtype == np.dtype('u1')
121+
assert gi_arr.shape == (6, 2)
122+
# Tractable to write out
123+
assert np.array_equal(gi_arr, [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2]])
124+
125+
shape = (2, 3, 4)
126+
gi = ps.GridIndices(shape)
127+
128+
assert gi.dtype == np.dtype('u1')
129+
assert gi.shape == (24, 3)
130+
assert repr(gi) == '<GridIndices(2, 3, 4)>'
131+
132+
gi_arr = np.asanyarray(gi)
133+
assert gi_arr.dtype == np.dtype('u1')
134+
assert gi_arr.shape == (24, 3)
135+
# Separate implementation
136+
assert np.array_equal(gi_arr, np.mgrid[:2, :3, :4].reshape(3, -1).T)
137+
138+
17139
class H5ArrayProxy:
18140
def __init__(self, file_like, dataset_name):
19141
self.file_like = file_like

0 commit comments

Comments
 (0)