Beispiel #1
0
    def __init__(self, image=None):
        if image is None:
            image = ReconImage(np.ones((4,4,4)), 1, 1, 1, 1)
        if not isinstance(image, ReconImage):
            image = ReconImage(np.asarray(image), 1, 1, 1, 1)
        for (attr, val) in image.__dict__.items():
            self.__dict__[attr] = val

        # get vox origin from zyx origin (can't use transform because
        # (these zyx are in the image's native space)
        self.r0 = np.array([self.z0, self.y0, self.x0])
        self.dr = np.array([self.ksize, self.jsize, self.isize])
        # orientation xform maps vx-space:xyz-space (Right,Anterior,Superior)
        # numpy arrays are in C-ordering (zyx), so I'm going to reverse the
        # rows and columns of the xform to be in zyx order
        M = self.orientation_xform.tomatrix()
        self.xform = reverse(reverse(M, axis=-1), axis=-2)
        self.pxform = nearest_simple_transform(M)
        self.pxform = reverse(reverse(self.pxform,axis=-1),axis=-2)
        if not np.allclose(self.xform, self.pxform):
            print 'OBLIQUE IMAGE: NEED TO PLOT IN ROTATED "VOXEL" SPACE'
            sl0_vox_center = np.array([0, self.jdim/2, self.idim/2])
            sl0_center = np.dot(self.xform*self.dr, sl0_vox_center) + self.r0
            # reset this r0 to correspond to the rotated voxel box
            self.r0 = sl0_center - np.dot(self.pxform*self.dr, sl0_vox_center)
            # reset the xform to be the planar xform
            self.xform = self.pxform
            print self.r0
        # These variables describe which dimension a given standard slicing
        # (axial, sagittal, coronal) slices in the data array
        self.ax, self.cor, self.sag = abs(np.dot(self.pxform, np.arange(3)).astype(np.int32)).tolist()            
        self.prefilter = None
        self.vox_coords = self.zyx2vox([0,0,0])
Beispiel #2
0
 def data_xform(self, slice_idx, zyx_coords):
     """Given the a sliceplots slicing index and the current vox position,
     get a slice of data.
     """
     slicer = [slice(0,d) for d in self.shape]
     slicer[slice_idx] = self.zyx2vox(zyx_coords)[slice_idx]
     slicer = tuple(slicer)
     Msub = self.plane_xform(slice_idx)
     Msub = reverse(reverse(Msub, axis=-1), axis=-2)
     xform = compose_xform(Msub)
     return xform(self[slicer])
Beispiel #3
0
def circularize(a):
    To = a.shape[-1]
    T = 3 * To - 2 + To % 2
    buf_dtype = np.dtype(a.dtype.char.upper())
    ts_buf = np.empty(a.shape[:-1] + (T, ), buf_dtype)
    ##     point-sharing, no negation or shift
    ##     if a = [2, 3, 4, 5, 6], then ts_buf will be:
    ##     [6, 5, 4, 3, (2, 3, 4, 5, 6,) 5, 4, 3, 2, ((2))]
    ts_buf[..., To - 1:2 * To - 1] = a
    # imaginary part of ts is odd.. ts[-t] = -ts[t]
    ts_buf[..., :To - 1] = np.conj(reverse(a[..., 1:]))
    #ts_buf[...,:To-1] = reverse(a[...,1:])
    ts_buf[..., 2 * To - 1:3 * To - 2] = reverse(a[..., :To - 1])
    if To % 2: ts_buf[..., -1] = ts_buf[..., -2]
    return ts_buf
