Beispiel #1
0
    def test_simulated_2d(self):


        # # Kind of neat - seeing how phase changes with coil sensitivity...
        # view(np.angle(coil_ims0))

        # Do GS solution to ESM then take SOS
        recon_gs = np.zeros(self.coil_ims0.shape,dtype='complex')
        for ii in range(self.num_coils):
            recon_gs[ii,...] = gs_recon(self.coil_ims0[ii,...],self.coil_ims1[ii,...],self.coil_ims2[ii,...],self.coil_ims3[ii,...])
        # view(np.angle(recon_gs)) # realize this is actually a movie - they all just look the same...
        recon_gs_sos = sos(recon_gs,axes=(0))
        view(recon_gs_sos)

        # Do PCA
        n_components = 4
        pca0 = coil_pca(self.coil_ims0,coil_dim=0,n_components=n_components)
        pca1 = coil_pca(self.coil_ims1,coil_dim=0,n_components=n_components)
        pca2 = coil_pca(self.coil_ims2,coil_dim=0,n_components=n_components)
        pca3,expl_var = coil_pca(self.coil_ims3,coil_dim=0,n_components=n_components,give_explained_var=True)
        # view(expl_var.real)

        # view(np.angle(pca3))

        # Do GS solution to ESM then take SOS, this time using PCA'd data
        recon_pca_gs = np.zeros(pca0.shape,dtype='complex')
        for ii in range(n_components):
            # view(np.concatenate((pca0[ii,...],pca1[ii,...],pca2[ii,...],pca3[ii,...])))
            recon_pca_gs[ii,...] = gs_recon(pca0[ii,...],pca1[ii,...],pca2[ii,...],pca3[ii,...])
        # view(np.angle(recon_pca_gs))
        recon_pca_gs_sos = sos(recon_pca_gs,axes=(0))
Beispiel #2
0
    def test_against_gre(self):

        TR = 15e-3
        TE = 6e-3
        h = 1e-4
        num_TRs = 100
        Nt = num_TRs*TR/h
        spins0 = bloch.gre(self.T1,self.T2,self.M0,Nt,h,*self.RF,TR,TE)
        spins0 = spins0[0,...] + 1j*spins0[1,...]

        spins1 = gre_sim(self.T1,self.T2,TR,TE,alpha=self.RF[1],field_map=None,phi=0,dphi=0,M0=self.M0,iter=num_TRs,spoil=True)
        view(np.stack((spins0,spins1)))
Beispiel #3
0
    def test_recon(self):
        '''See if the full recon matches the MATLAB output'''

        recon = GD_temporal_TV(self.prior,
                               self.reduced_kspace,
                               self.mask,
                               self.weight_fidelity,
                               self.weight_temporal,
                               self.uft.forward_s,
                               self.uft.inverse_s,
                               x=self.Coil)
        view(recon)
Beispiel #4
0
    def test_multiphase(self):
        # Check out what we got:
        # view(self.kspace,fft=True,movie_axis=0,montage_axis=3)

        # Under sample even, odd lines
        kspace = self.kspace.copy()
        Rx = 2
        kspace[0,0::Rx,:,:] = 0
        kspace[1,1::Rx,:,:] = 0
        # view(kspace[0,...],fft=False)

        # Make an autocalibration region by combining center lines from each
        # Right now still struggling to get GRAPPA to work...
        num_acl_lines = 24
        acl_idx = range(int(kspace.shape[2]/2-num_acl_lines/2),int(kspace.shape[2]/2+num_acl_lines/2))
        acl = self.kspace[0,:,acl_idx,:].transpose((2,0,1))
        view(acl,log=True)

        # We also need to get some coil sensitivity maps, let's try a crude one
        # first from original data.  Later we'll do espirit...
        imspace = np.fft.fftshift(np.fft.fft2(self.kspace,axes=(1,2)),axes=(1,2))
        comb_sos = sos(imspace[0,...],axes=-1)[...,None]
        sens = (np.abs(imspace[0,...])/np.tile(comb_sos,(1,1,4))).transpose((2,0,1))
        view(sens)

        # Get coils in the image domain with dims in order grappa2d expects
        coil_ims_pc_0 = np.fft.fftshift(np.fft.ifft2(kspace[0,...],axes=(0,1)),axes=(0,1)).transpose((2,0,1))
        view(coil_ims_pc_0)

        recon = grappa2d(coil_ims_pc_0,sens,acs=acl,Rx=2,Ry=1)
        recon = sos(recon,axes=0)
        view(recon)
Beispiel #5
0
 def test_view_coil_combine_walsh(self):
     '''Coil combine the image using the walsh iterative method.'''
     info = view(self.npy_filename,
                 fft=True,
                 fft_axes=(0, 1),
                 coil_combine_axis=-1,
                 test_run=True)
     self.assertTrue(info['data'].shape == (256, 256))
Beispiel #6
0
 def test_view_coil_combine_pca(self):
     '''Coil combine the image using the PCA method.'''
     info = view(self.npy_filename,
                 fft=True,
                 fft_axes=(0, 1),
                 coil_combine_axis=-1,
                 coil_combine_method='pca',
                 coil_combine_opts={'n_components': 1},
                 test_run=True)
     self.assertTrue(info['data'].shape == (260, 260))
