Пример #1
0
 def xformed_image_method(image, *args, **kwargs):
     print 'inverse transforming'
     util.ifft1(image.cdata, inplace=True, shift=True)
     util.ifft1(image.cacs_data, inplace=True, shift=True)
     fx = meth(image, *args, **kwargs)
     print 'forward transforming'
     util.fft1(image.cdata, inplace=True, shift=True)
     util.fft1(image.cacs_data, inplace=True, shift=True)
     if fx is not None:
         return fx
Пример #2
0
 def xformed_image_method(image, *args, **kwargs):
     print 'inverse transforming'
     util.ifft1(image.cdata, inplace=True, shift=True)
     util.ifft1(image.cacs_data, inplace=True, shift=True)
     fx = meth(image, *args, **kwargs)
     print 'forward transforming'
     util.fft1(image.cdata, inplace=True, shift=True)
     util.fft1(image.cacs_data, inplace=True, shift=True)
     if fx is not None:
         return fx
Пример #3
0
    def run(self, image):
        arrays = (image.data, )
        refs = (image.ref_data, )
        samps = (image.n2_sampling, slice(None))
        if hasattr(image, 'acs_data'):
            arrays += (image.acs_data, )
            refs += (image.acs_ref_data, )
        a, b = grappa_sampling(image.shape[-2], int(image.accel), image.n_acs)
        if len(b):
            init_acs_dir = (-1.0)**(a.tolist().index(b[0]))
        else:
            init_acs_dir = 1
        polarities = (1.0, init_acs_dir)
        nr = image.n_ramp
        nf = image.n_flat
        if image.pslabel == 'ep2d_bold_acs_test' or image.accel > 2:
            acs_xleave = int(image.accel)
        else:
            acs_xleave = 1

        xleaves = (1, int(acs_xleave))
        for arr, n2, ref_arr, r, x in zip(arrays, samps, refs, polarities,
                                          xleaves):
            if arr is None:
                continue
            util.ifft1(arr, inplace=True, shift=True)
            # enforce 4D arrays
            arr.shape = (1, ) * (4 - len(arr.shape)) + arr.shape
            ref_arr.shape = (1, ) * (4 - len(ref_arr.shape)) + ref_arr.shape
            sub_samp_slicing = [slice(None)] * len(arr.shape)
            sub_samp_slicing[-2] = n2
            Q2, Q1 = arr[sub_samp_slicing].shape[-2:]
            q1_ax = np.linspace(-Q1 / 2., Q1 / 2., Q1, endpoint=False)
            q2_pattern = r * np.power(-1.0, np.arange(Q2) / x)
            for v in xrange(arr.shape[0]):
                sub_samp_slicing[0] = v
                for sl in range(arr.shape[1]):
                    sub_samp_slicing[1] = sl
                    m = simple_unbal_phase_ramp(ref_arr[v, sl].copy(),
                                                nr,
                                                nf,
                                                image.pref_polarity,
                                                fov_lim=self.fov_lim,
                                                mask_noise=self.mask_noise)
                    soln_pln = (m * q1_ax[None, :]) * q2_pattern[:, None]
                    phs = np.exp(-1j * soln_pln)
                    arr[sub_samp_slicing] *= phs
            # correct for flat dimensions
            arr.shape = tuple([d for d in arr.shape if d > 1])
            util.fft1(arr, inplace=True, shift=True)
