Пример #1
0
    def test_FRM(self):
        import swig_frm
        from sh_alignment.frm import frm_align
        from pytom_volume import vol, rotate, shift
        from pytom.basic.structures import Rotation, Shift
        from pytom.tools.maths import rotation_distance

        v = vol(32,32,32)
        v.setAll(0)
        vMod = vol(32,32,32)
        vRot = vol(32,32,32)
        v.setV(1,10,10,10)
        v.setV(1,20,20,20)
        v.setV(1,15,15,15)
        v.setV(1,7,21,7)
        
        rotation = Rotation(10,20,30)
        shiftO = Shift(1,-3,5)
        
        rotate(v,vRot,rotation.getPhi(),rotation.getPsi(),rotation.getTheta())
        shift(vRot,vMod,shiftO.getX(),shiftO.getY(),shiftO.getZ())
        
        pos, ang, score = frm_align(vMod, None, v, None, [4, 64], 10)
        rotdist = rotation_distance(ang1=rotation, ang2=ang)
        diffx = shiftO[0] - (pos[0] - 16)
        diffy = shiftO[1] - (pos[1] - 16)
        diffz = shiftO[2] - (pos[2] - 16)

        self.assertTrue( rotdist < 5., msg='Rotations are different')
        self.assertTrue( diffx < .5, msg='x-difference > .5')
        self.assertTrue( diffy < .5, msg='y-difference > .5')
        self.assertTrue( diffz < .5, msg='z-difference > .5')
Пример #2
0
    def fromXML(self, xmlObj):
        """
        fromXML : Assigns values to result attributes from XML object
        @param xmlObj: A xml object  
        @author: Thomas Hrabe 
        """
        from lxml.etree import _Element

        if xmlObj.__class__ != _Element:
            from pytom.basic.exceptions import ParameterError
            raise ParameterError(
                'Is not a lxml.etree._Element! You must provide a valid XML object.'
            )

        from pytom.score.score import fromXML as fromXMLScore
        from pytom.angles.angle import AngleObject

        if xmlObj.tag == "Result":
            result = xmlObj
        else:
            result = xmlObj.xpath('Result')

            if len(result) == 0:
                raise PyTomClassError(
                    "This XML is not an MaximisationResult. No Result provided."
                )

            result = result[0]
        from pytom.basic.structures import Particle, Reference, Rotation, Shift
        particle_element = result.xpath('Particle')[0]
        p = Particle('')
        p.fromXML(particle_element)
        self._particle = p

        r = result.xpath('Reference')
        ref = Reference('')
        ref.fromXML(r[0])
        self._reference = ref

        scoreXML = result.xpath('Score')[0]
        self._score = fromXMLScore(scoreXML)

        shiftXML = result.xpath('Shift')[0]
        self._shift = Shift()
        self._shift.fromXML(shiftXML)

        rotationXML = result.xpath('Rotation')[0]
        self._rotation = Rotation()
        self._rotation.fromXML(rotationXML)

        angleElement = result.xpath('Angles')
        ang = AngleObject()
        self._angleObject = ang.fromXML(angleElement[0])
Пример #3
0
    def __init__(self,
                 particle='',
                 reference=-1.0,
                 score=-1.0,
                 shift=-1.0,
                 rotation=-1.0,
                 angleObject=-1):

        from pytom.basic.structures import Particle, Reference, Shift, Rotation
        from numpy import long

        if particle.__class__ == str:
            self._particle = Particle(particle)
        elif particle.__class__ == Particle:
            self._particle = particle
        else:
            self._particle = Particle()

        if reference.__class__ == str:
            self._reference = Reference(reference)
        elif reference.__class__ == Reference:
            self._reference = reference
        else:
            self._reference = Reference()

        if shift.__class__ == list:
            self._shift = Shift(shift)
        elif shift.__class__ == float:
            self._shift = Shift()
        else:
            self._shift = shift

        if rotation.__class__ == list:
            self._rotation = Rotation(rotation)
        elif rotation.__class__ == Rotation:
            self._rotation = rotation
        else:
            self._rotation = Rotation()

        if score.__class__ == float:
            from pytom.score.score import xcfScore
            self._score = xcfScore()
        else:
            self._score = score

        if angleObject.__class__ == float or isinstance(
                angleObject, (int, long)):
            from pytom.angles.angleList import AngleList
            self._angleObject = AngleList()
        else:
            self._angleObject = angleObject
Пример #4
0
    def getShift(self):
        from pytom.basic.structures import Shift

        if self._shift.__class__ == list:
            return Shift(self._shift)
        else:
            return self._shift
