axes=(0, 1)), axes=(0, 1)) def sos(x0): return np.sqrt(np.sum(np.abs(x0)**2, axis=-1)) if __name__ == '__main__': # Radially sampled Shepp-Logan N, spokes, nc = 288, 72, 8 kx, ky = radial(N, spokes) kx = np.reshape(kx, (N, spokes), 'F').flatten().astype(np.float32) ky = np.reshape(ky, (N, spokes), 'F').flatten().astype(np.float32) k = kspace_shepp_logan(kx, ky, ncoil=nc).astype(np.complex64) k = whiten(k) # whitening seems to help conditioning of Gx, Gy # # Instead of whitening, maybe you prefer to reduce coils: # nc = 4 # 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)
from pygrappa import ttgrappa from utils import gridder if __name__ == '__main__': # Simulate a radial trajectory sx, spokes, nc = 128, 128, 8 kx, ky = radial(sx, spokes) # We reorder the samples like this for easier undersampling later kx = np.reshape(kx, (sx, spokes)).flatten('F') ky = np.reshape(ky, (sx, spokes)).flatten('F') # Sample Shepp-Logan at points (kx, ky) with nc coils: kspace = kspace_shepp_logan(kx, ky, ncoil=nc) k = kspace.copy() # Get some calibration data -- ideally we would want to simulate # something other than the image we're going to reconstruct, but # since this is just proof of concept, we'll go ahead cx = kx.copy() cy = ky.copy() calib = k.copy() # calib = np.tile(calib[:, None, :], (1, 2, 1)) calib = calib[:, None, :] # middle axis is the through-time dim # Undersample: R=2 k[::2] = 0 # Reconstruct with Non-Cartesian GRAPPA
import matplotlib.pyplot as plt from phantominator import radial, kspace_shepp_logan from skimage.measure import compare_nrmse, compare_ssim from skimage.morphology import convex_hull_image from skimage.filters import threshold_li from pygrappa import radialgrappaop, grog if __name__ == '__main__': # 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 # # Instead of whitening, maybe you prefer to reduce coils: # nc = 4 # U, S, Vh = np.linalg.svd(k, full_matrices=False) # k = U[:, :nc] @ np.diag(S[:nc]) @ Vh[:nc, :nc] # Put in correct shape for radialgrappaop k = np.reshape(k, (N, spokes, nc)) kx = np.reshape(kx, (N, spokes)) ky = np.reshape(ky, (N, spokes)) # Take a look at the sampling pattern: plt.scatter(kx, ky, .1) plt.title('Radial Sampling Pattern')