def _fimtre6(I0, I1, TR0, TR1): ctr0 = gs_recon(I0, pc_axis=-1, second_pass=False) # find where circle intersects line, this is ctr1 (or there-abouts) # use equation of centered circle and line: # x^2 + y^2 = r^2 # r = |GS(I0)|, where GS(I) is the geometric center of ellipse I # (x0, y0) = 0 deg phase cycle of second TR ellipse # (x1, y1) = 180 deg phase cycle of second TR ellipse # y = mx + b # m = (y1 - y0)/(x1 - x0) # b = y - mx = y0 - m*x0 = y1 - m*x1 # x^2 + (mx + b)^2 = r^2 # => x = (sqrt((m^2 + 1)r^2 - b^2) - bm)/(m^2 + 1) # OR -(sqrt((m^2 + 1)r^2 - b^2) + bm)/(m^2 + 1) # Choose the smaller rotation, i.e. min |x| # y = mx + b # (x, y) is now GS(I1) r2 = np.real(np.conj(ctr0)*ctr0) I1 = I1*1e8 # scale I1 up to make sure endpoints don't miss ctr0 when rotating m = (I1[..., 0].imag - I1[..., 1].imag)/(I1[..., 0].real - I1[..., 1].real) m2 = m*m # avg b = ((y_0 - mx_0) + (y_1 - mx_1))/2 b = (I1[..., 0].imag - m*I1[..., 0].real + I1[..., 1].imag - m*I1[..., 1].real)/2 vals = (m2 + 1)*r2 - b**2 nonneg = vals >= 0 x = np.zeros(r2.shape) xalt = np.zeros(r2.shape) x[nonneg] = (np.sqrt(vals[nonneg]) - b[nonneg]*m[nonneg])/(m2[nonneg] + 1) xalt[nonneg] = -1*(np.sqrt(vals[nonneg]) + b[nonneg]*m[nonneg])/(m2[nonneg] + 1) idx = np.abs(xalt) < np.abs(x) x[idx] = xalt[idx] y = m*x + b return np.angle(ctr0*(x - 1j*y))
def _fimtre8(I0, I1, TR0, TR1): ctr0 = gs_recon(I0, pc_axis=-1, second_pass=False) ctr1 = gs_recon(I1, pc_axis=-1, second_pass=False) return np.angle(ctr0*np.conj(ctr1))
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 plt.plot(e2.real, e2.imag, 'r--') xr, yr = rotate_points(e2.real, e2.imag, phi=rad_est) plt.plot(xr, yr, 'rx') plt.plot(xr, yr, 'r--') ctr0 = gs_recon(np.atleast_2d(e1), pc_axis=-1, second_pass=False) plt.plot(ctr0.real, ctr0.imag, 'bo') plt.title(f'True: {df:.2f}Hz, Est: {df_est[0]:.2f}Hz') plt.legend() plt.xlabel('Real (a.u.)') plt.ylabel('Imag (a.u.)') plt.axis('square') plt.show()
data = data[pdx2:-pdx2, ...] sx, sy, npcs, nc = data.shape[:] TR, alpha = 6e-3, np.deg2rad(70) # MR params for bSSFP sim pcs = np.linspace(0, 2 * np.pi, npcs, endpoint=False) # Start timer t0 = time() # Coil combine (SOS + simple phase) res_rcc_simple = robustcc(data, method='simple', coil_axis=-1, pc_axis=-2) # Make a mask gs = np.array([ gs_recon(res_rcc_simple[..., ii::4], pc_axis=-1) for ii in range(npcs // 4) ]) gs = np.abs(np.mean(gs, axis=0)) thresh = threshold_li(gs) mask = gs > thresh # PLANET _Meff, T1map, T2map, _df = planet(res_rcc_simple, alpha, TR, T1_guess=1, mask=mask) # Stop timer print('Recon took %g sec' % (time() - t0))
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() res_rcc_simple = robustcc(data, method='simple') res_rcc_simple = np.abs(gs_recon(res_rcc_simple, pc_axis=-1)) print('Took %g seconds to do simple robustcc recon' % (time() - t0)) if include_full_robustcc: t0 = time() res_rcc_full = robustcc(data, method='full', mask=M0 > 0) res_rcc_full = np.abs(gs_recon(res_rcc_full, pc_axis=-1)) print('Took %g seconds to do full robustcc recon' % (time() - t0))
T1, T2 = M0 * 2, M0 / 2 # Simulate bSSFP acquisition with linear off-resonance TR, alpha = 3e-3, np.deg2rad(30) pcs = np.linspace(0, 2 * np.pi, 4, 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, phase_cyc=pcs[None, None, :], M0=M0) # Show the phase-cycled images nx, ny = 2, 2 plt.figure() for ii in range(nx * ny): plt.subplot(nx, ny, ii + 1) plt.imshow(np.abs(sig[..., ii])) plt.title('%d deg PC' % (ii * 90)) plt.show(block=False) # Dhow the recon recon = gs_recon(sig, pc_axis=-1) plt.figure() plt.imshow(np.abs(recon)) plt.title('GS Solution') plt.show()