Example #1
0
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))
Example #2
0
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))
Example #3
0
    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()
Example #4
0
    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))
Example #5
0
    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))
Example #6
0
    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()