Exemplo n.º 1
0
def determineClassSwaps(particleList1,particleList2):
    """
    determineClassSwaps
    @param particleList1: The previous particleList
    @param particleList2:  The current particleList
    @return: List of particles that swapped class and a corresponding list of [previous class, current class].
    @rtype: [L{pytom.basic.structures.ParticleList},[previousClass,currentClass]]
    """
    from pytom.basic.structures import ParticleList
    
    returnList = ParticleList(particleList1.getDirectory())
    classSwaps = []
    
    for particle in particleList1:
        
        particleName = particle.getFilename()
        particleClass = particle.getClassName()
        
        otherParticle = particleList2.getParticleByFilename(particleName)
        otherParticleClass = otherParticle.getClassName()
        
        if not particleClass == otherParticleClass:
            returnList.append(otherParticle)
            
        classSwaps.append([particleClass,otherParticleClass])
            
    return [returnList,classSwaps]
        

    
    
Exemplo n.º 2
0
def saveForFSC(newReferenceName, particleList, verbose=False):
    """
    saveForFSC: Split particles into even / odd and calculate the Fourier Shell Correlation out of these two sets.
    @param newReferenceName: Name of current alignment result
    @type newReferenceName: str
    @param particleList:
    @type particleList: L{pytom.basic.structures.ParticleList} 
    """
    if len(particleList) < 2:
        raise RuntimeError(
            'ParticleList must have at least 2 elements to run saveForFSC!')

    from pytom.basic.structures import ParticleList
    from pytom.alignment.alignmentFunctions import average

    even = ParticleList('/')
    odd = ParticleList('/')

    for particleCounter in range(len(particleList)):

        if particleCounter % 2 == 0:
            even.append(particleList[particleCounter])
        else:
            odd.append(particleList[particleCounter])

    if verbose:
        print('averaging even:')
    average(even, newReferenceName + 'even.em', verbose)
    if verbose:
        print('averaging odd:')

    average(odd, newReferenceName + 'odd.em', verbose)
Exemplo n.º 3
0
    def average_sub_pl(self, pl, name_prefix, weight_average):
        """For worker node, do two things, averaging & obtaining the even/odd partitions to save some time.
           @param pl: particle list
           @type ps: L{pytom.basic.structures.ParticleList}
           @param name_prefix: name prefix output densities
           @type name_prefix: C{str}
           @param weight_average: weighted average
           @type weight_average: C{str}
        """
        from pytom.basic.structures import ParticleList
        even = ParticleList('.')
        odd = ParticleList('.')

        for i in range(len(pl)):
            if i % 2 == 0:
                even.append(pl[i])
            else:
                odd.append(pl[i])

        even.average(name_prefix + 'even.em',
                     progressBar=False,
                     createInfoVolumes=False,
                     _mpiParallel=False,
                     weighting=weight_average)
        odd.average(name_prefix + 'odd.em',
                    progressBar=False,
                    createInfoVolumes=False,
                    _mpiParallel=False,
                    weighting=weight_average)
