示例#1
0
 def test_adjoint_stack_3D(self):
     """Test the adjoint operator for the 3D non-Cartesian Fourier transform
     """
     for channel in self.num_channels:
         print("Testing with num_channels=" + str(channel))
         for i in range(self.max_iter):
             mask = np.random.randint(2, size=(self.N, self.N))
             sampling_z = np.random.randint(2, size=self.N)
             sampling_z[self.N // 2 - 10:self.N // 2 + 10] = 1
             Nz = sampling_z.sum()
             mask = convert_mask_to_locations(mask)
             z_locations = np.repeat(
                 convert_mask_to_locations(sampling_z),
                 mask.shape[0],
             )
             z_locations = z_locations[:, np.newaxis]
             kspace_loc = np.hstack([np.tile(mask, (Nz, 1)), z_locations])
             print("Process Stacked3D-FFT test in 3D '{0}'...", i)
             fourier_op = Stacked3DNFFT(
                 kspace_loc=kspace_loc,
                 shape=(self.N, self.N, self.N),
                 implementation='cpu',
                 n_coils=channel,
             )
             Img = np.random.random((channel, self.N, self.N, self.N)) + \
                 1j * np.random.random((channel, self.N, self.N, self.N))
             f = np.random.random((channel, kspace_loc.shape[0])) + \
                 1j * np.random.random((channel, kspace_loc.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("Stacked FFT in 3D adjoint test passes")
 def test_self_calibrating_reconstruction(self):
     """ Test all the registered transformations.
     """
     self.num_channels = 2
     print("Process test for SelfCalibratingReconstructor ::")
     for i in range(len(self.test_cases)):
         print("Test Case " + str(i) + " " + str(self.test_cases[i]))
         image, nb_scale, optimizer, recon_type, name = self.test_cases[i]
         image_multichannel = np.repeat(image.data[np.newaxis],
                                        self.num_channels,
                                        axis=0)
         if optimizer == 'condatvu':
             formulation = "analysis"
         else:
             formulation = "synthesis"
         if recon_type == 'cartesian':
             fourier = FFT(samples=convert_mask_to_locations(self.mask),
                           shape=image.shape,
                           n_coils=self.num_channels)
         else:
             fourier = NonCartesianFFT(samples=convert_mask_to_locations(
                 self.mask),
                                       shape=image.shape,
                                       n_coils=self.num_channels)
         kspace_data = fourier.op(image_multichannel)
         linear_op, regularizer_op = \
             self.get_linear_n_regularization_operator(
                 wavelet_name=name,
                 dimension=len(fourier.shape),
                 nb_scale=2,
                 n_coils=self.num_channels,
                 gradient_formulation=formulation,
             )
         # For self calibrating reconstruction the n_coils
         # for wavelet operation is 1
         linear_op.n_coils = 1
         reconstructor = SelfCalibrationReconstructor(
             fourier_op=fourier,
             linear_op=linear_op,
             regularizer_op=regularizer_op,
             gradient_formulation=formulation,
             verbose=0,
         )
         x_final, costs, _ = reconstructor.reconstruct(
             kspace_data=kspace_data,
             optimization_alg=optimizer,
             num_iterations=self.num_iter,
         )
         fourier_0 = FFT(
             samples=convert_mask_to_locations(self.mask),
             shape=image.shape,
             n_coils=self.num_channels,
         )
         recon = fourier_0.adj_op(fourier_0.op(image_multichannel))
         np.testing.assert_allclose(np.abs(x_final),
                                    np.sqrt(np.sum(np.abs(recon)**2,
                                                   axis=0)),
                                    rtol=1e-3)
 def test_sparse_calibrationless_reconstruction(self):
     """ Test all the registered transformations.
     """
     self.num_channels = 2
     print("Process test for SparseCalibrationlessReconstructor ::")
     for i in range(len(self.test_cases)):
         print("Test Case " + str(i) + " " + str(self.test_cases[i]))
         image, nb_scale, optimizer, recon_type, name = self.test_cases[i]
         image_multichannel = np.repeat(image.data[np.newaxis],
                                        self.num_channels,
                                        axis=0)
         if optimizer == 'condatvu':
             formulation = "analysis"
         else:
             formulation = "synthesis"
         if recon_type == 'cartesian':
             fourier = FFT(samples=convert_mask_to_locations(self.mask),
                           shape=image.shape,
                           n_coils=self.num_channels)
         else:
             fourier = NonCartesianFFT(samples=convert_mask_to_locations(
                 self.mask),
                                       shape=image.shape,
                                       n_coils=self.num_channels)
         kspace_data = fourier.op(image_multichannel)
         linear_op, regularizer_op = \
             self.get_linear_n_regularization_operator(
                 wavelet_name=name,
                 dimension=len(fourier.shape),
                 nb_scale=2,
                 n_coils=2,
                 n_jobs=2,
                 gradient_formulation=formulation,
             )
         reconstructor = CalibrationlessReconstructor(
             fourier_op=fourier,
             linear_op=linear_op,
             regularizer_op=regularizer_op,
             gradient_formulation=formulation,
             verbose=1,
         )
         x_final, costs, _ = reconstructor.reconstruct(
             kspace_data=kspace_data,
             optimization_alg=optimizer,
             num_iterations=self.num_iter,
         )
         fourier_0 = FFT(
             samples=convert_mask_to_locations(self.mask),
             shape=image.shape,
             n_coils=self.num_channels,
         )
         data_0 = fourier_0.op(image_multichannel)
         # mu is 0 for above single channel reconstruction and
         # hence we expect the result to be the inverse fourier transform
         np.testing.assert_allclose(x_final, fourier_0.adj_op(data_0))
示例#4
0
 def test_extract_k_space_center_3D(self):
     """ This test ensures that the output of the non cartesian kspace
     extraction is same a that of mimicked cartesian extraction in 3D
     """
     _mask = np.ones((self.N, self.N, self.Nz))
     _samples = convert_mask_to_locations(_mask)
     Img = (np.random.randn(self.num_channel, self.N, self.N, self.Nz) +
            1j * np.random.randn(self.num_channel, self.N, self.N, self.Nz))
     Nby2_percent = self.N * self.percent / 2
     Nzby2_percent = self.Nz * self.percent / 2
     low = int(self.N / 2 - Nby2_percent)
     high = int(self.N / 2 + Nby2_percent + 1)
     lowz = int(self.Nz / 2 - Nzby2_percent)
     highz = int(self.Nz / 2 + Nzby2_percent + 1)
     center_Img = Img[:, low:high, low:high, lowz:highz]
     thresh = self.percent * 0.5
     data_thresholded, samples_thresholded = \
         extract_k_space_center_and_locations(
             data_values=np.reshape(Img, (self.num_channel,
                                          self.N * self.N * self.Nz)),
             samples_locations=_samples,
             thr=(thresh, thresh, thresh),
             img_shape=(self.N, self.N, self.Nz))
     np.testing.assert_allclose(center_Img.reshape(data_thresholded.shape),
                                data_thresholded)
示例#5
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")
示例#6
0
 def test_FFT(self):
     """Test the adjoint operator for the 2D non-Cartesian Fourier transform
     """
     for i, num_coil in product(range(self.max_iter), self.num_channels):
         _mask = np.random.randint(2, size=(self.N, self.N))
         _samples = convert_mask_to_locations(_mask)
         print("Process FFT test '{0}'...", i)
         fourier_op_dir = FFT(samples=_samples,
                              shape=(self.N, self.N),
                              n_coils=num_coil)
         fourier_op_adj = FFT(samples=_samples,
                              shape=(self.N, self.N),
                              n_coils=num_coil)
         Img = np.squeeze(
             np.random.randn(num_coil, self.N, self.N) +
             1j * np.random.randn(num_coil, self.N, self.N))
         f = np.squeeze(
             np.random.randn(num_coil, self.N, self.N) +
             1j * np.random.randn(num_coil, self.N, self.N))
         f_p = fourier_op_dir.op(Img)
         I_p = fourier_op_adj.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(" FFT adjoint test passes")
 def test_extract_k_space_center_2D_fft(self):
     """ Ensure that the extracted k-space center is right
     for cartesian case"""
     mask = np.random.randint(0, 2, (self.N, self.N))
     samples = convert_mask_to_locations(mask)
     Img = (np.random.randn(self.num_channel, self.N, self.N) +
            1j * np.random.randn(self.num_channel, self.N, self.N))
     Nby2_percent = self.N * self.percent / 2
     low = int(self.N / 2 - Nby2_percent)
     high = int(self.N / 2 + Nby2_percent + 1)
     center_Img = Img[:, low:high, low:high]
     cutoff_mask = mask[low:high, low:high]
     locations = np.where(cutoff_mask.reshape(cutoff_mask.size))
     center_Img = center_Img.reshape(
         (center_Img.shape[0], cutoff_mask.size))[:, locations[0]]
     thresh = self.percent * 0.5
     data_thresholded, samples_thresholded = \
         extract_k_space_center_and_locations(
             data_values=Img,
             samples_locations=samples,
             thr=(thresh, thresh),
             img_shape=(self.N, self.N))
     np.testing.assert_allclose(
         center_Img,
         data_thresholded)
 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)
 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)
示例#10
0
 def test_stack_3D_error(self):
     np.testing.assert_raises(ValueError, get_stacks_fourier,
                              np.random.randn(12, 3),
                              (self.N, self.N, self.N))
     # Generate random mask along z
     sampling_z = np.random.randint(2, size=self.N)
     _mask3D = np.zeros((self.N, self.N, self.N))
     for idx, acq_z in enumerate(sampling_z):
         _mask3D[:, :,
                 idx] = np.random.randint(2, size=(self.N, self.N)) * acq_z
     sampling = convert_mask_to_locations(_mask3D)
     np.testing.assert_raises(ValueError, get_stacks_fourier, sampling,
                              (self.N, self.N, self.N))
示例#11
0
 def test_sampling_converters(self):
     """Test the adjoint operator for the 2D non-Cartesian Fourier transform
     """
     for i in range(self.max_iter):
         print("Process test convert mask to samples test '{0}'...", i)
         Nx = np.random.randint(8, 512)
         Ny = np.random.randint(8, 512)
         mask = np.random.randint(2, size=(Nx, Ny))
         samples = convert_mask_to_locations(mask)
         recovered_mask = convert_locations_to_mask(samples, (Nx, Ny))
         self.assertEqual(mask.all(), recovered_mask.all())
         mismatch = 0. + (np.mean(np.allclose(mask, recovered_mask)))
         print("      mismatch = ", mismatch)
     print(" Test convert mask to samples and it's adjoint passes for",
           " the 2D cases")
示例#12
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 test_check_asserts(self):
     # Tests to check for asserts
     image, nb_scale, optimizer, recon_type, name = self.test_cases[0]
     fourier = NonCartesianFFT(
         samples=convert_mask_to_locations(self.mask),
         shape=image.shape,
     )
     kspace_data = fourier.op(image.data)
     linear_op, regularizer_op = \
         self.get_linear_n_regularization_operator(
             wavelet_name=name,
             dimension=len(fourier.shape),
             nb_scale=2,
             gradient_formulation="synthesis",
         )
     reconstructor = CalibrationlessReconstructor(
         fourier_op=fourier,
         linear_op=linear_op,
         regularizer_op=regularizer_op,
         gradient_formulation="synthesis",
         verbose=1,
     )
     np.testing.assert_raises(
         ValueError,
         reconstructor.reconstruct,
         kspace_data=kspace_data,
         optimization_alg="test_fail",
         num_iterations=self.num_iter,
     )
     fourier.n_coils = 10
     reconstructor = SelfCalibrationReconstructor(
         fourier_op=fourier,
         linear_op=linear_op,
         regularizer_op=regularizer_op,
         gradient_formulation="synthesis",
         verbose=1,
     )
     np.testing.assert_raises(
         ValueError,
         reconstructor.reconstruct,
         kspace_data=kspace_data,
         optimization_alg=optimizer,
         num_iterations=self.num_iter,
     )
 def test_extract_k_space_center_2D(self):
     """ Ensure that the extracted k-space center is right"""
     _mask = np.ones((self.N, self.N))
     _samples = convert_mask_to_locations(_mask)
     Img = (np.random.randn(self.num_channel, self.N, self.N) +
            1j * np.random.randn(self.num_channel, self.N, self.N))
     Nby2_percent = self.N * self.percent / 2
     low = int(self.N / 2 - Nby2_percent)
     high = int(self.N / 2 + Nby2_percent + 1)
     center_Img = Img[:, low:high, low:high]
     thresh = self.percent * 0.5
     data_thresholded, samples_thresholded = \
         extract_k_space_center_and_locations(
             data_values=np.reshape(Img, (self.num_channel,
                                          self.N * self.N)),
             samples_locations=_samples,
             thr=(thresh, thresh),
             img_shape=(self.N, self.N))
     np.testing.assert_allclose(center_Img.reshape(data_thresholded.shape),
                                data_thresholded)
示例#15
0
    def generate_test_stacked_NFFT(self, shape, field_scale):
        """ Factorized code to test 3D-stacked 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[:-1])
            mask = np.tile(mask[..., None], (1, 1, shape[-1]))
            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 = Stacked3DNFFT(
                kspace_loc=samples,
                shape=shape,
                implementation='cpu',
                n_coils=n_coils,
            )
            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)
示例#16
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")
示例#17
0
 def test_adjoint_stack_3D(self):
     """Test the adjoint operator for the 3D non-Cartesian Fourier transform
     """
     for channel in self.num_channels:
         print("Testing with num_channels=" + str(channel))
         for i in range(self.max_iter):
             _mask = np.random.randint(2, size=(self.N, self.N))
             _mask3D = np.asarray([_mask for i in np.arange(self.N)])
             _samples = convert_mask_to_locations(_mask3D.swapaxes(0, 2))
             print("Process Stacked3D-FFT test in 3D '{0}'...", i)
             fourier_op = Stacked3DNFFT(kspace_loc=_samples,
                                        shape=(self.N, self.N, self.N),
                                        implementation='cpu',
                                        n_coils=channel)
             Img = np.random.random((channel, self.N, self.N, self.N)) + \
                 1j * np.random.random((channel, self.N, self.N, self.N))
             f = np.random.random((channel, _samples.shape[0])) + \
                 1j * np.random.random((channel, _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("Stacked FFT in 3D adjoint test passes")
示例#18
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',
        )
示例#19
0
 def test_stack3d_self_calibration_recon(self):
     # This test carries out a self calibration recon using Stack3D
     self.num_channels = 2
     self.z_size = 10
     for i in range(len(self.test_cases)):
         image, nb_scale, optimizer, recon_type, name = self.test_cases[i]
         if recon_type == 'cartesian' or name == 24:
             continue
         # Make a dummy 3D image from 2D
         image = np.moveaxis(
             np.repeat(image.data[np.newaxis], self.z_size, axis=0), 0, 2)
         # Make dummy multichannel image
         image = np.repeat(image[np.newaxis], self.num_channels, axis=0)
         sampling_z = np.random.randint(2, size=image.shape[3])
         sampling_z[self.z_size // 2 - 3:self.z_size // 2 + 3] = 1
         Nz = sampling_z.sum()
         mask = convert_mask_to_locations(self.mask)
         z_locations = np.repeat(convert_mask_to_locations(sampling_z),
                                 mask.shape[0])
         z_locations = z_locations[:, np.newaxis]
         kspace_loc = np.hstack([np.tile(mask, (Nz, 1)), z_locations])
         fourier = Stacked3DNFFT(kspace_loc=kspace_loc,
                                 shape=image.shape[1:],
                                 implementation='cpu',
                                 n_coils=self.num_channels)
         kspace_obs = fourier.op(image)
         if optimizer == 'condatvu':
             formulation = "analysis"
         else:
             formulation = "synthesis"
         linear_op, regularizer_op = \
             self.get_linear_n_regularization_operator(
                 wavelet_name=name,
                 dimension=len(fourier.shape),
                 nb_scale=2,
                 n_coils=2,
                 n_jobs=2,
                 gradient_formulation=formulation,
             )
         # For self calibrating reconstruction the n_coils
         # for wavelet operation is 1
         linear_op.n_coils = 1
         reconstructor = SelfCalibrationReconstructor(
             fourier_op=fourier,
             linear_op=linear_op,
             regularizer_op=regularizer_op,
             gradient_formulation=formulation,
             num_check_lips=0,
             smaps_extraction_mode='Stack',
             verbose=1,
         )
         x_final, _, _, = reconstructor.reconstruct(
             kspace_data=kspace_obs,
             optimization_alg=optimizer,
             num_iterations=5,
         )
         fourier_0 = FFT(
             samples=kspace_loc,
             shape=image.shape[1:],
             n_coils=self.num_channels,
         )
         recon = fourier_0.adj_op(fourier_0.op(image))
         np.testing.assert_allclose(
             np.abs(x_final), np.sqrt(np.sum(np.abs(recon)**2, axis=0)),
             0.1)
示例#20
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,
     )
image = get_sample_data('3d-pmri')
image = pysap.Image(data=np.sqrt(np.sum(np.abs(image.data)**2, axis=0)))

# Reducing the size of the volume for faster computation
image.data = image.data[:, :, 48:-48]

# Obtain MRI non-cartesian sampling plane
mask_radial = get_sample_data("mri-radial-samples")

# Tiling the plane on the z-direction
# sampling_z = np.ones(image.shape[2])  # no sampling
sampling_z = np.random.randint(2, size=image.shape[2])  # random sampling
sampling_z[22:42] = 1
Nz = sampling_z.sum()  # Number of acquired plane

z_locations = np.repeat(convert_mask_to_locations(sampling_z),
                        mask_radial.shape[0])
z_locations = z_locations[:, np.newaxis]
kspace_loc = np.hstack([np.tile(mask_radial.data, (Nz, 1)), z_locations])
mask = pysap.Image(data=np.moveaxis(
    convert_locations_to_mask(kspace_loc, image.shape), -1, 0))

# View Input
# image.show()
# mask.show()

#############################################################################
# Generate the kspace
# -------------------
#
# From the 2D brain slice and the acquisition mask, we retrospectively
                      axis=-1)

# View Input
# image.show()
# mask.show()

#############################################################################
# Generate the kspace
# -------------------
#
# From the 3D Orange volume and the acquisition mask, we retrospectively
# undersample the k-space using a cartesian acquisition mask
# We then reconstruct the zero order solution as a baseline

# Get the locations of the kspace samples
kspace_loc = convert_mask_to_locations(mask.data)
# Generate the subsampled kspace
fourier_op = FFT(samples=kspace_loc, shape=image.shape)
kspace_data = fourier_op.op(image)

# Zero order solution
image_rec0 = pysap.Image(data=fourier_op.adj_op(kspace_data),
                         metadata=image.metadata)
# image_rec0.show()

# Calculate SSIM
base_ssim = ssim(image_rec0, image)
print(base_ssim)

#############################################################################
# FISTA optimization
示例#23
0
    def test_online_accumulating_calibrationless(self):
        self.num_channels = 2
        for i in range(len(self.test_cases)):
            image, nb_scale, optimizer, recon_type, name = self.test_cases[i]
            if recon_type != 'cartesian':
                continue
            if optimizer == 'condatvu':
                formulation = "analysis"
            else:
                formulation = "synthesis"
            image_multichannel = np.repeat(image.data[np.newaxis],
                                           self.num_channels,
                                           axis=0)

            fourier = FFT(samples=convert_mask_to_locations(self.mask),
                          shape=image.shape,
                          n_coils=self.num_channels)
            kspace_data = fourier.op(image_multichannel)

            linear_op, _ = \
                self.get_linear_n_regularization_operator(
                    wavelet_name=name,
                    dimension=len(fourier.shape),
                    nb_scale=2,
                    n_coils=2,
                    n_jobs=2,
                    image_shape=image.shape,
                )
            regularizer_op_gl = GroupLASSO(weights=0)
            linear_op.op(image_multichannel)
            regularizer_op_owl = OWL(
                alpha=0,
                beta=0,
                mode='band_based',
                n_coils=self.num_channels,
                bands_shape=linear_op.coeffs_shape,
            )
            for regularizer_op in [regularizer_op_gl, regularizer_op_owl]:
                print(image, nb_scale, optimizer, recon_type, name,
                      regularizer_op)
                kspace_gen = KspaceGeneratorBase(full_kspace=kspace_data,
                                                 mask=fourier.mask,
                                                 max_iter=10)
                reconstructor = CalibrationlessReconstructor(
                    fourier_op=fourier,
                    linear_op=linear_op,
                    regularizer_op=regularizer_op,
                    gradient_formulation=formulation,
                    num_check_lips=0,
                    verbose=1,
                )
                x_final, costs, _ = reconstructor.reconstruct(
                    kspace_data=kspace_gen,
                    optimization_alg=optimizer,
                )
                fourier_0 = FFT(
                    samples=convert_mask_to_locations(self.mask),
                    shape=image.shape,
                    n_coils=self.num_channels,
                )
                data_0 = fourier_0.op(image_multichannel)
                # mu is 0 for above single channel reconstruction and
                # hence we expect the result to be the inverse fourier
                # transform
                np.testing.assert_allclose(x_final, fourier_0.adj_op(data_0),
                                           0.01)