Пример #1
0
def FLCF(volume,
         template,
         mask=None,
         stdV=None,
         gpu=False,
         mempool=None,
         pinned_mempool=None):
    '''Fast local correlation function

    @param volume: target volume
    @param template: template to be searched. It can have smaller size then target volume.
    @param mask: template mask. If not given, a default sphere mask will be used.
    @param stdV: standard deviation of the target volume under mask, which do not need to be calculated again when the mask is identical.

    @return: the local correlation function
    '''

    meanT = meanUnderMask(template, mask, gpu=gpu)
    temp = ((template - meanT) /
            stdUnderMask(template, mask, meanT, gpu=gpu)) * mask

    res = xp.fft.fftshift(
        xp.fft.ifftn(xp.conj(xp.fft.fftn(temp)) *
                     xp.fft.fftn(volume))).real / stdV / mask.sum()
    meanT = None
    temp = None
    mempool.free_all_blocks()
    pinned_mempool.free_all_blocks()
def normalised_cross_correlation_mask(first, second, mask):
    """
    Do cross correlation with a running mask based on numpy

    @param first: The first dataset (numpy 2D)
    @type first: numpy array 2D
    @param second: The second dataset (numpy 2D)
    @type second: numpy array 2D
    @param mask: The mask
    @type mask: numpy array 2D
    @return: The cross correlation result
    @returntype: numpy array 2D

    @requires: the shape of first to be equal to the shape of second and the shape of the mask
    """
    # assert first.shape == second.shape
    # assert first.shape == mask.shape
    # assert len(first.shape) == 2

    import xp.fft as nf

    a = norm_inside_mask(first, mask)
    b = norm_inside_mask(second, mask)

    return xp.real(
        nf.fftshift(nf.ifftn(xp.multiply(nf.fftn(b), xp.conj(
            nf.fftn(a)))))) / xp.sum(mask)
def normalised_cross_correlation(first, second, filter_mask=None, device=0):
    """
    Do a cross correlation based on numpy

    @param first: The first dataset (numpy 2D)
    @type first: numpy array 2D
    @param second: The second dataset (numpy 2D)
    @type second: numpy array 2D
    @param filter_mask: a filter which is used to filter image 'first'
    @type filter_mask: numpy array 2D
    @return: The cross correlation result
    @returntype: numpy array 2D

    @requires: the shape of first to be equal to the shape of second, and equal t the shape of the filter (if used of course)
    """
    assert first.shape == second.shape
    assert len(first.shape) == 2
    if not (filter_mask is None): assert first.shape == filter_mask.shape

    # if filter_mask is None:
    ffirst = xp.fft.fft2(xp.array(first))
    # else:
    #     ffirst = xp.fft.fftshift(xp.fft.fftshift(xp.fft.fftn(first)) * filter_mask)

    ccmap = xp.real(
        xp.fft.fftshift(
            xp.fft.ifftn(xp.multiply(xp.fft.fftn(second),
                                     xp.conj(ffirst))))) / first.size

    return ccmap
Пример #4
0
def xcf(
    volume,
    template,
    mask=None,
    stdV=None,
):
    """
    XCF: returns the non-normalised cross correlation function. The xcf
    result is scaled only by the square of the number of elements.

    @param volume : The search volume
    @type volume: L{pytom_volume.vol}
    @param template : The template searched (this one will be used for conjugate complex multiplication)
    @type template: L{pytom_volume.vol}
    @param mask: Will be unused, only for compatibility reasons with FLCF
    @param stdV: Will be unused, only for compatibility reasons with FLCF
    @return: XCF volume
    @rtype: L{pytom_volume.vol}
    @author: Thomas Hrabe
    """

    # if mask:
    #    volume = volume * mask
    #	 template = template * mask

    # determine fourier transforms of volumes
    if template.dtype in (xp.float64, xp.float32):
        fvolume = xp.fft.fftn(volume)
    else:
        fvolume = volume

    if template.dtype in (xp.float32, xp.float64):
        ftemplate = xp.fft.fftn(template)
    else:
        ftemplate = template

    # perform element wise - conjugate multiplication
    ftemplate = xp.conj(ftemplate)
    fresult = fvolume * ftemplate

    # transform back to real space
    result = abs(xp.fft.ifftn(fresult))

    #xp.fft.iftshift(result)

    return result
Пример #5
0
def meanVolUnderMask(volume, mask):
    """
    meanUnderMask: calculate the mean volume under the given mask (Both should have the same size)
    @param volume: input volume
    @type volume:  L{numpy.ndarray} L{cupy.ndarray}
    @param mask: mask
    @type mask:  L{numpy.ndarray} L{cupy.ndarray}
    @param p: non zero value numbers in the mask
    @type p: L{int} or L{float}
    @param gpu: Boolean that indicates if the input volumes stored on a gpu.
    @type gpu: L{bool}
    @return: the calculated mean volume under mask
    @rtype:  L{numpy.ndarray} L{cupy.ndarray}
    @author: Gijs van der Schot
    """
    res = xp.fft.fftshift(
        xp.fft.irfftn(
            xp.fft.rfftn(volume) * xp.conj(xp.fft.rfftn(mask)))) / mask.sum()
    return res.real