Exemplo n.º 4
0
def initialize(pl, settings):
    from pytom.basic.structures import Particle
    # from pytom.alignment.alignmentFunctions import average2
    from pytom.basic.filter import lowpassFilter

    print("Initializing the class centroids ...")
    pl = pl.copy()
    pl.sortByScore()
    if settings["noise"]:
        pl = pl[:int((1-settings["noise"])*len(pl))]

    K = settings["ncluster"]
    freq = settings["frequency"]
    kn = len(pl)//K 
    references = {}
    frequencies = {}
    # get the first class centroid
    pp = pl[:kn]
    # avg, fsc = average2(pp, norm=True, verbose=False)
    pp.setClassAllParticles('0')
    res, tmp, tmp2 = calculate_averages(pp, settings["binning"], None, outdir=settings["output_directory"])
    avg = res['0']
    avg = lowpassFilter(avg, freq, freq/10.)[0]
    avg.write(os.path.join(settings['output_directory'], 'initial_0.em') )
    p = Particle(os.path.join(settings['output_directory'], 'initial_0.em'))
    p.setClass('0')
    references['0'] = p
    frequencies['0'] = freq

    for k in range(1, K):
        distances = [4]*len(pl)
        for c, ref in references.items():
            args = list(zip(pl, [ref]*len(pl), [freq]*len(pl), [settings["fmask"]]*len(pl), [settings["binning"]]*len(pl)))
            dist = mpi.parfor(distance, args)
            for i in range(len(pl)):
                if distances[i] > dist[i]:
                    distances[i] = dist[i]
        
        distances = np.asarray(distances)
        print('sum distances: ', distances.sum())
        distances = distances/np.sum(distances)
        idx = np.random.choice(len(pl), kn, replace=False, p=distances)
        pp = ParticleList()
        for i in idx:
            pp.append(pl[int(i)])
        # avg, fsc = average2(pp, norm=True, verbose=False)
        pp.setClassAllParticles('0')
        res, tmp, tmp2 = calculate_averages(pp, settings["binning"], None, outdir=settings["output_directory"])
        avg = res['0']
        avg = lowpassFilter(avg, freq, freq/10.)[0]
        kname = os.path.join(settings['output_directory'], 'initial_{}.em'.format(k))
        avg.write(kname)
        p = Particle(kname)
        p.setClass(str(k))
        references[str(k)] = p
        frequencies[str(k)] = freq
    
    return references, frequencies
Exemplo n.º 5
0
def writeSetOfVolumes(volSet, volXml, volDir):
    """ Convert a SetOfVolumes to a xml file used by PyTom.
    The volumes will be converted to .mrc format if not are '.em' or '.mrc' 
    Params:
        volSet: input SetOfVolumes.
        volXml: filename where to write the xml file.
        volDir: where to create links or copies (converted to mrc).
    """
    # Add to the path the root to pytom
    backupPath = list(sys.path)
    addPyTomPaths()
    
    from pytom.basic.structures import Particle, ParticleList, Wedge, SingleTiltWedge
    from pytom.score.score import Score, PeakPrior, xcfScore
    from pytom.frm.FRMAlignment import FRMScore
    
    w = SingleTiltWedge()
    #s = PeakPrior()
    pl = ParticleList()
    ih = em.convert.ImageHandler()
    
    for vol in volSet:
        index, fn = vol.getLocation()
        convert = True # by default, convert, which is the save way
        if index == em.NO_INDEX: # means single volumes
            volName = os.path.basename(fn)
            if fn.endswith('.em') or fn.endswith('.mrc'):
                convert = False # we can just create a link in this case
        else:
            volName = 'volume_%03d.mrc' % vol.getObjId()
        
        volFn = os.path.join(volDir, volName)
        if convert:
            ih.convert(vol, volFn)
        else:
            pwutils.createLink(fn, volFn)
        
        # Make the volumes names relative to the xml file
        # where the programs will be executed
        volRel = os.path.relpath(volFn, os.path.dirname(volXml))
        p = Particle()
        s = xcfScore()
        s.setValue(1.0)
        pytomInfo = getattr(vol, 'pytomInfo', None)
        if pytomInfo is None:
            p.setWedge(w)
        else:
            p.fromXML(pytomInfo.get()) # Get stored XML format from PyTom
        p.setFilename(volRel)
        p.setScore(s)
        pl.append(p)
        
    pl.toXMLFile(volXml)
    #pl.setWedgeAllParticles(w)
    sys.path = backupPath
