def extractClassesFromPL(pl_name, class_names, output): from pytom.basic.structures import ParticleList pl = ParticleList() pl.fromXMLFile(pl_name) pls = pl.splitByClass() class_labels = class_names.split(',') res = ParticleList() for pp in pls: if pp[0].getClass() in class_labels: res += pp if output: res.toXMLFile(output) return res
def averageClasses(particleListFilename, avName): """ write class averages of classified particles @param particleListFilename: particle list filename @type particleListFilename: str @param avName: Name for class averages (<avName>_iclass.em) @type avName: str @author: FF @date: Jan 2013 """ from pytom.basic.structures import ParticleList pl = ParticleList() pl.fromXMLFile(particleListFilename) pl.sortByClassLabel() pls = pl.splitByClass() for cl in pls: className = cl[0].getClassName() cl.average(avName + "_" + str(className) + '.em') print(className, ' contains ', len(cl), ' particles')
##!/bin/bash ## This script merges desired classes from one or multiple particleLists of individual tomograms. It utilizes the pytom function pl.splitByClass ## Utrecht University, 19.11.2019, RE #module load openmpi/2.1.1 pytom/0.971 from pytom.basic.structures import ParticleList import os ## The variable nice_classes_list contains arrays specifying the tomogram and classes. Each array should contain the index of the desired tomograms in the first position, followed by the indices of the desired classes from that tomogram. ## In the example below, the first array [8,0,1,3,4] specifies the classes 0, 1, 3 and 4 within tomogram 8. nice_classes_list = [[8,0,1,3,4], [9,0], [13,2], [14,0,1,2], [15,0,1,3], [16,0,1], [20,1], [21,3], [24,1], [27,2], [29,1], [30,1], [31,0], [32,1], [33,1], [34,1], [35,1], [36,1,4], [38,1], [43,3], [45,1], [46,1], [52,4], [53,1,3], [54,1], [79,3]] pl=ParticleList() ## Below, adjust the path inside pl.fromXMLFile to point to the individual particle lists. for nice_classes in nice_classes_list: pl.fromXMLFile('tomogram' + str(nice_classes_list[nice_classes][0]) + '/subtomograms/subtomos_bin6/AC3D/classified_pl_iter9.xml') lists=pl.splitByClass() for i in range(len(nice_classes_list[nice_classes])-1) ribos=ribos.append(lists[nice_classes_list[nice_classes][i + 1]) ## specify the desired output path below ribos.toXMLFile('AC3d_pickedClasses.xml')
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
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 ]
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]