Beispiel #7
0
    def test_gadgetron_grappa_coil_output(self):

        config = GadgetronConfig()
        config.add_reader('1008', 'GadgetIsmrmrdAcquisitionMessageReader')
        config.add_reader('1026', 'GadgetIsmrmrdWaveformMessageReader')
        config.add_writer('1022', 'MRIImageWriter')
        config.add_gadget('RemoveROOversampling')
        config.add_gadget('Grappa',
                          props=[('target_coils', '8'), ('use_gpu', 'false'),
                                 ('uncombined_channels',
                                  '1,2,3,4,5,6,7,8,9,10,11,12')])
        config.add_gadget('GrappaUnmixing')
        config.add_gadget('Extract',
                          props=[('extract_magnitude', 'false')('extract_real',
                                                                'true'),
                                 ('extract_imag', 'true')])
        config.add_gadget('ImageFinish')

        data, header = client(self.filename, config_local=config.tostring())
        data = data[0, ...] + 1j * data[1, ...]
        view(data, montage_axis=0)
Beispiel #8
0
from mr_utils import view
from ismrmrdtools.coils import calculate_csm_inati_iter, calculate_csm_walsh

if __name__ == '__main__':

    im0 = np.load('data/20190401_GASP_PHANTOM/set2_gre_tr34_te2_87.npy')
    im0 = np.mean(im0, axis=2)
    im0 = np.moveaxis(im0, -1, 0)

    im1 = np.load('data/20190401_GASP_PHANTOM/set2_gre_tr4_te5_74.npy')
    im1 = np.mean(im1, axis=2)
    im1 = np.moveaxis(im1, -1, 0)

    # Make a field map coil by coil
    fm0 = dual_echo_gre(im0, im1, 2.87e-3, 5.74e-3)
    np.save('data/20190401_GASP_PHANTOM/coil_fm_gre.npy', fm0)
    view(fm0)
    fm0 = np.mean(fm0, axis=0)

    # Coil combine im0 and im1 then get field map
    _, im0cc0 = calculate_csm_inati_iter(im0)
    _, im1cc0 = calculate_csm_inati_iter(im1)
    csm, _ = calculate_csm_walsh(im0)
    im0cc1 = np.sum(np.conj(im0) * csm, axis=0)
    csm, _ = calculate_csm_walsh(im1)
    im1cc1 = np.sum(np.conj(im1) * csm, axis=0)
    fm1 = dual_echo_gre(im0cc0, im1cc0, 2.87e-3, 5.74e-3)
    fm2 = dual_echo_gre(im0cc1, im1cc1, 2.87e-3, 5.74e-3)

    # Compare
    view(np.stack((fm0, fm1, fm2)))
