Exemplo n.º 1
0
class GrowingAverageJob(PyTomClass):
    """
    GrowingAverageJob:
    @ivar particleList: List of particles to be aligned
    @ivar angleObject: Angle object L{pytom.angles.AngleObject}
    @ivar startParticleNumber: Number of start particle (default 0)
    @ivar maskFile: Mask used for appedizing 
    """
    
    def __init__(self,particleList=None,angleObject=None,maskFile=None,scoreObject=None,startClassNumber=0,destinationDirectory='.',preprocessing = None):
        
        from pytom.tools.files import checkDirExists
        from pytom.angles.angleList import AngleList
        from pytom.basic.structures import ParticleList
        
        self._particleList = particleList or ParticleList('/')
        self._angleObject = angleObject or AngleList()
        self._startClassNumber = startClassNumber
        self._maskFile = maskFile or None
        
        if preprocessing:
            self._preprocessing = preprocessing
        else:
            from pytom.alignment.preprocessing import Preprocessing
            self._preprocessing = Preprocessing()
        
        
        if self._maskFile.__class__ == str:
            from pytom.basic.structures import Mask 
            self._maskFile = Mask(self.maskFile)
            
        self._score = scoreObject
        
        if not checkDirExists(destinationDirectory):
            raise Exception('Destination directory ' + destinationDirectory + ' does not exist.')
        
        if not destinationDirectory[len(destinationDirectory)-1] == '/':
            destinationDirectory = destinationDirectory + '/'
        
        self._destinationDirectory = destinationDirectory
        
    def toXML(self):
        """
        toXML : Compiles a XML file from result object
        rtype : L{lxml.etree._Element}
        @author: Thomas Hrabe
        """ 
        from lxml import etree
        
        job_element = etree.Element('GrowingAverageJob',StartClassNumber = str(self._startClassNumber), DestinationDirectory = str(self._destinationDirectory))
        
        job_element.append(self._maskFile.toXML())
        
        job_element.append(self._particleList.toXML())
        
        job_element.append(self._angleObject.toXML())
        
        job_element.append(self._score.toXML())
        
        job_element.append(self._preprocessing.toXML())
        
        return job_element
        
    def fromXML(self,xmlObj):
        """
        fromXML:
        @param xmlObj: A xml object  
        @type xmlObj: L{lxml.etree._Element}
        @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 XMLobject.')
        
        if xmlObj.tag == 'GrowingAverageJob':
            job_element = xmlObj
        else:
            from pytom.basic.exceptions import ParameterError
            raise ParameterError('Is not a GrowingAverageJobXML! You must provide a valid GrowingAverageJobXML object.')
        
        from pytom.angles.angle import AngleObject
        from pytom.score.score import fromXML as scoreFromXML
        from pytom.basic.structures import ParticleList
        from pytom.alignment.preprocessing import Preprocessing
        
        self._startClassNumber = int(job_element.get('StartClassNumber'))
        
        mask = job_element.xpath('Mask')[0]
        from pytom.basic.structures import Mask
        self._maskFile = Mask('')
        self._maskFile.fromXML(mask)
         
        self._destinationDirectory = job_element.get('DestinationDirectory')
        
        particleXML = job_element.xpath('ParticleList')[0]
        
        self._particleList = ParticleList('/',[])
        self._particleList.fromXML(particleXML)
        
        angleXML = job_element.xpath('Angles')[0]
        
        ang = AngleObject()
        self._angleObject = ang.fromXML(angleXML)
        
        scoreXML = job_element.xpath('Score')[0]
        
        self._score = scoreFromXML(scoreXML)
        
        self._preprocessing = Preprocessing()
        preprocessingXML = job_element.xpath('Preprocessing')[0]
        self._preprocessing.fromXML(preprocessingXML)
Exemplo n.º 2
0
class FRMJob(PyTomClass):  # i need to rename the class, but for now it works
    def __init__(self,
                 pl=None,
                 ref=None,
                 mask=None,
                 peak_offset=0,
                 sample_info=None,
                 bw_range=None,
                 freq=None,
                 dest='.',
                 max_iter=10,
                 r_score=False,
                 weighting=False,
                 bfactor=None,
                 symmetries=None,
                 adaptive_res=0.1,
                 fsc_criterion=0.5,
                 constraint=None,
                 binning=1):
        """
        initiate FRM job
        @param pl: particle list
        @type ps: L{pytom.basic.structures.ParticleList}
        @param ref: reference density
        @type ref: L{pytom.basic.structures.Reference}
        @param mask: mask 
        @type ref: L{pytom.basic.structures.Mask}
        @param peak_offset: peak offset in voxel
        @type peak_offset: C{int}
        @param sample_info: ?? (Default: None)
        @type sample_info: ??
        @param bw_range: bandwidth range in pixel (2-dim vector)
        @type bw_range: C{list}
        @param freq: frequency (default: None)
        @type: C{int}
        @param dest: distination directory (default: '.')
        @type: C{str}
        @param max_iter: maximum number of iterations
        @type max_iter: C{int}
        @param r_score: use r_score (??) (default: False)
        @type r_score: C{bool}
        @param weighting: weighting (default: False)
        @type weighting: C{bool}
        @param bfactor: B-factor (default: None)
        @type bfactor: C{float}?
        @param symmetries: symmetry (default: None)
        @type L{pytom.basic.structures.Symmetries}
        @param adaptive_res: adaptive resolution - add to resolution for filtering
        @type adaptive_res: C{float}
        @param fsc_criterion: FSC criterion (default: 0.5)
        @type fsc_criterion: C{float}
        @param constraint: Constraint on orientations (deafult: None)
        @type constraint: ??
        @param binning: Perform binning (downscale) of subvolumes by factor. Default=1.
        @type binning C{float}
        """
        self.particleList = pl
        self.reference = ref
        self.mask = mask
        self.peak_offset = peak_offset
        self.sampleInformation = sample_info
        self.bw_range = bw_range
        self.freq = freq
        self.destination = dest
        self.max_iter = max_iter
        self.r_score = r_score
        self.weighting = weighting
        self.bfactor = bfactor
        self.symmetries = symmetries
        self.adaptive_res = adaptive_res
        self.fsc_criterion = fsc_criterion
        self.constraint = constraint
        self.binning = binning

    def fromXML(self, xmlObj):
        """
        read from xml file
        @param xmlObj: xml object
        @type xmlObj: L{lxml.etree.Element}
        """
        from lxml.etree import _Element

        if xmlObj.__class__ != _Element:
            raise Exception('You must provide a valid XML object.')

        if xmlObj.tag == "FRMJob":
            jobDescription = xmlObj
        else:
            jobDescription = xmlObj.xpath('FRMJob')
            if len(jobDescription) == 0:
                raise Exception("This XML is not a FRMJob.")
            jobDescription = jobDescription[0]

        from pytom.basic.structures import ParticleList, Reference, Mask, SampleInformation, MultiSymmetries

        pl = ParticleList('.')
        particleList_element = jobDescription.xpath('ParticleList')
        if len(particleList_element) > 0:
            pl.fromXML(particleList_element[0])
        else:
            list_elements = jobDescription.xpath('ParticleListLocation')
            for e in list_elements:
                sub_pl = ParticleList()
                sub_pl.fromXMLFile(e.get('Path'))
                pl += sub_pl
        self.particleList = pl

        r = jobDescription.xpath('Reference')[0]
        self.reference = Reference('')
        self.reference.fromXML(r)

        m = jobDescription.xpath('Mask')[0]
        self.mask = Mask('')
        self.mask.fromXML(m)

        try:
            si = jobDescription.xpath('SampleInformation')[0]
            self.sampleInformation = SampleInformation()
            self.sampleInformation.fromXML(si)
        except:
            self.sampleInformation = SampleInformation()

        try:
            syms = jobDescription.xpath('MultiSymmetries')[0]
            self.symmetries = MultiSymmetries()
            self.symmetries.fromXML(syms)
        except:
            self.symmetries = MultiSymmetries()

        self.peak_offset = int(jobDescription.get('PeakOffset'))
        self.bw_range = [
            int(i)
            for i in jobDescription.get('BandwidthRange')[1:-1].split(',')
        ]
        self.freq = int(jobDescription.get('Frequency'))
        self.destination = jobDescription.get('Destination')
        self.max_iter = int(jobDescription.get('MaxIterations'))
        self.r_score = jobDescription.get('RScore') == 'True'
        self.weighting = jobDescription.get('WeightedAverage') == 'True'
        self.bfactor = jobDescription.get('BFactor')
        self.binning = int(jobDescription.get('binning'))
        if jobDescription.get('AdaptiveResolution'):
            adaptive_resolution = jobDescription.get('AdaptiveResolution')
            if adaptive_resolution == '+1':
                self.adaptive_res = False  # always increase by 1
            else:
                self.adaptive_res = float(adaptive_resolution)
        else:
            self.adaptive_res = 0.0  # default, if not specified
        if jobDescription.get('FSC'):
            self.fsc_criterion = float(jobDescription.get('FSC'))
        else:
            self.fsc_criterion = 0.5  # default value

        # for the constraint
        try:
            from sh_alignment.constrained_frm import AngularConstraint
            con = jobDescription.xpath('AngularConstraint')
            if len(con) != 0:
                ac = AngularConstraint()
                c = ac.fromXML(con[0])
                self.constraint = c
            else:
                self.constraint = None
        except:
            self.constraint = None

    def toXML(self):
        """
        copy to xml structure
        @return: xml object for job
        @rtype L{lxml.etree.Element}
        """
        from lxml import etree

        jobElement = etree.Element("FRMJob")
        jobElement.append(self.particleList.toXML())
        jobElement.append(self.reference.toXML())
        jobElement.append(self.mask.toXML())
        jobElement.append(self.sampleInformation.toXML())
        if self.symmetries is not None:
            jobElement.append(self.symmetries.toXML())
        jobElement.set("PeakOffset", str(self.peak_offset))
        jobElement.set("BandwidthRange", str(self.bw_range))
        jobElement.set("Frequency", str(self.freq))
        jobElement.set("Destination", self.destination)
        jobElement.set("MaxIterations", str(self.max_iter))
        jobElement.set("RScore", str(self.r_score))
        jobElement.set("WeightedAverage", str(self.weighting))
        jobElement.set("BFactor", str(self.bfactor))
        jobElement.set("binning", str(self.binning))
        if self.adaptive_res is False:
            jobElement.set("AdaptiveResolution", '+1')
        else:
            jobElement.set("AdaptiveResolution", str(self.adaptive_res))
        jobElement.set("FSC", str(self.fsc_criterion))
        if self.constraint:
            jobElement.append(self.constraint.toXML())

        return jobElement

    def check(self):
        from pytom.tools.files import checkDirExists
        self.particleList.check()
        self.reference.check()
        self.mask.check()
        if not checkDirExists(self.destination):
            raise RuntimeError('Destination path not found! ' +
                               self.destination)
Exemplo n.º 3
0
class FRMJob(PyTomClass):  # i need to rename the class, but for now it works
    def __init__(self,
                 pl=None,
                 ref=None,
                 mask=None,
                 peak_offset=0,
                 sample_info=None,
                 bw_range=None,
                 freq=None,
                 dest='.',
                 max_iter=10,
                 r_score=False,
                 weighting=False,
                 bfactor=None,
                 symmetries=None,
                 adaptive_res=0.1,
                 fsc_criterion=0.5,
                 constraint=None):
        self.particleList = pl
        self.reference = ref
        self.mask = mask
        self.peak_offset = peak_offset
        self.sampleInformation = sample_info
        self.bw_range = bw_range
        self.freq = freq
        self.destination = dest
        self.max_iter = max_iter
        self.r_score = r_score
        self.weighting = weighting
        self.bfactor = bfactor
        self.symmetries = symmetries
        self.adaptive_res = adaptive_res
        self.fsc_criterion = fsc_criterion
        self.constraint = constraint

    def fromXML(self, xmlObj):
        from lxml.etree import _Element

        if xmlObj.__class__ != _Element:
            raise Exception('You must provide a valid XML object.')

        if xmlObj.tag == "FRMJob":
            jobDescription = xmlObj
        else:
            jobDescription = xmlObj.xpath('FRMJob')
            if len(jobDescription) == 0:
                raise Exception("This XML is not a FRMJob.")
            jobDescription = jobDescription[0]

        from pytom.basic.structures import ParticleList, Reference, Mask, SampleInformation, MultiSymmetries

        pl = ParticleList('.')
        particleList_element = jobDescription.xpath('ParticleList')
        if len(particleList_element) > 0:
            pl.fromXML(particleList_element[0])
        else:
            list_elements = jobDescription.xpath('ParticleListLocation')
            for e in list_elements:
                sub_pl = ParticleList()
                sub_pl.fromXMLFile(e.get('Path'))
                pl += sub_pl
        self.particleList = pl

        r = jobDescription.xpath('Reference')[0]
        self.reference = Reference('')
        self.reference.fromXML(r)

        m = jobDescription.xpath('Mask')[0]
        self.mask = Mask('')
        self.mask.fromXML(m)

        try:
            si = jobDescription.xpath('SampleInformation')[0]
            self.sampleInformation = SampleInformation()
            self.sampleInformation.fromXML(si)
        except:
            self.sampleInformation = SampleInformation()

        try:
            syms = jobDescription.xpath('MultiSymmetries')[0]
            self.symmetries = MultiSymmetries()
            self.symmetries.fromXML(syms)
        except:
            self.symmetries = MultiSymmetries()

        self.peak_offset = int(jobDescription.get('PeakOffset'))
        self.bw_range = [
            int(i)
            for i in jobDescription.get('BandwidthRange')[1:-1].split(',')
        ]
        self.freq = int(jobDescription.get('Frequency'))
        self.destination = jobDescription.get('Destination')
        self.max_iter = int(jobDescription.get('MaxIterations'))
        self.r_score = jobDescription.get('RScore') == 'True'
        self.weighting = jobDescription.get('WeightedAverage') == 'True'
        self.bfactor = jobDescription.get('BFactor')
        if jobDescription.get('AdaptiveResolution'):
            adaptive_resolution = jobDescription.get('AdaptiveResolution')
            if adaptive_resolution == '+1':
                self.adaptive_res = False  # always increase by 1
            else:
                self.adaptive_res = float(adaptive_resolution)
        else:
            self.adaptive_res = 0.0  # default, if not specified
        if jobDescription.get('FSC'):
            self.fsc_criterion = float(jobDescription.get('FSC'))
        else:
            self.fsc_criterion = 0.5  # default value

        # for the constraint
        try:
            from sh_alignment.constrained_frm import AngularConstraint
            con = jobDescription.xpath('AngularConstraint')
            if len(con) != 0:
                ac = AngularConstraint()
                c = ac.fromXML(con[0])
                self.constraint = c
            else:
                self.constraint = None
        except:
            self.constraint = None

    def toXML(self):
        from lxml import etree

        jobElement = etree.Element("FRMJob")
        jobElement.append(self.particleList.toXML())
        jobElement.append(self.reference.toXML())
        jobElement.append(self.mask.toXML())
        jobElement.append(self.sampleInformation.toXML())
        if self.symmetries is not None:
            jobElement.append(self.symmetries.toXML())
        jobElement.set("PeakOffset", str(self.peak_offset))
        jobElement.set("BandwidthRange", str(self.bw_range))
        jobElement.set("Frequency", str(self.freq))
        jobElement.set("Destination", self.destination)
        jobElement.set("MaxIterations", str(self.max_iter))
        jobElement.set("RScore", str(self.r_score))
        jobElement.set("WeightedAverage", str(self.weighting))
        jobElement.set("BFactor", str(self.bfactor))
        if self.adaptive_res is False:
            jobElement.set("AdaptiveResolution", '+1')
        else:
            jobElement.set("AdaptiveResolution", str(self.adaptive_res))
        jobElement.set("FSC", str(self.fsc_criterion))
        if self.constraint:
            jobElement.append(self.constraint.toXML())

        return jobElement

    def check(self):
        from pytom.tools.files import checkDirExists
        self.particleList.check()
        self.reference.check()
        self.mask.check()
        if not checkDirExists(self.destination):
            raise RuntimeError('Destination path not found! ' +
                               self.destination)
Exemplo n.º 4
0
class CTFCorrectionJob(PyTomClass):
    """For the worker to actually run.
    """
    def __init__(self,
                 pl=None,
                 ctf_conv_pl=None,
                 ref=None,
                 mask=None,
                 peak_offset=0,
                 sample_info=None,
                 bw_range=None,
                 freq=None,
                 dest='.',
                 max_iter=10,
                 r_score=False,
                 weighting=False,
                 bfactor=None,
                 sum_ctf_sqr=None):
        self.particleList = pl
        self.ctf_conv_pl = ctf_conv_pl
        if ref is None:
            self.reference = []
        else:
            self.reference = ref
        self.mask = mask
        self.peak_offset = peak_offset
        self.sampleInformation = sample_info
        self.bw_range = bw_range
        self.freq = freq
        self.destination = dest
        self.max_iter = max_iter
        self.r_score = r_score
        self.weighting = weighting
        self.bfactor = bfactor
        self.sum_ctf_sqr = sum_ctf_sqr

    def fromXML(self, xmlObj):
        from lxml.etree import _Element

        if xmlObj.__class__ != _Element:
            raise Exception('You must provide a valid XML object.')

        if xmlObj.tag == "CTFCorrectionJob":
            jobDescription = xmlObj
        else:
            jobDescription = xmlObj.xpath('CTFCorrectionJob')
            if len(jobDescription) == 0:
                raise Exception("This XML is not a CTFCorrectionJob.")
            jobDescription = jobDescription[0]

        from pytom.basic.structures import ParticleList, Reference, Mask, SampleInformation

        particleList_element = jobDescription.xpath('ParticleList')[0]
        pl = ParticleList('.')
        pl.fromXML(particleList_element)
        self.particleList = pl

        self.reference = []
        r = jobDescription.xpath('Reference')
        for ref_obj in r:
            ref = Reference('')
            ref.fromXML(ref_obj)
            self.reference.append(ref)

        m = jobDescription.xpath('Mask')[0]
        self.mask = Mask('')
        self.mask.fromXML(m)

        try:
            si = jobDescription.xpath('SampleInformation')[0]
            self.sampleInformation = SampleInformation()
            self.sampleInformation.fromXML(si)
        except:
            self._sampleInformation = SampleInformation()

        self.ctf_conv_pl = jobDescription.get('CTFConvolutedParticleList')
        self.peak_offset = int(jobDescription.get('PeakOffset'))
        self.bw_range = [
            int(i)
            for i in jobDescription.get('BandwidthRange')[1:-1].split(',')
        ]
        self.freq = int(jobDescription.get('Frequency'))
        self.destination = jobDescription.get('Destination')
        self.max_iter = int(jobDescription.get('MaxIterations'))
        self.r_score = jobDescription.get('RScore') == 'True'
        self.weighting = jobDescription.get('WeightedAverage') == 'True'
        self.bfactor = jobDescription.get('BFactor')
        self.sum_ctf_sqr = jobDescription.get('CTFSquared')

    def toXML(self):
        from lxml import etree

        jobElement = etree.Element("CTFCorrectionJob")
        jobElement.append(self.particleList.toXML())
        for ref in self.reference:
            jobElement.append(ref.toXML())
        jobElement.append(self.mask.toXML())
        jobElement.append(self.sampleInformation.toXML())
        jobElement.set("CTFConvolutedParticleList", self.ctf_conv_pl)
        jobElement.set("PeakOffset", str(self.peak_offset))
        jobElement.set("BandwidthRange", str(self.bw_range))
        jobElement.set("Frequency", str(self.freq))
        jobElement.set("Destination", self.destination)
        jobElement.set("MaxIterations", str(self.max_iter))
        jobElement.set("RScore", str(self.r_score))
        jobElement.set("WeightedAverage", str(self.weighting))
        jobElement.set("BFactor", str(self.bfactor))
        jobElement.set("CTFSquared", str(self.sum_ctf_sqr))

        return jobElement
Exemplo n.º 5
0
class MaximisationJob(PyTomClass):
    """
    MaximisationJob : Stores all infos needed for a maximisation job
    """
    def __init__(self,
                 particle='',
                 reference='',
                 score='',
                 rotations='',
                 mask='',
                 numberRefinementRounds=1,
                 preprocessing='',
                 binning=1):
        """
        @param particle: particle to be aligned
        @type particle: L{pytom.basic.structures.Particle} or str
        @param reference: reference for particle alignment
        @param score: type of score used for alignment
        @param rotations: rotations scanned in search
        @param mask: mask on reference
        @param numberRefinementRounds: iteration number
        @param preprocessing: preprocessing parameters
        @param binning: Binning Factor
        @type binning: int
        """

        from lxml.etree import _Element

        if particle.__class__ == _Element:
            self.fromXML(particle)
        else:
            if particle.__class__ == str:
                from pytom.basic.structures import Particle
                self.particle = Particle(particle)
            else:
                self.particle = particle

            self.reference = reference
            self.score = score
            self.rotations = rotations
            self.mask = mask
            self.numberRefinementRounds = numberRefinementRounds
            self.preprocessing = preprocessing
            self.binning = binning

    def fromXML(self, xmlObj):
        """
        fromXML : Assigns values to job 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(
                'You must provide a valid XML-MaximisationJob object.')

        if xmlObj.tag == "JobDescription":
            jobDescription = xmlObj
        else:
            jobDescription = xmlObj.xpath('JobDescription')

            if len(jobDescription) == 0:
                from pytom.basic.structures import PyTomClassError
                raise PyTomClassError("This XML is not an JobDescription.")

            jobDescription = jobDescription[0]

        from pytom.angles.angle import AngleObject
        from pytom.score.score import fromXML as fromXMLScore
        from pytom.alignment.preprocessing import Preprocessing
        from pytom.basic.structures import Mask, Particle, Reference, ReferenceList

        self.binning = int(jobDescription.get('Binning'))

        particle_element = jobDescription.xpath('Particle')[0]
        p = Particle('')
        p.fromXML(particle_element)
        self.particle = p

        r = jobDescription.xpath('Reference')

        if len(r) > 0:
            ref = Reference('')
            ref.fromXML(r[0])
            self.reference = ref
        else:
            r = jobDescription.xpath('ReferenceList')
            ref = ReferenceList()
            ref.fromXML(r[0])
            self.reference = ref

        mask = jobDescription.xpath('Mask')[0]
        self.mask = Mask('')
        self.mask.fromXML(mask)

        self.numberRefinementRounds = jobDescription.get(
            'NumberRefinementRounds')
        self.numberRefinementRounds = int(self.numberRefinementRounds)

        score = jobDescription.xpath('Score')
        self.score = fromXMLScore(score[0])

        angles = jobDescription.xpath('Angles')
        ang = AngleObject()
        self.rotations = ang.fromXML(angles[0])

        preObj = xmlObj.xpath('Preprocessing')
        if len(preObj) == 0:
            self.preprocessing = Preprocessing()
        else:
            p = Preprocessing()
            p.fromXML(preObj[0])
            self.preprocessing = p

    def toXML(self):
        """
        toXML : Compiles a XML file from job object
        @author: Thomas Hrabe
        """

        from lxml import etree

        jobElement = etree.Element("JobDescription")

        jobElement.set("NumberRefinementRounds",
                       str(self.numberRefinementRounds))

        jobElement.set("Binning", str(self.binning))

        jobElement.append(self.particle.toXML())

        jobElement.append(self.reference.toXML())

        jobElement.append(self.mask.toXML())
        jobElement.append(self.rotations.toXML())

        if self.score.__class__ == str:
            jobElement.append(self.score)
        else:
            jobElement.append(self.score.toXML())

        preObj = self.preprocessing.toXML()
        jobElement.append(preObj)

        return jobElement

    def check(self):
        """
        check: Performs check on self whether all settings were sane. Paths and Files exists 
        """

        from pytom.tools.files import checkFileExists, checkDirExists

        returnValue = checkFileExists(self.particle.getFilename())
        if not returnValue:
            raise IOError(str(self.particle.getFilename()) + ' not found!')

        returnValue = returnValue and checkFileExists(
            self.reference.getFilename())

        if not returnValue:
            raise IOError(str(self.reference) + ' not found!')

        return returnValue