Пример #4
0
 def run(self, image):
     arrays = (image.data,)
     refs = (image.ref_data,)
     samps = (image.n2_sampling, 
              slice(None))
     if hasattr(image, 'acs_data'):
         arrays += (image.acs_data,)
         refs += (image.acs_ref_data,)
     a,b = grappa_sampling(image.shape[-2], int(image.accel), image.n_acs)
     if len(b):
         init_acs_dir = (-1.0) ** (a.tolist().index(b[0]))
     else:
         init_acs_dir = 1
     polarities = (1.0, init_acs_dir)
     nr = image.n_ramp
     nf = image.n_flat
     if image.pslabel == 'ep2d_bold_acs_test' or image.accel > 2:
         acs_xleave = int(image.accel)
     else:
         acs_xleave = 1
     
     xleaves = (1, int(acs_xleave))
     for arr, n2, ref_arr, r, x in zip(arrays, samps, refs, 
                                       polarities, xleaves):
         if arr is None:
             continue
         util.ifft1(arr, inplace=True, shift=True)
         # enforce 4D arrays
         arr.shape = (1,)*(4-len(arr.shape)) + arr.shape
         ref_arr.shape = (1,)*(4-len(ref_arr.shape)) + ref_arr.shape
         sub_samp_slicing = [slice(None)]*len(arr.shape)
         sub_samp_slicing[-2] = n2
         Q2, Q1 = arr[sub_samp_slicing].shape[-2:]
         q1_ax = np.linspace(-Q1/2., Q1/2., Q1, endpoint=False)
         q2_pattern = r*np.power(-1.0, np.arange(Q2)/x)
         for v in xrange(arr.shape[0]):
             sub_samp_slicing[0] = v
             for sl in range(arr.shape[1]):
                 sub_samp_slicing[1] = sl
                 m = simple_unbal_phase_ramp(ref_arr[v,sl].copy(),
                                             nr, nf, image.pref_polarity,
                                             fov_lim=self.fov_lim,
                                             mask_noise=self.mask_noise)
                 soln_pln = (m * q1_ax[None,:]) * q2_pattern[:,None]
                 phs = np.exp(-1j*soln_pln)
                 arr[sub_samp_slicing] *= phs
         # correct for flat dimensions
         arr.shape = tuple([d for d in arr.shape if d > 1])
         util.fft1(arr, inplace=True, shift=True)
Пример #5
0
def upsample(a, m):
    npts = a.shape[0]*m
    b = a.copy()
    # upsampe m times, stick the original ts in the middle of m samples
    a_up = np.zeros((npts,), a.dtype)
    a_up[m/2::m] = a
    util.fft1(a_up, inplace=True, shift=True)
    # LP filter to get sinc interpolation
    lpf = np.zeros((npts,))
    bw = a.shape[0]
    lpf[npts/2-bw/2 : npts/2+bw/2] = 1.
    a_up *= lpf
    util.ifft1(a_up, inplace=True, shift=True)
    a_up *= float(m)
    return a_up
Пример #6
0
def simple_unbal_phase_ramp(rdata,
                            nramp,
                            nflat,
                            pref_polarity,
                            fov_lim=None,
                            mask_noise=True,
                            debug=False):
    N1 = rdata.shape[-1]
    rdata[:, :nramp + 1] = 0.
    rdata[:, nflat + 1:] = 0.
    irdata = util.ifft1(rdata, shift=True)

    if pref_polarity == 1:
        # [(pos - neg), (neg - pos)]
        ref_funcs = irdata[:2] * irdata[1:3].conj()
    else:
        # [(pos - neg), (neg - pos)]
        ref_funcs = irdata[:2].conj() * irdata[1:3]
    ref = ref_funcs[0] * ref_funcs[1].conjugate()
    ref_funcs_phs = np.angle(ref_funcs)
    pos_neg_diff = ref_funcs_phs[0]
    neg_pos_diff = ref_funcs_phs[1]

    ref_peak = np.abs(ref).max()

    # if an FOV limit is requested, then make sure the rest of the algorithm
    # only considers data within the limit
    if fov_lim:
        fov_max, fov = fov_lim
        dx = fov / N1
        x_grid = np.arange(-N1 / 2, N1 / 2) * dx
        fov_q1_mask = np.where(np.abs(x_grid) > fov_max, 0, 1)
    else:
        fov_q1_mask = np.ones((N1, ), 'i')

    ref_peak = np.abs(ref * fov_q1_mask).max()
    if mask_noise:
        thresh = 0.1
        nz_q1_mask = np.where(np.abs(ref) > thresh * ref_peak, 1, 0)
        while nz_q1_mask.sum() < 10:
            thresh *= 0.5
            print 'relaxing threshold to include more points in the fit:', thresh
            nz_q1_mask = np.where(np.abs(ref) > thresh * ref_peak, 1, 0)
    else:
        nz_q1_mask = np.ones((N1, ), 'i')

    ref_phs = (pos_neg_diff - neg_pos_diff)

    q1_mask = nz_q1_mask & fov_q1_mask
    # only do the unwrapping in the method if noisy patches have been rejected
    m = util.find_ramp(ref_phs / 4.,
                       mask=q1_mask,
                       do_unwrap=mask_noise,
                       debug=debug)

    ##     m,b,r = util.lin_regression(ref_phs/4, mask=nz_q1_mask & fov_q1_mask)
    ##     m = m[0]; b = b[0]
    return m
