def test_sensitivity_extraction_2D(self):
     """ This test ensures that the output of the non cartesian kspace
     extraction is same a that of mimicked cartesian extraction in 2D
     """
     _mask = np.ones((self.N, self.N))
     _samples = convert_mask_to_locations(_mask)
     fourier_op = NonCartesianFFT(samples=_samples, shape=(self.N, self.N))
     Img = (np.random.randn(self.num_channel, self.N, self.N) +
            1j * np.random.randn(self.num_channel, self.N, self.N))
     F_img = np.asarray(
         [fourier_op.op(Img[i]) for i in np.arange(self.num_channel)])
     Smaps_gridding, SOS_Smaps = get_Smaps(k_space=F_img,
                                           img_shape=(self.N, self.N),
                                           samples=_samples,
                                           thresh=(0.4, 0.4),
                                           mode='gridding',
                                           min_samples=(-0.5, -0.5),
                                           max_samples=(0.5, 0.5),
                                           n_cpu=1)
     Smaps_NFFT, SOS_Smaps = get_Smaps(k_space=F_img,
                                       img_shape=(self.N, self.N),
                                       thresh=(0.4, 0.4),
                                       samples=_samples,
                                       min_samples=(-0.5, -0.5),
                                       max_samples=(0.5, 0.5),
                                       mode='NFFT')
     np.testing.assert_allclose(Smaps_gridding, Smaps_NFFT)
Exemple #2
0
 def test_NFFT_2D(self):
     """Test the adjoint operator for the 2D non-Cartesian Fourier
     transform, with density compensator set to 1, to vet the code
     path, the test is unchanged otherwise
     """
     for num_channels in self.num_channels:
         print("Testing with num_channels=" + str(num_channels))
         for i in range(self.max_iter):
             _mask = np.random.randint(2, size=(self.N, self.N))
             _samples = convert_mask_to_locations(_mask)
             print("Process NFFT in 2D test '{0}'...", i)
             fourier_op = NonCartesianFFT(samples=_samples,
                                          shape=(self.N, self.N),
                                          n_coils=num_channels,
                                          implementation='cpu',
                                          density_comp=np.ones(
                                              (num_channels,
                                               _samples.shape[0])))
             Img = np.random.randn(num_channels, self.N, self.N) + \
                 1j * np.random.randn(num_channels, self.N, self.N)
             f = np.random.randn(num_channels, _samples.shape[0]) + \
                 1j * np.random.randn(num_channels, _samples.shape[0])
             f_p = fourier_op.op(Img)
             I_p = fourier_op.adj_op(f)
             x_d = np.vdot(Img, I_p)
             x_ad = np.vdot(f_p, f)
             np.testing.assert_allclose(x_d, x_ad, rtol=1e-10)
     print(" NFFT in 2D adjoint test passes")
 def test_NUFFT_3D(self):
     """Test the adjoint operator for the 3D non-Cartesian Fourier transform
     on GPU
     """
     for num_channels in self.num_channels:
         for platform in self.platforms:
             _mask = np.random.randint(2, size=(self.N, self.N, self.N))
             _samples = convert_mask_to_locations(_mask)
             fourier_op_dir = NonCartesianFFT(samples=_samples,
                                              shape=(self.N, self.N,
                                                     self.N),
                                              implementation=platform,
                                              n_coils=num_channels)
             Img = (np.random.randn(num_channels, self.N, self.N, self.N) +
                    1j * np.random.randn(num_channels, self.N, self.N,
                                         self.N))
             f = (np.random.randn(num_channels, _samples.shape[0]) +
                  1j * np.random.randn(num_channels, _samples.shape[0]))
             f_p = fourier_op_dir.op(Img)
             I_p = fourier_op_dir.adj_op(f)
             x_d = np.vdot(Img, I_p)
             x_ad = np.vdot(f_p, f)
             np.testing.assert_allclose(x_d, x_ad, rtol=1e-5)
             print("NFFT in 3D adjoint test passes on GPU with"
                   "num_channels = " + str(num_channels) + " on "
                   "platform " + platform)