Пример #5
0
def frm_proxy(p, ref, freq, offset, binning, mask):
    from pytom_volume import read, pasteCenter, vol
    from pytom.basic.transformations import resize
    from pytom.basic.structures import Shift, Rotation
    from sh_alignment.frm import frm_align
    import time

    v = p.getVolume(binning)

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

    pos, angle, score = frm_align(v, p.getWedge(), ref.getVolume(), None,
                                  [4, 64], freq, offset, mask)

    return (Shift([
        pos[0] - v.sizeX() // 2, pos[1] - v.sizeY() // 2,
        pos[2] - v.sizeZ() // 2
    ]), Rotation(angle), score, p.getFilename())
Пример #6
0
def general_transform2d(v, rot=None, shift=None, scale=None, order=[0, 1, 2], crop=True):
    """Perform general transformation of 2D data using 3rd order spline interpolation.
    @param v: volume in 2d (it's got to be an image)
    @type v: L{pytom_volume.vol}
    @param rot: rotate
    @type rot: float
    @param shift: shift
    @type shift: L{pytom.basic.structures.Shift} or list [x,y]
    @param scale: uniform scale
    @type scale: float
    @param order: the order in which the three operations are performed (smaller means first) \
    e.g.: [2,1,0]: rotation: 2, scale: 1, translation:0 => translation 1st
    @type order: list
    @param crop: crop the resulting volume to have the same size as original volume (default: True)
    @type crop: boolean
    @return: pytom_volume
    """
    from pytom.basic.structures import Shift

    from pytom_volume import vol
    if not isinstance(v,vol):
        if isinstance(v,tuple) and isinstance(v[0],vol):
            v = v[0]
        else:
            raise TypeError('general_transform2d: v must be of type pytom_volume.vol! Got ' + str(v.__class__) + ' instead!')
    if v.sizeZ() != 1:
        raise RuntimeError('general_transform2d: v must be 2D!')
    if rot is None:
        rot = [0., 0., 0.]
    elif rot.__class__ != int and rot.__class__ != float:
        raise RuntimeError("Please provide only 1 angle because you are dealing with 2D data!")
    else:
        rot = [rot, 0., 0.]

    if shift.__class__ == list and len(shift) == 2:
        shift = Shift(shift[0], shift[1], 0.)
    if shift.__class__ == list and len(shift) == 3:
        shift = Shift(shift[0], shift[1], 0.) # you cannot shift 2D image along z axis, can you?

    if crop:
        vv= general_transform_crop(v, rot=rot, shift=shift, scale=[scale, scale, 1], order=order)
    else:
        vv = general_transform(v, rot, shift, [scale, scale, 1], order)
    return vv
Пример #7
0
def writeCroppedParticles(particleListName, output, center, cubesize):
    """
    @param particleListName: name of particle list
    @type particleListName: str
    @param output: Name of output particles
    @type output: str
    @param center: center of output particles in template orientation
    @type center: list
    @param cubesize: Size of output particles in pixel
    @type cubesize: int

    """
    from pytom.basic.structures import ParticleList, Particle, Shift
    from pytom_volume import transformSpline as transform
    from pytom_volume import subvolume, vol


    pl = ParticleList()
    pl.fromXMLFile(filename=particleListName)
    #copy particle list for list of cropped particles
    pl_new = pl.copy()
    pvol = pl[0].getVolume()
    sizeX = pvol.sizeX() 
    sizeY = pvol.sizeY()
    sizeZ = pvol.sizeZ() 
    pvol_ali = vol(sizeX, sizeY, sizeZ) 
    subV = vol(cubesize, cubesize, cubesize)

    sub_startX = center[0]-cubesize/2
    sub_startY = center[1]-cubesize/2
    sub_startZ = center[2]-cubesize/2
    if (sub_startX < 0) or (sub_startY < 0) or (sub_startZ < 0):
        raise ValueError('cubesize too large :(')

    for (ipart, part) in enumerate(pl):
        pvol_ali.setAll(0) 
        subV.setAll(0)
        pvol = part.getVolume()
        rot = part.getRotation()
        rotinvert = rot.invert()
        shiftV = part.getShift() 
        transform(pvol, pvol_ali, rotinvert[0], rotinvert[1], rotinvert[2], 
                  sizeX/2, sizeY/2, sizeZ/2, -shiftV[0], -shiftV[1], -shiftV[2], 0, 0, 0) 
        # box out subvolume
        subV = subvolume(pvol_ali,  sub_startX, sub_startY, sub_startZ, cubesize, cubesize, cubesize)
        transform(subV, subV, rot[0], rot[1], rot[2], cubesize/2, cubesize/2, cubesize/2, 0, 0, 0, 0, 0, 0)
        fname = part.getFilename()
        idx = fname.split('_')[-1].split('.')[0] 
        nfname = output+'_'+idx+'.em'
        print("write file " + nfname)
        subV.write(nfname)
        pl_new[ipart].setFilename(newFilename=nfname)
        pl_new[ipart].setShift(shift=Shift(0,0,0))
    return pl_new
