Source code for eman2.protocols.protocol_tiltvalidate

# **************************************************************************
# *
# *  Authors:     Grigory Sharov (
# *
# * MRC Laboratory of Molecular Biology (MRC-LMB)
# *
# * 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
# * 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 ''
# *
# **************************************************************************

import os

from pyworkflow.protocol.params import (PointerParam, FloatParam,
                                        LabelParam, EnumParam, StringParam,
                                        BooleanParam, IntParam, LEVEL_ADVANCED)
import pyworkflow.utils as pwutils
from pyworkflow.constants import PROD
from pwem.protocols import ProtAnalysis3D

from .. import Plugin
from ..constants import *
from ..convert import writeSetOfParticles

[docs]class EmanProtTiltValidate(ProtAnalysis3D): """ This protocol wraps the ** EMAN2 program. It performs tilt validation using the method described in Rosenthal and Henderson, JMB (2003). """ _label = 'tilt validate' _devStatus = PROD def __init__(self, **kwargs): ProtAnalysis3D.__init__(self, **kwargs) def _createFilenameTemplates(self): """ Centralize the names of the files. """ myDict = { 'untiltPartSet': 'sets/untilted_ptcls.lst', 'tiltPartSet': 'sets/tilted_ptcls.lst', 'outputAngles': self._getExtraPath('TiltValidate_01/perparticletilts.json'), 'outputContourPlot': self._getExtraPath('TiltValidate_01/contour.hdf') } self._updateFilenamesDict(myDict) # --------------------------- DEFINE param functions ---------------------- def _defineParams(self, form): form.addSection(label='Input') form.addParam('inputVolume', PointerParam, pointerClass='Volume', label="Input volume", help='Select the input volume that will be validated.') form.addParam('inputTiltPair', PointerParam, label="Input tilt pair particles", pointerClass='ParticlesTiltPair', help='Select the input set of tilt pair particles.') form.addParam('symmetry', StringParam, default='c1', label='Symmetry group', help='Set the symmetry; if no value is given then ' 'the model is assumed to have no symmetry. \n' 'Choices are: *i, c, d, tet, icos, or oct* \n' 'See\n' 'for a detailed description of symmetry in Eman.') form.addParam('maxtilt', FloatParam, default=180.0, label='Max tilt angle', help='Maximum tilt angle permitted when finding tilt ' 'distances.') form.addParam('quaternion', BooleanParam, default=False, label='Use quaternions', expertLevel=LEVEL_ADVANCED, help='Use quaternions for tilt distance computation') form.addParam('delta', FloatParam, default=5.0, label='Projection step (deg.)', help='Angular step size for alignment') form.addParam('shrink', IntParam, default=1, expertLevel=LEVEL_ADVANCED, label='Shrink particles', help='Optionally shrink the input particles by an integer ' 'amount prior to computing similarity scores. ' 'For speed purposes.') form.addParam('doContourPlot', BooleanParam, default=False, expertLevel=LEVEL_ADVANCED, label='Do contour plot?', help='Also make a contour plot similar to fig. 6 ' 'in Henderson paper') form.addParam('tiltRange', IntParam, default=15, expertLevel=LEVEL_ADVANCED, condition='doContourPlot', label='Tilt range', help='The angular tilt range to search') form.addParam('verbose', IntParam, default=0, expertLevel=LEVEL_ADVANCED, label='Verbose level', help='Verbose level from 0 to 9. ') form.addSection(label='Similarity matrix') form.addParam('paramsMsg', LabelParam, default=True, label='These parameters are for advanced users only!\n', help='For help please address to EMAN2 %s or run:\n' '* cmp -v 2* or\n' '* aligners -v 2*' % WIKI_URL) line = form.addLine('simcmp: ', help='The name of a cmp to be used in comparing ' 'the aligned images (default=ccc)') line.addParam('simcmpType', EnumParam, choices=['ccc', 'dot', 'frc', 'lod', 'optsub', 'optvariance', 'phase', 'quadmindot', 'sqeuclidean', 'vertical', 'None'], label='type', default=CMP_CCC, display=EnumParam.DISPLAY_COMBO) line.addParam('simcmpParams', StringParam, default='', label='params') group = form.addGroup('First stage aligner') line = group.addLine('simalign: ') line.addParam('simalignType', EnumParam, choices=['frm2d', 'rotate_flip', 'rotate_flip_iterative', 'rotate_precenter', 'rotate_trans_flip_scale', 'rotate_trans_flip_scale_iter', 'rotate_trans_scale_iter', 'rotate_translate', 'rotate_translate_bispec', 'rotate_translate_flip', 'rotate_translate_flip_iterative', 'rotate_translate_flip_resample', 'rotate_translate_iterative', 'rotate_translate_resample', 'rotate_translate_scale', 'rotate_translate_tree', 'rotational', 'rotational_bispec', 'rotational_iterative', 'rtf_exhaustive', 'rtf_slow_exhaustive', 'scale', 'symalign', 'symalignquat', 'translational', 'None'], label='type', default=ALN_ROTATE_TRANSLATE_TREE, display=EnumParam.DISPLAY_COMBO) line.addParam('simalignParams', StringParam, default='', label='params') line = group.addLine('simaligncmp: ') line.addParam('simaligncmpType', EnumParam, choices=['ccc', 'dot', 'frc', 'lod', 'optsub', 'optvariance', 'phase', 'quadmindot', 'sqeuclidean', 'vertical', 'None'], label='type', default=CMP_CCC, display=EnumParam.DISPLAY_COMBO) line.addParam('simaligncmpParams', StringParam, default='', label='params') group = form.addGroup('Second stage aligner') line = group.addLine('simralign: ') line.addParam('simralignType', EnumParam, choices=['None', 'refine', 'refine_3d', 'refine_3d_grid', 'refinecg'], label='type', default=RALN_NONE, display=EnumParam.DISPLAY_COMBO) line.addParam('simralignParams', StringParam, default='', label='params') line = group.addLine('simraligncmp: ') line.addParam('simraligncmpType', EnumParam, choices=['ccc', 'dot', 'frc', 'lod', 'optsub', 'optvariance', 'phase', 'quadmindot', 'sqeuclidean', 'vertical', 'None'], label='type', default=CMP_DOT, display=EnumParam.DISPLAY_COMBO) line.addParam('simraligncmpParams', StringParam, default='', label='params') form.addParallelSection(threads=1, mpi=0) # --------------------------- INSERT steps functions ---------------------- def _insertAllSteps(self): self._createFilenameTemplates() self._insertFunctionStep('convertImagesStep') args = self._prepareParams() self._insertFunctionStep('runValidateStep', args) self._insertFunctionStep('createOutputStep') # --------------------------- STEPS functions -----------------------------
[docs] def convertImagesStep(self): part = self.inputTiltPair.get() partUnt = part.getUntilted() partTilt = part.getTilted() storePath = self._getExtraPath("particles") pwutils.makePath(storePath) print("Converting input particle set..") for partSet, suffix in zip([partUnt, partTilt], ['_untilted_ptcls', '_tilted_ptcls']): partAlign = partSet.getAlignment() writeSetOfParticles(partSet, storePath, alignType=partAlign, suffix=suffix) setName = suffix.split('_')[1] program = Plugin.getProgram('') args = " particles/*%s.hdf --setname=%s --minhisnr=-1" % ( suffix, setName) self.runJob(program, args, cwd=self._getExtraPath(), numberOfMpi=1, numberOfThreads=1)
[docs] def runValidateStep(self, args): program = Plugin.getProgram('') self.runJob(program, args, cwd=self._getExtraPath(), numberOfThreads=1)
[docs] def createOutputStep(self): pass
# --------------------------- INFO functions ------------------------------ def _validate(self): errors = [] self._validateDim(self.inputTiltPair.get().getUntilted(), self.inputVolume.get(), errors, 'Input tilt pair particles', 'Input volume') return errors def _summary(self): summary = list() summary.append("Max. tilt angle: *%0.2f*" % self.maxtilt.get()) summary.append("Projection step: *%d deg.*" % summary.append("Symmetry: *%s*" % self.symmetry.get()) return summary # --------------------------- UTILS functions ----------------------------- def _prepareParams(self): args = " --untiltdata=%(untilt)s --tiltdata=%(tilt)s --volume=%(volume)s" args += " --maxtiltangle=%(maxtilt)f --sym=%(sym)s --delta=%(delta)f" args += " --verbose=%(verb)d" if self.shrink.get() != 1: args += " --shrink=%d" % self.shrink.get() if self.quaternion: args += " --quaternion" if self.doContourPlot: args += " --docontourplot --tiltrange %d" % self.tiltRange.get() if self.numberOfThreads.get() > 1: args += " --parallel=thread:%d" % self.numberOfThreads.get() params = {'untilt': self._getFileName("untiltPartSet"), 'tilt': self._getFileName("tiltPartSet"), 'volume': os.path.relpath(self.inputVolume.get().getFileName(), self._getExtraPath()).replace(":mrc", ""), 'maxtilt': self.maxtilt.get(), 'sym': self.symmetry.get(), 'delta':, 'verb': self.verbose.get() } args %= params for param in ['simcmp', 'simalign', 'simaligncmp', 'simralign', 'simraligncmp']: args += self._getSimmxOpts(param) return args def _getSimmxOpts(self, option): optionType = self.getEnumText(option + 'Type') optionParams = getattr(self, option + 'Params').get() if optionType == 'None': return '' if optionParams != '': argStr = ' --%s=%s:%s' % (option, optionType, optionParams) else: argStr = ' --%s=%s' % (option, optionType) return argStr