Пример #7
0
    def run(self, image):
        accel = int(image.accel)
        sub_data = image.cdata  # shape (nc, nsl, n2, n1)
        acs = image.cacs_data
        # cheap fix for new shape of potentially multi-acquisition acs
        if len(acs.shape) > 4:
            acs = acs[:, 0, :, :, :]
        # transpose to (nsl, nc, n2, n1)
        acs = acs.transpose(1, 0, 2, 3).copy()
        if self.ft:
            print "transforming readout..."
            util.ifft1(sub_data, inplace=True, shift=True)
            util.ifft1(acs, inplace=True, shift=True)

        n2_sampling = image.pe_sampling[:]
        n2_sampling.sort()

        for s in range(image.n_slice):
            N, e = grappa_coefs(acs[s],
                                accel,
                                self.nblocks,
                                sliding=self.sliding,
                                n1_window=self.n1_window,
                                loud=self.beloud,
                                fixed_window=not self.floating_window)
            # find weightings for each slide reconstruction based on the
            # errors of their fits (slide enumeration in axis=-2)
            w = find_weights(e, axis=-2)
            if self.beloud:
                print e
                print w.sum(axis=-2)
            Ssub = sub_data[:, :, s, :, :]
            Ssub[:] = grappa_synthesize(Ssub,
                                        N,
                                        n2_sampling,
                                        weights=w,
                                        loud=self.beloud,
                                        fixed_window=not self.floating_window)

        if self.ft:
            util.fft1(sub_data, inplace=True, shift=True)
            util.fft1(acs, inplace=True, shift=True)
        # by convention, set view to channel 0
        image.use_membuffer(0)
Пример #8
0
def simple_unbal_phase_ramp(rdata, nramp, nflat, pref_polarity, 
                            fov_lim=None, mask_noise=True,
                            debug=False):
    N1 = rdata.shape[-1]
    rdata[:,:nramp+1] = 0.
    rdata[:,nflat+1:] = 0.
    irdata = util.ifft1(rdata, shift=True)

    if pref_polarity==1:
        # [(pos - neg), (neg - pos)]
        ref_funcs = irdata[:2] * irdata[1:3].conj()
    else:
        # [(pos - neg), (neg - pos)]        
        ref_funcs = irdata[:2].conj()*irdata[1:3]
    ref = ref_funcs[0]*ref_funcs[1].conjugate()
    ref_funcs_phs = np.angle(ref_funcs)
    pos_neg_diff = ref_funcs_phs[0]
    neg_pos_diff = ref_funcs_phs[1]
    
    ref_peak = np.abs(ref).max()

    # if an FOV limit is requested, then make sure the rest of the algorithm
    # only considers data within the limit
    if fov_lim:
        fov_max, fov = fov_lim
        dx = fov/N1
        x_grid = np.arange(-N1/2, N1/2) * dx
        fov_q1_mask = np.where(np.abs(x_grid)>fov_max,0,1)
    else:
        fov_q1_mask = np.ones((N1,), 'i')

    ref_peak = np.abs(ref*fov_q1_mask).max()
    if mask_noise:
        thresh = 0.1
        nz_q1_mask = np.where(np.abs(ref) > thresh*ref_peak, 1, 0)
        while nz_q1_mask.sum() < 10:
            thresh *= 0.5
            print 'relaxing threshold to include more points in the fit:', thresh
            nz_q1_mask = np.where(np.abs(ref) > thresh*ref_peak, 1, 0)
    else:
        nz_q1_mask = np.ones((N1,), 'i')

    ref_phs = (pos_neg_diff-neg_pos_diff)

    q1_mask = nz_q1_mask & fov_q1_mask
    # only do the unwrapping in the method if noisy patches have been rejected
    m = util.find_ramp(ref_phs/4., mask=q1_mask, do_unwrap=mask_noise,
                       debug=debug)
    
##     m,b,r = util.lin_regression(ref_phs/4, mask=nz_q1_mask & fov_q1_mask)
##     m = m[0]; b = b[0]
    return m