Пример #8
0
    def run(self, verbose=False):
        from sh_alignment.frm import frm_align
        from pytom.basic.structures import Shift, Rotation
        from pytom.tools.ProgressBar import FixedProgBar

        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[0].getVolume()
            # run the job
            for p in job.particleList:
                if verbose:
                    prog.update(i)
                    i += 1
                v = p.getVolume()

                pos, angle, score = frm_align(v, p.getWedge(), ref, None,
                                              job.bw_range, job.freq,
                                              job.peak_offset,
                                              job.mask.getVolume())

                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(
                self.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()
Пример #9
0
def FRMAlignmentWrapper(particle,wedgeParticle, reference, wedgeReference,bandwidth, highestFrequency, mask = None , peakPrior = None):
    """
    FRMAlignmentWrapper: Wrapper for frm_align to handle PyTom objects.
    @param particle: The particle 
    @type particle: L{pytom.basic.structures.Particle}
    @param wedgeParticle: Wedge object of particle
    @type wedgeParticle: L{pytom.basic.structures.Wedge} 
    @param reference: Reference used for alignment
    @type reference: L{pytom.basic.structures.Reference}
    @param wedgeReference: Information about reference wedge 
    @type wedgeReference: L{pytom.basic.structures.Wedge}
    @param bandwidth: The bandwidth of the spherical harmonics - lowestBand used, highestBand used 
    @type bandwidth: [lowestBand,highestBand]
    @param highestFrequency: Highest frequency for lowpass filter in fourierspace
    @type highestFrequency: int
    @param mask: Mask that is applied to the particle
    @type mask: L{pytom.basic.structures.Mask}
    @param peakPrior: Maximum distance of peak from origin
    @type peakPrior: L{pytom.score.score.PeakPrior} or an integer
    @return: Returns a list of [L{pytom.basic.structures.Shift}, L{pytom.basic.structures.Rotation}, scoreValue]
    """
    from pytom.basic.structures import Particle,Reference,Mask,Wedge,Shift,Rotation
    from pytom.score.score import PeakPrior
    from sh_alignment.frm import frm_align
    
    if particle.__class__ == Particle:
        particle = particle.getVolume()
    
    if reference.__class__ == Reference:
        reference = reference.getVolume()
    
    if mask.__class__ == Mask:
        mask = mask.getVolume()
    else:
        mask = None
        
    if bandwidth.__class__ == list and len(bandwidth) != 2:
        raise RuntimeError('Bandwidth parameter must be a list of two integers!')

    if peakPrior and peakPrior.__class__ == PeakPrior:
        peakPrior = int(peakPrior.getRadius())
    
    if not peakPrior or peakPrior < 0.0001:
        peakPrior = None
        
    pos, angle, score = frm_align(particle, wedgeParticle.getWedgeObject(), reference*mask, wedgeReference.getWedgeObject(), bandwidth, int(highestFrequency), peakPrior)
            
    return [Shift([pos[0]-particle.sizeX()/2, pos[1]-particle.sizeY()/2, pos[2]-particle.sizeZ()/2]), Rotation(angle), score]
Пример #10
0
    def vector2transRot(self, rot_trans):
        """
        convert 6-dimensional vector to rotation and translation

        @param rot_trans: rotation and translation vector (6-dim: z1,z2,x \
            angles, x,y,z, translations)
        @type rot_trans: L{list}
        @return: rotation of vol2, translation of vol2
        @rtype: L{pytom.basic.Rotation}, L{pytom.basic.Shift}
        @author: FF
        """
        from pytom.basic.structures import Rotation, Shift

        rot = Rotation()
        trans = Shift()
        for ii in range(0, 3):
            rot[ii] = self.rot_trans[ii]
        for ii in range(3, 6):
            trans[ii - 3] = self.rot_trans[ii]
        return rot, trans
Пример #11
0
    def run(self, verbose=False):
        from pytom.gui.additional.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

        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()
            # run the job
            for p in job.particleList:
                if verbose:
                    prog.update(i)
                    i += 1
                v = p.getVolume()

                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)
                else:
                    pos, angle, score = frm_align(v, p.getWedge(), ref, None,
                                                  job.bw_range, job.freq,
                                                  job.peak_offset,
                                                  job.mask.getVolume())

                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 = 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()