Exemplo n.º 6
0
def simulationDescriptionToParticleList(directory,prefix = ''):
    """
    simulationDescriptionToParticleList: 
    """
    lenDir = len(directory)
    
    if not directory[lenDir-1] == '/':
        directory = directory + '/'
        
    xmlFile = directory + 'desc.xml'
    
    from lxml import etree
    
    simulationXML = etree.parse(xmlFile)
    
    #print etree.tostring(simulationXML,pretty_print=True)
    particles = simulationXML.xpath('particle')
    parameters = simulationXML.xpath('Simulation_Parameters')
    
    wedge = int(parameters[0].get('wangleEnd'))/2
    
    from pytom.basic.structures import Particle,ParticleList,WedgeInfo

    wi = WedgeInfo(wedge,[0.0,0.0,0.0])
    
    pl = ParticleList(directory)
    
    for particle in particles:
        
        filename = prefix + particle.get('filename')
        rotation = particle.get('rotation')
        rotation = rotation.replace('[','')
        rotation = rotation.replace(']','')
        rotation = rotation.split(',')
        rotation = [float(rotation[0]),float(rotation[1]),float(rotation[2])]
        
        shift = particle.get('shift')
        shift = shift.replace('[','')
        shift = shift.replace(']','')
        shift = shift.split(',')
        shift = [int(round(float(shift[0]))),int(round(float(shift[1]))),int(round(float(shift[2])))]
        
        p = Particle(filename,rotation = rotation,shift = shift,wedge=wi)
        
        pl.append(p)
    
    #al.toXMLFile(directory+'AlignmentList.xml')
    
    return pl
Exemplo n.º 7
0
 def average_sub_pl(self, pl, name_prefix):
     """For worker node, this function has been rewritten.
     """
     from pytom.basic.structures import ParticleList
     even = ParticleList('.')
     odd = ParticleList('.')
     
     for i in range(len(pl)):
         if i%2 == 0:
             even.append(pl[i])
         else:
             odd.append(pl[i])
     
     self.sum_sub_pl(even, name_prefix+'even')
     self.sum_sub_pl(odd, name_prefix+'odd')
Exemplo n.º 8
0
    def toParticleList(self):
        """
        toParticleList: Converts this object to a Particle List
        @return: A particle list that can be used for further processing
        @rtype: L{pytom.basic.structures.ParticleList} 
        """
        from pytom.basic.structures import ParticleList
        pl = ParticleList('/')

        for result in self._alignmentList:

            p = result.toParticle()
            pl.append(p)

        return pl
Exemplo n.º 9
0
    def average_sub_pl(self, pl, name_prefix, weight_average):
        """For worker node, do two things, averaging & obtaining the even/odd partitions to save some time.
        """
        from pytom.basic.structures import ParticleList
        even = ParticleList('.')
        odd = ParticleList('.')

        for i in xrange(len(pl)):
            if i % 2 == 0:
                even.append(pl[i])
            else:
                odd.append(pl[i])

        even.average(name_prefix + 'even.em',
                     progressBar=False,
                     createInfoVolumes=False,
                     _mpiParallel=False,
                     weighting=weight_average)
        odd.average(name_prefix + 'odd.em',
                    progressBar=False,
                    createInfoVolumes=False,
                    _mpiParallel=False,
                    weighting=weight_average)
Exemplo n.º 10
0
    def average_sub_pl(self, pl, name_prefix):
        """For worker node, this function has been rewritten.
        """
        from pytom.basic.structures import ParticleList
        even = ParticleList('.')
        odd = ParticleList('.')

        for p in pl:
            i = int(p.getClass())
            if i % 2 == 0:
                even.append(p)
            else:
                odd.append(p)

        assert len(
            even) > 0, "average_sub_pl: length even particle list == 0 :("
        assert len(odd) > 0, "average_sub_pl: length odd particle list == 0 :("

        # in some rare cases this would fail
        # that is: this worker only get one class, in this case, one of the pl will be null
        # just restart the job
        self.sum_sub_pl(even, name_prefix + 'even')
        self.sum_sub_pl(odd, name_prefix + 'odd')
