Source code for xmipp3.viewers.viewer_ml2d

# **************************************************************************
# *
# * Authors:     L. del Cano (ldelcano@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'
# *
# **************************************************************************
"""
This module implement the wrappers aroung Xmipp ML2D protocol
visualization program.
"""

import os

from pyworkflow.viewer import ProtocolViewer, DESKTOP_TKINTER, WEB_DJANGO
from pyworkflow.protocol.params import LabelParam
from pyworkflow.protocol.params import EnumParam, StringParam
import pyworkflow.utils as pwutils
from pwem.viewers import ClassesView
from xmipp3.protocols.protocol_ml2d import XmippProtML2D


ITER_LAST = 0
ITER_SEL = 1
ITER_CHOICES = ['last', 'selection']


[docs]class XmippML2DViewer(ProtocolViewer): """ Wrapper to visualize different type of data objects with the Xmipp program xmipp_showj """ _targets = [XmippProtML2D] _environments = [DESKTOP_TKINTER, WEB_DJANGO] _label = 'viewer ml2d' _plotVars = ['doShowLL', 'doShowPmax', 'doShowSignalChange', 'doShowMirror'] def _defineParams(self, form): form.addSection(label='Visualization') group = form.addGroup('Overall results') group.addParam('classesToShow', EnumParam, choices=ITER_CHOICES, default=ITER_LAST, display=EnumParam.DISPLAY_HLIST, label="Visualize 2D classes from iter", help="Select from which iteration do you want to visualize classes") group.addParam('iterSelection', StringParam, condition='classesToShow==%d' % ITER_SEL, label="Iter selection", help="Select several iterations such as: 1,3,4 or 3-5 ") group.addParam('doShowPlots', LabelParam, label="Show all plots per iteration?", help='Visualize several plots.') group = form.addGroup('Iteration plots') group.addParam('doShowLL', LabelParam, label="Show Log-Likehood over iterations?", help='The Log-Likelihood value should increase.') group.addParam('doShowPmax', LabelParam, label="Show maximum model probability?", help='Show the maximum probability for a model, \n' 'this should tend to be a deltha function.') group.addParam('doShowSignalChange', LabelParam, label="Show plot for signal change?", help='Should approach to zero when convergence.') group.addParam('doShowMirror', LabelParam, label="Show mirror fraction for last iteration?", help='the mirror fraction of each class in last iteration.') def _getVisualizeDict(self): return {'classesToShow': self._viewIterRefs, 'doShowPlots': self._viewAllPlots, 'doShowLL': self._viewPlot, 'doShowPmax': self._viewPlot, 'doShowSignalChange': self._viewPlot, 'doShowMirror': self._viewPlot} def _viewAllPlots(self, e=None): return createPlots(self.protocol, self._plotVars) def _viewPlot(self, paramName=None): return createPlots(self.protocol, [paramName]) def _viewIterRefs(self, e=None): self.protocol._defineFileNames() # Load filename templates viewFinalClasses = False if self.classesToShow == ITER_LAST: if os.path.exists(self.protocol._getFileName("final_classes")): viewFinalClasses = True iterations = [self.protocol._lastIteration()] else: iterations = pwutils.getListFromRangeString(self.iterSelection.get()) views = [] for it in iterations: if viewFinalClasses: fn = self.protocol._getFileName("final_classes") else: if it <= self.protocol._lastIteration(): fn = self.protocol._getIterClasses(it) views.append(ClassesView(self.getProject(), self.protocol.strId(), fn, self.protocol.inputParticles.get().strId())) return views
[docs]def createPlots(protML, selectedPlots): ''' Launch some plot for an ML2D protocol run ''' from xmipp3.viewers.plotter import XmippPlotter from pwem import emlib protML._plot_count = 0 lastIter = protML._lastIteration() if lastIter == 0: return refs = protML._getIterMdClasses(it=lastIter, block='classes') # if not exists(refs): # return # blocks = getBlocksInMetaDataFile(refs) # lastBlock = blocks[-1] def doPlot(plotName): return plotName in selectedPlots # Remove 'mirror' from list if DoMirror is false if doPlot('doShowMirror') and not protML.doMirror: selectedPlots.remove('doShowMirror') n = len(selectedPlots) if n == 0: #showWarning("ML2D plots", "Nothing to plot", protML.master) print("No plots") return elif n == 1: gridsize = [1, 1] elif n == 2: gridsize = [2, 1] else: gridsize = [2, 2] xplotter = XmippPlotter(x=gridsize[0], y=gridsize[1]) # Create data to plot iters = range(0, lastIter+1, 1) ll = [] pmax = [] for iter in iters: logs = protML._getIterMdImages(it=iter, block='info') md = emlib.MetaData(logs) id = md.firstObject() ll.append(md.getValue(emlib.MDL_LL, id)) pmax.append(md.getValue(emlib.MDL_PMAX, id)) if doPlot('doShowLL'): a = xplotter.createSubPlot('Log-likelihood (should increase)', 'iterations', 'LL', yformat=True) a.plot(iters, ll) #Create plot of mirror for last iteration if doPlot('doShowMirror'): from numpy import arange from matplotlib.ticker import FormatStrFormatter md = emlib.MetaData(refs) mirrors = [md.getValue(emlib.MDL_MIRRORFRAC, id) for id in md] nrefs = len(mirrors) ind = arange(1, nrefs + 1) width = 0.85 a = xplotter.createSubPlot('Mirror fractions on last iteration', 'classes', 'mirror fraction') a.set_xticks(ind + 0.45) a.xaxis.set_major_formatter(FormatStrFormatter('%1.0f')) a.bar(ind, mirrors, width, color='b') a.set_ylim([0, 1.]) #a.set_xlim([0.3, nrefs + 1]) if doPlot('doShowPmax'): a = xplotter.createSubPlot('Probabilities distribution', 'iterations', 'Pmax/Psum') a.plot(iters, pmax, color='green') if doPlot('doShowSignalChange'): md = emlib.MetaData() for iter in iters: fn = protML._getIterMdClasses(it=iter, block='classes') md2 = emlib.MetaData(fn) md2.fillConstant(emlib.MDL_ITER, str(iter)) md.unionAll(md2) # 'iter(.*[1-9].*)@2D/ML2D/run_004/ml2d_iter_refs.xmd') # a = plt.subplot(gs[1, 1]) # print("md: %s" % md) md2 = emlib.MetaData() md2.aggregate(md, emlib.AGGR_MAX, emlib.MDL_ITER, emlib.MDL_SIGNALCHANGE, emlib.MDL_MAX) signal_change = [md2.getValue(emlib.MDL_MAX, id) for id in md2] xplotter.createSubPlot('Maximum signal change', 'iterations', 'signal change') xplotter.plot(iters, signal_change, color='green') return [xplotter]