Пример #6
0
def meanVolUnderMaskPlanned(volume, mask, ifftnP, fftnP, plan):
    """
    meanUnderMask: calculate the mean volume under the given mask (Both should have the same size)
    @param volume: input volume
    @type volume:  L{numpy.ndarray} L{cupy.ndarray}
    @param mask: mask
    @type mask:  L{numpy.ndarray} L{cupy.ndarray}
    @param p: non zero value numbers in the mask
    @type p: L{int} or L{float}
    @param gpu: Boolean that indicates if the input volumes stored on a gpu.
    @type gpu: L{bool}
    @return: the calculated mean volume under mask
    @rtype:  L{numpy.ndarray} L{cupy.ndarray}
    @author: Gijs van der Schot
    """
    volume_fft = fftnP(volume.astype(xp.complex64), plan=plan)
    mask_fft = fftnP(mask.astype(xp.complex64), plan=plan)
    res = xp.fft.fftshift(ifftnP(volume_fft * xp.conj(mask_fft),
                                 plan=plan)) / mask.sum()
    return res.real
Пример #7
0
def normalised_cross_correlation(first, second, filter_mask=None):
    """
    Do a cross correlation based on numpy

    @param first: The first dataset (numpy 2D)
    @type first: numpy array 2D
    @param second: The second dataset (numpy 2D)
    @type second: numpy array 2D
    @param filter_mask: a filter which is used to filter image 'first'
    @type filter_mask: numpy array 2D
    @return: The cross correlation result
    @returntype: numpy array 2D

    @requires: the shape of first to be equal to the shape of second, and equal t the shape of the filter (if used of course)
    """
    import sys
    from pytom.tompy.io import write
    assert first.shape == second.shape
    assert len(first.shape) == 2
    if not (filter_mask is None): assert first.shape == filter_mask.shape

    from numpy.fft import fftshift, ifftn, fftn
    import numpy as xp

    prod = 1
    for d in first.shape:
        prod *= d

    if filter_mask is None:
        ffirst = xp.fft.fftn(first)
        fsecond = xp.fft.fftn(second)
    else:
        ffirst = ((xp.fft.fftn(first)) * xp.fft.fftshift(filter_mask))
        fsecond = xp.fft.fftn(second) * xp.fft.fftshift(filter_mask)
    ccmap = xp.real(xp.fft.fftshift(xp.fft.ifftn(
        fsecond * xp.conj(ffirst)))) / filter_mask.sum()

    # write('real_ccmap.mrc', ccmap)

    return ccmap
Пример #8
0
def fourier_reduced2full(data, isodd=False):
    """Return an Hermitian symmetried data.
    """
    # get the original shape
    sx = data.shape[0]
    sy = data.shape[1]
    if isodd:
        sz = (data.shape[2] - 1) * 2 + 1
    else:
        sz = (data.shape[2] - 1) * 2

    res = xp.zeros((sx, sy, sz), dtype=data.dtype)
    res[:, :, 0:data.shape[2]] = data

    # calculate the coodinates accordingly
    szz = sz - data.shape[2]
    x, y, z = xp.indices((sx, sy, szz))
    ind = [xp.mod(sx - x, sx), xp.mod(sy - y, sy), szz - z]

    # do the complex conjugate of the second part
    res[:, :, data.shape[2]:] = xp.conj(data[tuple(ind)])

    return res
Пример #9
0
def bandCC(volume, reference, band, verbose=False, shared=None, index=None):
    """
    bandCC: Determines the normalised correlation coefficient within a band
    @param volume: The volume
    @type volume: L{pytom_volume.vol}
    @param reference: The reference
    @type reference: L{pytom_volume.vol}
    @param band: [a,b] - specify the lower and upper end of band.
    @return: First parameter - The correlation of the two volumes in the specified band. 
             Second parameter - The bandpass filter used.
    @rtype: List - [float,L{pytom_freqweight.weight}]
    @author: Thomas Hrabe    
    """

    if not index is None: print(index)

    from pytom.tompy.filter import bandpass
    from pytom.tompy.correlation import xcf
    #from pytom.tompy.filter import vol_comp

    if verbose:
        print('lowest freq : ', band[0], ' highest freq', band[1])

    vf, m = bandpass(volume,
                     band[0],
                     band[1],
                     returnMask=True,
                     fourierOnly=True)
    rf = bandpass(reference, band[0], band[1], mask=m,
                  fourierOnly=True)  #,vf[1])
    #ccVolume = vol_comp(rf[0].shape[0],rf[0].shape[1],rf[0].shape[2])
    #ccVolume.copyVolume(rf[0])

    vf = vf.astype(xp.complex128)
    ccVolume = rf.astype(vf.dtype)

    ccVolume = ccVolume * xp.conj(vf)
    #pytom_volume.conj_mult(ccVolume,vf[0])

    cc = ccVolume.sum()

    cc = cc.real
    v = vf
    r = rf

    absV = xp.abs(v)
    absR = xp.abs(r)

    sumV = xp.sum(absV**2)
    sumR = xp.sum(absR**2)

    sumV = xp.abs(sumV)
    sumR = xp.abs(sumR)

    if sumV == 0:
        sumV = 1

    if sumR == 0:
        sumR = 1

    cc = cc / (xp.sqrt(sumV * sumR))

    #numerical errors will be punished with nan
    if abs(cc) > 1.1:
        cc = float('nan')

    return float(cc)