Skip to content

Commit

Permalink
change tests
Browse files Browse the repository at this point in the history
  • Loading branch information
fzimmermann89 committed Nov 20, 2024
1 parent 60668af commit 12de434
Showing 1 changed file with 49 additions and 28 deletions.
77 changes: 49 additions & 28 deletions tests/operators/test_fourier_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@
from tests.conftest import COMMON_MR_TRAJECTORIES, create_traj


class NufftTrajektory(KTrajectory):
"""Always returns non-grid trajectory type."""

def _traj_types(
self,
tolerance: float,
) -> tuple[tuple[TrajType, TrajType, TrajType], tuple[TrajType, TrajType, TrajType]]:
true_types = super()._traj_types(tolerance)
modified = tuple([tuple([t & (~TrajType.ONGRID) for t in ts]) for ts in true_types])
return modified


def create_data(im_shape, k_shape, nkx, nky, nkz, type_kx, type_ky, type_kz):
random_generator = RandomGenerator(seed=0)

Expand Down Expand Up @@ -39,13 +51,10 @@ def test_fourier_op_fwd_adj_property(
)
fourier_op = FourierOp(recon_matrix=recon_matrix, encoding_matrix=encoding_matrix, traj=trajectory)

# apply forward operator
(kdata,) = fourier_op(img)

# test adjoint property; i.e. <Fu,v> == <u, F^Hv> for all u,v
random_generator = RandomGenerator(seed=0)
u = random_generator.complex64_tensor(size=img.shape)
v = random_generator.complex64_tensor(size=kdata.shape)
u = random_generator.complex64_tensor(size=im_shape)
v = random_generator.complex64_tensor(size=k_shape)
dotproduct_adjointness_test(fourier_op, u, v)

Check failure on line 58 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py311)

test_fourier_op_fwd_adj_property[2d_single_shot_spiral] AssertionError

Check failure on line 58 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py311)

test_fourier_op_fwd_adj_property[radial_phase_encoding_3_coils_with_oversampling] ValueError: k-space data shape mismatch

Check failure on line 58 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py311)

test_fourier_op_fwd_adj_property[radial_phase_encoding_3_coils_non_cartesian_sampling] AssertionError

Check failure on line 58 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py312)

test_fourier_op_fwd_adj_property[2d_single_shot_spiral] AssertionError

Check failure on line 58 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py312)

test_fourier_op_fwd_adj_property[radial_phase_encoding_3_coils_with_oversampling] ValueError: k-space data shape mismatch

Check failure on line 58 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py312)

test_fourier_op_fwd_adj_property[radial_phase_encoding_3_coils_non_cartesian_sampling] AssertionError

Check failure on line 58 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py310)

test_fourier_op_fwd_adj_property[2d_single_shot_spiral] AssertionError

Check failure on line 58 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py310)

test_fourier_op_fwd_adj_property[radial_phase_encoding_3_coils_with_oversampling] ValueError: k-space data shape mismatch

Check failure on line 58 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py310)

test_fourier_op_fwd_adj_property[radial_phase_encoding_3_coils_non_cartesian_sampling] AssertionError


Expand All @@ -64,19 +73,21 @@ def test_fourier_op_norm(im_shape, k_shape, nkx, nky, nkz, type_kx, type_ky, typ
int(trajectory.kx.max() - trajectory.kx.min() + 1),
)
fourier_op = FourierOp(recon_matrix=recon_matrix, encoding_matrix=encoding_matrix, traj=trajectory)
# only do few iterations to speed up the test
norm = fourier_op.operator_norm(img, dim=None, max_iterations=20)
torch.testing.assert_close(norm.squeeze(), torch.tensor(1.0), atol=0.1, rtol=0.0)
(initial_value,) = fourier_op.adjoint(*fourier_op(img))
norm = fourier_op.operator_norm(initial_value, dim=None, max_iterations=4).squeeze()
torch.testing.assert_close(norm, torch.tensor(1.0), atol=0.1, rtol=0.0)

Check failure on line 78 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py311)

test_fourier_op_norm[2d_non_cartesian_mri_2_coils] AssertionError: Scalars are not close! Expected 1.0 but got 1.4746354818344116. Absolute difference: 0.4746354818344116 (up to 0.1 allowed) Relative difference: 0.4746354818344116 (up to 0.0 allowed)

Check failure on line 78 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py311)

test_fourier_op_norm[2d_single_shot_spiral] AssertionError: Scalars are not close! Expected 1.0 but got 0.7416239380836487. Absolute difference: 0.2583760619163513 (up to 0.1 allowed) Relative difference: 0.2583760619163513 (up to 0.0 allowed)