Exemple #4
0
    def test_similarity_stack_3D_nfft(self):
        """Test the similarity of stacked implementation of Fourier transform
        to that of NFFT
        """
        for channel in self.num_channels:
            print("Testing with num_channels=" + str(channel))
            for N in [16, 32]:
                # Nz is the number of slices, this would check both N=Nz
                # and N!=Nz
                Nz = 16
                _mask = np.random.randint(2, size=(N, N))

                # Generate random mask along z
                sampling_z = np.random.randint(2, size=Nz)
                _mask3D = np.zeros((N, N, Nz))
                for idx, acq_z in enumerate(sampling_z):
                    _mask3D[:, :, idx] = _mask * acq_z
                _samples = convert_mask_to_locations(_mask3D)

                print("Process Stack-3D similarity with NFFT for N=" + str(N))
                fourier_op_stack = Stacked3DNFFT(kspace_loc=_samples,
                                                 shape=(N, N, Nz),
                                                 implementation='cpu',
                                                 n_coils=channel)
                fourier_op_nfft = NonCartesianFFT(samples=_samples,
                                                  shape=(N, N, Nz),
                                                  implementation='cpu',
                                                  n_coils=channel)
                Img = np.random.random((channel, N, N, Nz)) + \
                    1j * np.random.random((channel, N, N, Nz))
                f = np.random.random((channel, _samples.shape[0])) + \
                    1j * np.random.random((channel, _samples.shape[0]))
                start_time = time.time()
                stack_f_p = fourier_op_stack.op(Img)
                stack_I_p = fourier_op_stack.adj_op(f)
                stack_runtime = time.time() - start_time
                start_time = time.time()
                nfft_f_p = fourier_op_nfft.op(Img)
                nfft_I_p = fourier_op_nfft.adj_op(f)
                np.testing.assert_allclose(stack_f_p, nfft_f_p, rtol=1e-9)
                np.testing.assert_allclose(stack_I_p, nfft_I_p, rtol=1e-9)
                nfft_runtime = time.time() - start_time
                print("For N=" + str(N) + " Speedup = " +
                      str(nfft_runtime / stack_runtime))
        print("Stacked FFT in 3D adjoint test passes")
    def generate_test_NFFT(self, shape, field_scale):
        """ Factorized code to test 2D and 3D wrapped NFFT with
        different homogeneous B0 field shifts at constant time.
        """
        for L, i, n_coils in product(self.L, range(self.max_iter),
                                     self.n_coils):
            mask = np.random.randint(2, size=shape)
            samples = convert_mask_to_locations(mask)
            samples = samples[:samples.shape[0]
                            - (samples.shape[0] % shape[0])]

            field_shift = field_scale * np.random.randint(-150, 150)
            field_map = field_shift * np.ones(shape)

            # Prepare reference and wrapper operators
            fourier_op = NonCartesianFFT(
                samples=samples,
                shape=shape,
                n_coils=n_coils,
                implementation='cpu',
                density_comp=np.ones((n_coils, samples.shape[0]))
            )
            wrapper_op = ORCFFTWrapper(fourier_op, field_map=field_map,
                                       time_vec=np.ones(shape[0]),
                                       mask=np.ones(shape),
                                       num_interpolators=L,
                                       n_bins=self.n_bins)

            # Forward operator
            img = np.squeeze(np.random.randn(n_coils, *shape) \
                      + 1j * np.random.randn(n_coils, *shape))
            ksp_fft = fourier_op.op(img)
            ksp_wra = wrapper_op.op(img * np.exp(-2j * np.pi * field_shift))
            np.testing.assert_allclose(ksp_fft, ksp_wra, rtol=self.rtol)

            # Adjoint operator
            ksp = np.squeeze(np.random.randn(n_coils, samples.shape[0]) \
                      + 1j * np.random.randn(n_coils, samples.shape[0]))
            img_fft = fourier_op.adj_op(ksp)
            img_wra = wrapper_op.adj_op(ksp * np.exp(2j * np.pi * field_shift))
            np.testing.assert_allclose(img_fft, img_wra, rtol=self.rtol)
