Ejemplo n.º 1
0
    def test_against_gre(self):
        '''Test implementation against GRE simulation.'''

        TR = 15e-3
        TE = 6e-3
        h = 1e-4
        num_TRs = 100
        Nt = num_TRs * TR / h
        spins0 = bloch.gre(self.T1, self.T2, self.M0, Nt, h, *self.RF, TR, TE)
        spins0 = spins0[0, ...] + 1j * spins0[1, ...]

        spins1 = gre_sim(self.T1,
                         self.T2,
                         TR,
                         TE,
                         alpha=self.RF[1],
                         field_map=None,
                         phi=0,
                         dphi=0,
                         M0=self.M0,
                         maxiter=num_TRs,
                         spoil=True)
        # from mr_utils import view
        # view(np.stack((spins0, spins1)))
        self.assertTrue(np.allclose(spins0, spins1))
Ejemplo n.º 2
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)))
Ejemplo n.º 3
0
    def test_gre_unspoiled_and_bssfp(self):
        '''Very balanced steady state solution.'''
        M0, T1, T2 = 5.0, 1.0, .5
        im1 = gre_sim(T1, T2, TR=self.TR, TE=self.TR/2, alpha=self.alpha,
                      field_map=np.zeros(1), M0=M0, spoil=False, maxiter=200)
        im2 = ssfp(T1, T2, TR=self.TR, alpha=self.alpha, field_map=np.zeros(1),
                   phase_cyc=0, M0=M0)

        # Currently failing...
        self.assertEqual(im1, im2)
Ejemplo n.º 4
0
    def test_against_gre(self):

        TR = 15e-3
        TE = 6e-3
        h = 1e-4
        num_TRs = 100
        Nt = num_TRs*TR/h
        spins0 = bloch.gre(self.T1,self.T2,self.M0,Nt,h,*self.RF,TR,TE)
        spins0 = spins0[0,...] + 1j*spins0[1,...]

        spins1 = gre_sim(self.T1,self.T2,TR,TE,alpha=self.RF[1],field_map=None,phi=0,dphi=0,M0=self.M0,iter=num_TRs,spoil=True)
        view(np.stack((spins0,spins1)))
Ejemplo n.º 5
0
    def test_gre_sim_using_tol_against_closed_form_sol(self):
        '''Verify iterative solution against closed form solution.

        Used tolerance instead of fixed number of iterations.
        '''
        im1 = spoiled_gre(self.T1s, self.T2s, TR=self.TR, TE=self.TE,
                          alpha=self.alpha, M0=self.PD)
        im2 = gre_sim(self.T1s, self.T2s, TR=self.TR, TE=self.TE,
                      alpha=self.alpha, field_map=None, M0=self.PD, tol=1)

        # same within a scale factor...
        val = np.abs(im1) - np.abs(im2)
        self.assertTrue(np.all(np.diff(val[np.nonzero(val)]) == 0))
Ejemplo n.º 6
0
def gre_acq(T1s, T2s, PD, field_map, TR, TE, alpha=np.pi / 2):
    return (gre_sim(T1s,
                    T2s,
                    TR=TR,
                    TE=TE,
                    alpha=alpha,
                    field_map=field_map,
                    phi=0,
                    dphi=0,
                    M0=PD,
                    tol=1e-5,
                    iter=None,
                    spoil=True))
Ejemplo n.º 7
0
def gre_acq(T1s, T2s, PD, field_map, TR, TE, alpha=np.pi / 2):
    '''Wrapper to simulate spoled GRE acquisition.'''
    return gre_sim(T1s,
                   T2s,
                   TR=TR,
                   TE=TE,
                   alpha=alpha,
                   field_map=field_map,
                   phi=0,
                   dphi=0,
                   M0=PD,
                   tol=1e-5,
                   maxiter=None,
                   spoil=True)
Ejemplo n.º 8
0
def spgr_2d_cylinder(TR=0.3,
                     TE=0.003,
                     alpha=np.pi / 3,
                     dims=(64, 64),
                     FOV=((-1, 1), (-1, 1)),
                     radius=.5,
                     field_map=None,
                     kspace=False):
    '''Simulates axial spoiled GRE scan of cylindrical phantom.

    Parameters
    ----------
    TR : float, optional
        Repetition time.
    TE : float, optional
        Echo time.
    alpha : float, optional
        Flip angle (in rad).
    dims : tuple of ints, optional
        Matrix size, (dim_x,dim_y)
    FOV : tuple of tuples, optional
        Field of view in arbitrary units, ( (x_min,x_max), (y_min,y_max) )
    radius : float, optional
        Radius of cylinder in arbitrary units.
    field_map : array_like, optional
        (dim_x,dim_y) field map. If None, linear gradient in x used.
    kspace : bool, optional
        Whether or not to return data in kspace or imspace.

    Returns
    -------
    im : array_like
        Complex simulated image with spoiled GRE contrast.
    '''

    # Get the base cylinder maps
    PD, T1s, T2s = cylinder_2d(dims=dims, FOV=FOV, radius=radius)

    # Do the sim
    # im = spoiled_gre(T1s,T2s,TR,TE,alpha,field_map=field_map,M0=PD)
    im = gre_sim(T1s, T2s, TR, TE, alpha, field_map, M0=PD)

    # Hand back what we asked for
    if kspace:
        return np.fft.fftshift(np.fft.fft2(np.fft.fftshift(im), axes=(0, 1)),
                               axes=(0, 1))
    #else...
    return im
Ejemplo n.º 9
0
    def test_gre_sim_using_tol_against_closed_form_sol(self):
        im1 = spoiled_gre(self.T1s,
                          self.T2s,
                          TR=self.TR,
                          TE=self.TE,
                          alpha=self.alpha,
                          M0=self.PD)
        im2 = gre_sim(self.T1s,
                      self.T2s,
                      TR=self.TR,
                      TE=self.TE,
                      alpha=self.alpha,
                      field_map=None,
                      M0=self.PD,
                      tol=1)

        # same within a scale factor...
        val = np.abs(im1) - np.abs(im2)
        self.assertTrue(np.all(np.diff(val[np.nonzero(val)]) == 0))
Ejemplo n.º 10
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]))
Ejemplo n.º 11
0
        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'],
                 field_map=args['field_map'],
                 dphi=0,
                 M0=PD,
                 tol=1e-4)
    grefm = dual_echo_gre(m1, m2, TE1, TE2)
    view(grefm)