Source code for continuousflex.protocols.pdb.protocol_pseudoatoms_base

# **************************************************************************
# *
# * Authors:  Carlos Oscar Sanchez Sorzano (coss@cnb.csic.es), May 2013
# *           Slavica Jonic                (jonic@impmc.upmc.fr)
# * Ported to Scipion:
# *           J.M. De la Rosa Trevin (jmdelarosa@cnb.csic.es), Jan 2014
# *
# * 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 basename, join, abspath
import os

from pyworkflow.object import String
from pyworkflow.utils import cleanPattern, moveFile
from pyworkflow.protocol.params import EnumParam, PointerParam, FloatParam
from pyworkflow.protocol.constants import LEVEL_ADVANCED
from pwem.protocols import Prot3D #this is not an error
from pwem.viewers.viewer_chimera import Chimera
from xmipp3.convert import getImageLocation


NMA_MASK_NONE = 0
NMA_MASK_THRE = 1
NMA_MASK_FILE = 2


[docs]class FlexProtConvertToPseudoAtomsBase(Prot3D): # --------------------------- DEFINE param functions -------------------- def _defineParams(self, form): form.addParam('maskMode', EnumParam, choices=['none', 'threshold', 'file'], default=NMA_MASK_NONE, label='Mask mode', display=EnumParam.DISPLAY_COMBO, help='Mask to remove the background noise in the volume. \n' 'If the volume was masked outside of this program, no need for masking here.') form.addParam('maskThreshold', FloatParam, default=0.01, condition='maskMode==%d' % NMA_MASK_THRE, label='Threshold value', help='Gray values below this threshold are set to 0') form.addParam('volumeMask', PointerParam, pointerClass='VolumeMask', label='Mask volume', condition='maskMode==%d' % NMA_MASK_FILE, ) form.addParam('pseudoAtomRadius', FloatParam, default=1, label='Pseudoatom radius (vox)', help='Pseudoatoms are defined as Gaussians whose ' 'standard deviation is this value in voxels.') form.addParam('pseudoAtomTarget', FloatParam, default=5, expertLevel=LEVEL_ADVANCED, label='Volume approximation error(%)', help='This value is a percentage (between 0.001 and ' '100) specifying how fine you want to ' 'approximate the EM volume by the pseudoatomic ' 'structure. Lower values imply lower ' 'approximation error, and consequently, more pseudoatoms.') # --------------------------- INSERT steps functions ---------------- def _insertMaskStep(self, fnVol, prefix=''): """ Check the mask selected and insert the necessary steps. Return the mask filename if needed. """ fnMask = '' if self.maskMode == NMA_MASK_THRE: fnMask = self._getExtraPath('mask%s.vol' % prefix) maskParams = '-i %s -o %s --select below %f --substitute binarize'\ % (fnVol, fnMask, self.maskThreshold.get()) self._insertRunJobStep('xmipp_transform_threshold', maskParams) elif self.maskMode == NMA_MASK_FILE: fnMask = getImageLocation(self.volumeMask.get()) return fnMask # --------------------------- STEPS functions ---------------------------
[docs] def convertToPseudoAtomsStep(self, inputFn, fnMask, sampling, prefix=''): pseudoatoms = 'pseudoatoms%s' % prefix outputFn = self._getPath(pseudoatoms) sigma = sampling * self.pseudoAtomRadius.get() targetErr = self.pseudoAtomTarget.get() #volume-to-pseudoatom conversion was not MPI-parallelized and the number of MPIs was removed from the gui #nthreads = self.numberOfThreads.get() * self.numberOfMpi.get() nthreads = self.numberOfThreads.get() params = "-i %(inputFn)s -o %(outputFn)s --sigma %(sigma)f --thr " \ "%(nthreads)d " params += "--targetError %(targetErr)f --sampling_rate %(sampling)f " \ "-v 2 --intensityColumn Bfactor" if fnMask: params += " --mask binary_file %(fnMask)s" self.runJob("xmipp_volume_to_pseudoatoms", params % locals()) for suffix in ["_approximation.vol", "_distance.hist"]: moveFile(self._getPath(pseudoatoms + suffix), self._getExtraPath(pseudoatoms + suffix)) self.runJob("xmipp_image_convert", "-i %s_approximation.vol -o %s_approximation.mrc -t vol" % (self._getExtraPath(pseudoatoms), self._getExtraPath(pseudoatoms))) self.runJob("xmipp_image_header", "-i %s_approximation.mrc --sampling_rate %f" % (self._getExtraPath(pseudoatoms), sampling)) cleanPattern(self._getPath(pseudoatoms + '_*'))
[docs] def createChimeraScript(self, volume, pdb): """ Create a chimera script to visualize a pseudoatoms pdb obteined from a given EM 3d volume. A property will be set in the pdb object to store the location of the script. """ pseudoatoms = pdb.getFileName() scriptFile = pseudoatoms + '_chimera.cxc' pdb._chimeraScript = String(scriptFile) sampling = volume.getSamplingRate() radius = sampling * self.pseudoAtomRadius.get() fnIn = getImageLocation(volume) if fnIn.endswith(":mrc"): fnIn = fnIn[:-4] x, y, z = volume.getOrigin(force=True).getShifts() xx, yy, zz = volume.getDim() dim = volume.getDim()[0] bildFileName = os.path.abspath(self._getExtraPath("axis.bild")) Chimera.createCoordinateAxisFile(dim, bildFileName=bildFileName, sampling=sampling) fhCxc = open(scriptFile, 'w') fhCxc.write("open %s\n" % basename(pseudoatoms)) fhCxc.write("color by bfactor target a range 0,0.5\n") fhCxc.write("setattr a radius %f\n" % radius) fhCxc.write("style #1 sphere\n") modelID = 1 fhCxc.write("open %s\n" % abspath(fnIn)) threshold = 0.01 if self.maskMode == NMA_MASK_THRE: self.maskThreshold.get() # set sampling fhCxc.write("volume #%d level %f transparency 0.5 voxelSize %f origin " "%0.2f,%0.2f,%0.2f\n" % (modelID + 1, threshold, sampling, x, y, z)) fhCxc.write("open %s\n" % bildFileName) fhCxc.write("move %0.2f,%0.2f,%0.2f model #%d coord #%d\n" % (x + (xx / 2. * sampling), y + (yy / 2. * sampling), z + (zz / 2. * sampling), modelID, modelID + 2)) fhCxc.close()