Source code for xmipp3.protocols.protocol_particle_pick

# **************************************************************************
# *
# * Authors:     Jose Gutierrez Tabuenca (
# *              J.M. De la Rosa Trevin (
# *
# * Unidad de  Bioinformatica of Centro Nacional de Biotecnologia , CSIC
# *
# * This program is free software; you can redistribute it and/or modify
# * it under the terms of the GNU General Public License as published by
# * the Free Software Foundation; either version 2 of the License, or
# * (at your option) any later version.
# *
# * This program is distributed in the hope that it will be useful,
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
# * GNU General Public License for more details.
# *
# * You should have received a copy of the GNU General Public License
# * along with this program; if not, write to the Free Software
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# * 02111-1307  USA
# *
# *  All comments concerning this program package may be sent to the
# *  e-mail address ''
# *
# **************************************************************************
from os.path import exists, join

from pyworkflow.object import String, Integer
from pyworkflow.protocol import BooleanParam, LEVEL_ADVANCED
from pyworkflow.utils.path import *

from pwem import EMObject
from pwem.protocols import ProtParticlePicking
from pwem.viewers import launchSupervisedPickerGUI

from pwem import emlib
from xmipp3.base import XmippProtocol
from xmipp3.convert import readSetOfCoordinates

[docs]class XmippProtParticlePicking(ProtParticlePicking, XmippProtocol): """ Picks particles in a set of micrographs either manually or in a supervised mode. """ _label = 'manual-picking (step 1)' def __init__(self, **args): ProtParticlePicking.__init__(self, **args) # The following attribute is only for testing self.importFolder = String(args.get('importFolder', None)) #--------------------------- DEFINE param functions ------------------------ def _defineParams(self, form): ProtParticlePicking._defineParams(self, form) form.addParam('saveDiscarded', BooleanParam, default=False, label='Save discarded particles', help='Generates an output with ' 'the manually discarded particles.') form.addParam('doInteractive', BooleanParam, default=True, label='Run in interactive mode', expertLevel=LEVEL_ADVANCED, help='If YES, you can pick particles in differents sessions.\n' 'If NO, once an outputCoordinates is created, ' 'the protocol finishes. \n' '(the last can be useful when other protocol ' 'waits until this finish -internal scheduled-)') #--------------------------- INSERT steps functions ------------------------ def _insertAllSteps(self): """The Particle Picking process is realized for a set of micrographs""" # Get pointer to input micrographs self.inputMics = self.inputMicrographs.get() micFn = self.inputMics.getFileName() # Launch Particle Picking GUI if not self.importFolder.hasValue(): self._insertFunctionStep('launchParticlePickGUIStep', micFn, interactive=self.doInteractive) else: # This is only used for test purposes self._insertFunctionStep('_importFromFolderStep') # Insert step to create output objects self._insertFunctionStep('createOutputStep')
[docs] def launchParticlePickGUIStep(self, micFn): # Launch the particle picking GUI extraDir = self._getExtraPath() process = launchSupervisedPickerGUI(micFn, extraDir, self) process.wait() # generate the discarded output only if there is a good output if self.saveDiscarded and exists(self._getPath('coordinates.sqlite')): self.createDiscardedStep() coordSet = self.getCoords() if coordSet: boxSize = Integer(coordSet.getBoxSize()) self._defineOutputs(boxsize=boxSize) self._defineSourceRelation(self.inputMicrographs.get(), boxSize)
def _importFromFolderStep(self): """ This function will copy Xmipp .pos files for simulating a particle picking run...this is only for testing purposes. """ for f in getFiles(self.importFolder.get()): copyFile(f, self._getExtraPath())
[docs] def createOutputStep(self): posDir = self._getExtraPath() coordSet = self._createSetOfCoordinates(self.inputMics) readSetOfCoordinates(posDir, self.inputMics, coordSet) self._defineOutputs(outputCoordinates=coordSet) self._defineSourceRelation(self.inputMicrographs, coordSet) boxSize = Integer(coordSet.getBoxSize()) self._defineOutputs(boxsize=boxSize) self._defineSourceRelation(self.inputMicrographs.get(), boxSize)
[docs] def createDiscardedStep(self): posDir = self._getExtraPath() suffixRoot = self._ProtParticlePicking__getOutputSuffix() suffix = '' if suffixRoot=='2' or suffixRoot=='' \ else str(int(suffixRoot)-1) coordSetDisc = self._createSetOfCoordinates(self.inputMics, suffix='Discarded'+suffix) readSetOfCoordinates(posDir, self.inputMics, coordSetDisc, readDiscarded=True) if coordSetDisc.getSize()>0: outputName = 'outputDiscardedCoordinates' + suffix outputs = {outputName: coordSetDisc} self._defineOutputs(**outputs) self._defineSourceRelation(self.inputMicrographs, coordSetDisc)
#--------------------------- INFO functions -------------------------------- def _citations(self): return ['Abrishami2013'] #--------------------------- UTILS functions ------------------------------- def __str__(self): """ String representation of a Supervised Picking run """ if not hasattr(self, 'outputCoordinates'): msg = "No particles picked yet." else: picked = 0 # Get the number of picked particles of the last coordinates set for key, output in self.iterOutputAttributes(EMObject): picked = output.getSize() msg = "%d particles picked (from %d micrographs)" % \ (picked, self.inputMicrographs.get().getSize()) return msg def _methods(self): if self.getOutputsSize() > 0: return ProtParticlePicking._methods(self) else: return [self._getTmpMethods()] def _getTmpMethods(self): """ Return the message when there is not output generated yet. We will read the Xmipp .pos files and other configuration files. """ configfile = join(self._getExtraPath(), 'config.xmd') existsConfig = exists(configfile) msg = '' if existsConfig: md = emlib.MetaData('properties@' + configfile) configobj = md.firstObject() pickingState = md.getValue(emlib.MDL_PICKING_STATE, configobj) particleSize = md.getValue(emlib.MDL_PICKING_PARTICLE_SIZE, configobj) isAutopick = pickingState != "Manual" manualParts = md.getValue(emlib.MDL_PICKING_MANUALPARTICLES_SIZE, configobj) autoParts = md.getValue(emlib.MDL_PICKING_AUTOPARTICLES_SIZE, configobj) if manualParts is None: manualParts = 0 if autoParts is None: autoParts = 0 msg = 'User picked %d particles ' % (autoParts + manualParts) msg += 'with a particle size of %d.' % particleSize if isAutopick: msg += "Automatic picking was used ([Abrishami2013]). " msg += "%d particles were picked automatically " % autoParts msg += "and %d manually." % manualParts return msg def _summary(self): if self.getOutputsSize() > 0: return ProtParticlePicking._summary(self) else: return [self._getTmpSummary()] def _getTmpSummary(self): summary = [] configfile = join(self._getExtraPath(), 'config.xmd') existsConfig = exists(configfile) if existsConfig: md = emlib.MetaData('properties@' + configfile) configobj = md.firstObject() pickingState = md.getValue(emlib.MDL_PICKING_STATE, configobj) particleSize = md.getValue(emlib.MDL_PICKING_PARTICLE_SIZE, configobj) activeMic = md.getValue(emlib.MDL_MICROGRAPH, configobj) isAutopick = pickingState != "Manual" manualParticlesSize = md.getValue(emlib.MDL_PICKING_MANUALPARTICLES_SIZE, configobj) autoParticlesSize = md.getValue(emlib.MDL_PICKING_AUTOPARTICLES_SIZE, configobj) summary.append("Manual particles picked: %d"%manualParticlesSize) summary.append("Particle size:%d" %(particleSize)) autopick = "Yes" if isAutopick else "No" summary.append("Autopick: " + autopick) if isAutopick: summary.append("Automatic particles picked: %d"%autoParticlesSize) summary.append("Last micrograph: " + activeMic) return "\n".join(summary)
[docs] def getCoordsDir(self): return self._getExtraPath()