Beispiel #9
0
def comparison_numerical_phantom(SNR=None):
    '''Compare coil by coil, Walsh method, and Inati iterative method.'''

    true_im = get_true_im_numerical_phantom()
    csms = get_coil_sensitivity_maps()
    params = get_numerical_phantom_params(SNR=SNR)
    pc_vals = params['pc_vals']
    dim = params['dim']
    noise_std = params['noise_std']
    coil_nums = params['coil_nums']

    # We want to solve gs_recon for each coil we have in the pc set
    err = np.zeros((5, len(csms)))
    rip = err.copy()
    for ii, csm in enumerate(csms):

        # I have coil sensitivities, now I need images to apply them to.
        # coil_ims: (pc,coil,x,y)
        coil_ims = np.zeros((len(pc_vals), csm.shape[0], dim, dim),
                            dtype='complex')
        for jj, pc in enumerate(pc_vals):
            im = bssfp_2d_cylinder(dims=(dim, dim), phase_cyc=pc)
            im += 1j * im
            coil_ims[jj, ...] = im * csm
            coil_ims[jj, ...] += np.random.normal(0, noise_std, coil_ims[
                jj, ...].shape) / 2 + 1j * np.random.normal(
                    0, noise_std, coil_ims[jj, ...].shape) / 2

        # Solve the gs_recon coil by coil
        coil_ims_gs = np.zeros((csm.shape[0], dim, dim), dtype='complex')
        for kk in range(csm.shape[0]):
            coil_ims_gs[kk, ...] = gs_recon(*[
                x.squeeze()
                for x in np.split(coil_ims[:, kk, ...], len(pc_vals))
            ])
        coil_ims_gs[np.isnan(coil_ims_gs)] = 0

        # Easy way out: combine all the coils using sos
        im_est_sos = sos(coil_ims_gs)
        # view(im_est_sos)

        # Take coil by coil solution and do Walsh on it to collapse coil dim
        # walsh
        csm_walsh, _ = calculate_csm_walsh(coil_ims_gs)
        im_est_recon_then_walsh = np.sum(csm_walsh * np.conj(coil_ims_gs),
                                         axis=0)
        im_est_recon_then_walsh[np.isnan(im_est_recon_then_walsh)] = 0
        # view(im_est_recon_then_walsh)

        # inati
        csm_inati, im_est_recon_then_inati = calculate_csm_inati_iter(
            coil_ims_gs)

        # Collapse the coil dimension of each phase-cycle using Walsh,Inati
        pc_est_walsh = np.zeros((len(pc_vals), dim, dim), dtype='complex')
        pc_est_inati = np.zeros((len(pc_vals), dim, dim), dtype='complex')
        for jj in range(len(pc_vals)):
            ## Walsh
            csm_walsh, _ = calculate_csm_walsh(coil_ims[jj, ...])
            pc_est_walsh[jj,
                         ...] = np.sum(csm_walsh * np.conj(coil_ims[jj, ...]),
                                       axis=0)
            # view(csm_walsh)
            # view(pc_est_walsh)

            ## Inati
            csm_inati, pc_est_inati[jj, ...] = calculate_csm_inati_iter(
                coil_ims[jj, ...], smoothing=1)
            # pc_est_inati[jj,...] = np.sum(csm_inati*np.conj(coil_ims[jj,...]),axis=0)
            # view(csm_inati)

        # Now solve the gs_recon using collapsed coils
        im_est_walsh = gs_recon(
            *[x.squeeze() for x in np.split(pc_est_walsh, len(pc_vals))])
        im_est_inati = gs_recon(
            *[x.squeeze() for x in np.split(pc_est_inati, len(pc_vals))])

        # view(im_est_walsh)
        # view(im_est_recon_then_walsh)

        # Compute error metrics
        err[0, ii] = compare_nrmse(im_est_sos, true_im)
        err[1, ii] = compare_nrmse(im_est_recon_then_walsh, true_im)
        err[2, ii] = compare_nrmse(im_est_recon_then_inati, true_im)
        err[3, ii] = compare_nrmse(im_est_walsh, true_im)
        err[4, ii] = compare_nrmse(im_est_inati, true_im)

        im_est_sos[np.isnan(im_est_sos)] = 0
        im_est_recon_then_walsh[np.isnan(im_est_recon_then_walsh)] = 0
        im_est_recon_then_inati[np.isnan(im_est_recon_then_inati)] = 0
        im_est_walsh[np.isnan(im_est_walsh)] = 0
        im_est_inati[np.isnan(im_est_inati)] = 0

        rip[0, ii] = ripple_normal(im_est_sos)
        rip[1, ii] = ripple_normal(im_est_recon_then_walsh)
        rip[2, ii] = ripple_normal(im_est_recon_then_inati)
        rip[3, ii] = ripple_normal(im_est_walsh)
        rip[4, ii] = ripple_normal(im_est_inati)

        # view(im_est_inati)

        # # SOS of the gs solution on each individual coil gives us low periodic
        # # ripple accross the phantom, similar to Walsh method:
        # plt.plot(np.abs(true_im[int(dim/2),:]),'--',label='True Im')
        # plt.plot(np.abs(im_est_sos[int(dim/2),:]),'-.',label='SOS')
        # plt.plot(np.abs(im_est_recon_then_walsh[int(dim/2),:]),label='Recon then Walsh')
        # plt.plot(np.abs(im_est_walsh[int(dim/2),:]),label='Walsh then Recon')
        # # plt.plot(np.abs(im_est_inati[int(dim/2),:]),label='Inati')
        # plt.legend()
        # plt.show()

    # # Let's show some stuff
    # plt.plot(coil_nums,err[0,:],'*-',label='SOS')
    # plt.plot(coil_nums,err[1,:],label='Recon then Walsh')
    # plt.plot(coil_nums,err[2,:],label='Walsh then Recon')
    # # plt.plot(coil_nums,err[3,:],label='Inati')
    # plt.legend()
    # plt.show()

    print('SOS RMSE:', np.mean(err[0, :]))
    print('recon then walsh RMSE:', np.mean(err[1, :]))
    print('recon then inati RMSE:', np.mean(err[2, :]))
    print('walsh then recon RMSE:', np.mean(err[3, :]))
    print('inati then recon RMSE:', np.mean(err[4, :]))

    print('SOS ripple:', np.mean(err[0, :]))
    print('recon then walsh ripple:', np.mean(rip[1, :]))
    print('recon then inati ripple:', np.mean(rip[2, :]))
    print('walsh then recon ripple:', np.mean(rip[3, :]))
    print('inati then recon ripple:', np.mean(rip[4, :]))

    view(im_est_recon_then_walsh[int(dim / 2), :])
    view(im_est_recon_then_inati[int(dim / 2), :])
    view(im_est_walsh[int(dim / 2), :])
    view(im_est_inati[int(dim / 2), :])
    # view(im_est_inati)

    # view(np.stack((im_est_recon_then_walsh,im_est_recon_then_inati,im_est_walsh,im_est_inati)))

    return (err)
    def test_reorder(self):
        from mr_utils.test_data.phantom import modified_shepp_logan
        from mr_utils.recon.reordering import get_patches

        # Get phantom
        dim = 64
        phantom = np.rot90(
            modified_shepp_logan((dim, dim, dim))[:, :, int(dim / 2)])
        kspace = np.fft.fftshift(np.fft.fft2(phantom))
        imspace = np.fft.ifft2(kspace)

        # Get patches
        patches = get_patches(imspace, (3, 3))

        # Take mean of each patch to be the pixel value
        im = np.mean(patches, axis=(-2, -1))
        # view(im)

        # # Try 2d reordering and using Ganesh's MATLAB script to do recon
        # # view(im)
        # im_sorted,idx = sort2d(im) # default sort by real
        # self.assertTrue(np.allclose(im.take(idx),im_sorted))
        # # Run Ganesh's recon
        # client = Client()
        # client.run('cd mr_utils/recon/reordering/spatial_tv')
        # client.run('run SCR_reordering.m')
        # data = client.get([ 'Coil1','img_est','measuredImgDomain','prior_data' ])
        # client.exit()

        # # Run Ganesh's temporal recon
        # client = Client()
        # client.run('cd mr_utils/recon/reordering/temporal_tv')
        # client.run('run TCR_reordering_main.m')
        # data = client.get([ 'Coil','mask_k_space_sparse','recon_data' ])
        # client.exit()
        # np.save('mr_utils/recon/reordering/temporal_tv/data.npy',data)
        data = np.load('mr_utils/recon/reordering/temporal_tv/data.npy').item()

        # Get reference, recon, and prior image estimates
        coil_imspace = np.fft.fftshift(np.fft.fft2(data['Coil'], axes=(0, 1)),
                                       axes=(0, 1))
        recon_flipped = np.rot90(np.rot90(data['recon_data'])).astype(
            coil_imspace.dtype)
        prior = np.fft.fftshift(np.fft.fft2(data['Coil'] *
                                            data['mask_k_space_sparse'],
                                            axes=(0, 1)),
                                axes=(0, 1))

        # Normalize so they are comparable
        abs_coil_imspace = np.abs(coil_imspace)
        abs_coil_imspace /= np.max(abs_coil_imspace)
        abs_recon_flipped = np.abs(recon_flipped)
        abs_recon_flipped /= np.max(abs_recon_flipped)
        abs_prior = np.abs(prior)
        abs_prior /= np.max(abs_prior)

        r_coil_imspace = coil_imspace.real / np.max(np.abs(coil_imspace.real))
        i_coil_imspace = coil_imspace.imag / np.max(np.abs(coil_imspace.imag))
        r_recon_flipped = recon_flipped.real / np.max(
            np.abs(recon_flipped.real))
        i_recon_flipped = recon_flipped.imag / np.max(
            np.abs(recon_flipped.imag))
        r_prior = prior.real / np.max(np.abs(prior.real))
        i_prior = prior.imag / np.max(np.abs(prior.imag))

        # Comparisons
        print('MSE  of px reorder: %g' %
              (.5 * (compare_mse(r_coil_imspace, r_recon_flipped) +
                     compare_mse(i_coil_imspace, i_recon_flipped))))
        print('SSIM of px reorder: %g' %
              compare_ssim(abs_coil_imspace, abs_recon_flipped))
        print('PSNR of px reorder: %g' %
              compare_psnr(abs_coil_imspace, abs_recon_flipped))

        print(
            'MSE  of patch reorder: %g' %
            (.5 *
             (compare_mse(r_coil_imspace, ) + compare_mse(i_coil_imspace, ))))
        print('SSIM of patch reorder: %g' % compare_ssim(abs_coil_imspace, ))
        print('PSNR of patch reorder: %g' % compare_psnr(abs_coil_imspace, ))

        # # These are different because of scaling:
        # # print('MSE  of prior: %g' % compare_mse(abs_coil_imspace,abs_prior))
        # print('MSE  of prior: %g' % ((compare_mse(r_coil_imspace,r_prior) + compare_mse(i_coil_imspace,i_prior))/2))
        # print('SSIM of prior: %g' % compare_ssim(abs_coil_imspace,abs_prior))
        # print('PSNR of prior: %g' % compare_psnr(abs_coil_imspace,abs_prior))

        view(prior)
        view(recon_flipped)
    # win = np.kaiser(M0a.shape[0], 5)
    # M0a = np.abs(np.fft.ifft2(M0a*np.outer(win, win)))
    # M0a /= np.pi*TR
    # view(M0a)


    # Solve for off-resonance at each voxel
    #     phi_rf + w0 = angle(M)
    Ma = np.angle(M)[:, pad:-pad, :]
    # view(Ma)
    # Ma = unwrap_phase(Ma)
    # Ma = np.fft.fft2(Ma, axes=(-2, -1))
    # win = np.kaiser(Ma.shape[1], .1)
    # Ma = np.fft.ifft2(Ma*np.outer(win, win), axes=(-2, -1)).real
    # Ma /= np.mean(np.abs(csm_est)[:, pad:-pad, :], axis=0)
    view(Ma)
    # view(Ma)
    csma = np.angle(csm_est)
    csma = csma[:, pad:-pad, :]
    csma = unwrap_phase(csma)
    view(csma)
    print(csma.shape)
    print(Ma.shape)
    x, y = int(265/2), 138
    num = 5
    print(csma[:, x:x+num, y])
    print(Ma[:, x:x+num, y])
    print(csma[:, x:x+num, y] - Ma[:, x:x+num, y])
    print(np.mean(
        csma[:, x:x+num, y] - Ma[:, x:x+num, y], axis=0)/(np.pi*TR))
    print(gre_fm[x:x+num, y])
                       disp=disp,
                       maxiter=maxiter)

    x_cp = proximal_GD(kspace_u,
                       forward_fun=uft.forward,
                       inverse_fun=uft.inverse,
                       sparsify=sparsify,
                       unsparsify=unsparsify,
                       reorder_fun=reorder_cp,
                       alpha=alpha,
                       selective=selective,
                       x=imspace,
                       ignore_residual=ignore,
                       disp=disp,
                       maxiter=maxiter)

    # Let's see how we did
    ys = [x_no, x_ro, x_bu, x_wd, x_cw, x_rw, x_cp]
    xs = ['None', 'sort2d', 'BU', 'WD', 'Col', 'Row', 'Comp']
    absx = np.abs(imspace)
    plt.figure()
    plt.scatter(xs, [compare_mse(absx, np.abs(x)) for x in ys])
    plt.title('MSE')
    plt.show(block=False)
    plt.figure()
    plt.scatter(xs, [compare_ssim(absx, np.abs(x)) for x in ys])
    plt.title('SSIM')
    plt.show()

    view(np.stack((imspace, imspace_u, *xs)))
