Esempio n. 1
0
 def test_gre_sim_mat_against_gre_sim_loop(self):
     '''Verify against loop implementation.'''
     T1s, T2s, PD = cylinder_2d(dims=(16, 16))
     dphi = np.pi
     im1 = gre_sim_loop(T1s, T2s, TR=self.TR, TE=self.TE, alpha=self.alpha,
                        field_map=None, dphi=dphi, M0=PD, maxiter=50)
     im2 = gre_sim(T1s, T2s, TR=self.TR, TE=self.TE, alpha=self.alpha,
                   field_map=None, dphi=dphi, M0=PD, maxiter=50)
     self.assertTrue(np.allclose(np.abs(im1), np.abs(im2)))
Esempio n. 2
0
from mr_utils.sim.ssfp import ssfp
from mr_utils.recon.ssfp import gs_recon
from mr_utils import view

if __name__ == '__main__':

    # Get a 2D image, since we can't seem to replicate using a single
    # voxel
    N = 64
    df_noise_std = 0
    radius = .8
    TR = 6e-3
    alpha = np.deg2rad(30)
    npcs = 4
    pcs = np.linspace(0, 2*np.pi, npcs, endpoint=False)
    PD, T1, T2 = cylinder_2d(dims=(N, N), radius=radius)

    df = 1000
    min_df, max_df = -df, df
    fx = np.linspace(min_df, max_df, N)
    fy = np.zeros(N)
    df, _ = np.meshgrid(fx, fy)

    if df_noise_std > 0:
        n = np.random.normal(0, df_noise_std, df.shape)
        df += n

    I = ssfp(T1, T2, TR, alpha, df, pcs, PD, phi_rf=0)


    recon = gs_recon(I, pc_axis=0)
Esempio n. 3
0
    # - Acquire two phase-cycles per slice, per time point during functional
    # - Use synthetic banding to get two more phase-cycles
    # - Compute field map using elliptical signal model
    # - Compare field maps directly to generate BOLD contrast

    # Simulation
    # - Specify T1,T2 maps
    # - Specify alpha,TR
    # - Change field map in areas that receive blood
    # - Simulate 4 phase-cycled acquisitions
    # - Compute field map
    # - Put field map directly into DICOM
    # - Compute t-tests in AFNI

    # Make a circle brain
    PD, T1s, T2s = cylinder_2d(radius=.8)
    field_map = np.zeros(PD.shape)
    brain = bssfp_acq(T1s, T2s, PD, field_map)
    # view(brain)

    # Make HDR
    t = np.linspace(0, 25, time_pts)
    dt = t[1] - t[0]
    hrf_kernel = hrf(t) * hrf_scale

    # Experiment timing design, assume convolve with BLOCK
    task_lens = [20, 20]  # lengths of each task
    reps = 3  # how many repetitions
    times = np.arange(0, np.sum(task_lens) * reps, dt)
    design = np.zeros(times.shape)
Esempio n. 4
0
    TR = 5e-3
    alpha = np.deg2rad(30)
    N = 256
    ncoils = 4
    npcs = 4
    pcs = np.linspace(0, 2 * np.pi, npcs, endpoint=False)
    min_df, max_df = -1 / TR, 1 / TR

    # Tissue parameters
    T1 = 1.200
    T2 = 0.030
    M0 = 1
    PD, T1s, T2s = cylinder_2d(dims=(N, N),
                               radius=.75,
                               params={
                                   'T1': T1,
                                   'T2': T2,
                                   'M0': M0
                               })

    # Use a linear off-resonance
    fx = np.linspace(min_df, max_df, N)
    fy = np.zeros(N)
    df, _ = np.meshgrid(fx, fy)

    # Create true coil sensitivity maps
    csm = generate_birdcage_sensitivities(N, number_of_coils=ncoils)
    phi_rf = np.angle(csm)
    plt.imshow(phi_rf[0, ...])
    plt.title('Coil sensitivity phase (rad)')
    plt.colorbar()
Esempio n. 5
0
    def setUp(self):
        self.T1s, self.T2s, self.PD = cylinder_2d()

        self.alpha = np.pi / 3
        self.TR, self.TE = 12e-3, 6e-3
