예제 #1
0
def dev(volume, template, mask=None, volumeIsNormalized=False):
    """
    dev: Calculates the squared deviation of volume and template in real space
    @param volume: A volume
    @type volume:  L{pytom_volume.vol}
    @param template: A template that is searched in volume. Must be of same size as volume.
    @type template:  L{pytom_volume.vol}
    @param mask: mask to constrain correlation
    @type mask: L{pytom_volume.vol}
    @param volumeIsNormalized: speed up if volume is already normalized
    @type volumeIsNormalized: L{bool}
    @return: deviation
    @raise exception: Raises a runtime error if volume and template have a different size.
    @author: FF
    """
    from pytom_volume import vol,sum
    from pytom.tools.macros import volumesSameSize

    assert type(volume) == vol, "dev: volume has to be of type vol!"
    assert type(template) == vol, "dev: template has to be of type vol!"
    if not volumesSameSize(volume,template):
        raise RuntimeError('Volume and template must have same size!')

    if not mask:
        p = volume.numelem()
        result = volume-template
    else:
        assert type(mask) == vol, "dev: mask has to be of type vol!"
        p = sum(mask)
        result = (volume-template)*mask

    deviat = sum(result**2)
    deviat = deviat / float(p)

    return deviat
예제 #2
0
def meanValueUnderMask(volume, mask=None, p=None):
    """
    meanValueUnderMask: Determines the mean value under a mask
    @param volume: The volume
    @type volume:  L{pytom_volume.vol}
    @param mask:  The mask
    @type mask:  L{pytom_volume.vol}
    @param p: precomputed number of voxels in mask
    @type p: float
    @return: A value (scalar)
    @rtype: single
    @change: support None as mask, FF 08.07.2014
    """
    from pytom_volume import vol, sum
  
    if not volume.__class__ == vol:
        raise TypeError("meanValueUnderMask: Volume parameter must be of type vol!")
    
    if mask:
        if not p:
            p = sum(mask)
        resV = volume*mask
        res = sum(resV)/p
    else:
        res = sum(volume)/(volume.sizeX()*volume.sizeY()*volume.sizeZ())
    
    return res
예제 #3
0
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]]
예제 #4
0
def theta_vol_projection(vol_src, theta):

    from pytom_volume import vol
    from pytom_volume import rotate
    from pytom_volume import subvolume
    from pytom_volume import sum

    vol_src_dim_x = vol_src.sizeX()
    vol_src_dim_y = vol_src.sizeY()
    vol_src_dim_z = vol_src.sizeZ()

    vol_dst = vol(vol_src_dim_x, vol_src_dim_y, vol_src_dim_z)
    vol_dst.setAll(0.0)

    rotate(vol_src, vol_dst, 270, 90, theta)

    vol_img = vol(vol_src_dim_x, vol_src_dim_y, 1)
    vol_img.setAll(0.0)

    for i in range(vol_src_dim_x):
        for j in range(vol_src_dim_y):

            vol_img.setV(sum(subvolume(vol_dst, i, j, 0, 1, 1, vol_src_dim_z)),
                         i, j, 0)

    return vol_img
예제 #5
0
def normaliseUnderMask(volume, mask, p=None):
    """
    normalize volume within a mask - take care: only normalization, but NOT multiplication with mask!

    @param volume: volume for normalization
    @type volume: pytom volume
    @param mask: mask
    @type mask: pytom volume
    @param p: sum of gray values in mask (if pre-computed)
    @type p: C{int} or C{float}
    @return: volume normalized to mean=0 and std=1 within mask, p
    @rtype: C{list}
    @author: FF
    """
    from pytom.basic.correlation import meanValueUnderMask, stdValueUnderMask
    #from math import sqrt
    if not p:
        from pytom_volume import sum
        p = sum(mask)
    #meanT = sum(volume) / p
    ## subtract mean and mask
    #res = mask * (volume - meanT)
    #stdT = sum(res*res) / p
    #stdT = sqrt(stdT)
    #res = res / stdT

    meanT = meanValueUnderMask(volume, mask, p)
    
    stdT = stdValueUnderMask(volume, mask, meanT, p)
    res = (volume - meanT)/stdT
    return (res,p)