Beispiel #13
0
 def test_view_coil_combine_inati(self):
     info = view(self.npy_filename,fft=True,fft_axes=(0,1),coil_combine_axis=-1,coil_combine_method='inati',test_run=True)
     self.assertTrue(info['data'].shape == (256,256))
Beispiel #14
0
    # Get a 2D image, since we can't seem to replicate using a single
    # voxel
    N = 64
    df_noise_std = 0
    radius = .8
    TR = 6e-3
    alpha = np.deg2rad(30)
    npcs = 4
    pcs = np.linspace(0, 2*np.pi, npcs, endpoint=False)
    PD, T1, T2 = cylinder_2d(dims=(N, N), radius=radius)

    df = 1000
    min_df, max_df = -df, df
    fx = np.linspace(min_df, max_df, N)
    fy = np.zeros(N)
    df, _ = np.meshgrid(fx, fy)

    if df_noise_std > 0:
        n = np.random.normal(0, df_noise_std, df.shape)
        df += n

    I = ssfp(T1, T2, TR, alpha, df, pcs, PD, phi_rf=0)


    recon = gs_recon(I, pc_axis=0)
    recon_no_second = gs_recon(I, pc_axis=0, second_pass=False)

    I0 = np.concatenate((
        I, recon[None, ...], recon_no_second[None, ...]), axis=0)
    view(I0, montage_axis=0)