Пример #12
0
def alignTwoVolumes(particle,reference,angleObject,mask,score,preprocessing,progressBar=False):
    """
    alignTwoVolumes: align two volumes with respect to each other
    @param particle: volume to be aligned
    @param reference: reference volume (not translated and rotated)
    @param angleObject: angular sampling
    @param mask: mask volume
    @param score: score type
    @param preprocessing: preprocessing parameters
    @param progressBar: show progress bar
    @type progressBar: bool
    """
    
    from pytom.alignment.structures import GrowingAverageInterimResult
    from pytom.basic.structures import Rotation,Shift
    
    partVolume = particle.getVolume()
    
    refVolume = reference.getVolume() 

    refWeight = reference.getWeighting()

    peak = bestAlignment(partVolume,refVolume,refWeight,particle.getWedge(),
            angleObject,score,mask,preprocessing)
    
    score.setValue(peak.getScoreValue())
    
    return GrowingAverageInterimResult(particle,reference,Rotation(peak.getRotation()),Shift(peak.getShift()),score)
Пример #13
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
Пример #14
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()
Пример #15
0
    def run(self, verbose=False):
        from sh_alignment.frm import frm_align
        from pytom.basic.structures import Shift, Rotation
        from pytom.tools.ProgressBar import FixedProgBar
        from pytom.basic.fourier import convolute
        from pytom_volume import read, power

        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 = []
            ref.append(job.reference[0].getVolume())
            ref.append(job.reference[1].getVolume())

            # convolute with the approximation of the CTF
            if job.sum_ctf_sqr:
                ctf = read(job.sum_ctf_sqr)
                power(ctf,
                      0.5)  # the number of CTFs should not matter, should it?
                ref0 = ref[0]
                ref1 = ref[1]
                ref0 = convolute(ref0, ctf, True)
                ref1 = convolute(ref1, ctf, True)
                ref = [ref0, ref1]

            if job.bfactor and job.bfactor != 'None':
                #                restore_kernel = create_bfactor_restore_vol(ref.sizeX(), job.sampleInformation.getPixelSize(), job.bfactor)
                from pytom_volume import vol, read
                bfactor_kernel = read(job.bfactor)
                unit = vol(bfactor_kernel)
                unit.setAll(1)
                restore_kernel = unit / bfactor_kernel

            # run the job
            for p in job.particleList:
                if verbose:
                    prog.update(i)
                    i += 1
                v = p.getVolume()

                #                if weights is None: # create the weights according to the bfactor
                #                    if job.bfactor == 0:
                #                        weights = [1 for k in xrange(job.freq)]
                #                    else:
                #                        restore_fnc = create_bfactor_restore_fnc(ref.sizeX(), job.sampleInformation.getPixelSize(), job.bfactor)
                #                        # cut out the corresponding part and square it to get the weights!
                #                        weights = restore_fnc[1:job.freq+1]**2

                if job.bfactor and job.bfactor != 'None':
                    v = convolute(v, restore_kernel,
                                  True)  # if bfactor is set, restore it

                pos, angle, score = frm_align(v, p.getWedge(),
                                              ref[int(p.getClass())], None,
                                              job.bw_range, job.freq,
                                              job.peak_offset,
                                              job.mask.getVolume())

                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 = self.node_name + '_' + str(job.max_iter)
            pair = ParticleListPair('', job.ctf_conv_pl, None, None)
            pair.set_phase_flip_pl(job.particleList)
            self.average_sub_pl(
                pair.get_ctf_conv_pl(),
                name_prefix)  # operate on the CTF convoluted projection!

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

        pytom_mpi.finalise()