Exemple #6
0
 def test_NFFT_3D(self):
     """Test the adjoint operator for the 3D non-Cartesian Fourier transform
     """
     for num_channels in self.num_channels:
         print("Testing with num_channels=" + str(num_channels))
         for i in range(self.max_iter):
             _mask = np.random.randint(2, size=(self.N, self.N, self.N))
             _samples = convert_mask_to_locations(_mask)
             print("Process NFFT test in 3D '{0}'...", i)
             fourier_op = NonCartesianFFT(samples=_samples,
                                          shape=(self.N, self.N, self.N),
                                          n_coils=num_channels,
                                          implementation='cpu')
             Img = np.random.randn(num_channels, self.N, self.N, self.N) + \
                 1j * np.random.randn(num_channels, self.N, self.N, self.N)
             f = np.random.randn(num_channels, _samples.shape[0]) + \
                 1j * np.random.randn(num_channels, _samples.shape[0])
             f_p = fourier_op.op(Img)
             I_p = fourier_op.adj_op(f)
             x_d = np.vdot(Img, I_p)
             x_ad = np.vdot(f_p, f)
             np.testing.assert_allclose(x_d, x_ad, rtol=1e-10)
     print(" NFFT in 3D adjoint test passes")
Exemple #7
0
    def test_sensitivity_extraction_2D(self):
        """ This test ensures that the output of the non cartesian kspace
        extraction is same a that of mimicked cartesian extraction in 2D
        """
        mask = np.ones((self.N, self.N))
        samples = convert_mask_to_locations(mask)
        fourier_op = NonCartesianFFT(samples=samples, shape=(self.N, self.N))
        Img = (np.random.randn(self.num_channel, self.N, self.N) +
               1j * np.random.randn(self.num_channel, self.N, self.N))
        F_img = np.asarray(
            [fourier_op.op(Img[i]) for i in np.arange(self.num_channel)])
        Smaps_gridding, SOS_Smaps = get_Smaps(k_space=F_img,
                                              img_shape=(self.N, self.N),
                                              samples=samples,
                                              thresh=(0.4, 0.4),
                                              mode='gridding',
                                              min_samples=(-0.5, -0.5),
                                              max_samples=(0.5, 0.5),
                                              n_cpu=1)
        Smaps_NFFT_dc, SOS_Smaps_dc = get_Smaps(k_space=F_img,
                                                img_shape=(self.N, self.N),
                                                thresh=(0.4, 0.4),
                                                samples=samples,
                                                min_samples=(-0.5, -0.5),
                                                max_samples=(0.5, 0.5),
                                                mode='NFFT',
                                                density_comp=np.ones(
                                                    samples.shape[0]))
        Smaps_NFFT, SOS_Smaps = get_Smaps(
            k_space=F_img,
            img_shape=(self.N, self.N),
            thresh=(0.4, 0.4),
            samples=samples,
            min_samples=(-0.5, -0.5),
            max_samples=(0.5, 0.5),
            mode='NFFT',
        )
        Smaps_hann_NFFT, SOS_Smaps = get_Smaps(
            k_space=F_img,
            img_shape=(self.N, self.N),
            thresh=0.4,
            samples=samples,
            min_samples=(-0.5, -0.5),
            max_samples=(0.5, 0.5),
            window_fun="Hann",
            mode='NFFT',
        )
        Smaps_hann_gridding, SOS_Smaps = get_Smaps(
            k_space=F_img,
            img_shape=(self.N, self.N),
            thresh=0.4,
            samples=samples,
            min_samples=(-0.5, -0.5),
            max_samples=(0.5, 0.5),
            window_fun="Hann",
            mode='gridding',
        )

        Smaps_hamming_NFFT, SOS_Smaps = get_Smaps(
            k_space=F_img,
            img_shape=(self.N, self.N),
            thresh=0.4,
            samples=samples,
            min_samples=(-0.5, -0.5),
            max_samples=(0.5, 0.5),
            window_fun="Hamming",
            mode='NFFT',
        )
        Smaps_hamming_gridding, SOS_Smaps = get_Smaps(
            k_space=F_img,
            img_shape=(self.N, self.N),
            thresh=0.4,
            samples=samples,
            min_samples=(-0.5, -0.5),
            max_samples=(0.5, 0.5),
            window_fun="Hamming",
            mode='gridding',
        )
        Smaps_call_gridding, SOS_Smaps = get_Smaps(
            k_space=F_img,
            img_shape=(self.N, self.N),
            thresh=0.4,
            samples=samples,
            min_samples=(-0.5, -0.5),
            max_samples=(0.5, 0.5),
            window_fun=lambda x: 1,
            mode='gridding',
        )
        Smaps_call_NFFT, SOS_Smaps = get_Smaps(
            k_space=F_img,
            img_shape=(self.N, self.N),
            thresh=0.4,
            samples=samples,
            min_samples=(-0.5, -0.5),
            max_samples=(0.5, 0.5),
            window_fun=lambda x: 1,
            mode='NFFT',
        )

        np.testing.assert_allclose(Smaps_gridding, Smaps_NFFT_dc)
        np.testing.assert_allclose(Smaps_gridding, Smaps_NFFT)
        np.testing.assert_allclose(Smaps_hann_gridding, Smaps_hann_NFFT)
        np.testing.assert_allclose(Smaps_hamming_gridding, Smaps_hamming_NFFT)
        np.testing.assert_allclose(Smaps_call_gridding, Smaps_call_NFFT)
        # Test that we raise assert for bad mode
        np.testing.assert_raises(ValueError,
                                 get_Smaps,
                                 k_space=F_img,
                                 img_shape=(self.N, self.N),
                                 thresh=(0.4, 0.4),
                                 samples=samples,
                                 min_samples=(-0.5, -0.5),
                                 max_samples=(0.5, 0.5),
                                 mode='test')
        # Test that we raise assert for bad window
        np.testing.assert_raises(
            ValueError,
            get_Smaps,
            k_space=F_img,
            img_shape=(self.N, self.N),
            thresh=(0.4, 0.4),
            samples=samples,
            min_samples=(-0.5, -0.5),
            max_samples=(0.5, 0.5),
            window_fun='test',
            mode='gridding',
        )