Check failure on line 78 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py311)

test_fourier_op_norm[3d_nonuniform_4_coils_2_other] AssertionError: Scalars are not close! Expected 1.0 but got 0.6982466578483582. Absolute difference: 0.30175334215164185 (up to 0.1 allowed) Relative difference: 0.30175334215164185 (up to 0.0 allowed)

Check failure on line 78 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py311)

test_fourier_op_norm[radial_phase_encoding_3_coils_non_cartesian_sampling] AssertionError: Scalars are not close! Expected 1.0 but got 1.54142427444458. Absolute difference: 0.5414242744445801 (up to 0.1 allowed) Relative difference: 0.5414242744445801 (up to 0.0 allowed)

Check failure on line 78 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py311)

test_fourier_op_norm[stack_of_stars_2_other_3_coil_with_oversampling] AssertionError: Scalars are not close! Expected 1.0 but got 0.8689930438995361. Absolute difference: 0.13100695610046387 (up to 0.1 allowed) Relative difference: 0.13100695610046387 (up to 0.0 allowed)

Check failure on line 78 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py311)

test_fourier_op_norm[2d_cartesian_irregular_sampling_with_oversampling] AssertionError: Scalars are not close! Expected 1.0 but got 0.6897003650665283. Absolute difference: 0.3102996349334717 (up to 0.1 allowed) Relative difference: 0.3102996349334717 (up to 0.0 allowed)

Check failure on line 78 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py312)

test_fourier_op_norm[2d_non_cartesian_mri_2_coils] AssertionError: Scalars are not close! Expected 1.0 but got 1.4746354818344116. Absolute difference: 0.4746354818344116 (up to 0.1 allowed) Relative difference: 0.4746354818344116 (up to 0.0 allowed)

Check failure on line 78 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py312)

test_fourier_op_norm[2d_single_shot_spiral] AssertionError: Scalars are not close! Expected 1.0 but got 0.7416239380836487. Absolute difference: 0.2583760619163513 (up to 0.1 allowed) Relative difference: 0.2583760619163513 (up to 0.0 allowed)

Check failure on line 78 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py312)

test_fourier_op_norm[3d_nonuniform_4_coils_2_other] AssertionError: Scalars are not close! Expected 1.0 but got 0.6982466578483582. Absolute difference: 0.30175334215164185 (up to 0.1 allowed) Relative difference: 0.30175334215164185 (up to 0.0 allowed)

Check failure on line 78 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py310)

test_fourier_op_norm[2d_non_cartesian_mri_2_coils] AssertionError: Scalars are not close! Expected 1.0 but got 1.4746354818344116. Absolute difference: 0.4746354818344116 (up to 0.1 allowed) Relative difference: 0.4746354818344116 (up to 0.0 allowed)

Check failure on line 78 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py310)

test_fourier_op_norm[2d_single_shot_spiral] AssertionError: Scalars are not close! Expected 1.0 but got 0.7416239380836487. Absolute difference: 0.2583760619163513 (up to 0.1 allowed) Relative difference: 0.2583760619163513 (up to 0.0 allowed)

Check failure on line 78 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py310)

test_fourier_op_norm[3d_nonuniform_4_coils_2_other] AssertionError: Scalars are not close! Expected 1.0 but got 0.6982466578483582. Absolute difference: 0.30175334215164185 (up to 0.1 allowed) Relative difference: 0.30175334215164185 (up to 0.0 allowed)


@COMMON_MR_TRAJECTORIES
def test_fourier_op_fft_nufft(im_shape, k_shape, nkx, nky, nkz, type_kx, type_ky, type_kz, type_k0, type_k1, type_k2):
def test_fourier_op_fft_nufft_forward(
im_shape, k_shape, nkx, nky, nkz, type_kx, type_ky, type_kz, type_k0, type_k1, type_k2
):
"""Test Nufft vs FFT for Fourier operator."""
if not any(t == 'uniform' for t in [type_kx, type_ky, type_kz]):
return # only test for uniform trajectories

# generate random images and k-space trajectories
img, trajectory = create_data(im_shape, k_shape, nkx, nky, nkz, type_kx, type_ky, type_kz)

