# **************************************************************************
# *
# * Authors:     Adrian Quintana (adrian@eyeseetea.com) [1]
# *
# * [1] EyeSeeTea Ltd, London, UK
# *
# * 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 implements visualization program
for input tomograms.
"""
import os
from distutils.spawn import find_executable
import tempfile
import pyworkflow.protocol.params as params
from pwem.viewers import EmProtocolViewer, ChimeraView
from pyworkflow.viewer import DESKTOP_TKINTER, WEB_DJANGO
import pwem.viewers as viewers
from pwem.emlib.image import ImageHandler
from tomo.protocols import ProtImportTomograms, \
    ProtImportSubTomograms
from tomo.objects import SetOfSubTomograms
TOMOGRAM_SLICES = 1
TOMOGRAM_CHIMERA = 0
[docs]class ViewerProtImportTomograms(EmProtocolViewer):
    """ Wrapper to visualize tomo objects
    with default viewers such as xmipp/showj and chimera. """
    _environments = [DESKTOP_TKINTER, WEB_DJANGO]
    _targets = []
    _label = 'viewer input tomogram'
    def _defineParams(self, form):
        form.addSection(label='Visualization of input tomograms')
        form.addParam('displayTomo', params.EnumParam,
                      choices=['chimera', 'slices'],
                      default=TOMOGRAM_CHIMERA,
                      display=params.EnumParam.DISPLAY_HLIST,
                      label='Display tomogram with',
                      help='*chimera*: display tomograms as surface with '
                           'Chimera.\n *slices*: display tomograms as 2D slices '
                           'along z axis.\n If number of tomograms == 1, '
                           'a system of coordinates is shown'
                      )
#    def visualize(self, obj, **args):
#        views = self._showTomogramsSlices()
#        if views:
#            for v in views:
#                v.show()
#
    def _getVisualizeDict(self):
        return {
            'displayTomo': self._showTomograms,
        }
    def _validate(self):
        if (self.displayTomo == TOMOGRAM_CHIMERA
                and find_executable(viewers.viewer_chimera.Chimera.getProgram()) is None):
            return ["chimera is not available. "
                    "Either install it or choose option 'slices'. "]
        return []
    # =========================================================================
    # ShowTomograms
    # =========================================================================
    def _showTomograms(self, paramName=None):
        if self.displayTomo == TOMOGRAM_CHIMERA:
            return self._showTomogramsChimera()
        elif self.displayTomo == TOMOGRAM_SLICES:
            return self._showTomogramsSlices()
    def _sourceIsOutput(self):
        """If source is a SetOfSubtomograms"""
        return isinstance(self.protocol, SetOfSubTomograms)
    def _getOutput(self):
        if self._sourceIsOutput():
            # Protocol here is a SetOfSubtomograms
            return self.protocol
        elif hasattr(self.protocol, 'outputTomograms'):
            return self.protocol.outputTomograms
        elif hasattr(self.protocol, 'outputSubTomograms'):
            return self.protocol.outputSubTomograms
    def _getSetAndSampling(self):
        setOfObjects = self._getOutput()
        sampling = setOfObjects.getSamplingRate()
        return sampling, setOfObjects
    def _getExtraFolder(self, fileName):
        if self._sourceIsOutput():
            return os.path.join(tempfile.mkdtemp(), fileName)
        else:
            return self.protocol._getExtraPath(fileName)
    def _showTomogramsChimera(self):
        """ Create a chimera script to visualize selected tomograms. """
        tmpFileNameCMD = self._getExtraFolder("chimera.cxc")
        f = open(tmpFileNameCMD, "w")
        sampling, _setOfObjects = self._getSetAndSampling()
        count = 1  # first model in chimera is a tomogram
        if len(_setOfObjects) == 1:
            count = 2  # first model in chimera is the bild file
            # if we have a single tomogram then create axis
            # as bild file. Chimera must read the bild file first
            # otherwise system of coordinates will not
            # be in the center of the window
            dim = _setOfObjects.getDim()[0]
            tmpFileNameBILD = os.path.abspath(self._getExtraFolder("axis.bild"))
            viewers.viewer_chimera.Chimera.createCoordinateAxisFile(dim,
                                                                    bildFileName=tmpFileNameBILD,
                                                                    sampling=sampling)
            f.write("open %s\n" % tmpFileNameBILD)
            f.write("cofr 0,0,0\n")  # set center of coordinates
        oldFileName = ""
        for tomo in _setOfObjects:
            fileName = tomo.getFileName()
            if fileName == oldFileName:
                continue
            else:
                oldFileName = fileName
            localTomo = os.path.abspath(ImageHandler.removeFileType(
                tomo.getFileName()))
            if localTomo.endswith("stk"):
                self.showError("Extension .stk is not supported")
            f.write("open %s\n" % localTomo)
            f.write("volume #%d style surface voxelSize %f\n" %
                    (count, sampling))
            f.write("volume #%d level 1\n" % count)
            count += 1
        if len(_setOfObjects) > 1:
            f.write('tile\n')
        else:
            x, y, z = tomo.getShiftsFromOrigin()
            f.write("volume #2 origin %0.2f,%0.2f,%0.2f\n" % (x, y, z))
        f.close()
        view = ChimeraView(tmpFileNameCMD)
        return [view]
    def _showTomogramsSlices(self):
        # Write an sqlite with all tomograms selected for visualization.
        sampling, setOfObjects = self._getSetAndSampling()
        viewParams = {viewers.showj.MODE: viewers.showj.MODE_MD}
        view = viewers.views.ObjectView(self._project, setOfObjects.strId(),
                                        setOfObjects.getFileName(), viewParams=viewParams)
        view.setMemory(viewers.showj.getJvmMaxMemory() + 2)
        return [view]