# Get the locations of the kspace samples and the associated observations
fourier_op = NonCartesianFFT(
    samples=kspace_loc,
    shape=image.shape,
    implementation='gpuNUFFT',
)
fourier_op_density_comp = NonCartesianFFT(
    samples=kspace_loc,
    shape=image.shape,
    implementation='gpuNUFFT',
    density_comp=density_comp
)
# Get the kspace data retrospectively. Note that this can be done with
# `fourier_op_density_comp` as the forward operator is the same
kspace_obs = fourier_op.op(image.data)

# Simple adjoint
image_rec0 = pysap.Image(data=np.abs(fourier_op.adj_op(kspace_obs)))
# image_rec0.show()
base_ssim = ssim(image_rec0, image)
print('The SSIM from Adjoint is : ' + str(base_ssim))

# Density Compensation adjoint:
# This preconditions k-space giving a result closer to inverse
image_rec1 = pysap.Image(data=np.abs(
    fourier_op_density_comp.adj_op(kspace_obs))
)
# image_rec1.show()
new_ssim = ssim(image_rec1, image)
print('The SSIM from Density '
Exemple #9
0
 def test_gridsearch_single_channel(self):
     """Test Gridsearch script in mri.scripts for
     single channel reconstruction this is a test of sanity
     and not if the reconstruction is right.
     """
     image = get_sample_data('2d-mri')
     mask = np.ones(image.shape)
     kspace_loc = convert_mask_to_locations(mask)
     fourier_op = NonCartesianFFT(samples=kspace_loc, shape=image.shape)
     kspace_data = fourier_op.op(image.data)
     # Define the keyword dictionaries based on convention
     metrics = {
         'ssim': {
             'metric': ssim,
             'mapping': {
                 'x_new': 'test',
                 'y_new': None
             },
             'cst_kwargs': {
                 'ref': image,
                 'mask': None
             },
             'early_stopping': True,
         },
     }
     linear_params = {
         'init_class': WaveletN,
         'kwargs': {
             'wavelet_name': 'sym8',
             'nb_scale': 4,
         }
     }
     regularizer_params = {
         'init_class': SparseThreshold,
         'kwargs': {
             'linear': Identity(),
             'weights': [0, 1e-5],
         }
     }
     optimizer_params = {
         # Just following convention
         'kwargs': {
             'optimization_alg': 'fista',
             'num_iterations': 10,
             'metrics': metrics,
         }
     }
     # Call the launch grid function and obtain results
     raw_results, test_cases, key_names, best_idx = launch_grid(
         kspace_data=kspace_data,
         fourier_op=fourier_op,
         linear_params=linear_params,
         regularizer_params=regularizer_params,
         optimizer_params=optimizer_params,
         reconstructor_kwargs={'gradient_formulation': 'synthesis'},
         reconstructor_class=SingleChannelReconstructor,
         compare_metric_details={'metric': 'ssim'},
         n_jobs=self.n_jobs,
         verbose=1,
     )
     # In this test we dont undersample the kspace so the
     # reconstruction is indeed with mu=0, ie best_idx=0
     np.testing.assert_equal(best_idx, 0)
     np.testing.assert_allclose(
         raw_results[best_idx][0],
         image,
         atol=1e-7,
     )
Exemple #10
0
import numpy as np
from mri.operators import NonCartesianFFT

traj = np.load('/volatile/temp_traj.npy')

fourier = NonCartesianFFT(traj, (384, 384, 208),
                          'gpuNUFFT',
                          n_coils=20,
                          smaps=np.ones((20, 384, 384, 208)),
                          osf=2)

for i in range(10):
    print(i)
    K = fourier.op(np.zeros((384, 384, 208)))
    I = fourier.adj_op(K)
# mask.show()

#############################################################################
# Generate the kspace
# -------------------
#
# From the 2D brain slice and the acquisition mask, we retrospectively
# undersample the k-space using a non cartesian acquisition mask
# We then grid the kspace to get the gridded solution as a baseline

# Get the kspace observation values for the kspace locations
fourier_op = NonCartesianFFT(samples=kspace_loc,
                             shape=image.shape,
                             n_coils=cartesian_ref_image.shape[0],
                             implementation='gpuNUFFT')
kspace_obs = fourier_op.op(cartesian_ref_image)

# Gridded solution
grid_space = np.linspace(-0.5, 0.5, num=image.shape[0])
grid2D = np.meshgrid(grid_space, grid_space)
grid_soln = np.asarray([
    gridded_inverse_fourier_transform_nd(kspace_loc, kspace_obs_ch,
                                         tuple(grid2D), 'linear')
    for kspace_obs_ch in kspace_obs
])
image_rec0 = pysap.Image(data=np.sqrt(np.sum(np.abs(grid_soln)**2, axis=0)))
# image_rec0.show()
base_ssim = ssim(image_rec0, image)
print('The Base SSIM is : ' + str(base_ssim))

# Obtain SMaps