예제 #6
0
def xcc(volume,template,mask=None, volumeIsNormalized=False):
    """
    xcc: Calculates the cross correlation coefficient in real space
    @param volume: A volume
    @type volume:  L{pytom_volume.vol}
    @param template: A template that is searched in volume. Must be of same size as volume.
    @type template:  L{pytom_volume.vol}
    @param mask: mask to constrain correlation
    @type mask: L{pytom_volume.vol}
    @param volumeIsNormalized: only used for compatibility with nxcc - not used
    @type volumeIsNormalized: L{bool}
    @return: A unscaled value
    @raise exception: Raises a runtime error if volume and template have a different size.  
    @author: Thomas Hrabe 
    """
    from pytom_volume import sum
    from pytom.tools.macros import volumesSameSize
    
    if not volumesSameSize(volume,template):
        raise RuntimeError('Volume and template must have same size!')
   
    if mask: # mask is given
        result = mask * volume * template
    else:
        result = volume * template
    
    cc = sum(result)
    
    cc = cc / float(volume.numelem())
    
    return cc 
def transform_single_vol(vol1, mask):
    from pytom_volume import sum
    from pytom.basic.correlation import meanValueUnderMask, stdValueUnderMask, meanUnderMask, stdUnderMask

    p = sum(mask)
    meanV = meanUnderMask(vol1, mask, p)
    stdV = stdUnderMask(vol1, mask, p, meanV)
    result = (vol1 - meanV) / stdV
    return result
예제 #8
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: 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
예제 #9
0
def nxcc(volume, template, mask=None, volumeIsNormalized=False):
    """
    nxcc: Calculates the normalized cross correlation coefficient in real space
    @param volume: A volume
    @type volume:  L{pytom_volume.vol}
    @param template: A template that is searched in volume. Must be of same size as volume.
    @type template:  L{pytom_volume.vol}
    @param mask: mask to constrain correlation
    @type mask: L{pytom_volume.vol}
    @param volumeIsNormalized: speed up if volume is already normalized
    @type volumeIsNormalized: L{bool}
    @return: A value between -1 and 1
    @raise exception: Raises a runtime error if volume and template have a different size.
    @author: Thomas Hrabe 
    @change: flag for pre-normalized volume, FF
    """

    from pytom_volume import vol,sum,limit
    from pytom.tools.macros import volumesSameSize
    
    if not volumesSameSize(volume,template):
        raise RuntimeError('Volume and template must have same size!')
    
    if not mask:
        from pytom.basic.normalise import mean0std1
        if not volumeIsNormalized:
           v = mean0std1(volume, True)
        t = mean0std1(template, True)
        p = volume.numelem()
        result = v*t
    else:
        from pytom_numpy import vol2npy
        from pytom.basic.normalise import normaliseUnderMask
        if not volumeIsNormalized:
            (v,p) = normaliseUnderMask(volume, mask)
            (t,p) = normaliseUnderMask(template, mask, p)
            t = t * mask # multiply with the mask
            result = v * t
        else:
            (t,p) = normaliseUnderMask(template,mask)
            t = t * mask # multiply with the mask
            result = volume * t
    
    ncc = sum(result)
    ncc = ncc / float(p)

    return ncc 
예제 #10
0
def stdValueUnderMask(volume, mask, meanValue, p=None):
    """
    stdValueUnderMask: Determines the std value under a mask

    @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{float} or L{int}
    @return: A value
    @rtype: L{float}
    @change: support None as mask, FF 08.07.2014
    """
    from pytom_volume import sum
    from pytom_volume import vol, power, variance
    
    assert volume.__class__ == vol
    if mask:
        if not p:
            p = sum(mask)
    else:
        p = volume.sizeX()*volume.sizeY()*volume.sizeZ()
    
    squareM = meanValue**2
    squareV = vol(volume.sizeX(), volume.sizeY(), volume.sizeZ())
    squareV.copyVolume(volume)
    power(squareV, 2)
    
    res = meanValueUnderMask(squareV, mask, p)

    res = res - squareM
    try:
        res = res**0.5
    except ValueError:
        print("Res = %.6f < 0 => standard deviation determination fails :(")
        print("   something went terribly wrong and program has to stop")
        raise ValueError('Program stopped in stdValueUnderMask')
    return res
