def planet_shepp_logan_example(): # Shepp-Logan N, nslices, npcs = 128, 1, 8 # 2 slices just to show we can M0, T1, T2 = shepp_logan((N, N, nslices), MR=True, zlims=(-.25, 0)) # Simulate bSSFP acquisition with linear off-resonance TR, alpha = 3e-3, np.deg2rad(15) pcs = np.linspace(0, 2 * np.pi, npcs, endpoint=False) df, _ = np.meshgrid(np.linspace(-1 / TR, 1 / TR, N), np.linspace(-1 / TR, 1 / TR, N)) sig = np.empty((npcs, ) + T1.shape, dtype='complex') for sl in range(nslices): sig[..., sl] = bssfp(T1[..., sl], T2[..., sl], TR, alpha, field_map=df, phase_cyc=pcs, M0=M0[..., sl]) # Do T1, T2 mapping for each pixel mask = np.abs(M0) > 1e-8 # Make it noisy np.random.seed(0) sig += 1e-5 * (np.random.normal(0, 1, sig.shape) + 1j * np.random.normal(0, 1, sig.shape)) * mask print(sig.shape, alpha, TR, mask.shape) # Show the phase-cycled images nx, ny = 2, 4 plt.figure() for ii in range(nx * ny): plt.subplot(nx, ny, ii + 1) plt.imshow(np.abs(sig[ii, :, :, 0])) plt.title('%d deg PC' % (ii * (360 / npcs))) plt.show() # Do the thing t0 = perf_counter() Mmap, T1est, T2est, dfest = planet(sig, alpha, TR, mask=mask, pc_axis=0) print('Took %g sec to run PLANET' % (perf_counter() - t0)) print(T1est.shape, T2est.shape, dfest.shape, T1.shape, T2.shape, mask.shape) # Look at a single slice sl = 0 T1est = T1est[..., sl] T2est = T2est[..., sl] dfest = dfest[..., sl] T1 = T1[..., sl] T2 = T2[..., sl] mask = mask[..., sl] # Simple phase unwrapping of off-resonance estimate dfest = unwrap_phase(dfest * 2 * np.pi * TR) / (2 * np.pi * TR) print('t1, mask:', T1.shape, mask.shape) nx, ny = 3, 3 plt.subplot(nx, ny, 1) plt.imshow(T1 * mask) plt.title('T1 Truth') plt.axis('off') plt.subplot(nx, ny, 2) plt.imshow(T1est) plt.title('T1 est') plt.axis('off') plt.subplot(nx, ny, 3) plt.imshow(T1 * mask - T1est) plt.title('NRMSE: %g' % normalized_root_mse(T1, T1est)) plt.axis('off') plt.subplot(nx, ny, 4) plt.imshow(T2 * mask) plt.title('T2 Truth') plt.axis('off') plt.subplot(nx, ny, 5) plt.imshow(T2est) plt.title('T2 est') plt.axis('off') plt.subplot(nx, ny, 6) plt.imshow(T2 * mask - T2est) plt.title('NRMSE: %g' % normalized_root_mse(T2, T2est)) plt.axis('off') plt.subplot(nx, ny, 7) plt.imshow(df * mask) plt.title('df Truth') plt.axis('off') plt.subplot(nx, ny, 8) plt.imshow(dfest) plt.title('df est') plt.axis('off') plt.subplot(nx, ny, 9) plt.imshow(df * mask - dfest) plt.title('NRMSE: %g' % normalized_root_mse(df * mask, dfest)) plt.axis('off') plt.show()
TR0, TR1 = 3e-3, 6e-3 alpha = np.deg2rad(80) alpha_lo = np.deg2rad(12) pcs8 = np.linspace(0, 2 * np.pi, 8, endpoint=False) pcs6 = np.linspace(0, 2 * np.pi, 6, endpoint=False) pcs4 = np.linspace(0, 2 * np.pi, 4, endpoint=False) pcs2 = np.linspace(0, 2 * np.pi, 2, endpoint=False) df, _ = np.meshgrid(np.linspace(-1 / (2 * TR1), 1 / (2 * TR1), N), np.linspace(-1 / (2 * TR1), 1 / (2 * TR1), N)) df *= mask if fimtre_results: I0_hi = bssfp(T1, T2, TR0, alpha, field_map=df, phase_cyc=pcs4[None, None, :], M0=M0) I1_6_hi = bssfp(T1, T2, TR1, alpha, field_map=df, phase_cyc=pcs2[None, None, :], M0=M0) I1_8_hi = bssfp(T1, T2, TR1, alpha, field_map=df,
'''Picture how FIMTRE works.''' import numpy as np import matplotlib.pyplot as plt from ssfp import bssfp, fimtre, gs_recon from ellipsinator import rotate_points if __name__ == '__main__': pbssfp = lambda TR, pcs: bssfp(T1, T2, TR=TR, alpha=alpha, field_map=df, phase_cyc=pcs) T1, T2 = 2, 1 TRs = [3e-3, 5e-3] alpha = np.deg2rad(87) pcs2 = np.linspace(0, 2*np.pi, 2, endpoint=False) pcs4 = np.linspace(0, 2*np.pi, 4, endpoint=False) many_pcs = np.linspace(0, 2*np.pi, 200, endpoint=True) df = 1/(2*TRs[0]) e1 = pbssfp(TRs[0], pcs4) e1_ext = pbssfp(TRs[0], many_pcs) e2 = pbssfp(TRs[1], pcs2) e2_ext = pbssfp(TRs[1], many_pcs) df_est = fimtre(e1, e2, *TRs, rad=False) rad_est = fimtre(e1, e2, *TRs, rad=True) plt.plot(e1_ext.real, e1_ext.imag, 'b', label='TR1') plt.plot(e1.real, e1.imag, 'bx') plt.plot(e2_ext.real, e2_ext.imag, 'r', label='TR2') plt.plot(e2.real, e2.imag, 'rx') # Annotations
pcs = np.linspace(0, 2 * np.pi, npcs, endpoint=False) M0, T1, T2 = shepp_logan((N, N, 1), MR=True, zlims=(-.25, .25)) M0, T1, T2 = np.squeeze(M0), np.squeeze(T1), np.squeeze(T2) # Linear off resonance TR, alpha = 6e-3, np.deg2rad(30) df, _ = np.meshgrid(np.linspace(-1 / TR, 1 / TR, N), np.linspace(-1 / TR, 1 / TR, N)) # Generate coil images csm = _gaussian_csm(N, N, nc) data = np.abs(csm[..., None, :]) * bssfp( T1, T2, TR, alpha, field_map=df, phase_cyc=pcs[None, None, :, None], M0=M0, phi_rf=np.angle(csm[..., None, :])) # Do coil-by-coil recon res_cbc = np.empty((N, N, nc), dtype=np.complex64) t0 = time() for ii in range(nc): res_cbc[..., ii] = gs_recon(data[..., ii], pc_axis=-1) res_cbc = np.sqrt(np.sum(np.abs(res_cbc)**2, axis=-1)) print('Took %g seconds to do coil-by-coil recon' % (time() - t0)) # Do robust coil combine then recon t0 = time()
import numpy as np import matplotlib.pyplot as plt from phantominator import shepp_logan from ssfp import bssfp, spoiled_gre if __name__ == '__main__': N = 128 M0, T1, T2 = shepp_logan((N, N, 1), MR=True, zlims=(-.25, -.25)) M0, T1, T2 = M0[..., 0], T1[..., 0], T2[..., 0] TR = 6e-3 TE = TR / 2 alpha = np.deg2rad(70) bssfp_res = np.abs(bssfp(T1, T2, TR, alpha=alpha, M0=M0)) gre_res = spoiled_gre(T1, T2, TR, TE, alpha=alpha, M0=M0) nx, ny = 1, 3 plt.subplot(nx, ny, 1) plt.imshow(bssfp_res) plt.title('bSSFP') plt.subplot(nx, ny, 2) plt.imshow(gre_res) plt.title('GRE') plt.subplot(nx, ny, 3) idx = np.logical_and(bssfp_res > 0, gre_res > 0) plt.plot(bssfp_res[idx] / gre_res[idx]) plt.ylim([0, 1])
if __name__ == '__main__': # Shepp-Logan N, nslices, npcs = 128, 2, 8 # 2 slices just to show we can M0, T1, T2 = shepp_logan((N, N, nslices), MR=True, zlims=(-.25, 0)) # Simulate bSSFP acquisition with linear off-resonance TR, alpha = 3e-3, np.deg2rad(15) pcs = np.linspace(0, 2 * np.pi, npcs, endpoint=False) df, _ = np.meshgrid(np.linspace(-1 / TR, 1 / TR, N), np.linspace(-1 / TR, 1 / TR, N)) sig = bssfp(T1, T2, TR, alpha, field_map=df[..., None], phase_cyc=pcs[None, None, None, :], M0=M0) # Do T1, T2 mapping for each pixel mask = np.abs(M0) > 1e-8 # Make it noisy np.random.seed(0) sig += 1e-5 * (np.random.normal(0, 1, sig.shape) + 1j * np.random.normal(0, 1, sig.shape)) * mask[..., None] # Do the thing t0 = perf_counter() Mmap, T1est, T2est, dfest = planet(sig, alpha, TR, mask=mask, pc_axis=-1)