def test_resize2D(self):
        """
        test re-sizing in Fourier space
        """
        from pytom.basic.transformations import resize
        from pytom_volume import vol
        from pytom.basic.fourier import fft

        dim = 32
        px = 11
        py = 19
        scf = dim * dim
        myVol = vol(dim, dim, 1)
        myVol.setAll(0.)
        myVol.setV(1., px, py, 0)
        #fmyVol = fft(myVol)
        (resizeVol, resizefVol) = resize(volume=myVol,
                                         factor=2.,
                                         interpolation='Fourier')
        resizeVol.write('test1.em')
        ftresizeVol = fft(data=resizeVol)
        for ix in range(resizefVol.sizeX()):
            for iy in range(resizefVol.sizeY()):
                diff = ftresizeVol.getV(
                    ix, iy, 0) - scf * 4 * resizefVol.getV(ix, iy, 0)
                self.assertTrue(expr=abs(diff) < .05,
                                msg="inconsistency FFT/IFFT for magnification")
        (resizeVol, resizefVol) = resize(volume=resizeVol,
                                         factor=.5,
                                         interpolation='Fourier')
        from pytom_volume import variance
        diff = myVol - resizeVol
        self.assertTrue(expr=variance(diff, False) < .0000001,
                        msg="2D image before and after rescales differs")
    def test_resize3D(self):
        """
        test 3D re-sizing in Fourier space
        """
        from pytom.basic.transformations import resize
        from pytom_volume import vol

        dim = 32
        px = 11
        py = 19
        pz = 21
        myVol = vol(dim, dim, dim)
        myVol.setAll(0.)
        myVol.setV(1., px, py, pz)
        (resizeVol, resizefVol) = resize(volume=myVol,
                                         factor=2.,
                                         interpolation='Fourier')
        (resizeVol, resizefVol) = resize(volume=resizeVol,
                                         factor=.5,
                                         interpolation='Fourier')
        from pytom_volume import variance
        diff = myVol - resizeVol
        self.assertTrue(expr=variance(diff, False) < .0000001,
                        msg="2D image before and after rescales differs")
def paverage(particleList, norm, binning, verbose, outdir='./'):
    from pytom_volume import read, vol
    from pytom_volume import transformSpline as transform
    from pytom.basic.structures import Particle
    from pytom.basic.normalise import mean0std1
    from pytom.tools.ProgressBar import FixedProgBar
    from pytom.basic.transformations import resize

    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

    result = None
    wedgeSum = None
    newParticle = None

    for particleObject in particleList:
        particle = read(particleObject.getFilename(), 0, 0, 0, 0, 0, 0, 0, 0,
                        0, 1, 1, 1)
        if binning != 1:
            particle, particlef = resize(volume=particle,
                                         factor=1. / binning,
                                         interpolation='Fourier')

        if norm:
            mean0std1(particle)

        wedgeInfo = particleObject.getWedge()
        if result 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

            result = vol(sizeX, sizeY, sizeZ)
            result.setAll(0.0)
            wedgeSum = wedgeInfo.returnWedgeVolume(sizeX, sizeY, sizeZ)
            wedgeSum.setAll(0)

        # create spectral wedge weighting
        rotation = particleObject.getRotation()
        wedge = wedgeInfo.returnWedgeVolume(sizeX, sizeY, sizeZ, False,
                                            rotation.invert())

        wedgeSum += 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)

        result += newParticle

        if verbose:
            numberAlignedParticles = numberAlignedParticles + 1
            progressBar.update(numberAlignedParticles)

    # write to the disk

    fname_result = os.path.join(outdir, 'avg_{}.em'.format(mpi.rank))
    fname_wedge = os.path.join(outdir, 'wedge_{}.em'.format(mpi.rank))

    result.write(fname_result)
    result = Particle(fname_result)
    wedgeSum.write(fname_wedge)
    wedgeSum = Particle(fname_wedge)

    return (result, wedgeSum)