Пример #9
0
    def run(self, image):
        accel = int(image.accel)
        sub_data = image.cdata # shape (nc, nsl, n2, n1)
        acs = image.cacs_data
        # cheap fix for new shape of potentially multi-acquisition acs
        if len(acs.shape) > 4:
            acs = acs[:,0,:,:,:]
        # transpose to (nsl, nc, n2, n1)
        acs = acs.transpose(1, 0, 2, 3).copy()
        if self.ft:
            print "transforming readout..."
            util.ifft1(sub_data, inplace=True, shift=True)
            util.ifft1(acs, inplace=True, shift=True)

        n2_sampling = image.pe_sampling[:]
        n2_sampling.sort()

        for s in range(image.n_slice):
            N, e = grappa_coefs(acs[s], accel, self.nblocks,
                                sliding=self.sliding,
                                n1_window=self.n1_window,
                                loud=self.beloud,
                                fixed_window=not self.floating_window)
            # find weightings for each slide reconstruction based on the
            # errors of their fits (slide enumeration in axis=-2)
            w = find_weights(e, axis=-2)
            if self.beloud:
                print e
                print w.sum(axis=-2)
            Ssub = sub_data[:,:,s,:,:]
            Ssub[:] = grappa_synthesize(Ssub, N, n2_sampling,
                                        weights=w, loud=self.beloud,
                                        fixed_window=not self.floating_window)

        if self.ft:
            util.fft1(sub_data, inplace=True, shift=True)
            util.fft1(acs, inplace=True, shift=True)
        # by convention, set view to channel 0 
        image.use_membuffer(0)
