Source code for eman2.protocols.protocol_tomo_template_match

# **************************************************************************
# *
# * Authors:     David Herreros Calero (dherreros@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 3 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'
# *
# **************************************************************************

import os
import math

from pyworkflow.utils.properties import Message
from pyworkflow import utils as pwutils
from pyworkflow.protocol.params import (PointerParam, IntParam,
                                        StringParam, FloatParam, LEVEL_ADVANCED)
from pyworkflow.utils.path import moveFile, copyFile

import eman2
from eman2.convert import loadJson, readSetOfCoordinates3D

from tomo.protocols import ProtTomoPicking
from tomo.objects import SetOfCoordinates3D


[docs]class EmanProtTomoTempMatch(ProtTomoPicking): """ This protocol wraps *e2spt_tempmatch.py* EMAN2 program. It will perform a sweep of an initial volume against a tomogram to find correlation peaks and extract the corresponding subtomogram coordinates """ _label = 'template matching' def __init__(self, **args): ProtTomoPicking.__init__(self, **args)
[docs] @classmethod def isDisabled(cls): """ Return True if this Protocol is disabled. Disabled protocols will not be offered in the available protocols.""" if eman2.Plugin.getActiveVersion(versions=[eman2.V2_31]): return True else: return False
# --------------------------- DEFINE param functions ---------------------- def _defineParams(self, form): form.addSection(label='Input') form.addParam('inputSet', PointerParam, pointerClass='SetOfTomograms', label="Input tomograms", important=True, help='Specify tomograms containing reference-like particles\n' 'to be extracted') form.addParam('ref', PointerParam, pointerClass="Volume", label='Reference volume', help='Specify a 3D volume') form.addParam('nptcl', IntParam, default=500, label='Number of particles', help='Maximum number of particles per tomogram') form.addParam('dthr', FloatParam, default=-1, label='Distance threshold', help='', expertLevel=LEVEL_ADVANCED) form.addParam('vthr', FloatParam, default=2.0, label='Value threshold', help='', expertLevel=LEVEL_ADVANCED) form.addParam('delta', FloatParam, default=30.0, label='Delta angle', help='', expertLevel=LEVEL_ADVANCED) form.addParam('sym', StringParam, default='c1', label='Point-group symmetry', help='') form.addParam('boxSize', FloatParam, important=True, label='Box size', help="The wizard selects same box size as reference size") # --------------------------- INSERT steps functions ---------------------- def _insertAllSteps(self): self._insertFunctionStep('preprocess') self._insertFunctionStep('tempMatchStep') self._insertFunctionStep("createOutputStep") # --------------------------- STEPS functions -----------------------------
[docs] def preprocess(self): program = eman2.Plugin.getProgram("e2proc3d.py") setDim = self.inputSet.get().getDim() if max(setDim) > 1000: sizeThreshold = max(self.inputSet.get().getDim()) self.correctOffset = None else: sizeThreshold = 1000 offset = math.floor((1000 - self.inputSet.get().getXDim()) / 2) self.correctOffset = lambda coord: coord.setPosition(coord.getX() - offset, coord.getY() - offset, coord.getZ()) if (setDim[0] < sizeThreshold) or (setDim[1] < sizeThreshold): for tomo in self.inputSet.get(): tomoFile = os.path.basename(tomo.getFileName()) tomoFile = os.path.abspath(self._getTmpPath(tomoFile)) self.runJob(program, '%s %s --clip=%d,%d,%d' % (tomo.getFileName(), tomoFile, sizeThreshold, sizeThreshold, tomo.getDim()[2]), env=eman2.Plugin.getEnviron()) else: for tomo in self.inputSet.get(): tomoFile = os.path.basename(tomo.getFileName()) tomoFile = os.path.abspath(self._getTmpPath(tomoFile)) copyFile(tomo.getFileName(), tomoFile)
[docs] def tempMatchStep(self): self.box = self.boxSize.get() volFile = os.path.abspath(self.ref.get().getFileName()).replace(':mrc', '') params = "" for tomo in self.inputSet.get(): tomoFile = os.path.basename(tomo.getFileName()) tomoFile = os.path.abspath(self._getTmpPath(tomoFile)) params = params + " %s" % self._getTmpPath(tomoFile) params = params + " --reference=%s --nptcl=%d --dthr=%f --vthr=%f --delta=%f --sym=%s " \ "--rmedge --rmgold --boxsz=%d" % (volFile, self.nptcl.get(), self.dthr.get(), self.vthr.get(), self.delta.get(), self.sym.get(), self.box) program = eman2.Plugin.getProgram("e2spt_tempmatch.py") self.runJob(program, params, cwd=os.path.abspath(self._getTmpPath()), env=eman2.Plugin.getEnviron(), numberOfMpi=1, numberOfThreads=1) # Move output files to Extra Path # moveFile(self._getTmpPath("ccc.hdf"), self._getExtraPath("particles" + ".hdf")) for tomo in self.inputSet.get(): tomoName = os.path.basename(tomo.getFileName()) tomoName = os.path.splitext(tomoName)[0] tomoCoord = tomoName + "_info.json" moveFile(self._getTmpPath(os.path.join("info", tomoCoord)), self._getExtraPath(tomoCoord))
# --------------------------- UTILS functions ------------------------------
[docs] def createOutputStep(self): # Create a Set of 3D Coordinates per class coord3DSetDict = dict() coord3DMap = dict() suffix = self._getOutputSuffix(SetOfCoordinates3D) coord3DSet = self._createSetOfCoordinates3D(self.inputSet.get(), suffix) coord3DSet.setBoxSize(self.box) coord3DSet.setName("tomoCoord") coord3DSet.setPrecedents(self.inputSet.get()) coord3DSet.setSamplingRate(self.inputSet.get().getSamplingRate()) for tomo in self.inputSet.get(): inputTomo = tomo.clone() tomoName = os.path.basename(tomo.getFileName()) tomoName = os.path.splitext(tomoName)[0] jsonFnbase = pwutils.join(self._getExtraPath(), '%s_info.json' % tomoName) jsonBoxDict = loadJson(jsonFnbase) for key, classItem in jsonBoxDict["class_list"].items(): index = int(key) coord3DSetDict[index] = coord3DSet name = self.OUTPUT_PREFIX + suffix coord3DMap[index] = name args = dict() args[name] = coord3DSet # Populate Set of 3D Coordinates with 3D Coordinates readSetOfCoordinates3D(jsonBoxDict, coord3DSetDict, inputTomo, self.correctOffset) self._defineOutputs(**args) self._defineSourceRelation(self.inputSet.get(), coord3DSet) # Update Outputs for index, coord3DSet in coord3DSetDict.items(): coord3DSet.setObjComment(self.getSummary(coord3DSet)) self._updateOutputSet(coord3DMap[index], coord3DSet, state=coord3DSet.STREAM_CLOSED)
# --------------------------- INFO functions ------------------------------ def _validate(self): errors = [] return errors
[docs] def getSummary(self, coord3DSet): summary = [] summary.append("Number of particles picked: %s" % coord3DSet.getSize()) summary.append("Particle size: %s" % coord3DSet.getBoxSize()) return "\n".join(summary)
def _summary(self): summary = [] if not self.isFinished(): summary.append("Output 3D Coordinates not ready yet.") if self.getOutputsSize() >= 1: for key, output in self.iterOutputAttributes(): summary.append("*%s:* \n %s " % (key, output.getObjComment())) else: summary.append(Message.TEXT_NO_OUTPUT_CO) return summary def _methods(self): tomos = self.inputSet.get() return [ "Subtomogram coordinates obtained with e2spt_tempmatch.py", "A total of %d tomograms of dimensions %s were used" % (tomos.getSize(), tomos.getDimensions()), ]