Пример #16
0
def create_RandomParticleList(reffile,
                              pl_filename='pl.xml',
                              pdir='./testparticles',
                              nparticles=10):
    """
    @param reffile: reference file
    @type reffile: C{str}
    @param nparticles: number of particles (default: 10)
    @type nparticles: C{int}
    @param pl_filename: particle list filename
    @type pl_filename: C{str}
    @param pdir: particle directory
    @type pdir: C{str}
    @return: particleList
    @rtype: L{pytom.basic.ParticleList}
    
    """
    from pytom.basic.structures import Particle, ParticleList, Rotation, Shift, Wedge
    from pytom_volume import vol, rotate, shift, read
    from pytom.basic.transformations import general_transform_crop
    from pytom.basic.functions import initSphere
    from pytom.simulation.whiteNoise import add as addNoise
    import random
    from os import mkdir
    from pytom.score.score import FLCFScore as score

    try:
        mkdir(pdir)
    except FileExistsError:
        print('directory ' + pdir + ' existed already - using this one')
    random.seed(0)

    a = 0

    wedge = Wedge(wedgeAngles=[30.0, 30.0], cutoffRadius=50.0)

    pl = ParticleList(directory='./')
    ref1 = read(reffile)
    ref2 = initSphere(sizeX=ref1.sizeX(),
                      sizeY=ref1.sizeY(),
                      sizeZ=ref1.sizeZ(),
                      radius=45)
    #ref2.write('testData/mask_45.em')
    parts = {0: ref1, 1: ref2}

    for ii in range(0, nparticles):
        if not ii % 2:
            ref = read(reffile)
        else:
            ref = initSphere(sizeX=ref1.sizeX(),
                             sizeY=ref1.sizeY(),
                             sizeZ=ref1.sizeZ(),
                             radius=30,
                             smooth=30 / 10)

        rot = Rotation(random.uniform(0, 360), random.uniform(0, 360),
                       random.uniform(0, 180))
        shift = Shift(x=a * random.uniform(-5, 5),
                      y=a * random.uniform(-5, 5),
                      z=a * random.uniform(-5, 5))
        rotvol = general_transform_crop(v=ref,
                                        rot=rot,
                                        shift=shift,
                                        scale=None,
                                        order=[0, 1, 2])
        # add some noise
        noisy = addNoise(volume=rotvol, SNR=1)
        fname = pdir + '/particle_' + str(ii) + '.em'

        #noisy.write( fname)
        p = Particle(filename=fname,
                     rotation=rot,
                     shift=shift,
                     wedge=wedge,
                     className=0,
                     pickPosition=None,
                     score=score,
                     sourceInfo=None)
        p.setScoreValue(0.0)

        wg = p.getWedge().getWedgeObject()
        wg.apply(noisy, Rotation(0, 0, 0)).write(fname)

        pl.append(particle=p)

    pl.setFileName(filename=pl_filename)
    pl.toXMLFile(filename=pl_filename)
    return pl
Пример #17
0
def create_RandomParticleList(reffile,
                              pl_filename='pl.xml',
                              pdir='./testparticles',
                              nparticles=10):
    """
    @param reffile: reference file
    @type reffile: C{str}
    @param nparticles: number of particles (default: 10)
    @type nparticles: C{int}
    @param pl_filename: particle list filename
    @type pl_filename: C{str}
    @param pdir: particle directory
    @type pdir: C{str}
    @return: particleList
    @rtype: L{pytom.basic.ParticleList}
    
    """
    from pytom.basic.structures import Particle, ParticleList, Rotation, Shift
    from pytom_volume import vol, rotate, shift, read
    from pytom.basic.transformations import general_transform_crop
    from pytom.simulation.whiteNoise import add as addNoise
    import random
    from os import mkdir
    from pytom.score.score import FLCFScore as score

    try:
        mkdir(pdir)
    except FileExistsError:
        print('directory ' + pdir + ' existed already - using this one')
    random.seed(0)

    pl = ParticleList(directory='./')
    ref = read(reffile)
    for ii in range(0, nparticles):
        rot = Rotation(random.uniform(0, 360), random.uniform(0, 360),
                       random.uniform(0, 180))
        shift = Shift(x=random.uniform(-5, 5),
                      y=random.uniform(-5, 5),
                      z=random.uniform(-5, 5))
        rotvol = general_transform_crop(v=ref,
                                        rot=rot,
                                        shift=shift,
                                        scale=None,
                                        order=[0, 1, 2])
        # add some noise
        noisy = addNoise(volume=rotvol, SNR=1)
        fname = pdir + '/particle_' + str(ii) + '.em'
        noisy.write(fname)
        p = Particle(filename=fname,
                     rotation=rot,
                     shift=shift,
                     wedge=None,
                     className=0,
                     pickPosition=None,
                     score=score,
                     sourceInfo=None)
        p.setScoreValue(0.0)
        pl.append(particle=p)

    pl.setFileName(filename=pl_filename)
    pl.toXMLFile(filename=pl_filename)
    return pl
