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))
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)))
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)
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)
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))
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))
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)
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)))
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)))
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))
# 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)
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(
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,
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)))
# 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)),
# 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, ...])
# 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)))
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')
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)))
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)
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)
def test_view_load_vanilla_npy(self): info = view(self.npy_filename,test_run=True) self.assertTrue(info['data'].size)
# 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()
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)
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)