Beispiel #4
0
def subsampInterp_regular(ts, c, axis=-1):
    """Makes a subsample sinc interpolation on an N-D array in a given axis.

    This uses sinc interpolation to return ts(t-a), where a is related to
    the factor c as described below.

    ts : the N-D array with a time series in "axis"
    c : the fraction of the sampling interval such that a = c*dt -- note that
      c is only useful in the interval (0, 1]
    axis : specifies the axis of the time dimension
    """
    To = ts.shape[axis]

    # put time series in the last dimension
    if axis != -1:
        ts = np.swapaxes(ts, axis, -1)
    ##     ts_buf = circularize(ts)
    ts_buf = ts.copy()
    T = ts_buf.shape[-1]
    Fn = T / 2 + 1
    # make sure the interpolating filter's dtype is complex!
    filter_dtype = np.dtype(ts.dtype.char.upper())
    phs_shift = np.empty((T,), filter_dtype)
    phs_shift[:Fn] = np.exp(-2.0j * np.pi * c * np.arange(Fn) / float(T))
    phs_shift[Fn:] = np.conjugate(reverse(phs_shift[1 : T - (Fn - 1)]))
    fft(ts_buf, shift=False, inplace=True)
    np.multiply(ts_buf, phs_shift, ts_buf)
    ifft(ts_buf, shift=False, inplace=True)

    ##     ts[:] = ts_buf[...,To-1:2*To-1]
    ts[:] = ts_buf[:]
    del ts_buf
    if axis != -1:
        ts = np.swapaxes(ts, axis, -1)
Beispiel #5
0
def circularize(a):
    To = a.shape[-1]
    T = 3 * To - 2 + To % 2
    buf_dtype = np.dtype(a.dtype.char.upper())
    ts_buf = np.empty(a.shape[:-1] + (T,), buf_dtype)
    ##     point-sharing, no negation or shift
    ##     if a = [2, 3, 4, 5, 6], then ts_buf will be:
    ##     [6, 5, 4, 3, (2, 3, 4, 5, 6,) 5, 4, 3, 2, ((2))]
    ts_buf[..., To - 1 : 2 * To - 1] = a
    # imaginary part of ts is odd.. ts[-t] = -ts[t]
    ts_buf[..., : To - 1] = np.conj(reverse(a[..., 1:]))
    # ts_buf[...,:To-1] = reverse(a[...,1:])
    ts_buf[..., 2 * To - 1 : 3 * To - 2] = reverse(a[..., : To - 1])
    if To % 2:
        ts_buf[..., -1] = ts_buf[..., -2]
    return ts_buf
Beispiel #6
0
def subsampInterp_regular(ts, c, axis=-1):
    """Makes a subsample sinc interpolation on an N-D array in a given axis.

    This uses sinc interpolation to return ts(t-a), where a is related to
    the factor c as described below.

    ts : the N-D array with a time series in "axis"
    c : the fraction of the sampling interval such that a = c*dt -- note that
      c is only useful in the interval (0, 1]
    axis : specifies the axis of the time dimension
    """
    To = ts.shape[axis]

    # put time series in the last dimension
    if axis != -1:
        ts = np.swapaxes(ts, axis, -1)


##     ts_buf = circularize(ts)
    ts_buf = ts.copy()
    T = ts_buf.shape[-1]
    Fn = T / 2 + 1
    # make sure the interpolating filter's dtype is complex!
    filter_dtype = np.dtype(ts.dtype.char.upper())
    phs_shift = np.empty((T, ), filter_dtype)
    phs_shift[:Fn] = np.exp(-2.j * np.pi * c * np.arange(Fn) / float(T))
    phs_shift[Fn:] = np.conjugate(reverse(phs_shift[1:T - (Fn - 1)]))
    fft(ts_buf, shift=False, inplace=True)
    np.multiply(ts_buf, phs_shift, ts_buf)
    ifft(ts_buf, shift=False, inplace=True)

    ##     ts[:] = ts_buf[...,To-1:2*To-1]
    ts[:] = ts_buf[:]
    del ts_buf
    if axis != -1:
        ts = np.swapaxes(ts, axis, -1)
