Source code for fsc3d.viewers

# **************************************************************************
# *
# * Authors:     Grigory Sharov (gsharov@mrc-lmb.cam.ac.uk)
# *
# * 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
# * 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 matplotlib.image as mpimg
import matplotlib.pyplot as plt

from pyworkflow.protocol.params import LabelParam, EnumParam
from pyworkflow.viewer import DESKTOP_TKINTER
from pwem.viewers import ChimeraView, ObjectView, EmProtocolViewer

from .protocols import Prot3DFSC
from .constants import *


[docs]class ThreedFscViewer(EmProtocolViewer): """ Visualization of 3D FSC results. """ _environments = [DESKTOP_TKINTER] _targets = [Prot3DFSC] _label = 'viewer' def __init__(self, **kwargs): EmProtocolViewer.__init__(self, **kwargs) def _defineParams(self, form): form.addSection(label='Visualization') group = form.addGroup('Volumes') group.addParam('displayVol', EnumParam, choices=['slices', 'chimera'], default=VOLUME_SLICES, display=EnumParam.DISPLAY_HLIST, label='Display volume with', help='*slices*: display volumes as 2D slices along z axis.\n' '*chimera*: display volumes as surface with Chimera.') group.addParam('doShowOutVol', EnumParam, default=VOL_ORIG, choices=['original', 'thresholded', 'thresholded and binarized', 'all'], display=EnumParam.DISPLAY_COMBO, label='3D FSC volume to display') form.addParam('doShowHistogram', LabelParam, label="Show histogram and directional FSC plot") form.addParam('doShowPlotFT', LabelParam, label="Show Fourier Transform Power plot") form.addParam('doShowPlot3DFSC', LabelParam, label="Show 3D FSC plots") form.addParam('doShowChimera', LabelParam, label="Show Chimera animation", default=True, help="Display 3D FSC and coloring original map by " "angular resolution.") def _getVisualizeDict(self): self.protocol._initialize() # Load filename templates return {'doShowOutVol': self._showVolumes, 'doShowHistogram': self._showHistogram, 'doShowPlotFT': self._showPlotFT, 'doShowPlot3DFSC': self._showPlot3DFSC, 'doShowChimera': self._showChimera } # ============================================================================= # ShowVolumes # ============================================================================= def _showVolumes(self, paramName=None): if self.displayVol == VOLUME_CHIMERA: return self._showVolumesChimera() elif self.displayVol == VOLUME_SLICES: return self._createVolumesSqlite() def _showVolumesChimera(self): """ Create a chimera script to visualize selected volumes. """ volumes = self._getVolumeNames() cmdFile = self.protocol._getExtraPath('chimera_volumes.cmd') with open(cmdFile, 'w+') as f: for vol in volumes: # We assume that the chimera script will be generated # at the same folder as 3DFSC volumes if os.path.exists(vol): localVol = os.path.relpath(vol, self.protocol._getExtraPath()) f.write("open %s\n" % localVol) f.write('tile\n') view = ChimeraView(cmdFile) return [view] def _createVolumesSqlite(self): """ Write an sqlite with all volumes selected for visualization. """ path = self.protocol._getExtraPath('3DFSC_viewer_volumes.sqlite') samplingRate = self.protocol.inputVolume.get().getSamplingRate() vols = self._getVolumeNames() files = [] for vol in vols: if os.path.exists(vol): files.append(vol) self.createVolumesSqlite(files, path, samplingRate) return [ObjectView(self._project, self.protocol.strId(), path)] # ============================================================================= def _showPlot(self, fn): img = mpimg.imread(self.protocol._getFileName(fn)) imgplot = plt.imshow(img) plt.axis('off') plt.show() return [imgplot] def _showHistogram(self, param=None): self._showPlot('out_histogram') def _showPlotFT(self, param=None): self._showPlot('out_plotFT') def _showPlot3DFSC(self, param=None): self._showPlot('out_plot3DFSC') def _showChimera(self, param=None): return [self.errorMessage('ChimeraX is not supported for this animation yet.', title="Visualization error")] # cmdFile = self.protocol._getFileName('out_cmdChimera') # view = ChimeraView(cmdFile) # return [view] def _getVolumeNames(self): volsFn = ['out_vol3DFSC', 'out_vol3DFSC-th', 'out_vol3DFSC-thbin'] if self.doShowOutVol.get() == VOL_ORIG: vols = [self.protocol._getFileName(volsFn[0])] elif self.doShowOutVol.get() == VOL_TH: vols = [self.protocol._getFileName(volsFn[1])] elif self.doShowOutVol.get() == VOL_THBIN: vols = [self.protocol._getFileName(volsFn[2])] else: vols = [self.protocol._getFileName(f) for f in volsFn] return vols