def bandCF(volume, reference, band=[0, 100]): """ bandCF: @param volume: The volume @param reference: The reference @param band: [a,b] - specify the lower and upper end of band. [0,1] if not set. @return: First parameter - The correlation of the two volumes in the specified ring. Second parameter - The bandpass filter used. @rtype: List - [L{pytom_volume.vol},L{pytom_freqweight.weight}] @author: Thomas Hrabe @todo: does not work yet -> test is disabled """ if gpu: import cupy as xp else: import numpy as xp import pytom_volume from math import sqrt from pytom.basic import fourier from pytom.basic.filter import bandpassFilter from pytom.basic.correlation import nXcf vf = bandpassFilter(volume, band[0], band[1], fourierOnly=True) rf = bandpassFilter(reference, band[0], band[1], vf[1], fourierOnly=True) v = pytom_volume.reducedToFull(vf[0]) r = pytom_volume.reducedToFull(rf[0]) absV = pytom_volume.abs(v) absR = pytom_volume.abs(r) pytom_volume.power(absV, 2) pytom_volume.power(absR, 2) sumV = abs(pytom_volume.sum(absV)) sumR = abs(pytom_volume.sum(absR)) if sumV == 0: sumV = 1 if sumR == 0: sumR = 1 pytom_volume.conjugate(rf[0]) fresult = vf[0] * rf[0] #transform back to real space result = fourier.ifft(fresult) fourier.iftshift(result) result.shiftscale(0, 1 / float(sqrt(sumV * sumR))) return [result, vf[1]]
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: changed: will be used if specified @type mask: L{pytom_volume.vol} @param stdV: Will be unused, only for compatibility reasons with FLCF @return: XCF volume @rtype: L{pytom_volume.vol} @author: Thomas Hrabe """ import pytom_volume from pytom.basic import fourier if mask != None: volume = volume * mask template = template * mask #determine fourier transforms of volumes if volume.__class__ == pytom_volume.vol: from pytom.basic.fourier import fft fvolume = fft(volume) else: fvolume = volume if template.__class__ == pytom_volume.vol: from pytom.basic.fourier import fft ftemplate = fft(template) else: ftemplate = template #perform element wise - conjugate multiplication pytom_volume.conjugate(ftemplate) fresult = fvolume * ftemplate #transform back to real space result = fourier.ifft(fresult) fourier.iftshift(result) n = result.numelem() if mask: n1 = pytom_volume.sum(mask) # real -> FFT requires n1, FFT -> real n result.shiftscale(0,1/float(n1*n)) else: result.shiftscale(0,1/float(n*n)) return result
def meanUnderMask(volume, mask, p): """ meanUnderMask: calculate the mean volume under the given mask (Both should have the same size) @param volume: input volume @type volume: L{pytom_volume.vol} @param mask: mask @type mask: L{pytom_volume.vol} @param p: non zero value numbers in the mask @type p: L{int} or L{float} @return: the calculated mean volume under mask @rtype: L{pytom_volume.vol} @author: Yuxiang Chen """ size = volume.numelem() from pytom.basic.fourier import fft, ifft, iftshift from pytom_volume import conjugate # for some reason, this has to be conjugated. (Otherwise the asym mask won't work) fMask = fft(mask) conjugate(fMask) result = iftshift(ifft(fMask*fft(volume)))/(size*p) return result
def FLCF(volume, template, mask=None, stdV=None): ''' Created on Apr 13, 2010 FLCF: compute the fast local correlation function This functions works only when the mask is in the middle. @param volume: target volume @type volume: L{pytom_volume.vol} @param template: template to be searched. It can have smaller size then target volume. @type template: L{pytom_volume.vol} @param mask: template mask. If not given, a default sphere mask will be generated which has the same size with the given template. @type mask: L{pytom_volume.vol} @param stdV: standard deviation of the target volume under mask, which do not need to be calculated again when the mask is identical. @type stdV: L{pytom_volume.vol} @return: the local correlation function @rtype: L{pytom_volume.vol} @author: Yuxiang Chen ''' from pytom_volume import vol, pasteCenter from pytom.basic.fourier import fft, ifft, iftshift from pytom_volume import conjugate from pytom.basic.structures import Mask from pytom_volume import sum from pytom.basic.files import write_em if volume.__class__ != vol and template.__class__ != vol: raise RuntimeError('Wrong input type!') if volume.sizeX()<template.sizeX() or volume.sizeY()<template.sizeY() or volume.sizeZ()<template.sizeZ(): raise RuntimeError('Template size is bigger than the target volume') # generate the mask if mask.__class__ != vol: from pytom_volume import initSphere mask = vol(template.sizeX(), template.sizeY(), template.sizeZ()) mask.setAll(0) initSphere(mask, template.sizeX()/2,0,0,template.sizeX()/2, template.sizeY()/2, template.sizeZ()/2) else: if template.sizeX()!=mask.sizeX() and template.sizeY()!=mask.sizeY() and template.sizeZ()!=mask.sizeZ(): raise RuntimeError('Template and mask size are not consistent!') # calculate the non-zeros p = sum(mask) # normalize the template under mask meanT = meanValueUnderMask(template, mask, p) stdT = stdValueUnderMask(template, mask, meanT, p) temp = (template - meanT)/stdT temp = temp * mask # construct both the template and the mask which has the same size as target volume tempV = temp if volume.sizeX() != temp.sizeX() or volume.sizeY() != temp.sizeY() or volume.sizeZ() != temp.sizeZ(): tempV = vol(volume.sizeX(), volume.sizeY(), volume.sizeZ()) tempV.setAll(0) pasteCenter(temp, tempV) maskV = mask if volume.sizeX() != mask.sizeX() or volume.sizeY() != mask.sizeY() or volume.sizeZ() != mask.sizeZ(): maskV = vol(volume.sizeX(), volume.sizeY(), volume.sizeZ()) maskV.setAll(0) pasteCenter(mask, maskV) # calculate the mean and std of volume if stdV.__class__ != vol: meanV = meanUnderMask(volume, maskV, p) stdV = stdUnderMask(volume, maskV, p, meanV) size = volume.numelem() fT = fft(tempV) conjugate(fT) result = iftshift(ifft(fT*fft(volume)))/stdV result.shiftscale(0,1/(size*p)) return result