Пример #1
0
def cut_patch(projection,
              ang,
              pick_position,
              vol_size=200,
              binning=8,
              dimz=None,
              offset=[0, 0, 0],
              projection_name=None):
    from pytom.tompy.tools import taper_edges
    #from pytom.gpu.initialize import xp
    from pytom.voltools import transform
    from pytom.tompy.transform import rotate3d, rotate_axis
    from pytom.tompy.transform import cut_from_projection
    from pytom.tompy.io import read

    # Get the size of the original projection
    dim_x = projection.shape[0]
    dim_z = dim_x if dimz is None else dimz

    x, y, z = pick_position
    x = (x + offset[0]) * binning
    y = (y + offset[1]) * binning
    z = (z + offset[2]) * binning

    # Get coordinates of the paricle adjusted for the tilt angle
    yy = y  # assume the rotation axis is around y
    xx = (xp.cos(ang * xp.pi / 180) *
          (x - dim_x / 2) - xp.sin(ang * xp.pi / 180) *
          (z - dim_z / 2)) + dim_x / 2

    # Cut the small patch out

    patch = projection[max(0,
                           int(xp.floor(xx)) -
                           vol_size // 2):int(xp.floor(xx)) + vol_size // 2,
                       int(yy) - vol_size // 2:int(yy) + vol_size // 2, :]
    shiftedPatch = xp.zeros_like(patch)
    transform(patch,
              output=shiftedPatch,
              translation=[xx % 1, yy % 1, 0],
              device=device,
              interpolation='filt_bspline')
    return shiftedPatch.squeeze()
Пример #2
0
def design_fsc_filter(fsc, fildim=None, fsc_criterion=0.143):
    """
    design spectral filter to weight by SNR of frequency
    @param fsc: input fsc
    @type fsc: 1-d list
    @param fildim: filter dimension
    @type fildim: int
    @return: filter
    @rtype: list
    @author: FF
    """
    from math import sqrt
    from pytom.basic.resolution import getResolutionBandFromFSC
    if not fildim:
        fildim = len(fsc)
    nband = len(fsc)
    if fsc_criterion != 0.0:
        resolutionBand = getResolutionBandFromFSC(fsc, criterion=fsc_criterion)
        smooth = max(resolutionBand / 5, 2)
    else:
        resolutionBand = len(fsc)
        smooth = 1
    #print "filter: fsc_criterion %2.3f, resolutionBand %d" % (fsc_criterion, resolutionBand)
    # filter by sqrt(FSC)
    fsc_fil = len(fsc) * [0.]
    for ii in range(0, len(fsc)):
        fscval = fsc[ii]
        if fscval > 0.:
            #fsc_fil[ii] = sqrt(fsc[ii])
            if ii <= resolutionBand:
                fsc_fil[ii] = sqrt(fsc[ii])
            elif (ii > resolutionBand) and (ii <= resolutionBand + smooth):
                fsc_fil[ii] = sqrt(fsc[ii]) * ((
                    (resolutionBand + smooth) - ii) /
                                               smooth)**2  # squared filter
            else:
                fsc_fil[ii] = 0.
        else:
            fsc_fil[ii] = 0.
    #design filter
    fil = xp.array(fildim * [0.])
    if nband != len(fil):
        shrinkfac = 1. / (len(fil) / nband)
    for ii in range(len(fil) - 1):
        # linear resample fsc if nband ~= size(fil)
        if nband != len(fil):
            ilow = int(xp.floor(shrinkfac * ii))
            dlow = shrinkfac * ii - ilow
            ihi = ilow + 1
            dhi = ihi - shrinkfac * ii
            fil[ii] = fsc_fil[ilow] * dhi + fsc_fil[ihi] * dlow
        else:
            fil[ii] = fsc_fil[ii]
    return fil
def cut_patch(projection,
              ang,
              pick_position,
              vol_size=200,
              binning=8,
              dimz=0,
              offset=[0, 0, 0],
              projection_name=None):
    #from pytom.gpu.initialize import xp
    from pytom.voltools import transform
    from pytom.tompy.transform import rotate3d, rotate_axis
    from pytom.tompy.transform import cut_from_projection
    from pytom.tompy.io import read

    # Get the size of the original projection
    dim_x = projection.shape[0]
    dim_z = dim_x if dimz is None else dimz

    x, y, z = pick_position
    x = (x + offset[0]) * binning
    y = (y + offset[1]) * binning
    z = (z + offset[2]) * binning

    # Get coordinates of the paricle adjusted for the tilt angle
    yy = y  # assume the rotation axis is around y
    xx = (xp.cos(ang * xp.pi / 180) *
          (x - dim_x / 2) - xp.sin(ang * xp.pi / 180) *
          (z - dim_z / 2)) + dim_x / 2

    # Cut the small patch out

    patch = projection[max(0,
                           int(xp.floor(xx)) -
                           vol_size // 2):int(xp.floor(xx)) + vol_size // 2,
                       int(yy) - vol_size // 2:int(yy) + vol_size // 2, :]
    #transform(patch, output=patch, translation=[0,xx-float(xx),0], device='gpu:1')
    #patch -= patch.mean()

    return patch, xx, yy
Пример #4
0
def profile2FourierVol(profile, dim=None, reduced=False):
    """
    create Volume from 1d radial profile, e.g., to modulate signal with \
    specific function such as CTF or FSC. Simple linear interpolation is used\
    for sampling.

    @param profile: profile
    @type profile: 1-d L{pytom_volume.vol} or 1-d python array
    @param dim: dimension of (cubic) output
    @type dim: L{int}
    @param reduced: If true reduced Fourier representation (N/2+1, N, N) is generated.
    @type reduced: L{bool}

    @return: 3-dim complex volume with spherically symmetrical profile
    @rtype: L{pytom_volume.vol}
    @author: FF
    """

    if dim is None:
        try:
            dim = [
                2 * profile.shape[0],
            ] * 3
        except:
            dim = [
                2 * len(profile),
            ] * 3

    is3D = (len(dim) == 3)

    nx, ny = dim[:2]
    if reduced:
        if is3D:
            nz = int(dim[2] // 2) + 1
        else:
            ny = int(ny // 2) + 1
    else:
        if is3D:
            nz = dim[2]

    try:
        r_max = profile.shape[0] - 1
    except:
        r_max = len(profile) - 1

    if len(dim) == 3:
        if reduced:
            X, Y, Z = xp.meshgrid(xp.arange(-nx // 2, nx // 2 + nx % 2),
                                  xp.arange(-ny // 2, ny // 2 + ny % 2),
                                  xp.arange(0, nz))
        else:
            X, Y, Z = xp.meshgrid(xp.arange(-nx // 2, nx // 2 + nx % 2),
                                  xp.arange(-ny // 2, ny // 2 + ny % 2),
                                  xp.arange(-nz // 2, nz // 2 + nz % 2))
        R = xp.sqrt(X**2 + Y**2 + Z**2)

    else:
        if reduced:
            X, Y = xp.meshgrid(xp.arange(-nx // 2, ny // 2 + ny % 2),
                               xp.arange(0, ny))
        else:
            X, Y = xp.meshgrid(xp.arange(-nx // 2, nx // 2 + nx % 2),
                               xp.arange(-ny // 2, ny // 2 + ny % 2))
        R = xp.sqrt(X**2 + Y**2)

    IR = xp.floor(R).astype(xp.int64)
    valIR_l1 = IR.copy()
    valIR_l2 = valIR_l1 + 1
    val_l1, val_l2 = xp.zeros_like(X, dtype=xp.float64), xp.zeros_like(
        X, dtype=xp.float64)

    l1 = R - IR.astype(xp.float32)
    l2 = 1 - l1

    try:
        profile = xp.array(profile)
    except:
        import numpy
        profile = xp.array(numpy.array(profile))

    for n in xp.arange(r_max):
        val_l1[valIR_l1 == n] = profile[n]
        val_l2[valIR_l2 == n + 1] = profile[n + 1]

    val_l1[IR == r_max] = profile[n + 1]
    val_l2[IR == r_max] = profile[n + 1]

    val_l1[R > r_max] = 0
    val_l2[R > r_max] = 0

    fkernel = l2 * val_l1 + l1 * val_l2

    if reduced:
        fkernel = xp.fft.fftshift(fkernel, axes=(0, 1))
    else:
        fkernel = xp.fft.fftshift(fkernel)

    return fkernel
Пример #5
0
def resizeFourier(fvol, factor, isodd=False):
    """
    resize Fourier transformed by factor

    @param fvol: Fourier transformed of a volume  - reduced complex
    @type fvol: L{pytom_volume.vol_comp}
    @param factor:  a factor > 0. Factors < 1 will de-magnify the volume, factors > 1 will magnify.
    @type factor: float
    @return: resized Fourier volume (deruced complex)
    @rtype: L{pytom_volume.vol_comp}
    @author: FF
    """

    fvol = fvol.squeeze()
    if factor == 1: return fvol
    oldFNx = fvol.shape[0]
    oldFNy = fvol.shape[1]

    # new dims in real and Fourier space
    newNx = newFNx = int(xp.floor(oldFNx * factor + 0.5))
    newNy = newFNy = int(xp.floor(oldFNy * factor + 0.5))

    # check 3D images
    if len(fvol.shape) == 3:
        oldNz = int((fvol.shape[2] - 1) * 2 + 1 * isodd)
        newNz = int(xp.floor(oldNz * factor + 0.5))
        newFNz = newNz // 2 + 1
        oldFNz = fvol.shape[2]

        scf = 1  #oldNz **3 / (newNx * newNy * newNz)
        newxIsEven = newFNx % 2
        newyIsEven = newFNy % 2

        fvol_center_scaled = xp.fft.fftshift(fvol, axes=(0, 1)) * scf
        newfvol = xp.zeros((newFNx, newFNy, newFNz), dtype=fvol.dtype)
        if factor >= 1:
            # Effectively zero-padding
            newfvol[newFNx // 2 - oldFNx // 2 + newxIsEven:newFNx // 2 +
                    oldFNx // 2 + isodd + newxIsEven, newFNy // 2 -
                    oldFNy // 2 + newyIsEven:newFNy // 2 + oldFNy // 2 +
                    isodd + newyIsEven, :oldFNz] = fvol_center_scaled
            # newFNz // 2 - oldFNz // 2 :newFNz // 2 + oldFNz // 2 + 1] = fvol_center_scaled
        else:
            # Effectively cropping
            newfvol = fvol_center_scaled[oldFNx // 2 - newFNx // 2 -
                                         newxIsEven:oldFNx // 2 + newFNx // 2 +
                                         isodd, oldFNy // 2 - newFNy // 2 -
                                         newyIsEven:oldFNy // 2 + newFNy // 2 +
                                         isodd, :newFNz]
        newfvol = xp.fft.fftshift(newfvol, axes=(0, 1))

    else:
        newNz = 1
        scf = 1. / (newNx * newNy * newNz)
        newFNz = 1
        newFNy = newNy  #// 2 + 1
        fvol_center_scaled = xp.fft.fftshift(fvol, axes=(0))
        newfvol = xp.zeros((newFNx, newFNy), dtype=fvol.dtype) * scf

        if factor >= 1:
            newfvol[newFNx // 2 - oldFNx // 2:newFNx // 2 + oldFNx // 2 +
                    isodd, :oldFNx] = fvol_center_scaled
        else:
            newfvol = fvol_center_scaled[oldFNx // 2 -
                                         newFNx // 2:oldFNx // 2 +
                                         newFNx // 2 + isodd, :newFNy]

        newfvol = xp.fft.fftshift(newfvol, axes=(0))
        #newfvol = xp.expand_dims(newfvol,2)

    return newfvol
Пример #6
0
def scale(volume, factor, interpolation='Spline'):
    """
    scale: Scale a volume by a factor in REAL SPACE - see also resize function for more accurate operation in Fourier \
    space
    @param volume: input volume
    @type volume: L{pytom_volume.vol}
    @param factor: a factor > 0. Factors < 1 will de-magnify the volume, factors > 1 will magnify.
    @type factor: L{float}
    @param interpolation: Can be Spline (default), Cubic or Linear
    @type interpolation: L{str}

    @return: The scaled volume
    @author: Thomas Hrabe
    """

    from pytom.voltools import transform
    from pytom.tompy.tools import paste_in_center
    if factor <= 0:
        raise RuntimeError('Scaling factor must be > 0!')

    interpolation_dict = {
        'Spline': 'filt_bspline',
        'Linear': 'linear',
        'Cubic': 'filt_bspline',
        'filt_bspline': 'filt_bspline',
        'linear': 'linear'
    }
    interpolation = interpolation_dict[interpolation]

    volume = volume.squeeze()

    sizeX = volume.shape[0]
    sizeY = volume.shape[1]
    sizeZ = 1
    newSizeX = int(xp.floor(sizeX * float(factor) + 0.5))
    newSizeY = int(xp.floor(sizeY * float(factor) + 0.5))
    newSizeZ = 1

    if len(volume.shape) == 3:
        sizeZ = volume.shape[2]
        newSizeZ = int(xp.floor(sizeZ * factor + 0.5))
        scaleF = [1 / factor, 1 / factor, 1 / factor]
    else:
        scaleF = [1 / factor, 1 / factor, 1]
        volume = xp.expand_dims(volume, 2)

    if factor == 1:
        rescaledVolume = volume
    elif factor > 1:
        newVolume = xp.zeros((newSizeX, newSizeY, newSizeZ),
                             dtype=volume.dtype)
        newVolume = paste_in_center(volume, newVolume)
        rescaledVolume = xp.zeros_like(newVolume)
        transform(newVolume,
                  scale=scaleF,
                  output=rescaledVolume,
                  device=device,
                  interpolation=interpolation)
    else:
        rescaledVolumeFull = xp.zeros_like(volume)
        transform(volume,
                  scale=scaleF,
                  output=rescaledVolumeFull,
                  device=device,
                  interpolation=interpolation)
        rescaledVolume = xp.zeros((newSizeX, newSizeY, newSizeZ),
                                  dtype=volume.dtype)
        rescaledVolume = paste_in_center(rescaledVolumeFull, rescaledVolume)

    return rescaledVolume