Пример #10
0
def ksp_calib_hybrid_synth(image, Ny_blk, Nx_blk, sl=-1):
    R = int(image.accel)
    Nc = image.n_chan
    Nacs = int(image.n_acs)
    Nx = image.N1
    Nv = image.n_vol
    Nfy = Nacs - (Ny_blk - 1) * R
    Nfx = Nx - (Nx_blk - 1)
    x_start = Nx_blk / 2  # lower inclusive limit for x target points
    x_end = x_start + Nfx - 1  # upper limit, inclusive, for x target points
    Npe = image.n_pe
    acs = image.cacs_data
    acs.shape = tuple([d for d in acs.shape if d > 1])
    cdata = image.cdata

    # set up 2D neighborhood offsets
    xblk_offsets = np.arange(-(Nx_blk / 2), -(Nx_blk / 2) + Nx_blk)
    yblk_offsets = np.arange(-((Ny_blk - 1) / 2), -(
        (Ny_blk - 1) / 2) + Ny_blk) * R - 1

    # fitting stage
    Ssrc = np.empty((Nfy * Nfx, Nc * Ny_blk * Nx_blk), 'F')
    Stgt = np.empty((Nfy * Nfx, (R - 1) * Nc), 'F')
    tgt_row0 = R * ((Ny_blk - 1) / 2) + 1
    tgt_rows = np.arange(tgt_row0, tgt_row0 + Nfy)

    # transpose this array, since we will be indexing over x
    Wpad = np.zeros((Nx, Nc, Ny_blk, (R - 1) * Nc), 'F')
    Wpad_slice = [slice(None)] * len(Wpad.shape)
    kx0 = Nx / 2 + xblk_offsets[0]
    kx1 = Nx / 2 + xblk_offsets[-1] + 1
    Wpad_slice[0] = slice(kx0, kx1)
    Wpad_slice = tuple(Wpad_slice)

    # synthesis stage
    pe_sampling = image.pe_sampling[:]
    pe_sampling.sort()
    acq_row0 = pe_sampling[0]  # == 1
    acq_rowf = pe_sampling[-1] + 1  # == last-sampled + 1
    syn_rows = np.arange(tgt_row0 + 1, acq_rowf, R)
    Nu = len(syn_rows)
    # make Sacq with full readout points, and assume circularity in kx direction
    Sacq = np.empty((Nu * Nx * Nv, Nc * Ny_blk), 'F')
    Ssyn = np.empty((Nx, Nv * Nu, Nc * (R - 1)), 'F')

    sl_range = sl >= 0 and [sl] or xrange(image.n_slice)

    W_list = []
    for s in sl_range:
        Dy_idx = tgt_rows[:, None] + yblk_offsets
        Stgt.shape = (Nfy, Nfx, (R - 1), Nc)
        print 'filling Stgt'
        inline(Stgt_fill, [
            'R', 'tgt_rows', 'Nfy', 'Nc', 'acs', 'Stgt', 'x_start', 'x_end',
            's'
        ],
               type_converters=blitz)
        Stgt.shape = (Nfy * Nfx, (R - 1) * Nc)

        Ssrc.shape = (Nfy, Nfx, Nc, Ny_blk, Nx_blk)
        print 'filling Ssrc'
        inline(Ssrc_fill, [
            'Nc', 'Nfy', 'Nfx', 'Ny_blk', 'Nx_blk', 'Dy_idx', 'x_start',
            'xblk_offsets', 'Ssrc', 'acs', 's'
        ],
               type_converters=blitz)
        Ssrc.shape = (Nfy * Nfx, Nc * Ny_blk * Nx_blk)
        W = np.linalg.lstsq(Ssrc, Stgt)[0]
        W.shape = (Nc, Ny_blk, Nx_blk, (R - 1) * Nc)
        W_list.append(W)

    util.ifft1(cdata, inplace=True, axis=-1)
    cdata *= Nx
    for W, s in zip(W_list, sl_range):
        # W indexes in rows as (chan, yn_idx, xn_idx)
        # W indexes in cols as (m, chan)
        Wpad[Wpad_slice] = W.transpose(2, 0, 1, 3)
        Wx = util.ifft1(Wpad, shift=True, inplace=False, axis=0)
        # Now each W(x) index in rows as (chan, yn_idx)
        # Now each W(x) index in cols as (m, chan)
        Wx.shape = (Nx, Nc * Ny_blk, (R - 1) * Nc)
        Wx *= Nx
        # want to repeatedly perform the linear combination of (Nc*Ny_blk)
        # points at all combinations of (Nu, Nx)
        # (Nu(x), Nc*Ny_blk) * W(x)
        Dy_idx = syn_rows[:, None] + yblk_offsets
        Sacq.shape = (Nx, Nv, Nu, Nc, Ny_blk)
        print 'filling acquisition rows, offsets', yblk_offsets
        inline(
            Sacq_fill,
            ['Nu', 'Nx', 'Nv', 'Nc', 'Ny_blk', 'Dy_idx', 'Sacq', 'cdata', 's'],
            type_converters=blitz)
        Sacq.shape = (Nx, Nv * Nu, Nc * Ny_blk)
        print 'synthesizing rows', syn_rows
        for xsyn, xacq, w in zip(Ssyn, Sacq, Wx):
            xsyn[:] = np.dot(xacq, w)
        Ssyn.shape = (Nx, Nv, Nu, R - 1, Nc)
        print 'filling synth rows'
        inline(Ssyn_fill,
               ['Nc', 'Nv', 'Nu', 'syn_rows', 'R', 'cdata', 'Ssyn', 's'],
               type_converters=blitz)
    util.fft1(cdata, inplace=True, axis=-1)