Пример #18
0
def general_transform(v, rot=None, shift=None, scale=None, order=[0, 1, 2]):
    """Perform general transformation using 3rd order spline interpolation.
    @param v: volume
    @type v: L{pytom_volume.vol}
    @param rot: rotate
    @type rot: pytom.basic.structures.Rotate or list
    @param shift: shift
    @type shift: pytom.basic.structures.Shift or list
    @param scale: scale / magnification along each dimension
    @type scale: list
    @param order: the order in which the three operations are performed (smaller means first)
    @type order: list
    @return: pytom_volume
    """
    from pytom.basic.structures import Rotation, Shift

    from pytom_volume import vol
    if not isinstance(v,vol):
        raise TypeError('general_transform: v must be of type pytom_volume.vol! Got ' + str(v.__class__) + ' instead!')

    if rot is None:
        rot = Rotation(0.,0.,0.)
    if rot.__class__ == list and len(rot) == 3:
        rot = Rotation(rot[0], rot[1], rot[2])
    if shift is None:
        shift = Shift(0.,0.,0.)
    if shift.__class__ == list and len(shift) == 3:
        shift = Shift(shift[0], shift[1], shift[2])
    if scale is None:
        scale = [1.0, 1.0, 1.0]
    if scale.__class__ == list and len(scale) == 3:
        #check
        if int(v.sizeX()*scale[0]) < 1 or int(v.sizeY()*scale[1]) < 1 or int(v.sizeZ()*scale[2]) < 1:
            raise Exception("Scale not possible! Please check all the dimension after scaling is bigger than 1!")
    else:
        raise Exception("Scale parameter invalid! Should be a list of 3 values!")
    
    from pytom_volume import vol, general_transform
    from pytom.tools.maths import Matrix
    
    # invert matrix
    rotM = rot.toMatrix(True)
    shiftM = shift.toMatrix()
    scaleM = Matrix(4,4)
    scaleM[0,0] = scale[0]
    scaleM[1,1] = scale[1]
    scaleM[2,2] = scale[2]
    scaleM[3,3] = 1
    
    # multiply them according to the order
    all_mtx = [None, None, None]
    try:
        if order[2] > order[0]: # rotation first
            rotCenter1 = Shift(-int(v.sizeX()/2), -int(v.sizeY()/2), -int(v.sizeZ()/2)).toMatrix()
            rotCenter2 = Shift(int(v.sizeX()/2), int(v.sizeY()/2), int(v.sizeZ()/2)).toMatrix()
        else: # scale first, so the center is different
            rotCenter1 = Shift(-int(v.sizeX()*scale)/2, -int(v.sizeY()*scale)/2, -int(v.sizeZ()*scale)/2).toMatrix()
            rotCenter2 = Shift(int(v.sizeX()*scale)/2, int(v.sizeY()*scale)/2, int(v.sizeZ()*scale)/2).toMatrix()
        all_mtx[order[0]] = rotCenter2 * (rotM * rotCenter1) # for the rotation center!
        all_mtx[order[1]] = shiftM
        all_mtx[order[2]] = scaleM
    except:
        raise Exception("The given order is wrong! Should be a list of 0,1,2!")
    
    mtx = all_mtx[2] * (all_mtx[1] * all_mtx[0])
    
    res = vol(int(v.sizeX()*scale[0]), int(v.sizeY()*scale[1]), int(v.sizeZ()*scale[2]))
    general_transform(v, res, mtx._matrix)
    return res
