예제 #1
0
    def determine_resolution(self,
                             even,
                             odd,
                             criterion,
                             numberBands,
                             mask,
                             verbose=False):
        """For the master node, determine the resolution.
        """
        from pytom.basic.correlation import FSC, determineResolution

        if not numberBands:
            numberBands = even.sizeX() / 2

        fsc = FSC(even, odd, numberBands, mask, verbose=False)
        if verbose:
            print(self.node_name + ': FSC: ' + str(fsc))

        return determineResolution(fsc, criterion, verbose=False)
예제 #2
0
    def determine_resolution(self,
                             even,
                             odd,
                             criterion,
                             numberBands,
                             mask,
                             verbose=False):
        """For the master node, determine the resolution.
           @param even: particle list even
           @type even: L{pytom.basic.structures.ParticleList}
           @param odd: particle list odd
           @type odd: L{pytom.basic.structures.ParticleList}
        """
        from pytom.basic.correlation import FSC, determineResolution

        if not numberBands:
            numberBands = even.sizeX() / 2

        fsc = FSC(even, odd, numberBands, mask, verbose=False)
        if verbose:
            print(self.node_name + ': FSC: ' + str(fsc))

        return determineResolution(fsc, criterion, verbose=False)
예제 #3
0
def calculate_averages(pl, binning, mask, outdir='./'):
    """
    calcuate averages for particle lists
    @param pl: particle list
    @type pl: L{pytom.basic.structures.ParticleList}
    @param binning: binning factor
    @type binning: C{int}

    last change: Jan 18 2020: error message for too few processes, FF
    """
    import os
    from pytom_volume import complexDiv, vol, pasteCenter
    from pytom.basic.fourier import fft, ifft
    from pytom.basic.correlation import FSC, determineResolution
    from pytom_fftplan import fftShift
    from pytom_volume import reducedToFull

    pls = pl.copy().splitByClass()
    res = {}
    freqs = {}
    wedgeSum = {}

    for pp in pls:
        # ignore the -1 class, which is used for storing the trash class
        class_label = pp[0].getClass()
        if class_label != '-1':
            assert len(pp) > 3
            if len(pp) >= 4 * mpi.size:
                spp = mpi._split_seq(pp, mpi.size)
            else:  # not enough particle to do averaging on one node
                spp = [None] * 2
                spp[0] = pp[:len(pp) // 2]
                spp[1] = pp[len(pp) // 2:]

            args = list(
                zip(spp, [True] * len(spp), [binning] * len(spp),
                    [False] * len(spp), [outdir] * len(spp)))
            avgs = mpi.parfor(paverage, args)

            even_a, even_w, odd_a, odd_w = None, None, None, None
            even_avgs = avgs[1::2]
            odd_avgs = avgs[::2]

            for a, w in even_avgs:
                if even_a is None:
                    even_a = a.getVolume()
                    even_w = w.getVolume()
                else:
                    even_a += a.getVolume()
                    even_w += w.getVolume()
                os.remove(a.getFilename())
                os.remove(w.getFilename())

            for a, w in odd_avgs:
                if odd_a is None:
                    odd_a = a.getVolume()
                    odd_w = w.getVolume()
                else:
                    odd_a += a.getVolume()
                    odd_w += w.getVolume()
                os.remove(a.getFilename())
                os.remove(w.getFilename())

            # determine the resolution
            # raise error message in case even_a == None - only one processor used
            if even_a == None:
                from pytom.basic.exceptions import ParameterError
                raise ParameterError(
                    'cannot split odd / even. Likely you used only one processor - use: mpirun -np 2 (or higher!)?!'
                )

            if mask and mask.__class__ == str:
                from pytom_volume import read, pasteCenter, vol

                maskBin = read(mask, 0, 0, 0, 0, 0, 0, 0, 0, 0, binning,
                               binning, binning)
                if even_a.sizeX() != maskBin.sizeX() or even_a.sizeY(
                ) != maskBin.sizeY() or even_a.sizeZ() != maskBin.sizeZ():
                    mask = vol(even_a.sizeX(), even_a.sizeY(), even_a.sizeZ())
                    mask.setAll(0)
                    pasteCenter(maskBin, mask)
                else:
                    mask = maskBin

            fsc = FSC(even_a, odd_a, int(even_a.sizeX() // 2), mask)
            band = determineResolution(fsc, 0.5)[1]

            aa = even_a + odd_a
            ww = even_w + odd_w
            fa = fft(aa)
            r = complexDiv(fa, ww)
            rr = ifft(r)
            rr.shiftscale(0.0, 1. / (rr.sizeX() * rr.sizeY() * rr.sizeZ()))

            res[class_label] = rr
            freqs[class_label] = band

            ww2 = reducedToFull(ww)
            fftShift(ww2, True)
            wedgeSum[class_label] = ww2
    print('done')
    return res, freqs, wedgeSum
예제 #4
0
def average2(particleList, weighting=False, norm=False, determine_resolution=False,
             mask=None, binning=1, verbose=False):
    """
    2nd version of average function. Will not write the averages to the disk. Also support internal \
    resolution determination.
    """
    from pytom_volume import read, vol, complexDiv, complexRealMult
    from pytom_volume import transformSpline as transform
    from pytom.basic.fourier import fft, ifft, convolute
    from pytom.basic.normalise import mean0std1
    from pytom.tools.ProgressBar import FixedProgBar
    from pytom.basic.filter import lowpassFilter, rotateWeighting
    from math import exp
    
    if len(particleList) == 0:
        raise RuntimeError('The particlelist provided is empty. Aborting!')
    
    if verbose:
        progressBar = FixedProgBar(0,len(particleList),'Particles averaged ')
        progressBar.update(0)
        numberAlignedParticles = 0
    
    even = None
    odd = None
    wedgeSum_even = None
    wedgeSum_odd = None
    newParticle = None
    
    is_odd = True
    for particleObject in particleList:
        particle = read(particleObject.getFilename(), 0,0,0,0,0,0,0,0,0, binning,binning,binning)
        if norm:
            mean0std1(particle)
        wedgeInfo = particleObject.getWedge()
        
        # apply its wedge to itself
        particle = wedgeInfo.apply(particle)
        
        if odd is None: # initialization
            sizeX = particle.sizeX() 
            sizeY = particle.sizeY()
            sizeZ = particle.sizeZ()
            
            newParticle = vol(sizeX,sizeY,sizeZ)
            
            centerX = sizeX/2 
            centerY = sizeY/2 
            centerZ = sizeZ/2 
            
            odd = vol(sizeX,sizeY,sizeZ)
            odd.setAll(0.0)
            even = vol(sizeX,sizeY,sizeZ)
            even.setAll(0.0)
            
            wedgeSum_odd = wedgeInfo.returnWedgeVolume(sizeX,sizeY,sizeZ)
            wedgeSum_odd.setAll(0)
            wedgeSum_even = wedgeInfo.returnWedgeVolume(sizeX,sizeY,sizeZ)
            wedgeSum_even.setAll(0)
        

        # create spectral wedge weighting
        rotation = particleObject.getRotation()
        rotinvert =  rotation.invert()
        if analytWedge:
            # > original buggy version
            wedge = wedgeInfo.returnWedgeVolume(sizeX,sizeY,sizeZ,False, rotinvert)
            # < original buggy version
        else:
            # > FF: interpol bugfix
            wedge = rotateWeighting( weighting=wedgeInfo.returnWedgeVolume(sizeX,sizeY,sizeZ,False),
                                     z1=rotinvert[0], z2=rotinvert[1], x=rotinvert[2], mask=None,
                                     isReducedComplex=True, returnReducedComplex=True)
            # < FF
            # > TH bugfix
            #wedgeVolume = wedgeInfo.returnWedgeVolume(wedgeSizeX=sizeX, wedgeSizeY=sizeY, wedgeSizeZ=sizeZ,
            #                                          humanUnderstandable=True, rotation=rotinvert)
            #wedge = rotate(volume=wedgeVolume, rotation=rotinvert, imethod='linear')
            # < TH
        if is_odd:
            wedgeSum_odd = wedgeSum_odd + wedge
        else:
            wedgeSum_even = wedgeSum_even + wedge
        
        # shift and rotate particle
        shiftV = particleObject.getShift()
        newParticle.setAll(0)
        transform(particle,newParticle,-rotation[1],-rotation[0],-rotation[2],
                  centerX,centerY,centerZ,-shiftV[0]/binning,
                  -shiftV[1]/binning,-shiftV[2]/binning,0,0,0)

        if is_odd:
            if weighting:
                weight = 1. - particleObject.getScore().getValue()
                #weight = weight**2
                weight = exp(-1.*weight)
                odd = odd + newParticle * weight
            else:
                odd = odd + newParticle
        else:
            if weighting:
                weight = 1. - particleObject.getScore().getValue()
                #weight = weight**2
                weight = exp(-1.*weight)
                even = even + newParticle * weight
            else:
                even = even + newParticle
        
        is_odd = not is_odd
        
        if verbose:
            numberAlignedParticles = numberAlignedParticles + 1
            progressBar.update(numberAlignedParticles)

    # determine resolution if needed
    fsc = None
    if determine_resolution:
        # apply spectral weighting to sum
        f_even = fft(even)
        w_even = complexDiv(f_even, wedgeSum_even)
        w_even = ifft(w_even)        
        w_even.shiftscale(0.0,1/float(sizeX*sizeY*sizeZ))
        
        f_odd = fft(odd)
        w_odd = complexDiv(f_odd, wedgeSum_odd)
        w_odd = ifft(w_odd)        
        w_odd.shiftscale(0.0,1/float(sizeX*sizeY*sizeZ))
        
        from pytom.basic.correlation import FSC
        fsc = FSC(w_even, w_odd, sizeX/2, mask, verbose=False)
    
    # add together
    result = even+odd
    wedgeSum = wedgeSum_even+wedgeSum_odd

    invert_WedgeSum( invol=wedgeSum, r_max=sizeX/2-2., lowlimit=.05*len(particleList), lowval=.05*len(particleList))
    #wedgeSum.write(averageName[:len(averageName)-3] + '-WedgeSumInverted.em')
    result = convolute(v=result, k=wedgeSum, kernel_in_fourier=True)
    # do a low pass filter
    #result = lowpassFilter(result, sizeX/2-2, (sizeX/2-1)/10.)[0]
    
    return (result, fsc)
예제 #5
0
def alignVolumesAndFilterByFSC(vol1,
                               vol2,
                               mask=None,
                               nband=None,
                               iniRot=None,
                               iniTrans=None,
                               interpolation='linear',
                               fsc_criterion=0.143,
                               verbose=0):
    """
    align two volumes, compute their FSC, and filter by FSC
    @param vol1: volume 1
    @param vol2: volume 2
    @mask: mask volume
    @type mask: L{pytom_volume.vol}
    @param nband: Number of bands
    @type nband: L{int}
    @param iniRot: initial guess for rotation
    @param iniTrans: initial guess for translation
    @param interpolation: interpolation type - 'linear' (default) or 'spline'
    @param fsc_criterion: filter -> 0 according to resolution criterion
    @type fsc_criterion: float
    @param verbose: verbose level (0=mute, 1 some output, 2=talkative)
    @type verbose: int
    @type interpolation: str
    @return: (filvol1, filvol2, fsc, fsc_fil, optiRot, optiTrans) i.e., filtered volumes, their FSC, the corresponding\
        filter that was applied to the volumes, and the optimal rotation and translation of vol2 with respect to vol1\
        note: filvol2 is NOT rotated and translated!
    @author: FF
    """
    from pytom_volume import transformSpline, vol
    from pytom.basic.correlation import FSC
    from pytom.basic.filter import filter_volume_by_profile
    from pytom.alignment.localOptimization import Alignment
    from pytom.basic.correlation import nxcc

    assert isinstance(object=vol1, class_or_type_or_tuple=vol
                      ), "alignVolumesAndFilterByFSC: vol1 must be of type vol"
    assert isinstance(object=vol2, class_or_type_or_tuple=vol
                      ), "alignVolumesAndFilterByFSC: vol2 must be of type vol"
    # filter volumes prior to alignment according to SNR
    fsc = FSC(volume1=vol1, volume2=vol2, numberBands=nband)
    fil = design_fsc_filter(fsc=fsc, fildim=int(vol2.sizeX() / 2))
    #filter only one volume so that resulting CCC is weighted by SNR only once
    filvol2 = filter_volume_by_profile(volume=vol2, profile=fil)
    # align vol2 to vol1
    if verbose == 2:
        alignment = Alignment(vol1=vol1,
                              vol2=filvol2,
                              score=nxcc,
                              mask=mask,
                              iniRot=iniRot,
                              iniTrans=iniTrans,
                              opti='fmin_powell',
                              interpolation=interpolation,
                              verbose=verbose)
    else:
        alignment = Alignment(vol1=vol1,
                              vol2=filvol2,
                              score=nxcc,
                              mask=mask,
                              iniRot=iniRot,
                              iniTrans=iniTrans,
                              opti='fmin_powell',
                              interpolation=interpolation,
                              verbose=False)
    optiScore, optiRot, optiTrans = alignment.localOpti(iniRot=iniRot,
                                                        iniTrans=iniTrans)
    if verbose:
        from pytom.angles.angleFnc import differenceAngleOfTwoRotations
        from pytom.basic.structures import Rotation
        diffAng = differenceAngleOfTwoRotations(rotation1=Rotation(0, 0, 0),
                                                rotation2=optiRot)
        print(
            "Alignment densities: Rotations: %2.3f, %2.3f, %2.3f; Translations: %2.3f, %2.3f, %2.3f "
            % (optiRot[0], optiRot[1], optiRot[2], optiTrans[0], optiTrans[1],
               optiTrans[2]))
        print("Orientation difference: %2.3f deg" % diffAng)
    vol2_alig = vol(vol2.sizeX(), vol2.sizeY(), vol2.sizeZ())
    transformSpline(vol2, vol2_alig, optiRot[0], optiRot[1], optiRot[2],
                    int(vol2.sizeX() / 2), int(vol2.sizeY() / 2),
                    int(vol2.sizeY() / 2), 0, 0, 0, optiTrans[0], optiTrans[1],
                    optiTrans[2])
    # finally compute FSC and filter of both volumes
    if not nband:
        nband = int(vol2.sizeX() / 2)
    fsc = FSC(volume1=vol1, volume2=vol2_alig, numberBands=nband)
    fil = design_fsc_filter(fsc=fsc,
                            fildim=int(vol2.sizeX() / 2),
                            fsc_criterion=fsc_criterion)
    filvol1 = filter_volume_by_profile(volume=vol1, profile=fil)
    #filvol2 = filter_volume_by_profile( volume=vol2_alig, profile=fil)
    filvol2 = filter_volume_by_profile(volume=vol2, profile=fil)

    return (filvol1, filvol2, fsc, fil, optiRot, optiTrans)
예제 #6
0
for i in xrange(n):
    print i
    vl2 = vol(vl)
    rotate(vl2, vl, step, 0, 0)
    vc2 = vol(vc)
    rotateCubic(vc2, vc, step, 0, 0)
    vs2 = vol(vs)
    rotateSpline(vs2, vs, step, 0, 0)
    vf = rotateFourierSpline(vf, step, 0, 0)
    vv = fourier_rotate_vol(vv, [step, 0, 0])

    # step = -step

vl.write('vl.em')
vc.write('vc.em')
vs.write('vs.em')
vf.write('vf.em')
vv.write('vv.em')

sl = FSC(v, vl, v.sizeX() / 2)
sc = FSC(v, vc, v.sizeX() / 2)
ss = FSC(v, vs, v.sizeX() / 2)
sf = FSC(v, vf, v.sizeX() / 2)
sv = FSC(v, vv, v.sizeX() / 2)

print sl
print sc
print ss
print sf
print sv
예제 #7
0
            randomize = float(randomize)
    except ValueError or randomize > 1 or randomize < 0:
        raise ValueError(
            'The value of randomizePhases should be a float between 0 and 1.')

    if outdir is None:
        outdir = './'

    if v1Filename and v2Filename:
        v1 = read(v1Filename)
        v2 = read(v2Filename)

        if not numberBands:
            numberBands = int(v1.sizeX() // 2)

        f = FSC(v1, v2, numberBands, mask, verbose)
        #f = [1, 0.9999816330959427, 0.9998727543638058, 0.9986706311763134, 0.9967503089610698, 0.9945473896086455, 0.9953391452631559, 0.9926167503040506, 0.9886499997836082, 0.9846988786130074, 0.9850170987613799, 0.9849222409268831, 0.9820779872082366, 0.981161445747785, 0.978102618561267, 0.9749670311874213, 0.9710488103484851, 0.9686564997495193, 0.9643854526532541, 0.9621314730670771, 0.9568606791204185, 0.9488084842261655, 0.9416015322427522, 0.9316703960630233, 0.9106972097966776, 0.8912878863048055, 0.8795187076235272, 0.8713474813842144, 0.8508750246010772, 0.8195820950483931, 0.8065990902773463, 0.7823660922709397, 0.7521861621134768, 0.7236765089946452, 0.6967229052025852, 0.6815563485825349, 0.6606856188994277, 0.6513326589007892, 0.6340321380485363, 0.6057709663336085, 0.584793117868313, 0.5612341962238455, 0.5623548376402193, 0.5564192235463952, 0.5397585867441497, 0.5089376925831242, 0.4647300273454635, 0.4310334881504598, 0.41741429413879966, 0.4195952490948154, 0.4066609275881065, 0.37019375197265786, 0.31936001816491055, 0.275903152373691, 0.2538399661514517, 0.24197349348826183, 0.20730706794873432, 0.1823204187105925, 0.17041895753522998, 0.16153106667416953, 0.13872290716093824, 0.12428131231796732, 0.09594749780671366, 0.09281895056407187, 0.0950512406930502, 0.07845013400157819, 0.06778918720241832, 0.05699422426625805, 0.04004787096713291, 0.035285330785697615, 0.02761223114687527, 0.029854265039150632, 0.030802679570736933, 0.02855574408867763, 0.04062783248396335, 0.046982827702621556, 0.044667285930674615, 0.03327190294513204, 0.028879433147898908, 0.019113096081122542, 0.018889519864393182, 0.03363102079214279, 0.030416314115916717, 0.015045702588444513, 0.007700419599421394, 0.013662921155622407, 0.02549288977161008, 0.01648898979277964, 0.004577992397744576, 0.003687537468279412, 0.015624522796941348, 0.012150048589636583, 0.013236997547964386, 0.024818980351894827, 0.017881736272355488, 0.008875703095090339, 0.004009836930167128, 0.005169522148403328, 0.013778610598594218, 0.024255111798589142]

        if verbose: print('FSC:\n', f)

        import pytom.tompy.correlation as correlation
        from pytom_numpy import vol2npy
        import numpy as np
        from pytom.tompy.io import write
        if randomize is None:
            for (ii, fscel) in enumerate(f):
                f[ii] = 2. * fscel / (1. + fscel)
            r = determineResolution(f, fscCriterion, verbose)
        else:
            randomizationFrequency = np.floor(
                determineResolution(np.array(f), randomize, verbose)[1])