Пример #11
0
def ksp_calib_hybrid_synth(image, Ny_blk, Nx_blk, sl=-1):
    R = int(image.accel)
    Nc = image.n_chan
    Nacs = int(image.n_acs)
    Nx = image.N1
    Nv = image.n_vol
    Nfy = Nacs - (Ny_blk-1)*R
    Nfx = Nx - (Nx_blk-1)
    x_start = Nx_blk/2 # lower inclusive limit for x target points
    x_end = x_start + Nfx - 1 # upper limit, inclusive, for x target points
    Npe = image.n_pe
    acs = image.cacs_data
    acs.shape = tuple([d for d in acs.shape if d > 1])
    cdata = image.cdata

    # set up 2D neighborhood offsets
    xblk_offsets = np.arange(-(Nx_blk/2), -(Nx_blk/2)+Nx_blk)
    yblk_offsets = np.arange(-((Ny_blk-1)/2), -((Ny_blk-1)/2)+Ny_blk)*R - 1

    # fitting stage
    Ssrc = np.empty((Nfy*Nfx, Nc*Ny_blk*Nx_blk), 'F')
    Stgt = np.empty((Nfy*Nfx, (R-1)*Nc), 'F')
    tgt_row0 = R * ((Ny_blk-1)/2) + 1
    tgt_rows = np.arange(tgt_row0, tgt_row0 + Nfy)

    # transpose this array, since we will be indexing over x
    Wpad = np.zeros((Nx, Nc, Ny_blk, (R-1)*Nc), 'F')
    Wpad_slice = [slice(None)] * len(Wpad.shape)
    kx0 = Nx/2 + xblk_offsets[0]
    kx1 = Nx/2 + xblk_offsets[-1] + 1
    Wpad_slice[0] = slice(kx0, kx1)
    Wpad_slice = tuple(Wpad_slice)
                    
    # synthesis stage
    pe_sampling = image.pe_sampling[:]
    pe_sampling.sort()
    acq_row0 = pe_sampling[0] # == 1
    acq_rowf = pe_sampling[-1]+1  # == last-sampled + 1
    syn_rows = np.arange(tgt_row0+1, acq_rowf, R)
    Nu = len(syn_rows)
    # make Sacq with full readout points, and assume circularity in kx direction
    Sacq = np.empty((Nu*Nx*Nv, Nc*Ny_blk), 'F')
    Ssyn = np.empty((Nx, Nv*Nu, Nc*(R-1)), 'F')

    sl_range = sl>=0 and [sl] or xrange(image.n_slice)
    
    W_list = []
    for s in sl_range:
        Dy_idx = tgt_rows[:,None] + yblk_offsets
        Stgt.shape = (Nfy, Nfx, (R-1), Nc)
        print 'filling Stgt'
        inline(Stgt_fill, ['R', 'tgt_rows', 'Nfy', 'Nc', 'acs',
                           'Stgt', 'x_start', 'x_end', 's'],
               type_converters=blitz)
        Stgt.shape = (Nfy*Nfx, (R-1)*Nc)

        Ssrc.shape = (Nfy, Nfx, Nc, Ny_blk, Nx_blk)
        print 'filling Ssrc'
        inline(Ssrc_fill, ['Nc', 'Nfy', 'Nfx', 'Ny_blk', 'Nx_blk', 'Dy_idx',
                           'x_start', 'xblk_offsets', 'Ssrc', 'acs', 's'],
               type_converters=blitz)
        Ssrc.shape = (Nfy*Nfx, Nc*Ny_blk*Nx_blk)
        W = np.linalg.lstsq(Ssrc, Stgt)[0]
        W.shape = (Nc, Ny_blk, Nx_blk, (R-1)*Nc)
        W_list.append(W)

    util.ifft1(cdata, inplace=True, axis=-1)
    cdata *= Nx
    for W, s in zip(W_list, sl_range):
        # W indexes in rows as (chan, yn_idx, xn_idx)
        # W indexes in cols as (m, chan)
        Wpad[Wpad_slice] = W.transpose(2, 0, 1, 3)
        Wx = util.ifft1(Wpad, shift=True, inplace=False, axis=0)
        # Now each W(x) index in rows as (chan, yn_idx)
        # Now each W(x) index in cols as (m, chan)
        Wx.shape = (Nx, Nc*Ny_blk, (R-1)*Nc)
        Wx *= Nx
        # want to repeatedly perform the linear combination of (Nc*Ny_blk)
        # points at all combinations of (Nu, Nx)
        # (Nu(x), Nc*Ny_blk) * W(x)
        Dy_idx = syn_rows[:,None] + yblk_offsets
        Sacq.shape = (Nx, Nv, Nu, Nc, Ny_blk)
        print 'filling acquisition rows, offsets', yblk_offsets
        inline(Sacq_fill, ['Nu', 'Nx', 'Nv', 'Nc', 'Ny_blk',
                           'Dy_idx', 'Sacq', 'cdata', 's'],
               type_converters=blitz)
        Sacq.shape = (Nx, Nv*Nu, Nc*Ny_blk)
        print 'synthesizing rows', syn_rows
        for xsyn, xacq, w in zip(Ssyn, Sacq, Wx):
            xsyn[:] = np.dot(xacq, w)
        Ssyn.shape = (Nx, Nv, Nu, R-1, Nc)
        print 'filling synth rows'
        inline(Ssyn_fill, ['Nc','Nv','Nu','syn_rows','R',
                           'cdata','Ssyn','s'],
               type_converters=blitz)
    util.fft1(cdata, inplace=True, axis=-1)