Beispiel #15
0
        return dct(x, norm='ortho')

    def inverse_dct(self, x):
        '''Inverse sparsifying transform, DCT.'''
        return idct(x, norm='ortho')


if __name__ == '__main__':

    # Load in a data set
    filename = ('/home/nicholas/Documents/research/reordering_data/'
                'STCR_72_rays/Trio/P010710/meas_MID42_CV_Radial7Off_'
                'triple_2.9ml_FID242_GROG.mat')

    data = load_mat(filename, 'Image')
    view(data)
    sx, sy, st, _ = data.shape[:]
    tcurves = data[..., 0].reshape((sx * sy, st))
    view(tcurves[(sx * 133 + 130):(sx * 133 + 150), :])
    print(tcurves.shape)

    # Pick one pixel we know is going to have a nice time curve
    pt = (133, 130)
    px = data[pt[0], pt[1], :, 0]
    # view(px)

    # # Get orderings for real and imaginary parts
    # sr = Sparsify(px.real)
    # si = Sparsify(px.imag)
    # k = 1
    # rpi = ordinator1d(
Beispiel #16
0
                                                                   axes=(1,
                                                                         2)),
                                                   axes=(1, 2)),
                                       axes=(1, 2))
    kspace_coil_ims2 = np.fft.fftshift(np.fft.fft2(np.fft.fftshift(coil_ims2,
                                                                   axes=(1,
                                                                         2)),
                                                   axes=(1, 2)),
                                       axes=(1, 2))
    kspace_coil_ims3 = np.fft.fftshift(np.fft.fft2(np.fft.fftshift(coil_ims3,
                                                                   axes=(1,
                                                                         2)),
                                                   axes=(1, 2)),
                                       axes=(1, 2))

    view(np.angle(coil_ims0))

    # Do GS solution to ESM then take SOS
    recon_gs = np.zeros(coil_ims0.shape, dtype='complex')
    for ii in range(num_coils):
        recon_gs[ii, ...] = gs_recon(coil_ims0[ii, ...], coil_ims1[ii, ...],
                                     coil_ims2[ii, ...], coil_ims3[ii, ...])
    recon_gs_sos = sos(recon_gs, axes=(0))
    view(recon_gs_sos)

    # Do PCA
    n_components = 4
    pca0 = coil_pca(coil_ims0, coil_dim=0, n_components=n_components)
    pca1 = coil_pca(coil_ims1, coil_dim=0, n_components=n_components)
    pca2 = coil_pca(coil_ims2, coil_dim=0, n_components=n_components)
    pca3, expl_var = coil_pca(coil_ims3,
Beispiel #17
0
                      selective=None,
                      x=x,
                      ignore_residual=ignore,
                      disp=disp,
                      maxiter=maxiter)

    x_ri = proximal_GD(y,
                       forward_fun=uft.forward_ortho,
                       inverse_fun=uft.inverse_ortho,
                       sparsify=sparsify,
                       unsparsify=unsparsify,
                       reorder_fun=None,
                       alpha=alpha,
                       thresh_sep=True,
                       selective=None,
                       x=x,
                       ignore_residual=ignore,
                       disp=disp,
                       maxiter=maxiter)

    xabs = np.abs(x)
    x_cabs = np.abs(x_c)
    x_riabs = np.abs(x_ri)
    print('Thresholding complex:')
    print('     MSE: %g' % compare_mse(xabs, x_cabs))
    print('    SSIM: %g' % compare_ssim(xabs, x_cabs))
    print('Thresholding real/imag separately:')
    print('     MSE: %g' % compare_mse(xabs, x_riabs))
    print('    SSIM: %g' % compare_ssim(xabs, x_riabs))
    view(np.stack((x, uft.inverse_ortho(y), x_c, x_ri)))