예제 #11
0
def bestAlignment(particle, reference, referenceWeighting, wedgeInfo, rotations,
         scoreObject=0, mask=None, preprocessing=None, progressBar=False, binning=1,
         bestPeak=None, verbose=False):
    """
    bestAlignment: Determines best alignment of particle relative to the reference
    @param particle: A particle
    @type particle: L{pytom_volume.vol}
    @param reference: A reference
    @type reference: L{pytom_volume.vol}
    @param referenceWeighting: Fourier weighting of the reference (sum of wedges for instance)
    @type referenceWeighting: L{pytom.basic.structures.vol}
    @param wedgeInfo: What does the wedge look alike?
    @type wedgeInfo: L{pytom.basic.structures.Wedge}
    @param rotations: All rotations to be scanned
    @type rotations: L{pytom.angles.AngleObject}
    @param scoreObject: 
    @type scoreObject: L{pytom.score.score.Score}
    @param mask: real-space mask for correlation function
    @type mask: L{pytom.basic.structures.Particle}
    @param preprocessing: Class storing preprocessing of particle and reference such as bandpass
    @type preprocessing: L{pytom.alignment.preprocessing.Preprocessing}
    @param progressBar: Display progress bar of alignment. False by default.
    @param binning: binning factor - e.g. binning=2 reduces size by FACTOR of 2
    @type binning: int or float
    @param bestPeak: Initialise best peak with old values.   
    @param verbose: Print out infos. Writes CC volume to disk!!! Default is False  
    @return: Returns the best rotation for particle and the corresponding scoring result.
    @author: Thomas Hrabe
    """
    from pytom.basic.correlation import subPixelPeak, subPixelPeakParabolic
    from pytom.alignment.structures import Peak
    from pytom_volume import peak, vol, vol_comp
    from pytom.basic.filter import filter,rotateWeighting
    from pytom.basic.structures import Rotation, Shift, Particle, Mask
    from pytom.angles.angle import AngleObject
    from pytom.alignment.preprocessing import Preprocessing
    from pytom.basic.transformations import resize, resizeFourier
    binningType = 'Fourier' # or 'Fourier'

    assert isinstance(rotations, AngleObject), "bestAlignment: rotations must be " \
                                                                             "AngleObject!"
    currentRotation = rotations.nextRotation()
    if currentRotation == [None,None,None]:
        raise Exception('bestAlignment: No rotations are sampled! Something is wrong with input rotations')

    assert particle.__class__ == vol, "particle not of type vol"
    assert reference.__class__ == vol, "reference not of type vol"
    assert (referenceWeighting.__class__ == vol or referenceWeighting.__class__ == str), \
        "referenceWeighting not volume or str"
    if mask:
        assert mask.__class__ == Mask, "Mask not of type Mask"
        m = mask.getVolume()

    if scoreObject == 0 or not scoreObject:
        from pytom.score.score import xcfScore
        scoreObject = xcfScore()
    # fix binning
    if binning == 0:
        binning = 1
    if binning != 1:
        particleUnbinned = vol(particle.sizeX(), particle.sizeY(), particle.sizeZ())
        particleUnbinned.copyVolume(particle)
        particle = resize(volume=particle, factor=1./binning, interpolation=binningType)
        if type(particle) == tuple:
            particle = particle[0]
        referenceUnbinned = vol(reference.sizeX(), reference.sizeY(), reference.sizeZ())
        referenceUnbinned.copyVolume(reference)
        reference = resize(volume=reference, factor=1./binning, interpolation=binningType)
        if type(reference) == tuple:
            reference = reference[0]
        if mask:
            m = resize(volume=m, factor=1./binning, interpolation='Spline')
        if not referenceWeighting.__class__ == str:
            referenceWeightingUnbinned = vol_comp(referenceWeighting.sizeX(), referenceWeighting.sizeY(),
                                                  referenceWeighting.sizeZ())
            referenceWeightingUnbinned.copyVolume(referenceWeighting)
            if binning != 1:
                referenceWeighting = resizeFourier(fvol=referenceWeighting, factor=1./binning)
    centerX, centerY, centerZ = int(particle.sizeX()/2), int(particle.sizeY()/2), int(particle.sizeZ()/2)

    # create buffer volume for transformed particle 
    particleCopy = vol(particle.sizeX(),particle.sizeY(),particle.sizeZ())
    particle = wedgeInfo.apply(particle) #apply wedge to itself
    if preprocessing is None:
        preprocessing = Preprocessing()
    preprocessing.setTaper( taper=particle.sizeX()/10.)
    particle = preprocessing.apply(volume=particle, bypassFlag=True)  # filter particle to some resolution
    particleCopy.copyVolume(particle)
    # compute standard veviation volume really only if needed
    if mask and (scoreObject._type=='FLCFScore'):
        from pytom_volume import sum
        from pytom.basic.correlation import meanUnderMask, stdUnderMask
        p = sum(m)
        meanV = meanUnderMask(particle, m, p)
        stdV = stdUnderMask(particle, m, p, meanV)
    else:
        meanV = None
        stdV = None

    while currentRotation != [None,None,None]:
        if mask:
            m = mask.getVolume(currentRotation)
            if binning != 1:
                m = resize(volume=m, factor=1./binning, interpolation='Spline')
            #update stdV if mask is not a sphere
            # compute standard deviation volume really only if needed
            if not mask.isSphere() and (scoreObject._type=='FLCFScore'):
                meanV   = meanUnderMask(particle, m, p)
                stdV    = stdUnderMask(particle, m, p, meanV)
        else:
            m = None
        
        simulatedVol = _rotateWedgeReference(reference, currentRotation, wedgeInfo, m, [centerX, centerY, centerZ])
        simulatedVol = preprocessing.apply(volume=simulatedVol, bypassFlag=True)
        
        #weight particle
        if not referenceWeighting.__class__ == str:
            from pytom_freqweight import weight
            weightingRotated = rotateWeighting(weighting=referenceWeighting, z1=currentRotation[0],
                                               z2=currentRotation[1], x=currentRotation[2], isReducedComplex=True,
                                               returnReducedComplex=True, binarize=False)
            particleCopy.copyVolume(particle)
            r = list(filter(particleCopy, weight(weightingRotated)))
            particleCopy = r[0]
        
        scoringResult = scoreObject.score(particleCopy, simulatedVol, m, stdV)
        
        pk = peak(scoringResult)

        #with subPixelPeak
        [peakValue,peakPosition] = subPixelPeak(scoreVolume=scoringResult, coordinates=pk,
                                               interpolation='Quadratic', verbose=False)
        #[peakValue,peakPosition] = subPixelPeakParabolic(scoreVolume=scoringResult, coordinates=pk, verbose=False)

        # determine shift relative to center
        shiftX = (peakPosition[0] - centerX) * binning
        shiftY = (peakPosition[1] - centerY) * binning
        shiftZ = (peakPosition[2] - centerZ) * binning

        #NANs would fail this test.
        assert peakValue == peakValue, "peakValue seems to be NaN"
        
        newPeak = Peak(peakValue, Rotation(currentRotation), Shift(shiftX, shiftY, shiftZ))
        
        if verbose:
            print('Rotation: z1=%3.1f, z2=%3.1f, x=%3.1f; Dx=%2.2f, Dy=%2.2f, Dz=%2.2f, CC=%2.3f' % \
                  (currentRotation[0], currentRotation[1], currentRotation[2], shiftX, shiftY, shiftZ, peakValue))

        if bestPeak is None:
            bestPeak = newPeak
            if verbose:
                scoringResult.write('BestScore.em')
        if bestPeak < newPeak:
            bestPeak = newPeak
            if verbose:
                scoringResult.write('BestScore.em')

        currentRotation = rotations.nextRotation()
    # repeat ccf for binned sampling to get translation accurately
    if binning != 1:
        m = mask.getVolume(bestPeak.getRotation())
        centerX, centerY, centerZ = int(particleUnbinned.sizeX()/2), int(particleUnbinned.sizeY()/2), \
                                    int(particleUnbinned.sizeZ()/2)
        simulatedVol = _rotateWedgeReference(referenceUnbinned, bestPeak.getRotation(), wedgeInfo, m,
                                             [centerX, centerY, centerZ])
        simulatedVol = preprocessing.apply(volume=simulatedVol, bypassFlag=True)
        if mask and scoreObject._type=='FLCFScore':
            p = sum(m)
            meanV = meanUnderMask(volume=particleUnbinned, mask=m, p=p)
            stdV  = stdUnderMask(volume=particleUnbinned, mask=m, p=p, meanV=meanV)
        scoreObject._peakPrior.reset_weight()
        scoringResult = scoreObject.score(particle=particleUnbinned, reference=simulatedVol, mask=m, stdV=stdV)
        pk = peak(scoringResult)
        [peakValue,peakPosition] = subPixelPeak(scoreVolume=scoringResult, coordinates=pk, interpolation='Quadratic',
                                                verbose=False)
        shiftX = (peakPosition[0] - centerX)
        shiftY = (peakPosition[1] - centerY)
        shiftZ = (peakPosition[2] - centerZ)
        bestPeak = Peak(peakValue, bestPeak.getRotation(), Shift(shiftX, shiftY, shiftZ))
    if verbose:
            print('BestAlignment: z1=%3.1f, z2=%3.1f, x=%3.1f; Dx=%2.2f, Dy=%2.2f, Dz=%2.2f, CC=%2.3f' % \
                  (bestPeak.getRotation()[0], bestPeak.getRotation()[1], bestPeak.getRotation()[2],
                   bestPeak.getShift()[0], bestPeak.getShift()[1], bestPeak.getShift()[2], bestPeak.getScoreValue()))
    rotations.reset()
    scoreObject._peakPrior.reset_weight()
    return bestPeak