Esempio n. 6
0
    def test_simulated_phantom_2d(self):

        # Create the target field map
        dim = 64
        min_df, max_df = -500, 500
        fx = np.linspace(min_df, max_df, dim)
        fy = np.zeros(dim)
        field_map, _ = np.meshgrid(fx, fy)
        # field_map = 100*np.random.normal(0,1,(dim,dim))
        # view(field_map)

        # Simulate phase-cycled bSSFP acquisitons
        # Seems to be better with higher flip angle!
        # For some reason worse with higher TR
        args = {
            'TR': 5e-3,
            'alpha': np.pi / 3,
            'dims': (dim, dim),
            'FOV': ((-1, 1), (-1, 1)),
            'radius': .75,
            'field_map': field_map
        }
        pc_vals = [0, np.pi / 2, np.pi, 3 * np.pi / 2]
        pcs = np.zeros((len(pc_vals), dim, dim), dtype='complex')
        for ii, pc in enumerate(pc_vals):
            pcs[ii, ...] = bssfp_2d_cylinder(**args, phase_cyc=pc)
        # view(pcs)

        # Estimate field map using GS to ESM
        gsfm = gs_field_map(
            *[x.squeeze() for x in np.split(pcs, len(pc_vals))],
            TR=args['TR'],
            gs_recon_opts={'second_pass': False})
        # TODO: Interestingly, the second pass solution fails... Why is this?

        # Now do sims for GRE for a sanity check
        TE1 = args['TR'] / 2
        TE2 = TE1 - args['TR'] / 2
        PD, T1s, T2s = cylinder_2d(dims=args['dims'],
                                   FOV=args['FOV'],
                                   radius=args['radius'])
        m1 = gre_sim(T1s,
                     T2s,
                     TR=args['TR'],
                     TE=TE1,
                     alpha=args['alpha'],
                     field_map=args['field_map'],
                     dphi=0,
                     M0=PD,
                     tol=1e-4)
        m2 = gre_sim(T1s,
                     T2s,
                     TR=args['TR'],
                     TE=TE2,
                     alpha=args['alpha'],
                     field_map=args['field_map'],
                     dphi=0,
                     M0=PD,
                     tol=1e-4)
        grefm = dual_echo_gre(m1, m2, TE1, TE2)

        # Phase wrap the real field map so we prove equivalence up to phase
        # unwrapping...
        dTE = np.abs(TE1 - TE2)
        field_map_pw = np.mod(field_map - 1 /
                              (2 * dTE), 1 / dTE) - 1 / (2 * dTE)

        # Make sure we're getting the same thing when wrapped
        idx = np.where(np.abs(grefm) > 0)
        self.assertTrue(np.allclose(grefm[idx], field_map_pw[idx]))

        idx = np.where(np.abs(gsfm) > 0)
        self.assertTrue(np.allclose(gsfm[idx], field_map_pw[idx]))

        # Just for fun, try phase unwrapping...
        mask = np.zeros(gsfm.shape).astype(bool)
        mask[idx] = True

        # scale between [-pi,pi], do unwrap, scale back up
        scale_fac = np.pi / np.max(np.abs(gsfm)) * np.sign(np.max(gsfm))
        val = unwrap_phase(mask * gsfm * scale_fac) / scale_fac

        # For some reason the edges are off by about pi, so let's clip it...
        val = val[:, 19:-19]
        field_map_clipped = field_map[:, 19:-19]
        idx = np.where(np.abs(val) > 0)
        self.assertTrue(np.allclose(field_map_clipped[idx], val[idx]))
Esempio n. 7
0
    for ii, pc in enumerate(pc_vals):
        pcs[ii, ...] = bssfp_2d_cylinder(**args, phase_cyc=pc)
    view(pcs)

    # Estimate field map using GS to ESM
    gsfm = gs_field_map(*[x.squeeze() for x in np.split(
        pcs, len(pc_vals))], \
        TR=args['TR'], gs_recon_opts={'second_pass': False})
    # TODO: Interestingly, the second pass solution fails... Why is this?
    view(gsfm)

    # Now do sims for GRE for a sanity check
    TE1 = args['TR'] / 2
    TE2 = TE1 - args['TR'] / 2
    PD, T1s, T2s = cylinder_2d(dims=args['dims'],
                               FOV=args['FOV'],
                               radius=args['radius'])
    m1 = gre_sim(T1s,
                 T2s,
                 TR=args['TR'],
                 TE=TE1,
                 alpha=args['alpha'],
                 field_map=args['field_map'],
                 dphi=0,
                 M0=PD,
                 tol=1e-4)
    m2 = gre_sim(T1s,
                 T2s,
                 TR=args['TR'],
                 TE=TE2,
                 alpha=args['alpha'],