Пример #19
0
    def __init__(self,
                 vol1,
                 vol2,
                 score,
                 mask=None,
                 iniRot=None,
                 iniTrans=None,
                 opti='fmin_powell',
                 interpolation='linear',
                 verbose=False):
        """
        alignment of a particle against a reference

        @param vol1: (constant) volume
        @type vol1: L{pytom_volume.vol}
        @param vol2: volume that is matched to reference
        @type vol2: L{pytom_volume.vol}
        @param score: score for alignment - e.g., pytom.basic.correlation.nxcc
        @type score: L{pytom.basic.correlation}
        @param mask: mask correlation is constrained on
        @type mask: L{pytom_volume.vol}
        @param iniRot: initial rotation of vol2
        @type iniRot: L{pytom.basic.Rotation}
        @param iniTrans: initial translation of vol2
        @type iniTrans: L{pytom.basic.Shift}
        @param opti: optimizer ('fmin_powell', 'fmin', 'fmin_cg', 'fmin_slsqp', 'fmin_bfgs')
        @param interpolation: interpolation type - 'linear' (default) or 'spline'
        @type interpolation: str
        @type opti: L{str}

        @author: FF
        """
        from pytom.basic.normalise import normaliseUnderMask, mean0std1
        from pytom.tools.macros import volumesSameSize
        from pytom_volume import vol
        from pytom.basic.structures import Rotation, Shift
        assert isinstance(interpolation,
                          str), "interpolation must be of type str"

        self.verbose = verbose
        if not volumesSameSize(vol1, vol2):
            raise RuntimeError('Vol1 and vol2 must have same size!')

        # normalize constant volume
        if mask:
            (v, p) = normaliseUnderMask(vol1, mask)
        else:
            v = mean0std1(vol1, True)

        self.vol1 = v
        self.vol2 = vol2
        self.rotvol2 = vol(self.vol1.sizeX(), self.vol2.sizeY(),
                           self.vol2.sizeZ())
        self.mask = mask

        if not iniRot:
            iniRot = Rotation()
        if not iniTrans:
            iniTrans = Shift()
        self.rot_trans = self.transRot2vector(rot=iniRot, trans=iniTrans)

        self.score = score
        self.val = -100000.
        self.centX = int(self.vol1.sizeX() // 2)
        self.centY = int(self.vol1.sizeY() // 2)
        self.centZ = int(self.vol1.sizeZ() // 2)
        self.binning = 1
        self.interpolation = interpolation

        # set optimizer
        self.opti = opti
        if opti == 'fmin':
            self.optimizer = scipy.optimize.fmin
        elif opti == 'fmin_slsqp':
            self.optimizer = scipy.optimize.fmin_slsqp
        elif opti == 'fmin_cg':
            self.optimizer = scipy.optimize.fmin_cg
        elif opti == 'fmin_bfgs':
            self.optimizer = scipy.optimize.fmin_bfgs
        elif opti == 'fmin_powell':
            self.optimizer = scipy.optimize.fmin_powell
        else:
            raise TypeError('opti must be of type str')
Пример #20
0
 def _startGrowingAverageLoop(self):
     """
     _startGrowingAverageLoop: Loops over all particles in self.particleList and computes growing average
     """
     
     from pytom.alignment.structures import GrowingAverageInterimResult
     from pytom.basic.structures import Rotation,Shift
     from pytom.alignment.alignmentFunctions import alignTwoVolumes
     numberParticles = len(self._particleList)
     
     self._resultList = []
     
     result = GrowingAverageInterimResult(self._particleList[self._startParticleNumber],self._reference,Rotation(0,0,0),Shift(0,0,0),self._score)
 
     #init result list with first element 
     self._resultList.append(result)
     self._createNewAverage(self._startParticleNumber)
     
     for particleIterator in range(numberParticles):
         
         if particleIterator == self._startParticleNumber:
             continue
                 
         print('Running particle no ' + str(particleIterator)) 
                 
         particle = self._particleList[particleIterator]
         
         #determine alignment of current reference with particle
         result = alignTwoVolumes(particle,self._reference,self._angleObject,self._maskFile,self._score,self._preprocessing)
         
         self._angleObject.reset()
         
         self._resultList.append(result)
         
         self._createNewAverage(particleIterator)
from pytom_volume import read
from sh.frm import frm_align_vol
from pytom.tools.maths import rotation_distance, euclidianDistance
from pytom.tools.timing import Timing
from pytom.basic.structures import ParticleList
from pytom.basic.structures import Shift, Rotation

pl = ParticleList('.')
pl.fromXMLFile('/fs/home/ychen/4Chen/first100.xml')

r = read('/fs/home/ychen/4Chen/avg_first100.em')

for pp in pl:
    v = read(pp.getFilename())
    pos, ang = frm_align_vol(v, [-60.0, 60.0], r, [8, 32], 10, mask=30)
    pp.setShift(
        Shift([
            pos[0] - v.sizeX() / 2, pos[1] - v.sizeY() / 2,
            pos[2] - v.sizeZ() / 2
        ]))
    pp.setRotation(Rotation(ang))

pl.average('average.em', True)
Пример #22
0
class MaximisationResult(PyTomClass):
    """
    MaximisationResult : Stores results of one maximisation process
    """
    def __init__(self,
                 particle='',
                 reference=-1.0,
                 score=-1.0,
                 shift=-1.0,
                 rotation=-1.0,
                 angleObject=-1):

        from pytom.basic.structures import Particle, Reference, Shift, Rotation
        from numpy import long

        if particle.__class__ == str:
            self._particle = Particle(particle)
        elif particle.__class__ == Particle:
            self._particle = particle
        else:
            self._particle = Particle()

        if reference.__class__ == str:
            self._reference = Reference(reference)
        elif reference.__class__ == Reference:
            self._reference = reference
        else:
            self._reference = Reference()

        if shift.__class__ == list:
            self._shift = Shift(shift)
        elif shift.__class__ == float:
            self._shift = Shift()
        else:
            self._shift = shift

        if rotation.__class__ == list:
            self._rotation = Rotation(rotation)
        elif rotation.__class__ == Rotation:
            self._rotation = rotation
        else:
            self._rotation = Rotation()

        if score.__class__ == float:
            from pytom.score.score import xcfScore
            self._score = xcfScore()
        else:
            self._score = score

        if angleObject.__class__ == float or isinstance(
                angleObject, (int, long)):
            from pytom.angles.angleList import AngleList
            self._angleObject = AngleList()
        else:
            self._angleObject = angleObject

    def toParticle(self):
        """
        toParticle: Converts this object to a Particle object.
        @return:
        @rtype: L{pytom.basic.structures.Particle}
        """
        from pytom.basic.structures import Particle
        particle = self._particle
        particle.setRotation(self._rotation)
        particle.setShift(self._shift)
        particle.setScore(self._score)

        return particle

    def getParticle(self):
        return self._particle

    def getShift(self):
        from pytom.basic.structures import Shift

        if self._shift.__class__ == list:
            return Shift(self._shift)
        else:
            return self._shift

    def setShift(self, shift):
        from pytom.basic.structures import Shift

        assert shift.__class__ == Shift

        self._shift = shift

    def getAngleObject(self):
        return self._angleObject

    def getRotation(self):

        from pytom.basic.structures import Rotation

        if self._rotation.__class__ == list:
            return Rotation(self._rotation[0], self._rotation[1],
                            self._rotation[2])
        else:
            return self._rotation.copy()

    def getScore(self):
        """
        getScore: Returns score object
        """
        return self._score

    def setRotation(self, rotation):
        """
        setRotation:
        @param rotation: 
        """
        from pytom.basic.structures import Rotation

        if rotation.__class__ == list:
            rotation = Rotation(rotation)

        self._rotation = rotation

    def fromXML(self, xmlObj):
        """
        fromXML : Assigns values to result attributes from XML object
        @param xmlObj: A xml object  
        @author: Thomas Hrabe 
        """
        from lxml.etree import _Element

        if xmlObj.__class__ != _Element:
            from pytom.basic.exceptions import ParameterError
            raise ParameterError(
                'Is not a lxml.etree._Element! You must provide a valid XML object.'
            )

        from pytom.score.score import fromXML as fromXMLScore
        from pytom.angles.angle import AngleObject

        if xmlObj.tag == "Result":
            result = xmlObj
        else:
            result = xmlObj.xpath('Result')

            if len(result) == 0:
                raise PyTomClassError(
                    "This XML is not an MaximisationResult. No Result provided."
                )

            result = result[0]
        from pytom.basic.structures import Particle, Reference, Rotation, Shift
        particle_element = result.xpath('Particle')[0]
        p = Particle('')
        p.fromXML(particle_element)
        self._particle = p

        r = result.xpath('Reference')
        ref = Reference('')
        ref.fromXML(r[0])
        self._reference = ref

        scoreXML = result.xpath('Score')[0]
        self._score = fromXMLScore(scoreXML)

        shiftXML = result.xpath('Shift')[0]
        self._shift = Shift()
        self._shift.fromXML(shiftXML)

        rotationXML = result.xpath('Rotation')[0]
        self._rotation = Rotation()
        self._rotation.fromXML(rotationXML)

        angleElement = result.xpath('Angles')
        ang = AngleObject()
        self._angleObject = ang.fromXML(angleElement[0])

    def toXML(self):
        """
        toXML : Compiles a XML from result object
        @author: Thomas Hrabe
        """
        from lxml import etree

        resultElement = etree.Element("Result")

        resultElement.append(self._particle.toXML())

        if self._reference.hasGeneratedByInfo():
            from pytom.basic.structures import Reference
            newRef = Reference(self._reference.getReferenceFilename())
            resultElement.append(newRef.toXML())
        else:
            resultElement.append(self._reference.toXML())

        resultElement.append(self._shift.toXML())

        resultElement.append(self._rotation.toXML())

        resultElement.append(self._score.toXML())

        resultElement.append(self._angleObject.toXML())

        return resultElement

    def copy(self):
        return MaximisationResult(self._particle, self._reference, self._score,
                                  self._shift, self._rotation,
                                  self._angleObject)