예제 #12
0
def extractPeaks(volume,
                 reference,
                 rotations,
                 scoreFnc=None,
                 mask=None,
                 maskIsSphere=False,
                 wedgeInfo=None,
                 **kwargs):
    '''
    Created on May 17, 2010
    @param volume: target volume
    @type volume: L{pytom_volume.vol}
    @param reference: reference
    @type reference: L{pytom_volume.vol}
    @param rotations: rotation angle list
    @type rotations: L{pytom.angles.globalSampling.GlobalSampling}
    @param scoreFnc: score function that is used
    @type scoreFnc: L{pytom.basic.correlation}
    @param mask: mask volume
    @type mask: L{pytom_volume.vol}
    @param maskIsSphere: flag to indicate whether the mask is sphere or not
    @type maskIsSphere: boolean
    @param wedgeInfo: wedge information
    @type wedgeInfo: L{pytom.basic.structures.WedgeInfo}
    @return: both the score volume and the corresponding rotation index volume
    @rtype: L{pytom_volume.vol}
    @author: chen
    '''
    #    from pytom.tools.timing import timing
    #    t = timing(); t.start()

    # parse the parameters
    nodeName = kwargs.get('nodeName', '')
    verbose = kwargs.get('verboseMode', True)
    if verbose not in [True, False]:
        verbose = True
    moreInfo = kwargs.get('moreInfo', False)
    if moreInfo not in [True, False]:
        moreInfo = False

    from pytom.basic.correlation import FLCF
    from pytom.basic.structures import WedgeInfo, Wedge
    from pytom_volume import vol, pasteCenter
    from pytom_volume import rotateSpline as rotate  # for more accuracy
    from pytom_volume import updateResFromIdx
    from pytom.basic.files import write_em

    if scoreFnc == None:
        scoreFnc = FLCF

    # only FLCF needs mask
    if scoreFnc == FLCF:
        if mask.__class__ != vol:  # construct a sphere mask by default
            from pytom_volume import initSphere
            mask = vol(reference.sizeX(), reference.sizeY(), reference.sizeZ())
            mask.setAll(0)
            initSphere(mask,
                       reference.sizeX() / 2, 0, 0,
                       reference.sizeX() / 2,
                       reference.sizeX() / 2,
                       reference.sizeX() / 2)
            maskIsSphere = True

    # result volume which stores the score
    result = vol(volume.sizeX(), volume.sizeY(), volume.sizeZ())
    result.setAll(-1)

    # result orientation of the peak value (index)
    orientation = vol(volume.sizeX(), volume.sizeY(), volume.sizeZ())
    orientation.setAll(0)

    currentRotation = rotations.nextRotation()
    index = 0

    if verbose == True:
        from pytom.tools.ProgressBar import FixedProgBar
        max = rotations.numberRotations() - 1
        prog = FixedProgBar(0, max, nodeName)
    if moreInfo:
        sumV = vol(volume.sizeX(), volume.sizeY(), volume.sizeZ())
        sumV.setAll(0)
        sqrV = vol(volume.sizeX(), volume.sizeY(), volume.sizeZ())
        sqrV.setAll(0)
    else:
        sumV = None
        sqrV = None

    if wedgeInfo.__class__ == WedgeInfo or wedgeInfo.__class__ == Wedge:
        print('Applied wedge to volume')
        volume = wedgeInfo.apply(volume)

    while currentRotation != [None, None, None]:
        if verbose == True:
            prog.update(index)

        # rotate the reference
        ref = vol(reference.sizeX(), reference.sizeY(), reference.sizeZ())
        rotate(reference, ref, currentRotation[0], currentRotation[1],
               currentRotation[2])

        # apply wedge
        if wedgeInfo.__class__ == WedgeInfo or wedgeInfo.__class__ == Wedge:
            ref = wedgeInfo.apply(ref)

        # rotate the mask if it is asymmetric
        if scoreFnc == FLCF:
            if maskIsSphere == False:  # if mask is not a sphere, then rotate it
                m = vol(mask.sizeX(), mask.sizeY(), mask.sizeZ())
                rotate(mask, m, currentRotation[0], currentRotation[1],
                       currentRotation[2])
            else:
                m = mask

        # compute the score
        # if mask is sphere and it is the first run, compute the standard deviation of the volume under mask for late use
        if scoreFnc == FLCF and index == 0 and maskIsSphere == True:
            # compute standard deviation of the volume under mask
            maskV = m
            if volume.sizeX() != m.sizeX() or volume.sizeY() != m.sizeY(
            ) or volume.sizeZ() != m.sizeZ():
                maskV = vol(volume.sizeX(), volume.sizeY(), volume.sizeZ())
                maskV.setAll(0)
                pasteCenter(m, maskV)
            from pytom_volume import sum
            p = sum(m)
            from pytom.basic.correlation import meanUnderMask, stdUnderMask
            meanV = meanUnderMask(volume, maskV, p)
            stdV = stdUnderMask(volume, maskV, p, meanV)

        # ref.write('template_cpu.em')

        if scoreFnc == FLCF:
            if maskIsSphere == True:
                score = scoreFnc(volume, ref, m, stdV, wedge=1)
            else:
                score = scoreFnc(volume, ref, m)
        else:  # not FLCF, so doesn't need mask as parameter and perhaps the reference should have the same size
            _ref = vol(volume.sizeX(), volume.sizeY(), volume.sizeZ())
            _ref.setAll(0)
            pasteCenter(ref, _ref)

            score = scoreFnc(volume, _ref)

        # update the result volume and the orientation volume
        updateResFromIdx(result, score, orientation, index)

        if moreInfo:
            sumV = sumV + score
            sqrV = sqrV + score * score

        currentRotation = rotations.nextRotation()
        index = index + 1


