Skip to content

Commit

Permalink
add methods and tests for voxel_to_world
Browse files Browse the repository at this point in the history
  • Loading branch information
kaitj committed Aug 30, 2023
1 parent 61fde32 commit b4b4926
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 15 deletions.
6 changes: 3 additions & 3 deletions afids_utils/tests/strategies.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)),
Expand Down
43 changes: 34 additions & 9 deletions afids_utils/tests/test_transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
7 changes: 4 additions & 3 deletions afids_utils/transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit b4b4926

Please sign in to comment.