kx = np.reshape(kx, (N, spokes)) ky = np.reshape(ky, (N, spokes)) # Get the GRAPPA operators! t0 = time() Gx, Gy = radialgrappaop(kx, ky, k) print('Gx, Gy computed in %g seconds' % (time() - t0)) # Put in correct order for GROG kx = kx.flatten() ky = ky.flatten() k = np.reshape(k, (-1, nc)) # Do GROG without primefac t0 = time() res = grog(kx, ky, k, N, N, Gx, Gy, use_primefac=False) print('Gridded in %g seconds' % (time() - t0)) # Do GROG with primefac t0 = time() res_prime = grog(kx, ky, k, N, N, Gx, Gy, use_primefac=True) print('Gridded in %g seconds (primefac)' % (time() - t0)) res = np.fft.fftshift(np.fft.ifft2(np.fft.ifftshift(res, axes=(0, 1)), axes=(0, 1)), axes=(0, 1)) res = np.sqrt(np.sum(np.abs(res)**2, axis=-1)) res_prime = np.fft.fftshift(np.fft.ifft2(np.fft.ifftshift(res_prime, axes=(0, 1)), axes=(0, 1)),
# Radially sampled Shepp-Logan N, spokes, nc = 288, 72, 8 kx, ky = radial(N, spokes) kx = np.reshape(kx, (N, spokes), 'F').flatten() ky = np.reshape(ky, (N, spokes), 'F').flatten() k = kspace_shepp_logan(kx, ky, ncoil=nc) k = whiten(k) # whitening seems to help conditioning of Gx, Gy # Get the GRAPPA operators t0 = time() Gx, Gy = radialgrappaop(kx, ky, k, nspokes=spokes) print('Gx, Gy computed in %g seconds' % (time() - t0)) # Do forward GROG (with oversampling) t0 = time() res_cart = grog(kx, ky, k, 2 * N, 2 * N, Gx, Gy) print('Gridded in %g seconds' % (time() - t0)) # Now back to radial (inverse GROG) res_radial = grog(kx, ky, np.reshape(res_cart, (-1, nc), order='F'), 2 * N, 2 * N, Gx, Gy, inverse=True) # Make sure we gridded something recognizable nx, ny = 1, 3 plt.subplot(nx, ny, 1)
# U, S, Vh = np.linalg.svd(k, full_matrices=False) # k = U[:, :nc] @ np.diag(S[:nc]) @ Vh[:nc, :nc] # Take a look at the sampling pattern: plt.scatter(kx, ky, .1) plt.title('Radial Sampling Pattern') plt.show() # Get the GRAPPA operators! t0 = time() Gx, Gy = radialgrappaop(kx, ky, k, nspokes=spokes) print('Gx, Gy computed in %g seconds' % (time() - t0)) # Do GROG t0 = time() res, Dx, Dy = grog(kx, ky, k, N, N, Gx, Gy, ret_dicts=True) print('Gridded in %g seconds' % (time() - t0)) # We can do it faster again if we pass back in the dictionaries! # t0 = time() # res = grog(kx, ky, k, N, N, Gx, Gy, Dx=Dx, Dy=Dy) # print('Gridded in %g seconds' % (time() - t0)) # Get the Cartesian grid tx, ty = np.meshgrid(np.linspace(np.min(kx), np.max(kx), N), np.linspace(np.min(ky), np.max(ky), N)) tx, ty = tx.flatten(), ty.flatten() kc = kspace_shepp_logan(tx, ty, ncoil=nc) kc = whiten(kc) outside = np.argwhere(np.sqrt(tx**2 + ty**2) > np.max(kx)).squeeze() kc[outside] = 0 # keep region of support same as radial
# Example usage (requires pygrappa package to be installed!) sx, spokes, ncoil = 288, 72, 8 kx, ky = radial(sx, spokes) kx = np.reshape(kx, (sx, spokes), 'F').flatten() ky = np.reshape(ky, (sx, spokes), 'F').flatten() k = kspace_shepp_logan(kx, ky, ncoil=ncoil) k = whiten(k) # Grid via GROG and check out the results: Gx, Gy = radialgrappaop( np.reshape(kx, (sx, spokes)), np.reshape(ky, (sx, spokes)), np.reshape(k, (sx, spokes, ncoil))) coil_ims = np.abs(np.fft.fftshift(np.fft.ifft2(np.fft.ifftshift( grog(kx, ky, k, sx, sx, Gx, Gy), axes=(0, 1)), axes=(0, 1)), axes=(0, 1))) # Some code to look at the animation fig = plt.figure() ax = plt.imshow(coil_ims[..., 0], cmap='gray') def init(): '''Initialize ax data.''' ax.set_array(coil_ims[..., 0]) return(ax,) def animate(frame): '''Update frame.''' ax.set_array(coil_ims[..., frame]) return(ax,)
kx, ky = radial(sx, spokes) kx = np.reshape(kx, (sx, spokes), 'F').flatten() ky = np.reshape(ky, (sx, spokes), 'F').flatten() k = kspace_shepp_logan(kx, ky, ncoil=nc) k = whiten(k) # We will prefer a gridding approach to keep things simple. The # helper function gridder wraps scipy.interpolate.griddata(): t0 = time() grid_imspace = gridder(kx, ky, k, sx, sx, os=os, method=method) grid_time = time() - t0 # Take a gander plt.figure() plt.imshow(sos(grid_imspace)) plt.title('scipy.interpolate.griddata') plt.xlabel('Recon: %g sec' % grid_time) plt.show(block=False) # We could also use GROG to grid t0 = time() Gx, Gy = radialgrappaop(kx, ky, k, nspokes=spokes) grog_res = grog(kx, ky, k, sx, sx, Gx, Gy) grid_time = time() - t0 plt.figure() plt.imshow(sos(ifft(grog_res))) plt.title('GROG') plt.xlabel('Recon: %g sec' % grid_time) plt.show()