Beispiel #18
0
    # Load in the data
    path = 'mr_utils/test_data/tests/gadgetron/client/'
    file = 'grappa_test_data.h5'
    load_test_data(path, [file], do_return=False)
    data = '%s/%s' % (path, file)

    # Look at the data to make sure we got what we got
    with h5py.File(data, 'r') as f:
        coil_images = f['dataset']['coil_images']
        coil_images = coil_images['real'] + 1j * coil_images['imag']

        # R = 2
        tmp = np.fft.fft2(coil_images)
        tmp[..., ::2, :] = 0
        aliased = np.fft.ifft2(tmp)
        view(aliased, montage_axis=0)

    # Make the config
    num_coils = 16
    config = GadgetronConfig()
    config.add_reader('1008', 'GadgetIsmrmrdAcquisitionMessageReader')
    config.add_reader('1026', 'GadgetIsmrmrdWaveformMessageReader')
    config.add_writer('1022', 'MRIImageWriter')
    config.add_gadget('NoiseAdjust')
    config.add_gadget('CoilReduction', props=[('coils_out', str(num_coils))])
    # RO asymmetric echo handling
    config.add_gadget('AsymmetricEcho', 'AsymmetricEchoAdjustROGadget')
    config.add_gadget('RemoveROOversampling')
    config.add_gadget('Grappa',
                      props=[
                          ('target_coils', str(num_coils)),
Beispiel #19
0
    # selectives = [ None,select_n,select_patch ]
    selectives = [None, select_n]
    # selectives = [ None ]
    x_hats = np.zeros((len(selectives), ) + y.shape, dtype=y.dtype)
    for ii, selective in enumerate(selectives):
        x_hats[ii, ...] = proximal_GD(y,
                                      forward_fun=uft.forward_ortho,
                                      inverse_fun=uft.inverse_ortho,
                                      sparsify=sparsify,
                                      unsparsify=unsparsify,
                                      reorder_fun=reorder,
                                      alpha=alpha,
                                      selective=selective,
                                      x=x,
                                      ignore_residual=ignore,
                                      disp=disp,
                                      maxiter=maxiter)

    for ii, selective in enumerate(selectives):
        if selective is None:
            name = 'None'
        else:
            name = selective.__name__
        print('For %s:' % name)
        print('  Compare  MSE: %g' % compare_mse(np.abs(x_hats[ii, ...]), x))
        print('  Compare SSIM: %g' % compare_ssim(np.abs(x_hats[ii, ...]), x))

    # Take a look at 'em!
    view(x_hats)
    res = np.zeros((len(ccs), nx, ny), dtype='complex')
    err_cc_then_gs = np.zeros(len(ccs))
    for fun, cc in enumerate(ccs):

        tmp = np.zeros((nx, ny, ngs), dtype='complex')
        idx = list(range(npcs))[::4]
        for ii, jj in enumerate(idx):
            tmp[..., ii] = cc(imspace[..., jj].transpose((2, 0, 1)))
        res[fun, ...] = gs_recon(tmp, pc_axis=-1) * mask
        # view(res[fun, ...])

        # view(np.stack((im_true, res[fun, ...])))
        err_cc_then_gs[fun] = compare_mse(im_true,
                                          np.abs(np.nan_to_num(res[fun, ...])))
    view(
        np.concatenate(
            (res[:, trim:-trim, ...], im_true[trim:-trim, :][None, ...]),
            axis=0))
    # plt.bar(list(range(len(ccs))), err_cc_then_gs)
    # plt.show()

    # Do ESM then coil combine
    res = np.zeros((len(ccs), nx, ny), dtype='complex')
    err_gs_then_cc = np.zeros(len(ccs))
    for fun, cc in enumerate(ccs):

        tmp = np.zeros((nc, nx, ny), dtype='complex')
        for ii in range(nc):
            tmp[ii, ...] = gs_recon(imspace[..., ii, ::4], pc_axis=-1)

        res[fun, ...] = cc(tmp) * mask
        # view(res[coil, fun, ...])
Beispiel #21
0
    # Acquire all pcs at all TRs for all coils
    I = np.zeros((ncoils, nTRs, npcs, height, width), dtype='complex')
    I_comp = I.copy()
    for ii, TR in tqdm(enumerate(TRs), leave=False, total=len(TRs)):
        for cc in trange(ncoils, leave=False):
            I_comp[cc, ii, ...] = csm[cc, ...] * ssfp(
                T1s, T2s, TR, alpha, coil_fm_gre[cc, ...].T * mask, pcs, PDs)
            # df0 = unwrap_phase(fac*coil_fm_gre[0, ...].T*mask)/fac
            # I[cc, ii, ...] = csm[cc, ...]*ssfp( T1s, T2s, TR, alpha, df0, pcs, PDs)
            I[cc, ii,
              ...] = csm[cc, ...] * ssfp(T1s, T2s, TR, alpha, _df, pcs, PDs)
            print(np.stack((I[cc, ii, ...], I_comp[cc, ii, ...])).shape)
            view(np.stack(
                (I[cc, ii,
                   ...], I_comp[cc, ii,
                                ...], I[cc, ii, ...] - I_comp[cc, ii, ...])),
                 fft_axes=(3, 4),
                 montage_axis=0,
                 movie_axis=1)

            # Compensate for phase accrual during the TE
            # I[cc, ii, ...] *= np.tile(np.exp(-2j * np.pi * coil_fm_gre[cc, ...].T * TR / 2), (npcs, 1, 1))
            # I[cc, ii, ...] *= np.tile(np.exp(-2j * np.pi * _df * TR / 2), (npcs, 1, 1))

    # Combine TR/phase-cycle dimension
    I = I.reshape((ncoils, nTRs * npcs, height, width))

    # Do a neat thing a sweep across left to right while GASPing
    fig = plt.figure()
    im = plt.imshow(np.abs(I[0, 0, ...]), vmin=0, vmax=1)
    plt.title('Results of GASP swept across spatial extent')
    # Do reconstruction using gradient descent without reordering
    do_reordering = False
    x_hat_wo = GD_TV(
        kspace_u,
        forward_fun=uft.forward,
        inverse_fun=uft.inverse,
        alpha=.5,
        lam=.004,
        do_reordering=do_reordering,
        x=imspace,
        ignore_residual=True,
        disp=True,
        maxiter=50)

    # Do reconstruction using gradient descent with reordering
    do_reordering = True
    x_hat_w = GD_TV(
        kspace_u,
        forward_fun=uft.forward,
        inverse_fun=uft.inverse,
        alpha=.5,
        lam=.004,
        do_reordering=do_reordering,
        x=imspace,
        ignore_residual=True,
        disp=True,
        maxiter=50)

    # Checkout how well we did
    view(np.hstack((imspace, imspace_u, x_hat_wo, x_hat_w)))
Beispiel #23
0
        plt.xlabel('time index')
        plt.ylabel('a.u.')
        plt.legend()
        plt.show()

    # Choose what areas to varying in time
    pd, t1s, t2s = cylinder_2d(radius=.1)
    pd = np.roll(pd, 15)
    t1s = np.roll(t1s, -15)
    idx0 = pd > 0
    idx1 = t1s > 0
    print('Cluster size: %d' % np.sum(idx0))
    idx = idx0 + idx1

    if plots:
        view(idx1 + idx0 + brain * 50)

    # Make time varying field to simulate blood flow
    tv_field_map = np.zeros(field_map.shape + (time_pts, ))
    tv_field_map += np.random.normal(0, sigma, tv_field_map.shape)
    tv_field_map[idx, :] += hrf0

    # tv_field_map[0,0,:] = 1 # reference scaling pixel
    # view(tv_field_map,movie_axis=-1)

    # Now acquire 4 phase-cycles at each time point
    # also get GRE sims for comparison - we'll also use the first bSSFP phase
    # cycle to do quantitative reconstruction of the field map.
    pc_vals = [0, np.pi / 2, np.pi, 3 * np.pi / 2]
    bssfp_acqs = np.zeros((len(pc_vals), ) + tv_field_map.shape,
                          dtype='complex')
Beispiel #24
0
if __name__ == '__main__':

    # Same binary smiley face example
    do_reordering = True
    N = 1000
    x = binary_smiley(N)
    k = np.sum(np.abs(np.diff(x)) > 0)
    np.random.seed(5)
    samp = cartesian_pe(x.shape, undersample=.2, reflines=5)
    uft = UFT(samp)

    # Make the complex measurement in kspace
    # Note this is different than uft.forward, as fftshift must be performed
    y = uft.forward_ortho(x)

    # Solve inverse problem using gradient descent with TV sparsity constraint
    x_hat = GD_TV(y,
                  forward_fun=uft.forward_ortho,
                  inverse_fun=uft.inverse_ortho,
                  alpha=.5,
                  lam=.022,
                  do_reordering=do_reordering,
                  x=x,
                  ignore_residual=True,
                  disp=True,
                  maxiter=50)

    # Look at the before/after shots
    view(np.stack((uft.inverse_ortho(y), x_hat)))
Beispiel #25
0
 def test_view_load_npy_with_load_opts(self):
     with self.assertRaises(TypeError):
         info = view(self.npy_filename,load_opts={ 'not':'an option' },test_run=True)
Beispiel #26
0
                phi_rf=phi_rf[cc])

        # Do PLANET rotation to get vertical ellipse
        xr, yr, _C0, phis[cc] = do_planet_rotation(I[cc, :])
        I0[cc, :] = xr + 1j*yr

        # plt.plot(I[cc, :].real, I[cc, :].imag)
        # plt.plot(I0[cc, :].real, I0[cc, :].imag)
        # plt.axis('square')
        # plt.show()

    # Get coil sensitivity map estimates
    from ismrmrdtools.coils import calculate_csm_walsh
    recons = np.zeros(ncoils, dtype='complex')
    for cc in range(ncoils):
        view(gs_recon(I[cc, :]))
        # recons[cc] = gs_recon(I[cc, :][:, None, None], pc_axis=-1)
    # csm_est = calculate_csm_walsh(recons[:, None, None])
    # view(csm_est)

    # # Can we find the null?
    # fig, ax1 = plt.subplots()
    # ax2 = ax1.twinx()
    # dfs = np.linspace(-1/TR, 1/TR, lpcs)
    # print(np.rad2deg(phi_rf))
    # print(np.rad2deg(phis))
    # for cc in range(ncoils):
    #     im0 = np.atleast_2d(I[cc, ::2])
    #     im1 = np.atleast_2d(I[cc, 1::2])
    #     recon0 = gs_recon(im0, pc_axis=-1)
    #     recon1 = gs_recon(im1, pc_axis=-1)
Beispiel #27
0
 def test_view_load_vanilla_npy(self):
     info = view(self.npy_filename,test_run=True)
     self.assertTrue(info['data'].size)
Beispiel #28
0
    # twix = mapVBVD('meas_MID00026_FID08491_t1_starvibe_60spokes_benz.dat')
    # print('Num images: %d' % len(twix))
    #
    # twix = twix[1]
    # # for p in [ x for x in dir(twix['image']) if x[0] != '_' ]:
    # #     print(p,getattr(twix['image'],p))
    # print('dataSize',twix['image'].dataSize())
    # print('NAcq',twix['image'].NAcq)
    # print('getSqzDims',twix['image'].getSqzDims())
    # print('getSqzSize',twix['image'].getSqzSize())
    #
    # twix['image'].setFlagDoAverage(True)
    # twix['image'].setFlagRemoveOS(True)
    #
    # print('dataSize',twix['image'].dataSize())
    #
    # data = twix['image'].readData()
    # view(data)

    twix = mapVBVD(362)
    twix['image'].setFlagDoAverage(True)
    twix['image'].setFlagRemoveOS(True)
    data = twix['image'].readData()
    print(data.shape)

    test_im = data[:,0,:,...].squeeze()
    print(test_im.shape)
    view(test_im,log=True)
    # plt.imshow(np.abs(test_im[:,:]))
    # plt.show()
Beispiel #29
0
        else:
            # Sorting doesn't suppress motion!
            sord = np.argsort(np.abs(imspace_true[ii, jj, :]))

        recon_sort[ii, jj, sord] = ptv.tv1_1d( #pylint: disable=E1137
            np.abs(imspace_u[ii, jj, sord]), w)

    plt.plot(np.abs(imspace_true[ctr[0], ctr[1], :]))
    plt.plot(np.abs(recon_sort[ctr[0], ctr[1], :]))
    plt.plot(np.abs(recon_l1[ctr[0], ctr[1], :]))
    plt.show()

    # Take a look
    ims = [
        imspace_u,
        # recon,
        recon_l1,
        recon_l2,
        recon_sort,
        imspace_true,
        # np.abs(imspace_true - recon0),
        # np.abs(imspace_true - recon1)
    ]
    ims0 = list()
    for im in ims:
        norm = np.linalg.norm(im)
        im /= norm
        ims0.append(im)
    ims = np.array(ims0)
    view(ims)
Beispiel #30
0
    else:
        # Else we'll have to do it ourselves
        data = np.load(dirname(__file__) + '/data.npy')
        # Put 'er in image space
        print('Starting fft...')
        data = np.fft.fftshift(np.fft.fft2(data, axes=(0, 1)), axes=(0, 1))
        np.save(data_fft_filename, data)
        print('Finished saving fft!')

    # Tell me about it
    print('Data shape is:', data.shape)
    sx, sy, nc, nt, ns = data.shape[:]

    # Take a look at it in all its glory -- notice significant motion
    view(sos(data[..., 1::16, :], axes=2).squeeze(),
         montage_axis=-1,
         movie_axis=-2)

    # For each coil for all slices for each possible GS recon in N time points
    N = 16  # since we have 16 unique phase-cycles...
    print('Starting GS recons...')
    sh = np.array(data.shape)
    num_gs_recons = int(N / 4)  # need 4 coil images for GS recon
    sh[3] = num_gs_recons
    recons = np.zeros(sh, dtype=data.dtype)
    for ii in trange(num_gs_recons, desc='GS recons', leave=False):
        for cc in trange(nc, desc='Coils', leave=False):
            ims = data[..., cc, ii:N:4, :]
            recons[..., cc, ii, :] = gs_recon3d(
                *[x.squeeze() for x in np.split(ims, 4, axis=-2)])
    print('Finished GS recons:', recons.shape)