# create operator
recon_matrix = SpatialDimension(im_shape[-3], im_shape[-2], im_shape[-1])
encoding_matrix = SpatialDimension(
int(trajectory.kz.max() - trajectory.kz.min() + 1),
Expand All @@ -85,35 +96,45 @@ def test_fourier_op_fft_nufft(im_shape, k_shape, nkx, nky, nkz, type_kx, type_ky
)
fourier_op = FourierOp(recon_matrix=recon_matrix, encoding_matrix=encoding_matrix, traj=trajectory)

class NufftTrajektory(KTrajectory):
"""Always returns non-grid trajectory type."""

def _traj_types(
self,
tolerance: float,
) -> tuple[tuple[TrajType, TrajType, TrajType], tuple[TrajType, TrajType, TrajType]]:
true_types = super()._traj_types(tolerance)
modified = tuple([tuple([t & (~TrajType.ONGRID) for t in ts]) for ts in true_types])
return modified

nufft_fourier_op = FourierOp(
recon_matrix=recon_matrix,
encoding_matrix=encoding_matrix,
traj=NufftTrajektory(trajectory.kz, trajectory.ky, trajectory.kx),
nufft_oversampling=8.0,
)

(result_normal,) = fourier_op(img)
(result_nufft,) = nufft_fourier_op(img)
torch.testing.assert_close(result_normal, result_nufft, atol=1e-5, rtol=1e-4)
torch.testing.assert_close(result_normal, result_nufft, atol=1e-4, rtol=5e-3)

Check failure on line 108 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py311)

test_fourier_op_fft_nufft_forward[radial_phase_encoding_3_coils_with_oversampling] AssertionError: Tensor-likes are not close! Mismatched elements: 127 / 110592 (0.1%) Greatest absolute difference: 0.000497964269015938 at index (1, 2, 1, 53, 70) (up to 0.0001 allowed) Greatest relative difference: 0.16935928165912628 at index (1, 2, 0, 27, 37) (up to 0.005 allowed)


@COMMON_MR_TRAJECTORIES
def test_fourier_op_fft_nufft_adjoint(
im_shape, k_shape, nkx, nky, nkz, type_kx, type_ky, type_kz, type_k0, type_k1, type_k2
):
"""Test AdjointNufft vs IFFT for Fourier operator."""
if not any(t == 'uniform' for t in [type_kx, type_ky, type_kz]):
return # only test for uniform trajectories
img, trajectory = create_data(im_shape, k_shape, nkx, nky, nkz, type_kx, type_ky, type_kz)
recon_matrix = SpatialDimension(im_shape[-3], im_shape[-2], im_shape[-1])
encoding_matrix = SpatialDimension(
int(trajectory.kz.max() - trajectory.kz.min() + 1),
int(trajectory.ky.max() - trajectory.ky.min() + 1),
int(trajectory.kx.max() - trajectory.kx.min() + 1),
)
fourier_op = FourierOp(recon_matrix=recon_matrix, encoding_matrix=encoding_matrix, traj=trajectory)

nufft_fourier_op = FourierOp(
recon_matrix=recon_matrix,
encoding_matrix=encoding_matrix,
traj=NufftTrajektory(trajectory.kz, trajectory.ky, trajectory.kx),
nufft_oversampling=8.0,
)

k = RandomGenerator(0).complex64_tensor(size=k_shape)
(result_normal,) = fourier_op.H(k)

Check failure on line 135 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py310)

test_fourier_op_fft_nufft_adjoint[radial_phase_encoding_3_coils_with_oversampling] ValueError: k-space data shape mismatch
(result_nufft,) = nufft_fourier_op.H(k)
torch.testing.assert_close(result_normal, result_nufft, atol=1e-5, rtol=1e-4)

(result_normal,) = fourier_op(img)
(result_nufft,) = nufft_fourier_op(img)
torch.testing.assert_close(result_normal, result_nufft, atol=1e-5, rtol=1e-4)
torch.testing.assert_close(result_normal, result_nufft, atol=3e-4, rtol=5e-3)

Check failure on line 137 in tests/operators/test_fourier_op.py

View workflow job for this annotation

GitHub Actions / Run Tests and Coverage Report (mrpro_py310)

test_fourier_op_fft_nufft_adjoint[stack_of_stars_2_other_3_coil_with_oversampling] AssertionError: Tensor-likes are not close! Mismatched elements: 227 / 147456 (0.2%) Greatest absolute difference: 0.0009539038874208927 at index (1, 1, 25, 15, 28) (up to 0.0003 allowed) Greatest relative difference: 0.18000340461730957 at index (1, 1, 19, 6, 29) (up to 0.005 allowed)


@COMMON_MR_TRAJECTORIES
Expand Down

0 comments on commit 12de434

Please sign in to comment.