Exemple #4
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
Exemple #5
0
def writeAlignedProjections(TiltSeries_,
                            weighting=None,
                            lowpassFilter=None,
                            binning=None,
                            verbose=False,
                            write_images=True):
    """write weighted and aligned projections to disk1

       @param TiltSeries_: Tilt Series
       @type TiltSeries_: reconstruction.TiltSeries
       @param weighting: weighting (<0: analytical weighting, >1 exact weighting (value corresponds to object diameter in pixel AFTER binning)
       @type weighting: float
       @param lowpassFilter: lowpass filter (in Nyquist)
       @type lowpassFilter: float
       @param binning: binning (default: 1 = no binning). binning=2: 2x2 pixels -> 1 pixel, binning=3: 3x3 pixels -> 1 pixel, etc.

       @author: FF
    """
    import numpy
    from pytom_numpy import vol2npy
    from pytom.basic.files import read_em, write_em
    from pytom.basic.functions import taper_edges
    from pytom.basic.transformations import general_transform2d
    from pytom.basic.fourier import ifft, fft
    from pytom.basic.filter import filter as filterFunction, bandpassFilter
    from pytom.basic.filter import circleFilter, rampFilter, exactFilter, fourierFilterShift, rotateFilter
    from pytom_volume import complexRealMult, vol
    import pytom_freqweight
    from pytom.basic.transformations import resize
    from pytom.gui.guiFunctions import fmtAR, headerAlignmentResults, datatypeAR
    import os

    if binning:
        imdim = int(float(TiltSeries_._imdim) / float(binning) + .5)
    else:
        imdim = TiltSeries_._imdim
    print('imdim', imdim)

    sliceWidth = imdim

    # pre-determine analytical weighting function and lowpass for speedup
    if (weighting != None) and (weighting < -0.001):
        w_func = fourierFilterShift(rampFilter(imdim, imdim))
    print('start weighting')
    # design lowpass filter
    if lowpassFilter:
        if lowpassFilter > 1.:
            lowpassFilter = 1.
            print("Warning: lowpassFilter > 1 - set to 1 (=Nyquist)")
        # weighting filter: arguments: (angle, cutoff radius, dimx, dimy,
        lpf = pytom_freqweight.weight(0.0, lowpassFilter * imdim / 2, imdim,
                                      imdim // 2 + 1, 1,
                                      lowpassFilter / 5. * imdim)
        #lpf = bandpassFilter(volume=vol(imdim, imdim,1),lowestFrequency=0,highestFrequency=int(lowpassFilter*imdim/2),
        #                     bpf=None,smooth=lowpassFilter/5.*imdim,fourierOnly=False)[1]

    tilt_angles = []

    for projection in TiltSeries_._ProjectionList:
        tilt_angles.append(projection._tiltAngle)
    tilt_angles = sorted(tilt_angles)
    print(tilt_angles)
    #q = numpy.matrix(abs(numpy.arange(-imdim//2, imdim//2)))

    alignmentResults = numpy.zeros((len(TiltSeries_._ProjectionList)),
                                   dtype=datatypeAR)
    alignmentResults['TiltAngle'] = tilt_angles

    for (ii, projection) in enumerate(TiltSeries_._ProjectionList):

        alignmentResults['FileName'][ii] = os.path.join(
            os.getcwd(), projection._filename)
        transX = -projection._alignmentTransX / binning
        transY = -projection._alignmentTransY / binning
        rot = -(projection._alignmentRotation + 90.)
        mag = projection._alignmentMagnification

        alignmentResults['AlignmentTransX'][ii] = transX
        alignmentResults['AlignmentTransY'][ii] = transY
        alignmentResults['InPlaneRotation'][ii] = rot
        alignmentResults['Magnification'][ii] = mag

        if write_images:
            if projection._filename.split('.')[-1] == 'st':
                from pytom.basic.files import EMHeader, read
                header = EMHeader()
                header.set_dim(x=imdim, y=imdim, z=1)
                idx = projection._index
                if verbose:
                    print("reading in projection %d" % idx)
                image = read(file=projection._filename,
                             subregion=[
                                 0, 0, idx - 1, TiltSeries_._imdim,
                                 TiltSeries_._imdim, 1
                             ],
                             sampling=[0, 0, 0],
                             binning=[0, 0, 0])
                if not (binning == 1) or (binning == None):
                    image = resize(volume=image, factor=1 / float(binning))[0]
            else:
                # read projection files
                from pytom.basic.files import EMHeader, read, read_em_header
                print(projection._filename)
                image = read(projection._filename)
                image = resize(volume=image, factor=1 / float(binning))[0]

                if projection._filename[-3:] == '.em':
                    header = read_em_header(projection._filename)
                else:
                    header = EMHeader()
                    header.set_dim(x=imdim, y=imdim, z=1)

            if lowpassFilter:
                filtered = filterFunction(volume=image,
                                          filterObject=lpf,
                                          fourierOnly=False)
                image = filtered[0]
            tiltAngle = projection._tiltAngle
            header.set_tiltangle(tiltAngle)
            # normalize to contrast - subtract mean and norm to mean
            immean = vol2npy(image).mean()
            image = (image - immean) / immean
            # smoothen borders to prevent high contrast oscillations
            image = taper_edges(image, imdim // 30)[0]
            # transform projection according to tilt alignment

            if projection._filename.split('.')[-1] == 'st':
                newFilename = (TiltSeries_._alignedTiltSeriesName + "_" +
                               str(projection.getIndex()) + '.em')
            else:
                TiltSeries_._tiltSeriesFormat = 'mrc'
                newFilename = (TiltSeries_._alignedTiltSeriesName + "_" +
                               str(projection.getIndex()) + '.' +
                               TiltSeries_._tiltSeriesFormat)
            if verbose:
                tline = ("%30s" % newFilename)
                tline = tline + (" (tiltAngle=%6.2f)" % tiltAngle)
                tline = tline + (": transX=%6.1f" % transX)
                tline = tline + (", transY=%6.1f" % transY)
                tline = tline + (", rot=%6.2f" % rot)
                tline = tline + (", mag=%5.4f" % mag)
                print(tline)

            image = general_transform2d(v=image,
                                        rot=rot,
                                        shift=[transX, transY],
                                        scale=mag,
                                        order=[2, 1, 0],
                                        crop=True)

            # smoothen once more to avoid edges
            image = taper_edges(image, imdim // 30)[0]

            # analytical weighting
            if (weighting != None) and (weighting < 0):
                image = (ifft(complexRealMult(fft(image), w_func)) /
                         (image.sizeX() * image.sizeY() * image.sizeZ()))

            elif (weighting != None) and (weighting > 0):
                if abs(weighting - 2) < 0.001:
                    w_func = fourierFilterShift(
                        rotateFilter(tilt_angles, tiltAngle, imdim, imdim,
                                     sliceWidth))
                else:
                    w_func = fourierFilterShift(
                        exactFilter(tilt_angles, tiltAngle, imdim, imdim,
                                    sliceWidth))

                image = (ifft(complexRealMult(fft(image), w_func)) /
                         (image.sizeX() * image.sizeY() * image.sizeZ()))
            header.set_tiltangle(tilt_angles[ii])

            if newFilename.endswith('.mrc'):
                data = copy.deepcopy(vol2npy(image))
                mrcfile.new(newFilename,
                            data.T.astype(float32),
                            overwrite=True)
            else:
                write_em(filename=newFilename, data=image, header=header)

            if verbose:
                tline = ("%30s written ..." % newFilename)

    outname = os.path.join(os.path.dirname(TiltSeries_._alignedTiltSeriesName),
                           'alignmentResults.txt')
    numpy.savetxt(outname,
                  alignmentResults,
                  fmt=fmtAR,
                  header=headerAlignmentResults)
    print('Alignment successful. See {} for results.'.format(outname))
Exemple #6
0
    def run(self, verbose=False):
        from sh_alignment.frm import frm_align
        from sh_alignment.constrained_frm import frm_constrained_align, AngularConstraint
        from pytom.basic.structures import Shift, Rotation
        from pytom.tools.ProgressBar import FixedProgBar
        from pytom.basic.transformations import resize, resizeFourier
        binningType = 'Fourier'

        while True:
            # get the job
            try:
                job = self.get_job()
            except:
                if verbose:
                    print(self.node_name + ': end')
                break  # get some non-job message, break it

            if verbose:
                prog = FixedProgBar(0,
                                    len(job.particleList) - 1,
                                    self.node_name + ':')
                i = 0
            ref = job.reference.getVolume()
            if job.binning > 1:
                ref = resize(volume=ref,
                             factor=1. / job.binning,
                             interpolation=binningType)
                if type(ref) == tuple:
                    ref = ref[0]
            # re-set max frequency in case it exceeds Nyquist - a bit brute force
            job.freq = min(job.freq, ref.sizeX() // 2 - 1)
            # run the job
            for p in job.particleList:
                if verbose:
                    prog.update(i)
                    i += 1
                v = p.getVolume()
                if job.binning > 1:
                    v = resize(volume=v,
                               factor=1. / job.binning,
                               interpolation=binningType)
                    if type(v) == tuple:
                        v = v[0]
                mask = job.mask.getVolume()
                if job.binning > 1:
                    mask = resize(volume=mask,
                                  factor=1. / job.binning,
                                  interpolation='Spline')
                    if type(mask) == tuple:
                        mask = mask[0]
                if job.constraint:
                    constraint = job.constraint
                    if job.constraint.type == AngularConstraint.ADP_ANGLE:  # set the constraint around certain angle
                        rot = p.getRotation()
                        constraint.setAngle(rot.getPhi(), rot.getPsi(),
                                            rot.getTheta())
                    #pos, angle, score = frm_constrained_align(v, p.getWedge(), ref, None, job.bw_range, job.freq, job.peak_offset, job.mask.getVolume(), constraint)
                    if job.binning > 1:
                        pos, angle, score = frm_constrained_align(
                            v, p.getWedge(), ref, None, job.bw_range, job.freq,
                            job.peak_offset / job.binning, mask, constraint)
                    else:
                        pos, angle, score = frm_constrained_align(
                            v, p.getWedge(), ref, None, job.bw_range, job.freq,
                            job.peak_offset, mask, constraint)
                else:
                    #pos, angle, score = frm_align(v, p.getWedge(), ref, None, job.bw_range, job.freq, job.peak_offset, job.mask.getVolume())
                    #if job.binning >1:
                    #    print(job.peak_offset)
                    #    print(type(job.peak_offset))
                    #    print(job.peak_offset/job.binning)
                    #    print(type(job.binning))
                    #    pos, angle, score = frm_align(v, p.getWedge(), ref, None, job.bw_range, job.freq,
                    #                            job.peak_offset/job.binning, mask)
                    #else:
                    pos, angle, score = frm_align(v, p.getWedge(), ref, None,
                                                  job.bw_range, job.freq,
                                                  job.peak_offset, mask)

                if job.binning > 1:
                    pos[0] = job.binning * (pos[0] - v.sizeX() / 2)
                    pos[1] = job.binning * (pos[1] - v.sizeY() / 2)
                    pos[2] = job.binning * (pos[2] - v.sizeZ() / 2)
                    p.setShift(Shift([pos[0], pos[1], pos[2]]))
                else:
                    p.setShift(
                        Shift([
                            pos[0] - v.sizeX() / 2, pos[1] - v.sizeY() / 2,
                            pos[2] - v.sizeZ() / 2
                        ]))
                p.setRotation(Rotation(angle))
                p.setScore(FRMScore(score))

            # average the particle list
            name_prefix = os.path.join(
                job.destination, self.node_name + '_' + str(job.max_iter))
            self.average_sub_pl(job.particleList, name_prefix, job.weighting)

            # send back the result
            self.send_result(
                FRMResult(name_prefix, job.particleList, self.mpi_id))

        pytom_mpi.finalise()
Exemple #7
0
def subPixelPeak(scoreVolume,
                 coordinates,
                 cubeLength=8,
                 interpolation='Spline',
                 verbose=False):
    """
    subPixelPeak: Will determine the sub pixel area of peak. Utilizes spline, fourier or parabolic interpolation.

    @param verbose: be talkative
    @type verbose: L{str}
    @param scoreVolume: The score volume
    @param coordinates: [x,y,z] coordinates where the sub pixel peak will be determined
    @param cubeLength: length of cube - only used for Spline and Fourier interpolation
    @type cubeLength: int (even)
    @param interpolation: interpolation type: 'Spline', 'Quadratic', or 'Fourier'
    @type interpolation: str
    @return: Returns [peakValue,peakCoordinates] with sub pixel accuracy

    last change: 02/07/2013 FF: 2D functionality added
    """
    assert type(
        interpolation) == str, 'subPixelPeak: interpolation must be str'
    if (interpolation.lower() == 'quadratic') or (interpolation.lower()
                                                  == 'parabolic'):
        (peakValue,
         peakCoordinates) = subPixelPeakParabolic(scoreVolume=scoreVolume,
                                                  coordinates=coordinates,
                                                  verbose=verbose)
        return [peakValue, peakCoordinates]

    if gpu:
        import cupy as xp
    else:
        import numpy as xp

    from pytom_volume import vol, subvolume, rescaleSpline, peak
    from pytom.basic.transformations import resize

    #extend function for 2D
    twoD = (scoreVolume.shape) == 2

    cubeStart = cubeLength // 2
    sizeX = scoreVolume.sizeX()
    sizeY = scoreVolume.sizeY()
    sizeZ = scoreVolume.sizeZ()

    if twoD:
        if (coordinates[0]-cubeStart < 1 or coordinates[1]-cubeStart < 1) or\
            (coordinates[0]-cubeStart + cubeLength >= sizeX or coordinates[1]-cubeStart + cubeLength >= sizeY):
            if verbose:
                print(
                    "SubPixelPeak: position too close to border for sub-pixel")
            return [
                scoreVolume(coordinates[0], coordinates[1], coordinates[2]),
                coordinates
            ]

        subVolume = subvolume(scoreVolume, coordinates[0] - cubeStart,
                              coordinates[1] - cubeStart, 0, cubeLength,
                              cubeLength, 1)
    else:
        if (coordinates[0]-cubeStart < 1 or coordinates[1]-cubeStart < 1 or coordinates[2]-cubeStart < 1) or \
                (coordinates[0]-cubeStart + cubeLength >= sizeX or coordinates[1]-cubeStart + cubeLength >= sizeY or \
                 coordinates[2]-cubeStart + cubeLength >= sizeZ):
            if verbose:
                print(
                    "SubPixelPeak: position too close to border for sub-pixel")
            return [
                scoreVolume(coordinates[0], coordinates[1], coordinates[2]),
                coordinates
            ]

        subVolume = subvolume(scoreVolume, coordinates[0] - cubeStart,
                              coordinates[1] - cubeStart,
                              coordinates[2] - cubeStart, cubeLength,
                              cubeLength, cubeLength)

    #size of interpolated volume
    scaleSize = 10 * cubeLength

    #ratio between interpolation area and large volume
    scaleRatio = 1.0 * cubeLength / scaleSize

    #resize into bigger volume
    if interpolation == 'Spline':
        if twoD:
            subVolumeScaled = vol(scaleSize, scaleSize, 1)
        else:
            subVolumeScaled = vol(scaleSize, scaleSize, scaleSize)
        rescaleSpline(subVolume, subVolumeScaled)
    else:
        subVolumeScaled = resize(volume=subVolume, factor=10)[0]

    peakCoordinates = peak(subVolumeScaled)

    peakValue = subVolumeScaled(peakCoordinates[0], peakCoordinates[1],
                                peakCoordinates[2])

    #calculate sub pixel coordinates of interpolated peak
    peakCoordinates[
        0] = peakCoordinates[0] * scaleRatio - cubeStart + coordinates[0]
    peakCoordinates[
        1] = peakCoordinates[1] * scaleRatio - cubeStart + coordinates[1]
    if twoD:
        peakCoordinates[2] = 0
    else:
        peakCoordinates[
            2] = peakCoordinates[2] * scaleRatio - cubeStart + coordinates[2]
    if (peakCoordinates[0] > scoreVolume.sizeX()
            or peakCoordinates[1] > scoreVolume.sizeY()
            or peakCoordinates[2] > scoreVolume.sizeZ()):
        if verbose:
            print(
                "SubPixelPeak: peak position too large :( return input value")
        #something went awfully wrong here. return regular value
        return [
            scoreVolume(coordinates[0], coordinates[1], coordinates[2]),
            coordinates
        ]

    return [peakValue, peakCoordinates]