Source code for continuousflex.viewers.viewer_nma

# **************************************************************************
# *
# * Authors:     J.M. De la Rosa Trevin (jmdelarosa@cnb.csic.es)
# *              Slavica Jonic  (slavica.jonic@upmc.fr)
# *
# * 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'
# *
# **************************************************************************
"""
This module implement the wrappers around Xmipp NMA protocol
visualization program.
"""

from pyworkflow.gui.project import ProjectWindow
from pyworkflow.protocol.params import LabelParam, IntParam
from pyworkflow.viewer import ProtocolViewer, DESKTOP_TKINTER, WEB_DJANGO

from pwem.viewers import ObjectView, VmdView, DataView
from pwem.emlib import MDL_NMA_ATOMSHIFT
from pwem.objects import SetOfNormalModes

from continuousflex.protocols import FlexProtNMA
from continuousflex.viewers.nma_plotter import FlexNmaPlotter

import os


OBJCMD_NMA_PLOTDIST = "Plot distance profile"
OBJCMD_NMA_VMD = "Display VMD animation"


[docs]class FlexNMAViewer(ProtocolViewer): """ Visualization of results from the NMA protocol. Normally, NMA modes with high collectivity and low NMA score are preferred. """ _label = 'viewer nma' _targets = [FlexProtNMA, SetOfNormalModes] _environments = [DESKTOP_TKINTER, WEB_DJANGO] # def setProtocol(self, protocol): # ProtocolViewer.setProtocol(self, protocol) # inputPdb = protocol.inputStructure.get() # self.isEm.set(inputPdb.getPseudoAtoms()) def _defineParams(self, form): if isinstance(self.protocol, SetOfNormalModes): protocol_path = os.path.dirname(os.path.dirname(self.protocol[1].getModeFile())) vmdFiles = protocol_path + "/extra/animations/" nmdFile = protocol_path + "/modes.nmd" else: vmdFiles = self.protocol._getExtraPath("animations") nmdFile = self.protocol._getPath("modes.nmd") form.addSection(label='Visualization') form.addParam('displayModes', LabelParam, label="Display output Normal Modes?", important=True) form.addParam('displayMaxDistanceProfile', LabelParam, label="Plot max distance profile?", help="Maximum unitary shift of each atom or pseudoatom over all computed modes.") group = form.addGroup('Single mode') group.addParam('modeNumber', IntParam, default=7, label='Mode number') group.addParam('displayVmd', LabelParam, condition=os.path.isdir(vmdFiles), label='Display mode animation with VMD?') group.addParam('displayDistanceProfile', LabelParam, default=False, label="Plot mode distance profile?", help="Unitary shift of each atom or pseudoatom along the mode that is requested to be animated.") form.addParam('displayVmd2', LabelParam, condition=os.path.isfile(nmdFile), label="Display mode animations with VMD NMWiz?", help="Use ProDy Normal Mode Wizard to view all modes in a more interactive way. " "See http://prody.csb.pitt.edu/tutorials/nmwiz_tutorial/nmwiz.html") def _getVisualizeDict(self): return {'displayModes': self._viewParam, 'displayMaxDistanceProfile': self._viewParam, 'displayVmd': self._viewSingleMode, 'displayVmd2': self._viewSingleMode, 'displayDistanceProfile': self._viewSingleMode, } def _viewParam(self, paramName): if paramName == 'displayModes': # The following two lines display modes.sqlite file # modes = self.protocol.outputModes # return [ObjectView(self._project, modes.strId(), modes.getFileName())] # The following two lines display modes.xmd file if isinstance(self.protocol, SetOfNormalModes): modes = os.path.dirname(self.protocol[1].getModeFile()) + ".xmd" else: modes = self.protocol._getPath("modes.xmd") return [DataView(modes)] elif paramName == 'displayMaxDistanceProfile': if isinstance(self.protocol, SetOfNormalModes): fn = os.path.dirname(os.path.dirname(self.protocol[1].getModeFile())) + "/extra/maxAtomShifts.xmd" else: fn = self.protocol._getExtraPath("maxAtomShifts.xmd") return [createShiftPlot(fn, "Maximum atom shifts", "maximum shift")] def _viewSingleMode(self, paramName): """ visualization for a selected mode. """ if isinstance(self.protocol, SetOfNormalModes): modes = self.protocol else: modes = self.protocol.outputModes modeNumber = self.modeNumber.get() mode = modes[modeNumber] if mode is None: return [self.errorMessage("Invalid mode number *%d*\n" "Display the output Normal Modes to see " "the availables ones." % modeNumber, title="Invalid input")] elif paramName == 'displayVmd': return [createVmdView(self.protocol, modeNumber)] elif paramName == 'displayVmd2': return [createVmdNmwizView(self.protocol, modeNumber)] elif paramName == 'displayDistanceProfile': return [createDistanceProfilePlot(self.protocol, modeNumber)]
[docs]def createShiftPlot(mdFn, title, ylabel): plotter = FlexNmaPlotter() plotter.createSubPlot(title, 'atom index', ylabel) plotter.plotMdFile(mdFn, None, MDL_NMA_ATOMSHIFT) return plotter
[docs]def createDistanceProfilePlot(protocol, modeNumber): if isinstance(protocol, SetOfNormalModes): vectorMdFn = os.path.dirname(os.path.dirname(protocol[1].getModeFile( ))) + "/extra/distanceProfiles/vec%d.xmd" % modeNumber else: vectorMdFn = protocol._getExtraPath("distanceProfiles","vec%d.xmd" % modeNumber) plotter = createShiftPlot(vectorMdFn, "Atom shifts for mode %d" % modeNumber, "shift") return plotter
[docs]def createVmdView(protocol, modeNumber): if isinstance(protocol, SetOfNormalModes): vmdFile = os.path.dirname(os.path.dirname(protocol[1].getModeFile())) + "/extra/animations/animated_mode_%03d.vmd" % modeNumber else: vmdFile = protocol._getExtraPath("animations", "animated_mode_%03d.vmd" % modeNumber) return VmdView('-e "%s"' % vmdFile)
[docs]def createVmdNmwizView(protocol, modeNumber): if isinstance(protocol, SetOfNormalModes): nmdFile = os.path.dirname(os.path.dirname(protocol[1].getModeFile())) + "/modes.nmd" else: nmdFile = protocol._getPath("modes.nmd") return VmdView('-e %s' % nmdFile)
[docs]def showDistanceProfilePlot(protocol, modeNumber): createDistanceProfilePlot(protocol, modeNumber).show()
[docs]def showVmdView(protocol, modeNumber): createVmdView(protocol, modeNumber).show()
ProjectWindow.registerObjectCommand(OBJCMD_NMA_PLOTDIST, showDistanceProfilePlot) ProjectWindow.registerObjectCommand(OBJCMD_NMA_VMD, showVmdView)