Source code for locscale.protocols.protocol_locscale

# **************************************************************************
# *
# * Authors:    David Maluenda (dmaluenda@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 pwem.protocols import Prot3D
from pyworkflow.protocol import params
from pwem.objects import Volume
from pyworkflow.utils import removeBaseExt

from ..convert import *

try:
    emanPlugin = Domain.importFromPlugin("eman2", "Plugin", doRaise=True)
except Exception as e:
    print("Eman plugin not found! You need to install it first.")


[docs]class ProtLocScale(Prot3D): """ This protocol computes contrast-enhanced cryo-EM maps by local amplitude scaling using a reference model. """ _label = 'local sharpening' # --------------------------- DEFINE param functions ---------------------- def _defineParams(self, form): form.addSection(label='Input') form.addParam('inputVolume', params.PointerParam, pointerClass='Volume', important=True, label='Input volume', help='Input EM volume') form.addParam('refObj', params.PointerParam, label="Reference Volume", pointerClass='Volume', help='Choose a model to take it as reference ' '(usually this volume should come from a PDB).') form.addParam('binaryMask', params.PointerParam, pointerClass='VolumeMask', label='3D mask', allowsNull=True, help='Binary mask (optional)') form.addParam('patchSize', params.IntParam, label='Patch size', help='Window size for local scale.\n' 'Recommended: 7 * ' 'average_map_resolution / pixel_size') form.addParallelSection(threads=0, mpi=3) # --------------------------- INSERT steps functions ---------------------- def _insertAllSteps(self): self._insertFunctionStep('convertStep') self._insertFunctionStep('refineStep') self._insertFunctionStep('createOutputStep') # --------------------------- STEPS functions -----------------------------
[docs] def convertStep(self): tmpFn = self._getTmpPath() self.inputVolFn = convertBinaryVol(self.inputVolume.get(), tmpFn) self.refVolFn = convertBinaryVol(self.refObj.get(), tmpFn) if self.binaryMask.hasValue(): self.maskVolFn = convertBinaryVol(self.binaryMask.get(), tmpFn)
[docs] def refineStep(self): """ Run the LocScale program (with EMAN enviroment) to refine a volume. """ self.info("Launching LocScale method") args = self.prepareParams() python, program, env = getEmanPythonProgram('locscale_mpi.py') program_args = "%s %s" % (program, args) self.runJob(python, program_args, env=env)
[docs] def createOutputStep(self): """ Create the output volume """ outputVolume = Volume() outputVolume.setSamplingRate(self.getSampling()) outputVolume.setFileName(self.getOutputFn()) self._defineOutputs(outputVolume=outputVolume) self._defineTransformRelation(self.inputVolume, outputVolume)
# --------------------------- INFO functions ------------------------------ def _validate(self): """ We validate if eman is installed and if inputs make sense """ errors = [] errors = validateEmanVersion(errors) inputVol = self.inputVolume.get() reference = self.refObj.get() if inputVol is not None and reference is not None: inputSize = inputVol.getDim() refSize = reference.getDim() refSamp = reference.getSamplingRate() if inputSize != refSize or self.getSampling() != refSamp: errors.append('Input volume and reference volume should be ' 'of the same size and samplig rate') return errors def _warnings(self): """ The input volume and the mask should be of the same size but the progran can run. """ warnings = [] if self.binaryMask.hasValue() and \ self.binaryMask.get().getDim() != self.inputVolume.get().getDim(): warnings.append('Input volume and binary mask should be ' 'of the same size') return warnings def _summary(self): summary = [] if not hasattr(self, 'outputVolume'): summary.append("Output volumes not ready yet.") else: summary.append('We obtained a sharpened volume of the %s ' 'using %s as reference.' % (self.getObjectTag('inputVolume'), self.getObjectTag('refObj'))) return summary def _methods(self): methods = list() methods.append('LocScale has locally scaled the amplitude of the %s ' 'using %s as reference with a window size of %d.' % (self.getObjectTag('inputVolume'), self.getObjectTag('refObj'), self.patchSize)) return methods def _citations(self): return ['Jakobi2017'] # --------------------------- UTILS functions -------------------------------
[docs] def prepareParams(self): """ The input params of the program are as follows (from source): '-em', '--em_map', required=True, help='Input filename EM map') '-mm', '--model_map', required=True, help='Input filename PDB map') '-p', '--apix', type=float, required=True, help='pixel size in Angstrom') '-ma', '--mask', help='Input filename mask') '-w', '--window_size', type=int, help='window size in pixel') '-o', '--outfile', required=True, help='Output filename') '-mpi', '--mpi', action='store_true', default=False, help='MPI version call by: \"{0}\"'.format(mpi_cmd) """ # Input volume args = "--em_map '%s'" % self.inputVolFn self.info("Input file: " + self.inputVolFn) # Reference volume args += " --model_map '%s'" % self.refVolFn self.info("Model file: " + self.refVolFn) # Samplig rate args += " --apix %f" % self.getSampling() self.info("Sampling rate: %f" % self.getSampling()) # Mask if self.binaryMask.hasValue(): args += " --mask '%s'" % self.maskVolFn self.info("Mask file: " + self.maskVolFn) # Windows size args += " --window_size %d" % self.patchSize self.info("Window size: %d" % self.patchSize) # MPI flag if self.numberOfMpi > 1: args += " -mpi" # Output file args += " -o '%s'" % self.getOutputFn() self.info("Output file: " + self.getOutputFn()) return args
[docs] def getSampling(self): return self.inputVolume.get().getSamplingRate()
[docs] def getOutputFn(self): """ Returns the scaled output file name. """ outputFnBase = removeBaseExt(self.inputVolFn) return self._getExtraPath(outputFnBase) + '_scaled.mrc'