Exemplo n.º 11
0
def applySymmetryOnParticleList(particleList,symmetry):
    """
    applySymmetryOnParticleList
    @deprecated: use L{pytom.basic.structures.Symmetry.apply} instead!
    """
    
    if symmetry.isOneFold():
        return particleList

    from pytom.basic.structures import ParticleList,Rotation
    newList = ParticleList(particleList.getDirectory())

    for i in range(len(particleList)):
        particle = particleList[i] 
        
        originalRotation = particle.getRotation()
        
        symmetry.setPsi(originalRotation.getPsi())
        symmetry.setTheta(originalRotation.getTheta())
        
        phi = originalRotation.getPhi()
        angleList = symmetry.getAngleList(phi)
    
        rotation = angleList.nextRotation()
        rotation = angleList.nextRotation()
    
        while not rotation == [None,None,None]:
        
            p2 = particle.copy()
        
            p2.setRotation(Rotation(rotation))
            
            newList.append(p2)
        
            rotation = angleList.nextRotation()
        
    return newList + particleList
Exemplo n.º 12
0
def growingAverageNew(particleList=None,angleObject=None,maskFile=None,scoreObject=None,startClassNumber=0,destinationDirectory='.',preprocessing = None,binning=1,verbose=False):
    """
    
    """
    
    from pytom.alignment.alignmentFunctions import bestAlignment
    from pytom.basic.structures import Reference,Particle,Rotation,ParticleList
    from pytom.alignment.preprocessing import Preprocessing
    
    if not preprocessing:
        preprocessing = Preprocessing()
    
    
    numberOfClasses = len(particleList.splitByClass())
    if verbose:
        print('Processing ' + str(numberOfClasses) + ' classes.')
        print('Generating start average')
        
    startAverageList = particleList.particlesFromClass(float(startClassNumber))
    
    startAverageList.average(destinationDirectory + '/GA_it0.em',progressBar=verbose)
    
    currentReference = Reference(destinationDirectory + '/GA_it0.em')
    
    growingAverageParticleList = ParticleList(particleList.getDirectory())
    
    for p in startAverageList:
        p.setRotation(Rotation(0,0,0))
        
        growingAverageParticleList.append(p)
    
    for i in range(2,numberOfClasses):
        
        currentParticleList = particleList.particlesFromClass(float(i))
        
        if verbose:
            print('Generating ' + str(i) + '. class average')
            
        currentParticleList.average(destinationDirectory + '/CA_it'+str(i)+'.em',progressBar=verbose)
        
        currentParticle = Particle(destinationDirectory + '/CA_it'+str(i)+'.em',wedgeInfo=currentParticleList[0].getWedgeInfo())
        
        if verbose:
            print('Running alignment iteration ' + str(i))
            print(currentParticle)
            print(currentReference)    
        
        currentPeak = bestAlignment(currentParticle.getVolume(),currentReference.getVolume(),currentReference.getWeighting(),currentParticle.getWedgeInfo(),angleObject,scoreObject,maskFile,preprocessing=preprocessing,binning=binning)
        
        if verbose:
            print('Parameters determined:')
            print(currentPeak)
            
        for p in currentParticleList:
            p.setRotation(currentPeak.getRotation())
            p.setShift(currentPeak.getShift())
            
            growingAverageParticleList.append(p)
        
        if verbose:
            print('Generating growing average ' + str(i))
            
        growingAverageParticleList.average(destinationDirectory + '/GA_it'+ str(i) +'.em',progressBar=verbose)
        
        currentReference = Reference(destinationDirectory + '/GA_it'+ str(i) +'.em')
        angleObject.reset()
