diff --git a/afids_utils/tests/strategies.py b/afids_utils/tests/strategies.py index 772c37a5..f8d929c5 100644 --- a/afids_utils/tests/strategies.py +++ b/afids_utils/tests/strategies.py @@ -8,7 +8,7 @@ from hypothesis.extra.numpy import arrays from numpy.typing import NDArray -from afids_utils.afids import AfidPosition, AfidSet +from afids_utils.afids import AfidPosition, AfidSet, AfidVoxel @st.composite @@ -105,8 +105,8 @@ def voxel_coords( draw: st.DrawFn, min_value: int = -50, max_value: int = 50, -) -> AfidPosition: - return AfidPosition( +) -> AfidVoxel: + return AfidVoxel( label=draw(st.integers(min_value=1, max_value=32)), i=draw(st.integers(min_value=min_value, max_value=max_value)), j=draw(st.integers(min_value=min_value, max_value=max_value)), diff --git a/afids_utils/tests/test_transforms.py b/afids_utils/tests/test_transforms.py index 0e7b9c3c..c45d0e76 100644 --- a/afids_utils/tests/test_transforms.py +++ b/afids_utils/tests/test_transforms.py @@ -4,21 +4,46 @@ from hypothesis import HealthCheck, given, settings from numpy.typing import NDArray -from afids_utils.tests.strategies import affine_xfm, world_coord -from afids_utils.transforms import afid_world2voxel +from afids_utils.afids import AfidPosition, AfidVoxel +from afids_utils.tests.strategies import ( + affine_xfms, + world_coords, + voxel_coords, +) +from afids_utils.transforms import world_to_voxel, voxel_to_world class TestAfidWorld2Voxel: - @given(world_coord=world_coord(), nii_affine=affine_xfm()) + @given(world_coord=world_coords(), nii_affine=affine_xfms()) @settings( deadline=400, suppress_health_check=[HealthCheck.function_scoped_fixture], ) - def test_transform_output( - self, world_coord: NDArray[np.float_], nii_affine: NDArray[np.float_] + def test_world_to_voxel_xfm( + self, world_coord: AfidPosition, nii_affine: NDArray[np.float_] ): - voxel_coord = afid_world2voxel(world_coord, nii_affine) + voxel_coord = world_to_voxel(world_coord, nii_affine) - assert isinstance(voxel_coord, np.ndarray) - assert voxel_coord.dtype == np.int_ - assert voxel_coord.shape == (3,) + assert isinstance(voxel_coord, AfidVoxel) + # Have to assert specific int dtype + assert isinstance(voxel_coord.i, np.int64) + assert isinstance(voxel_coord.j, np.int64) + assert isinstance(voxel_coord.k, np.int64) + + +class TestAfidVoxel2World: + @given(voxel_coord=voxel_coords(), nii_affine=affine_xfms()) + @settings( + deadline=400, + suppress_health_check=[HealthCheck.function_scoped_fixture], + ) + def test_voxel_to_world_xfm( + self, voxel_coord: AfidVoxel, nii_affine: NDArray[np.float_] + ): + world_coord = voxel_to_world(voxel_coord, nii_affine) + + assert isinstance(world_coord, AfidPosition) + # Have to assert specific float dtype + assert isinstance(world_coord.x, np.float64) + assert isinstance(world_coord.y, np.float64) + assert isinstance(world_coord.z, np.float64) diff --git a/afids_utils/transforms.py b/afids_utils/transforms.py index 28f0b94f..e0994b80 100644 --- a/afids_utils/transforms.py +++ b/afids_utils/transforms.py @@ -71,11 +71,12 @@ def voxel_to_world( """ # Put into numpy array for easier computation - voxel_pos = np.asarray([afid_voxel.i, afid_voxel.j, afid_voxel.k, 1]) + voxel_pos = np.asarray([afid_voxel.i, afid_voxel.j, afid_voxel.k]) # Convert to float, perform rotation, translation - world_pos = np.dot(nii_affine[:3, :3], voxel_pos) - world_pos = world_pos + nii_affine[:3, 3:4] + world_pos = voxel_pos.astype(float) + world_pos = np.dot(nii_affine[:3, :3], world_pos) + world_pos = world_pos + nii_affine[:3, 3:4].T[0] return AfidPosition( label=afid_voxel.label,