Exemplo n.º 6
0
class PeakJob(PyTomClass):
    """
    PeakJob: stores all the infos needed for calculation of the peak score
    """
    def __init__(self,
                 volume='',
                 reference='',
                 mask='',
                 wedge='',
                 rotations='',
                 score='',
                 jobID=0,
                 members=1,
                 dstDir='./',
                 bandpass=None):
        """
        @param volume: target volume
        @type volume: L{pytom.localization.structures.Volume}
        @param reference: reference volume
        @type reference: L{pytom.basic.structures.Reference}
        @param mask: mask volume
        @type mask: L{pytom.basic.structures.Mask}
        @param wedge: wedge information
        @type wedge: L{pytom.basic.structures.WedgeInfo}
        @param rotations: rotation list
        @type rotations: L{pytom.angles.angle}
        @param score: score function
        @type score: L{pytom.score.score}
        @param jobID: job identification
        @type jobID: integer
        @param members: how many members are there available to accomplish this job (1 means only itself)
        @type members: integer
        @param dstDir: destination directory where the result is written to
        @type dstDir: string
        @param bandpass: bandpass object that will be applied to the reference
        @type bandpass: L{pytom.basic.structure.BandPassFilter}
        """
        self.volume = volume
        self.reference = reference
        self.mask = mask
        self.wedge = wedge
        self.rotations = rotations
        self.score = score
        self.jobID = jobID
        self.members = members
        if dstDir[-1] == '/':
            self.dstDir = dstDir
        else:
            self.dstDir = dstDir + '/'
        self.bandpass = bandpass

    def copy(self, fromJob):
        self.volume = fromJob.volume
        self.reference = fromJob.reference
        self.mask = fromJob.mask
        self.wedge = fromJob.wedge
        self.rotations = fromJob.rotations
        self.score = fromJob.score
        self.jobID = fromJob.jobID
        self.members = fromJob.members
        self.dstDir = fromJob.dstDir
        self.bandpass = fromJob.bandpass

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

        if xmlObj.__class__ != _Element:
            raise Exception('You must provide a valid XML object.')

        if xmlObj.tag == "JobDescription":
            jobDescription = xmlObj
        else:
            jobDescription = xmlObj.xpath('JobDescription')

            if len(jobDescription) == 0:
                raise Exception("This XML is not an JobDescription.")

            jobDescription = jobDescription[0]

        id = jobDescription.get('ID')
        if id != None and id != 'None':
            self.jobID = int(id)

        members = jobDescription.get('Members')
        if members != None and members != 'None':
            self.members = int(members)

        dstDir = jobDescription.get('Destination')
        if dstDir != None:
            if dstDir[-1] == '/':
                self.dstDir = dstDir
            else:
                self.dstDir = dstDir + '/'

        from pytom.score.score import fromXML as fromXMLScore
        from pytom.basic.structures import Mask, Reference, Wedge
        #        from pytom.angles.angleList import AngleList
        from pytom.localization.structures import Volume

        e = jobDescription.xpath('Volume')[0]
        v = Volume()
        v.fromXML(e)
        self.volume = v

        ref = jobDescription.xpath('Reference')[0]
        self.reference = Reference('')
        self.reference.fromXML(ref)

        wedgeXML = jobDescription.xpath('Wedge')

        if len(wedgeXML) == 0:
            wedgeXML = jobDescription.xpath('SingleTiltWedge')

        if len(wedgeXML) == 0:
            wedgeXML = jobDescription.xpath('WedgeInfo')

        if len(wedgeXML) == 0:
            wedgeXML = jobDescription.xpath('DoubleTiltWedge')

        assert len(wedgeXML) > 0

        self.wedge = Wedge()
        self.wedge.fromXML(wedgeXML[0])

        mask = jobDescription.xpath('Mask')[0]
        self.mask = Mask('')
        self.mask.fromXML(mask)

        score = jobDescription.xpath('Score')
        self.score = fromXMLScore(score[0])

        rot = jobDescription.xpath('Angles')[0]
        from pytom.angles.angle import AngleObject
        ang = AngleObject()
        self.rotations = ang.fromXML(rot)
        #        self.rotations = AngleList()
        #        self.rotations.fromXML(rot)

        bp = jobDescription.xpath('BandPassFilter')
        if bp != []:
            bp = bp[0]
            from pytom.basic.structures import BandPassFilter
            self.bandpass = BandPassFilter(0, 0, 0)
            self.bandpass.fromXML(bp)
        else:
            self.bandpass = None

    def toXML(self):
        """
        toXML : Compiles a XML file from job object
        @author: chen
        """

        from lxml import etree

        jobElement = etree.Element("JobDescription",
                                   ID=str(self.jobID),
                                   Members=str(self.members),
                                   Destination=str(self.dstDir))

        jobElement.append(self.volume.toXML())
        jobElement.append(self.reference.toXML())
        jobElement.append(self.mask.toXML())
        jobElement.append(self.wedge.toXML())
        jobElement.append(self.rotations.toXML())
        jobElement.append(self.score.toXML())
        if self.bandpass:
            jobElement.append(self.bandpass.toXML())

        return jobElement

    def check(self):
        """
        check: Performs check whether all settings are valid. Paths and Files exist
        @author: chen 
        """

        from pytom.tools.files import checkFileExists, checkDirExists

        returnValue = checkFileExists(self.volume.getFilename())
        if not returnValue:
            raise IOError('File: ' + str(self.volume) + ' not found!')

        returnValue = checkFileExists(self.reference.getReferenceFilename())
        if not returnValue:
            raise IOError('File: ' + str(self.reference) + ' not found!')

        returnValue = checkFileExists(self.mask.getFilename())
        if not returnValue:
            raise IOError('File: ' + str(self.mask) + ' not found!')

        returnValue = checkDirExists(self.dstDir[:-1])
        if not returnValue:
            raise IOError('Directory: ' + str(self.dstDir) + ' not found!')

        return returnValue

    def send(self, source, destination):
        """
        send: Send the job-relevant message from source to destination
        @param source: source machine id gained from pytom_mpi
        @type source: int
        @param destination: destination machine id
        @type destination: int
        @author: chen
        """

        from pytom.localization.peak_job_msg import PeakJobMsg

        #        self.check()
        msg = PeakJobMsg(str(source), str(destination))
        msg.setJob(self)

        import pytom_mpi
        print(f'destination: {destination}\ntype: {type(destination)}')
        pytom_mpi.send(str(msg), int(destination))