Exemplo n.º 13
0
        if particlePath[-1] != os.sep:
            particlePath += os.sep

        for particle in res:
            newParticle = particle.toParticle()
            newParticle.setWedge(wedge)
            newParticle.setFilename(particlePath + newParticle.getFilename())

            if scale != 1.0:
                pi = newParticle.getPickPosition()
                pi.setX(pi.getX() * scale)
                pi.setY(pi.getY() * scale)
                pi.setZ(pi.getZ() * scale)
                newParticle.setPickPosition(pi)

            pl.append(newParticle)

        pl.toXMLFile(plFilename)

    if motlFilename:
        from pytom.basic.structures import ParticleList

        pl = ParticleList()
        for newParticle in res:

            if scale != 1.0:
                pi = newParticle.getPickPosition()
                pi.setX(pi.getX() * scale)
                pi.setY(pi.getY() * scale)
                pi.setZ(pi.getZ() * scale)
                newParticle.setPickPosition(pi)
Exemplo n.º 14
0
        dir_name, name_prefix, wedge_angle, output, bHelp = parse_script_options(
            sys.argv[1:], helper)
    except:
        sys.exit()
    if bHelp is True:
        print(helper)
        sys.exit()

    if name_prefix is None:
        name_prefix = ''
    wedge_angle = float(wedge_angle)
    w = SingleTiltWedge(wedge_angle)

    pl = ParticleList()
    all_files = os.listdir(dir_name)
    for fname in all_files:
        p = None
        name_suffix = fname.split('.')[-1]
        if len(name_prefix):
            if name_prefix in fname and name_suffix in ['em', 'mrc']:
                p = Particle(dir_name + '/' + fname)
        else:
            if name_suffix in ['em', 'mrc']:
                p = Particle(dir_name + '/' + fname)
        if p is not None:
            pl.append(p)

    pl.setWedgeAllParticles(w)

    pl.toXMLFile(output)
Exemplo n.º 15
0
 if not dest_dir:
     dest_dir = '.'
 
 from pytom_volume import read, subvolume
 v = read(vol_filename)
 
 from pytom.basic.structures import ParticleList, Particle, WedgeInfo
 pl = ParticleList("./")
 pl.fromXMLFile(pl_filename)
 
 def regulaize(xx, dim):
     if xx*binning-radius < 0:
         if 2*radius > dim:
             raise Exception("Volume size to be cut is too big!")
         return 0
     if xx*binning+radius > dim:
         if dim-2*radius < 0:
             raise Exception("Volume size to be cut is too big!")
         return dim-2*radius
     return xx*binning-radius
 
 res = ParticleList(dest_dir)
 for p in pl:
     x,y,z = p.getPickPosition().toVector()
     x = regulaize(int(x), v.sizeX()); y = regulaize(int(y), v.sizeY()); z = regulaize(int(z), v.sizeZ())
     new_vol = subvolume(v, x, y, z, 2*radius, 2*radius, 2*radius)
     name = dest_dir+'/'+p.getFilename()
     new_vol.write(name) # write the subtomograms to the disk
     res.append(Particle(name, p.getRotation(), None, WedgeInfo(w), 1, p.getPickPosition(), p.getScore())) # append it to the particle list for alignment
 
 res.toXMLFile(dest_dir+'/'+res_name)
Exemplo n.º 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
    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
Exemplo n.º 17
0
def classifyParticleList(particleList, alignmentLists, verbose=False):
    """
    classifyParticleList: Classifies input particle list according to scores determined in alignment lists. 
    @param particleList:
    @param alignmentLists:
    @param verbose:
    @return: Will return particle list in same order as input but with assigned class memberships.
    """

    from pytom.basic.structures import ParticleList
    classifiedParticleList = ParticleList(particleList.getDirectory())

    for alignmentList in alignmentLists:
        alignmentList.sortByParticleList(particleList)

    for particleIndex in range(len(particleList)):

        particle = particleList[particleIndex]
        score = particle.getScore()

        if verbose:
            print(particle.getFilename())

        if not score:
            bestScore = -999999999
        else:
            bestScore = particle.getScore().getWorstValue()

        bestResult = []
        bestCluster = []

        for alignmentIterator in range(len(alignmentLists)):
            alignmentList = alignmentLists[alignmentIterator]

            result = alignmentList[particleIndex]

            score = result.getScore()

            value = float(score.getValue())

            if verbose:
                print(value)

            if value >= bestScore:
                bestResult = result
                bestCluster = alignmentIterator
                bestScore = value

        if bestResult == []:
            raise Exception('Could not determine best cluster for particle ' +
                            particle.getFilename())

        classifiedParticle = bestResult.toParticle()
        classifiedParticle.setClass(bestCluster)

        if verbose:
            print(classifiedParticle)

        classifiedParticleList.append(classifiedParticle)

    return classifiedParticleList