#    if moreInfo:
#        sumV = sumV/rotations.numberRotations()
#        sqrV = sqrV/rotations.numberRotations()

#    time = t.end(); print 'The overall execution time: %f' % time

    return [result, orientation, sumV, sqrV]
예제 #13
0
def bandCC(volume,reference,band,verbose = False):
    """
    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    
    """
    import pytom_volume
    from pytom.basic.filter import bandpassFilter
    from pytom.basic.correlation import xcf
    from math import sqrt
    
    if verbose:
        print('lowest freq : ', band[0],' highest freq' , band[1])
        
    vf = bandpassFilter(volume,band[0],band[1],fourierOnly=True)
    rf = bandpassFilter(reference,band[0],band[1],vf[1],fourierOnly=True)
    
    ccVolume = pytom_volume.vol_comp(rf[0].sizeX(),rf[0].sizeY(),rf[0].sizeZ())
    ccVolume.copyVolume(rf[0])
    
    pytom_volume.conj_mult(ccVolume,vf[0])
    
    cc = pytom_volume.sum(ccVolume)

    cc = cc.real
    
    v = vf[0]
    r = rf[0]
    
    absV = pytom_volume.abs(v)
    absR = pytom_volume.abs(r)
    
    pytom_volume.power(absV,2)
    pytom_volume.power(absR,2)
    
    sumV = pytom_volume.sum(absV)
    sumR = pytom_volume.sum(absR)
    
    sumV = abs(sumV)
    sumR = abs(sumR)
    
    if sumV == 0:
        sumV =1
        
    if sumR == 0:
        sumR =1
        
    cc = cc / (sqrt(sumV*sumR)) 
    
    #numerical errors will be punished with nan
    if abs(cc) > 1.1 :
        cc = float('nan')
    
    return [cc,vf[1]];
예제 #14
0
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