Skip to content

Commit

Permalink
Update generate meshgrid (#168)
Browse files Browse the repository at this point in the history
* Use apply_affine to reduce error, cast as floats and use np.arange

* Fix test that was broken due to casting as floats (there was an error since it was ints)

* Create new test for generate_meshgrid

* Remove TODO
  • Loading branch information
po09i committed Nov 10, 2020
1 parent 4c0d76b commit 9c5a59d
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 8 deletions.
12 changes: 6 additions & 6 deletions shimmingtoolbox/coils/coordinates.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
# -*- coding: utf-8 -*
# Deals with coordinate systems, going from voxel-based to physical-based coordinates.

# TODO: create a test for this API

import numpy as np
from nibabel.affines import apply_affine


def generate_meshgrid(dim, affine):
Expand All @@ -19,15 +18,16 @@ def generate_meshgrid(dim, affine):
"""

nx, ny, nz = dim
coord_vox = np.meshgrid(np.array(range(nx)), np.array(range(ny)), np.array(range(nz)), indexing='ij')
coord_phys = [np.zeros_like(coord_vox[0]), np.zeros_like(coord_vox[1]), np.zeros_like(coord_vox[2])]
coord_vox = np.meshgrid(np.arange(nx), np.arange(ny), np.arange(nz), indexing='ij')
coord_phys = [np.zeros_like(coord_vox[0]).astype(float),
np.zeros_like(coord_vox[1]).astype(float),
np.zeros_like(coord_vox[2]).astype(float)]

# TODO: Better code
for ix in range(nx):
for iy in range(ny):
for iz in range(nz):
coord_phys_list = \
np.dot([coord_vox[i][ix, iy, iz] for i in range(3)], affine[0:3, 0:3]) + affine[0:3, 3]
coord_phys_list = apply_affine(affine, [coord_vox[i][ix, iy, iz] for i in range(3)])
for i in range(3):
coord_phys[i][ix, iy, iz] = coord_phys_list[i]
return coord_phys
35 changes: 35 additions & 0 deletions test/test_coordinates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*

import numpy as np

from shimmingtoolbox.coils.coordinates import generate_meshgrid


def test_generate_meshgrid():
"""Test to verify generate_meshgrid outputs the correct scanner coordinates from input voxels"""

affine = np.array([[0., 0., 3., -3.61445999],
[-2.91667008, 0., 0., 101.76699829],
[0., 2.91667008, 0., -129.85464478],
[0., 0., 0., 1.]])

nx = 2
ny = 2
nz = 2
coord = generate_meshgrid((nx, ny, nz), affine)

expected = [np.array([[[-3.61445999, -0.61445999],
[-3.61445999, -0.61445999]],
[[-3.61445999, -0.61445999],
[-3.61445999, -0.61445999]]]),
np.array([[[101.76699829, 101.76699829],
[101.76699829, 101.76699829]],
[[98.85032821, 98.85032821],
[98.85032821, 98.85032821]]]),
np.array([[[-129.85464478, -129.85464478],
[-126.9379747, -126.9379747]],
[[-129.85464478, -129.85464478],
[-126.9379747, -126.9379747]]])]

assert(np.all(np.isclose(coord, expected)))
4 changes: 2 additions & 2 deletions test/test_siemens_basis.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ def test_siemens_basis_resample():
basis = siemens_basis(coord_phys[0], coord_phys[1], coord_phys[2])

# Hard-coded values corresponding to the mid-point of the FOV.
expected = np.array([5.21405621e-18, -8.51520000e-02, 1.02182400e+00, 2.44386240e-02,
2.50274698e-19, -4.08729600e-03, -1.70304000e-04, -2.08562248e-20])
expected = np.array([5.31991104e-18, -8.68807405e-02, 1.03212742e+00, 2.49321889e-02,
2.57930573e-19, -4.21232592e-03, -1.77289155e-04, -2.17116596e-20])

nx, ny, nz = nii.get_fdata().shape
assert(np.all(np.isclose(basis[int(nx/2), int(ny/2), int(nz/2), :], expected, rtol=1e-05)))

0 comments on commit 9c5a59d

Please sign in to comment.