Exemplo n.º 18
0
    if help is True:
        print(helper)
        sys.exit()

    cubeSize = int(cubeSize)

    particleList = ParticleList()
    try:
        particleList.fromXMLFile(plFilename)
    except:
        from pytom.localization.structures import readParticleFile
        particles = readParticleFile(plFilename)

        particleList = ParticleList()
        for particle in particles:
            particleList.append(particle.toParticle())

    particlePath = particleList[0].getFilename()
    particleFolder = particlePath[0:particlePath.rfind('/')]

    if not checkDirExists(particleFolder):
        os.makedirs(particleFolder)

    prog = FixedProgBar(0, len(particleList) - 1, '')

    newParticleList = ParticleList()

    vol = read(volFilename)
    volX = vol.sizeX()
    volY = vol.sizeY()
    volZ = vol.sizeZ()
Exemplo n.º 19
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
Exemplo n.º 20
0
def classifyParticleListThreads(particleList,
                                alignmentLists,
                                criterion,
                                temperature,
                                verbose=False):
    """
    classifyParticleListThreads: Same as above, but distributes classifyParticleList to threads
    @param particleList:
    @param alignmentLists:
    @param criterion: 
    @param temperature:
    @param verbose: Print classification process. (Default is False)   
    """

    from pytom.basic.structures import ParticleList
    from pytom.cluster.mcoEXMXStructures import SwapList

    for alignmentList in alignmentLists:
        alignmentList.sortByParticleList(particleList)

    temperature.initializeTemperature(alignmentLists)

    priorClassNumber = len(particleList.splitByClass())

    iteration = 0
    clusterSizeSame = False

    #prevent that annealing deletes clusters.
    #leave at least one particle in class! repeat for 10 iterations if criterion.getAllowClassCollapse() == False!

    while iteration < 10 and not clusterSizeSame:
        swapList = SwapList()
        classifiedParticleList = ParticleList(particleList.getDirectory())

        for particleIndex in range(len(particleList)):

            particle = particleList[particleIndex]

            results = []

            for alignmentIterator in range(len(alignmentLists)):

                alignmentList = alignmentLists[alignmentIterator]
                results.append(alignmentList[particleIndex])

            #results = sorted(results, key=lambda MaximisationResult: MaximisationResult.getScore().getValue(),reverse=True)

            if verbose:
                print('')
                print('')
                print('')
                print('----------------------')
                print(results)

            [bestResult, bestCluster,
             swapList] = criterion.apply(results, temperature, swapList, False)

            if bestResult == []:
                raise RuntimeError(
                    'Could not determine best cluster for particle ' +
                    particle.getFilename())

            classifiedParticle = bestResult.toParticle()
            classifiedParticle.setClass(bestCluster)
            classifiedParticle.setRotation(particle.getRotation())
            classifiedParticle.setShift(particle.getShift())

            if verbose:
                print(classifiedParticle)

            classifiedParticleList.append(classifiedParticle)

        iteration += 1

        clusterSizeSame = priorClassNumber == len(
            classifiedParticleList.splitByClass(False))
        clusterSizeSame = clusterSizeSame or criterion.getAllowClassCollapse()

    return [classifiedParticleList, swapList]
