Source code for xmipp3.protocols.protocol_particle_pick_automatic

# **************************************************************************
# *
# * Authors:     Jose Gutierrez Tabuenca (jose.gutierrez@cnb.csic.es)
# *              Laura del Cano (laura.cano@cnb.csic.es)
# *
# * 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
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# * 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 'scipion@cnb.csic.es'
# *
# **************************************************************************
from os.path import exists, basename, join

from pyworkflow.protocol.params import STEPS_PARALLEL, PointerParam, EnumParam, FileParam
from pyworkflow.utils.path import *

from pwem.protocols import ProtParticlePickingAuto

from pwem import emlib
from xmipp3.base import XmippProtocol
from xmipp3.convert import readSetOfCoordinates
from pyworkflow import BETA, UPDATED, NEW, PROD


MICS_SAMEASPICKING = 0
MICS_OTHER = 1
SRC_MANUAL_PICKING = 0
SRC_DIR = 1


[docs]class XmippParticlePickingAutomatic(ProtParticlePickingAuto, XmippProtocol): """Protocol to pick particles automatically in a set of micrographs using previous training """ _label = 'auto-picking (step 2)' _devStatus = UPDATED filesToCopy = ['model_svm.txt', 'model_pca_model.stk', 'model_rotpca_model.stk', 'model_particle_avg.xmp', 'templates.stk'] def __init__(self, **kwargs): ProtParticlePickingAuto.__init__(self, **kwargs) self.stepsExecutionMode = STEPS_PARALLEL # --------------------------- DEFINE param functions ----------------------- def _defineParams(self, form): form.addSection(label='Input') form.addParam('modelSource', EnumParam, label="Model source", choices=["Manual picking in this project", "External directory"], default=0, help="The files model_* can be copied from a previous protocol execution within this " "project or copied from an external directory. This latter option is useful in" "cases in which the same kind of molecule is processed many times.") form.addParam('xmippParticlePicking', PointerParam, label="Xmipp particle picking run", pointerClass='XmippProtParticlePicking', condition="modelSource==%d"%SRC_MANUAL_PICKING, #pointerCondition='isFinished', help='Select the previous xmipp particle picking run.') form.addParam('xmippParticlePickingDir', FileParam, label="Xmipp particle picking model directory", allowsNull=True, condition="modelSource==%d"%SRC_DIR, #pointerCondition='isFinished', help='The directory must contain the files model_*, config.xmd and templates.stk') form.addParam('micsToPick', EnumParam, choices=['Same as supervised', 'Other'], default=0, label='Micrographs to pick', display=EnumParam.DISPLAY_LIST, help="Select from which set of micrographs to pick using " "the training from supervised run." "If you use Same as supervised, the same set of " "micrographs used for training the picker will be " "used at this point. If you select Other, you can " "select another set of micrograph (normally from " "the same specimen) and pick them completely " "automatic using the trained picker.") form.addParam('inputMicrographs', PointerParam, pointerClass='SetOfMicrographs', condition='micsToPick==%d' % MICS_OTHER, label="Micrographs", help="Select other set of micrographs to pick using the " "trained picker.") self._defineStreamingParams(form) form.addParallelSection(threads=1, mpi=1) # --------------------------- INSERT steps functions ----------------------- def _insertInitialSteps(self): # Get pointer to input micrographs self.particlePickingRun = self.xmippParticlePicking.get() copyId = self._insertFunctionStep('copyInputFilesStep') return [copyId] # --------------------------- STEPS functions ------------------------------
[docs] def getSrcDir(self): if self.modelSource == SRC_MANUAL_PICKING: return self.xmippParticlePicking.get()._getExtraPath() else: return self.xmippParticlePickingDir.get()
[docs] def copyInputFilesStep(self): # Copy training model files to current run srcDir = self.getSrcDir() for f in self.filesToCopy: createLink(os.path.join(srcDir, f), self._getExtraPath(f)) copyFile(os.path.join(srcDir, "config.xmd"), self._getExtraPath("config.xmd")) # Get the box size mdInfo = emlib.MetaData("properties@"+self._getExtraPath("config.xmd")) self.boxSize = mdInfo.getValue(emlib.MDL_PICKING_PARTICLE_SIZE,mdInfo.firstObject()) mdInfo.setValue(emlib.MDL_PICKING_MANUALPARTICLES_SIZE,0,mdInfo.firstObject()) mdInfo.write("properties@"+self._getExtraPath("config.xmd"),emlib.MD_APPEND)
def _pickMicrograph(self, mic, *args): micPath = mic.getFileName() # Get particle picking boxsize from the previous run modelRoot = self._getExtraPath('model') micName = removeBaseExt(micPath) proceed = True if self.micsToPick == MICS_SAMEASPICKING: basePos = replaceBaseExt(micPath, "pos") fnPos = self.particlePickingRun._getExtraPath(basePos) if exists(fnPos): blocks = emlib.getBlocksInMetaDataFile(fnPos) copy = True if 'header' in blocks: mdheader = emlib.MetaData("header@" + fnPos) state = mdheader.getValue(emlib.MDL_PICKING_MICROGRAPH_STATE, mdheader.firstObject()) if state == "Available": copy = False if copy: # Copy manual .pos file of this micrograph copyFile(fnPos, self._getExtraPath(basename(fnPos))) proceed = False if proceed: args = "-i %s " % micPath args += "--particleSize %d " % self.boxSize args += "--model %s " % modelRoot args += "--outputRoot %s " % self._getExtraPath(micName) args += "--mode autoselect --thr %d" % self.numberOfThreads self.runJob("xmipp_micrograph_automatic_picking", args)
[docs] def readSetOfCoordinates(self, workingDir, coordSet): readSetOfCoordinates(workingDir, self.getInputMicrographs(), coordSet)
[docs] def readCoordsFromMics(self, workingDir, micList, coordSet): readSetOfCoordinates(workingDir, micList, coordSet)
# --------------------------- INFO functions ------------------------------- def _validate(self): validateMsgs = [] if self.modelSource == SRC_MANUAL_PICKING and not hasattr(self.xmippParticlePicking.get(),"outputCoordinates"): validateMsgs.append("You need to generate coordinates for the " "supervised picking") srcDir = self.getSrcDir() srcPaths = [os.path.join(srcDir,k) for k in self.filesToCopy] # Check that all needed files exist if missingPaths(*srcPaths): validateMsgs.append('Input picking run has not been trained, ' 'use *Autopick* for at least one micrograph') # If other set of micrographs is provided they should have same # sampling rate and acquisition if self.micsToPick.get() == MICS_OTHER and self.modelSource != SRC_DIR: inputMics = self.inputMicrographs.get() manualMics = self.xmippParticlePicking.get().inputMicrographs.get() # FIXME: manualMics is always None when scheduled... # it should be fixed in the update step at Scipion scheduler app if manualMics is not None: pixsizeInput = inputMics.getSamplingRate() pixsizeMics = manualMics.getSamplingRate() acq = manualMics.getAcquisition() if pixsizeInput != pixsizeMics: validateMsgs.append('New micrographs should have same sampling ' 'rate as the ones already picked.') if not inputMics.getAcquisition().equalAttributes(acq): validateMsgs.append('New micrographs should have same ' 'acquisition parameters as the ones ' 'already picked.') if self.modelSource.get()==SRC_DIR and self.micsToPick.get()==MICS_SAMEASPICKING: validateMsgs.append("You cannot take the model from a directory and indicate that the set of micrograohs " "is the same as picking. If you take the model from a directory, probably you want " "to pick from a different set.") return validateMsgs
[docs] def getSummary(self, coordSet): summary = [] if self.modelSource == SRC_MANUAL_PICKING: summary.append("Previous run: %s" % self.xmippParticlePicking.get().getNameId()) else: summary.append("Model from: %s" % self.xmippParticlePickingDir.get()) return "\n".join(summary)
[docs] def getMethods(self, output): manualPickName = self.xmippParticlePicking.get().getNameId() msg = 'Program picked %d particles ' % output.getSize() msg += 'of size %d ' % output.getBoxSize() msg += 'using training from %s. ' % manualPickName msg += 'For more detail see [Abrishami2013]' return msg
def _citations(self): return ['Abrishami2013'] # --------------------------- UTILS functions ------------------------------
[docs] def getCoordsDir(self): return self._getExtraPath()
[docs] def getInputMicrographsPointer(self): # Get micrographs to pick if self.micsToPick == MICS_SAMEASPICKING: inputPicking = self.xmippParticlePicking.get() return inputPicking.inputMicrographs if inputPicking else None else: return self.inputMicrographs
[docs] def getInputMicrographs(self): """ Return the input micrographs that can be the same of the supervised picking or other ones selected by the user. (This can be used to pick a new set of micrographs with the same properties than a previous trained ones. ) """ return self.getInputMicrographsPointer().get() if self.getInputMicrographsPointer() else None