Beispiel #7
0
def subsampInterp(ts, c, axis=-1):
    """Makes a subsample sinc interpolation on an N-D array in a given axis.

    This uses sinc interpolation to return ts(t-a), where a is related to
    the factor c as described below.

    ts : the N-D array with a time series in "axis"
    c : the fraction of the sampling interval such that a = c*dt -- note that
      c is only useful in the interval (0, 1]
    axis : specifies the axis of the time dimension
    """
    To = ts.shape[axis]

    # find ramps and subtract them
    ramps = np.empty_like(ts)
    rax_shape = [1] * len(ts.shape)
    rax_shape[axis] = To
    rax = np.arange(To)
    rax.shape = rax_shape
    (mre, b, r) = lin_regression(ts.real, axis=axis)
    ramps.real[:] = rax * mre
    if ts.dtype.type in np.sctypes["complex"]:
        (mim, b, r) = lin_regression(ts.imag, axis=axis)
        ramps.imag[:] = rax * mim
    np.subtract(ts, ramps, ts)
    # find biases and subtract them
    ts_mean = ts.mean(axis=axis)
    if len(ts_mean.shape):
        mean_shape = list(ts.shape)
        mean_shape[axis] = 1
        ts_mean.shape = tuple(mean_shape)
    np.subtract(ts, ts_mean, ts)

    # put time series in the last dimension
    if axis != -1:
        ts = np.swapaxes(ts, axis, -1)
    ts_buf = circularize(ts)
    ##     ts_buf = ts.copy()
    T = ts_buf.shape[-1]
    Fn = T / 2 + 1
    # make sure the interpolating filter's dtype is complex!
    filter_dtype = np.dtype(ts.dtype.char.upper())
    phs_shift = np.empty((T,), filter_dtype)
    phs_shift[:Fn] = np.exp(-2.0j * np.pi * c * np.arange(Fn) / float(T))
    phs_shift[Fn:] = np.conjugate(reverse(phs_shift[1 : T - (Fn - 1)]))
    fft(ts_buf, shift=False, inplace=True)
    np.multiply(ts_buf, phs_shift, ts_buf)
    ifft(ts_buf, shift=False, inplace=True)

    ts[:] = ts_buf[..., To - 1 : 2 * To - 1]
    ##     ts[:] = ts_buf[:]
    del ts_buf
    if axis != -1:
        ts = np.swapaxes(ts, axis, -1)

    # add back biases and analytically interpolated ramps
    np.subtract(rax, c, rax)
    # np.add(rax, c, rax)
    ramps.real[:] = rax * mre
    if ts.dtype.type in np.sctypes["complex"]:
        ramps.imag[:] = rax * mim
    np.add(ts, ramps, ts)
    np.add(ts, ts_mean, ts)
Beispiel #8
0
def subsampInterp(ts, c, axis=-1):
    """Makes a subsample sinc interpolation on an N-D array in a given axis.

    This uses sinc interpolation to return ts(t-a), where a is related to
    the factor c as described below.

    ts : the N-D array with a time series in "axis"
    c : the fraction of the sampling interval such that a = c*dt -- note that
      c is only useful in the interval (0, 1]
    axis : specifies the axis of the time dimension
    """
    To = ts.shape[axis]

    # find ramps and subtract them
    ramps = np.empty_like(ts)
    rax_shape = [1] * len(ts.shape)
    rax_shape[axis] = To
    rax = np.arange(To)
    rax.shape = rax_shape
    (mre, b, r) = lin_regression(ts.real, axis=axis)
    ramps.real[:] = rax * mre
    if ts.dtype.type in np.sctypes['complex']:
        (mim, b, r) = lin_regression(ts.imag, axis=axis)
        ramps.imag[:] = (rax * mim)
    np.subtract(ts, ramps, ts)
    # find biases and subtract them
    ts_mean = ts.mean(axis=axis)
    if len(ts_mean.shape):
        mean_shape = list(ts.shape)
        mean_shape[axis] = 1
        ts_mean.shape = tuple(mean_shape)
    np.subtract(ts, ts_mean, ts)

    # put time series in the last dimension
    if axis != -1:
        ts = np.swapaxes(ts, axis, -1)
    ts_buf = circularize(ts)
    ##     ts_buf = ts.copy()
    T = ts_buf.shape[-1]
    Fn = T / 2 + 1
    # make sure the interpolating filter's dtype is complex!
    filter_dtype = np.dtype(ts.dtype.char.upper())
    phs_shift = np.empty((T, ), filter_dtype)
    phs_shift[:Fn] = np.exp(-2.j * np.pi * c * np.arange(Fn) / float(T))
    phs_shift[Fn:] = np.conjugate(reverse(phs_shift[1:T - (Fn - 1)]))
    fft(ts_buf, shift=False, inplace=True)
    np.multiply(ts_buf, phs_shift, ts_buf)
    ifft(ts_buf, shift=False, inplace=True)

    ts[:] = ts_buf[..., To - 1:2 * To - 1]
    ##     ts[:] = ts_buf[:]
    del ts_buf
    if axis != -1:
        ts = np.swapaxes(ts, axis, -1)

    # add back biases and analytically interpolated ramps
    np.subtract(rax, c, rax)
    #np.add(rax, c, rax)
    ramps.real[:] = rax * mre
    if ts.dtype.type in np.sctypes['complex']:
        ramps.imag[:] = rax * mim
    np.add(ts, ramps, ts)
    np.add(ts, ts_mean, ts)