Exemplo n.º 21
0
def createClassificationResultDictionaries(classifiedParticleList,
                                           groundTruthParticleList,
                                           verbose=False):
    """
    assessClassification: Comment in LB 31.1.2011
    @param classifiedParticleList: list of classified particles
    @param groundTruthParticleList: ground truth
    @param verbose: If True, will print the class dictionaries generated. Default is false.
    @return:  A dictionary that maps new classnames to groundTruthClasses
    """
    from pytom.basic.structures import Particle, ParticleList

    #from file if filename
    if classifiedParticleList.__class__ == str:
        classifiedParticleListFile = classifiedParticleList

        classifiedParticleList = ParticleList('/')
        classifiedParticleList.fromXMLFile(classifiedParticleListFile)

    #from file if filename
    if groundTruthParticleList.__class__ == str:

        groundTruthParticleList = ParticleList('/')
        groundTruthParticleList.fromXMLFile(groundTruthParticleList)

    newClassesToGroundTruthMap = {
    }  #maps new class name to a ground truth class name
    gtClassNames = {}  #maps if one class has been determined

    for gtClass in groundTruthParticleList.splitByClass():
        particle = gtClass[0]
        gtClassNames[particle.getClassName()] = False

    if verbose:
        print('gtClassNames : ', gtClassNames)

    groundTruthParticleListXML = groundTruthParticleList.toXML()

    for newClass in classifiedParticleList.splitByClass():

        if verbose:
            print('')
            print('newClass : ', newClass)

        particlesFromGroundTruth = ParticleList('/')

        for particle in newClass:
            #collect all particles that were assigned to newClass
            particleName = particle.getFilename()
            #gtParticle = groundTruthParticleList.getParticleByFilename(particleName)
            particleXML = groundTruthParticleListXML.xpath(
                '/ParticleList/Particle[@Filename="' + str(particleName) +
                '"]')
            gtParticle = Particle('a')
            gtParticle.fromXML(particleXML[0])

            particlesFromGroundTruth.append(gtParticle)

        if verbose:
            print('len(particlesFromGroundTruth) : ',
                  len(particlesFromGroundTruth))

        #sort classes according to size to descending order
        sortedClasses = sorted(particlesFromGroundTruth.splitByClass(),
                               key=lambda x: len(x),
                               reverse=True)

        classWasAssigned = False
        classIndex = 0

        if verbose:
            print('len(sortedClasses) : ', len(sortedClasses))

        while not classWasAssigned and classIndex < len(sortedClasses):
            sortedClass = sortedClasses[classIndex]
            className = sortedClass[0].getClassName()

            if verbose:
                print('className : ' + className)
                print('len(sortedClass) : ', len(sortedClass))

            classWasAssigned = not gtClassNames[className]

            if verbose:
                print('classWasAssigned : ', classWasAssigned)

            if not classWasAssigned:
                classIndex = classIndex + 1
            else:
                gtClassNames[className] = True
                newClassesToGroundTruthMap[
                    newClass[0].getClassName()] = className

                if verbose:
                    print('gtClassNames : ', gtClassNames)
                    print('newClassesToGroundTruthMap : ',
                          newClassesToGroundTruthMap)

    return newClassesToGroundTruthMap
Exemplo n.º 22
0
def assessClassification(classifiedParticleList,
                         groundTruthParticleList,
                         verbose=False):
    """
    assessClassification: Comment in LB 31.1.2011
    @param classifiedParticleList: list of classified particles
    @param groundTruthParticleList: ground truth
    @param verbose: If True, will print the class dictionaries generated. Default is false.
    @return:  [trueHits,falseHits,trueHitsPercent,falseHitsPercent,numberClusters,[clusterSizes]]
    """
    from pytom.basic.structures import Particle, ParticleList

    #from file if filename
    if classifiedParticleList.__class__ == str:
        classifiedParticleListFile = classifiedParticleList

        classifiedParticleList = ParticleList('/')
        classifiedParticleList.fromXMLFile(classifiedParticleListFile)

    #from file if filename
    if groundTruthParticleList.__class__ == str:
        groundTruthParticleListFile = groundTruthParticleList

        groundTruthParticleList = ParticleList('/')
        groundTruthParticleList.fromXMLFile(groundTruthParticleListFile)

    gtClassNamesAssigned = {}  #maps if one class has been determined

    for gtClass in groundTruthParticleList.splitByClass():
        particle = gtClass[0]
        gtClassNamesAssigned[particle.getClassName()] = False

    if verbose:
        print('GT Classes ', gtClassNamesAssigned)

    gtClassesPerClass = {}

    newClasses = classifiedParticleList.splitByClass()
    newClassNamesAssigned = {}
    numberClasses = len(newClasses)
    classSizes = []

    for i in range(len(newClasses)):
        classSizes.append(len(newClasses[i]))

    for newClass in newClasses:

        newClassParticleList = ParticleList(newClass.getDirectory())
        newClassNamesAssigned[newClass[0].getClassName()] = False

        for particle in newClass:
            pp = groundTruthParticleList[particle.getFilename()]
            newClassParticleList.append(pp)

        gtClassSizeDictionary = {}

        for gtClass in newClassParticleList.splitByClass():
            particle = gtClass[0]
            gtParticle = groundTruthParticleList[particle.getFilename()]
            gtClassSizeDictionary[gtParticle.getClassName()] = len(gtClass)

        gtClassesPerClass[newClass[0].getClassName()] = [
            newClassParticleList, gtClassSizeDictionary
        ]

    if verbose:
        print('Class distribution dictionary')
        for k in list(gtClassesPerClass.keys()):
            print(k, gtClassesPerClass[k])

    gtToClassDictionary = {}

    for gtName in list(gtClassNamesAssigned.keys()):

        newClassIndex = 0
        classSizeList = []

        largestClass = -1
        maxClassName = 'unknown'
        assigned = False
        for newClassName in list(gtClassesPerClass.keys()):

            l = gtClassesPerClass[newClassName]
            gtClassSizeDictionary = l[1]
            if verbose:
                print('GT Name', gtName, ' New Class Name', newClassName)
                print('GT Name Size', gtClassSizeDictionary)

            try:
                if verbose:
                    print(gtClassSizeDictionary[gtName])
                if largestClass < gtClassSizeDictionary[
                        gtName] and not newClassNamesAssigned[newClassName]:
                    largestClass = gtClassSizeDictionary[gtName]
                    maxClassName = newClassName
                    if verbose:
                        print('SWAP')

            except KeyError:
                pass

        gtToClassDictionary[gtName] = maxClassName
        newClassNamesAssigned[maxClassName] = True
        gtClassNamesAssigned[gtName] = True

        for newClassName in list(gtClassesPerClass.keys()):
            try:
                l = gtClassesPerClass[newClassName]
                gtClassSizeDictionary = l[1]

                del gtClassSizeDictionary[gtName]
                l[1] = gtClassSizeDictionary

                gtClassesPerClass[newClassName] = l
            except KeyError:
                pass
    if verbose:
        print('GT to New Dictionary')
        print(gtToClassDictionary)

    trueHits = 0
    falseHits = 0

    classifiedParticleListXML = classifiedParticleList.toXML()

    for gtParticle in groundTruthParticleList:

        particleXML = classifiedParticleListXML.xpath(
            '/ParticleList/Particle[@Filename="' +
            str(gtParticle.getFilename()) + '"]')
        particle = Particle('a')
        particle.fromXML(particleXML[0])

        if particle.getClassName() == gtToClassDictionary[
                gtParticle.getClassName()]:
            trueHits += 1
        else:
            falseHits += 1

    return [
        trueHits, falseHits,
        float(trueHits) / len(classifiedParticleList),
        float(falseHits) / len(classifiedParticleList), numberClasses,
        classSizes
    ]