Beispiel #9
0
    def run(self, image):

        if not verify_scanner_image(self, image):
            return -1

        if not hasattr(image, "ref_data") or image.ref_data.shape[0] < 2:
            self.log("Not enough reference volumes, quitting.")
            return -1

        self.volShape = image.shape[-3:]
        inv_ref0 = ifft(image.ref_data[0])
        inv_ref1 = ifft(reverse(image.ref_data[1], axis=-1))

        inv_ref = inv_ref0 * N.conjugate(inv_ref1)

        n_slice, n_pe, n_fe = self.refShape = inv_ref0.shape

        #phs_vol comes back shaped (n_slice, n_pe, lin2-lin1)
        phs_vol = unwrap_ref_volume(inv_ref)

        q1_mask = N.zeros((n_slice, n_pe, n_fe))

        # get slice positions (in order) so we can throw out the ones
        # too close to the backplane of the headcoil (or not ???)
        if self.backplane_adj:
            s_idx = tag_backplane_slices(image)
        else:
            s_idx = range(n_slice)
        q1_mask[s_idx] = 1.0
        q1_mask[s_idx, 0::2, :] = qual_map_mask(phs_vol[s_idx, 0::2, :],
                                                self.percentile)
        q1_mask[s_idx, 1::2, :] = qual_map_mask(phs_vol[s_idx, 1::2, :],
                                                self.percentile)
        theta = N.empty(self.refShape, N.float64)
        s_line = N.arange(n_slice)
        r_line = N.arange(n_fe) - n_fe / 2

        B1, B2, B3 = range(3)

        # planar solution
        nrows = n_slice * n_fe
        M = N.zeros((nrows, 3), N.float64)
        M[:, B1] = N.outer(N.ones(n_slice), r_line).flatten()
        M[:, B2] = N.repeat(s_line, n_fe)
        M[:, B3] = 1.

        A = N.empty((n_slice, 3), N.float64)
        B = N.empty((3, n_fe), N.float64)
        A[:, 0] = 1.
        A[:, 1] = s_line
        A[:, 2] = 1.
        if not self.fitmeans:
            for m in range(n_pe):
                P = N.reshape(0.5 * phs_vol[:, m, :], (nrows, ))
                pt_mask = N.reshape(q1_mask[:, m, :], (nrows, ))
                nz = pt_mask.nonzero()[0]
                Msub = M[nz]
                P = P[nz]
                [u, sv, vt] = N.linalg.svd(Msub, full_matrices=0)
                coefs = N.dot(vt.transpose(),
                              N.dot(N.diag(1 / sv), N.dot(u.transpose(), P)))

                B[0, :] = coefs[B1] * r_line
                B[1, :] = coefs[B2]
                B[2, :] = coefs[B3]
                theta[:, m, :] = N.dot(A, B)
        else:
            for rows in ('evn', 'odd'):
                if rows is 'evn':
                    slicing = (slice(None), slice(0, n_pe, 2), slice(None))
                else:
                    slicing = (slice(None), slice(1, n_pe, 2), slice(None))
                P = N.reshape(0.5 * phs_vol[slicing].mean(axis=-2), (nrows, ))
                pt_mask = q1_mask[slicing].prod(axis=-2)
                pt_mask.shape = (nrows, )
                nz = pt_mask.nonzero()[0]
                Msub = M[nz]
                P = P[nz]
                [u, sv, vt] = N.linalg.svd(Msub, full_matrices=0)
                coefs = N.dot(vt.transpose(),
                              N.dot(N.diag(1 / sv), N.dot(u.transpose(), P)))
                B[0, :] = coefs[B1] * r_line
                B[1, :] = coefs[B2]
                B[2, :] = coefs[B3]
                theta[slicing] = N.dot(A, B)[:, None, :]

        phase = N.exp(-1.j * theta).astype(image[:].dtype)
        from recon.tools import Recon
        if Recon._FAST_ARRAY:
            apply_phase_correction(image[:], phase)
        else:
            for dvol in image:
                apply_phase_correction(dvol[:], phase)
    def run(self, image):
        
        if not verify_scanner_image(self, image):
            return -1
        
        if not hasattr(image, "ref_data") or image.ref_data.shape[0] < 2:
            self.log("Not enough reference volumes, quitting.")
            return -1

        self.volShape = image.shape[-3:]
        inv_ref0 = ifft(image.ref_data[0])
        inv_ref1 = ifft(reverse(image.ref_data[1], axis=-1))

        inv_ref = inv_ref0*N.conjugate(inv_ref1)
        
        n_slice, n_pe, n_fe = self.refShape = inv_ref0.shape

        #phs_vol comes back shaped (n_slice, n_pe, lin2-lin1)
        phs_vol = unwrap_ref_volume(inv_ref)
        
        q1_mask = N.zeros((n_slice, n_pe, n_fe))

        # get slice positions (in order) so we can throw out the ones
        # too close to the backplane of the headcoil (or not ???)
        if self.backplane_adj:
            s_idx = tag_backplane_slices(image)
        else:
            s_idx = range(n_slice)
        q1_mask[s_idx] = 1.0
        q1_mask[s_idx,0::2,:] =  qual_map_mask(phs_vol[s_idx,0::2,:],
                                              self.percentile)
        q1_mask[s_idx,1::2,:] = qual_map_mask(phs_vol[s_idx,1::2,:],
                                              self.percentile)
        theta = N.empty(self.refShape, N.float64)
        s_line = N.arange(n_slice)
        r_line = N.arange(n_fe) - n_fe/2

        B1, B2, B3 = range(3)

        # planar solution
        nrows = n_slice * n_fe
        M = N.zeros((nrows, 3), N.float64)
        M[:,B1] = N.outer(N.ones(n_slice), r_line).flatten()
        M[:,B2] = N.repeat(s_line, n_fe)
        M[:,B3] = 1.
        
        A = N.empty((n_slice, 3), N.float64)
        B = N.empty((3, n_fe), N.float64)
        A[:,0] = 1.
        A[:,1] = s_line
        A[:,2] = 1.
        if not self.fitmeans:
            for m in range(n_pe):
                P = N.reshape(0.5*phs_vol[:,m,:], (nrows,))
                pt_mask = N.reshape(q1_mask[:,m,:], (nrows,))
                nz = pt_mask.nonzero()[0]
                Msub = M[nz]
                P = P[nz]
                [u,sv,vt] = N.linalg.svd(Msub, full_matrices=0)
                coefs = N.dot(vt.transpose(),
                              N.dot(N.diag(1/sv), N.dot(u.transpose(), P)))
                
                B[0,:] = coefs[B1]*r_line
                B[1,:] = coefs[B2]
                B[2,:] = coefs[B3]
                theta[:,m,:] = N.dot(A,B)
        else:
            for rows in ( 'evn', 'odd' ):
                if rows is 'evn':
                    slicing = ( slice(None), slice(0, n_pe, 2), slice(None) )
                else:
                    slicing = ( slice(None), slice(1, n_pe, 2), slice(None) )
                P = N.reshape(0.5*phs_vol[slicing].mean(axis=-2), (nrows,))
                pt_mask = q1_mask[slicing].prod(axis=-2)
                pt_mask.shape = (nrows,)
                nz = pt_mask.nonzero()[0]
                Msub = M[nz]
                P = P[nz]
                [u,sv,vt] = N.linalg.svd(Msub, full_matrices=0)
                coefs = N.dot(vt.transpose(),
                              N.dot(N.diag(1/sv), N.dot(u.transpose(), P)))
                B[0,:] = coefs[B1]*r_line
                B[1,:] = coefs[B2]
                B[2,:] = coefs[B3]
                theta[slicing] = N.dot(A,B)[:,None,:]

            
        phase = N.exp(-1.j*theta).astype(image[:].dtype)
        from recon.tools import Recon
        if Recon._FAST_ARRAY:
            apply_phase_correction(image[:], phase)
        else:
            for dvol in image:
                apply_phase_correction(dvol[:], phase)