Source code for fsleyes.plugins.tools.addroihistogram

#
# addroihistogram.py - The AddROIHistogramAction class.
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
"""This module provides the :class:`AddROIHistogramAction` class, an
action used by the :class:`.HistogramPanel`.
"""


import          wx
import numpy as np

import fsl.data.image                          as fslimage
import fsleyes.views.histogrampanel            as histogrampanel
import fsleyes.strings                         as strings
import fsleyes.plotting.dataseries             as dataseries
import fsleyes.plotting.histogramseries        as histogramseries
import fsleyes.plugins.tools.addmaskdataseries as addmaskdataseries
import fsleyes.actions.base                    as base



[docs]class AddROIHistogramAction(base.Action): """The ``AddROIHistogramAction`` class is used by the :class:`.HistogramPanel`. It performs a very similar task to the :class:`.AddMaskDataSeriesAction` - the user selects a binary mask, the data within the base image is extracted for that mask, and the histogram of that data is added to the plot. """
[docs] @staticmethod def supportedViews(): """The ``AddROIHistogramAction`` is restricted for use with the :class:`.HistogramPanel`. """ return [histogrampanel.HistogramPanel]
[docs] def __init__(self, overlayList, displayCtx, plotPanel): """Create an ``AddROIHistogramAction``. :arg overlayList: The :class:`.OverlayList`. :arg displayCtx: The :class:`.DisplayContext`. :arg plotPanel: The :class:`.HistogramPanel`. """ base.Action.__init__( self, overlayList, displayCtx, self.__addROIHistogram) self.__plotPanel = plotPanel self.__roiOptions = [] overlayList.addListener('overlays', self.name, self.__overlayListChanged) displayCtx .addListener('selectedOverlay', self.name, self.__overlayListChanged) self.__overlayListChanged()
[docs] def destroy(self): """Must be called when this ``AddROIHistogramAction`` is no longer in use. """ if self.destroyed: return self.overlayList.removeListener('overlays', self.name) self.displayCtx .removeListener('selectedOverlay', self.name) self.__plotPanel = None self.__roiOptions = None base.Action.destroy(self)
def __overlayListChanged(self, *a): """Called when the :class:`.OverlayList` or the :attr:`.DisplayContext.selectedOverlay` changes. Updates a list of valid mask images for the currently selected overlay. """ overlay = self.displayCtx.getSelectedOverlay() if (len(self.overlayList) == 0 or (not isinstance(overlay, fslimage.Image))): self.enabled = False return self.__roiOptions = [o for o in self.overlayList if isinstance(o, fslimage.Image) and o is not overlay and o.sameSpace(overlay)] self.enabled = len(self.__roiOptions) > 0 def __addROIHistogram(self): """Prompts the user to select an ROI mask, calculates the histogram of that mask on the currently selected overlay, and adds the result to the ``HistogramPanel``. """ overlay = self.displayCtx.getSelectedOverlay() opts = self.displayCtx.getOpts(overlay) roiOptions = self.__roiOptions frame = wx.GetApp().GetTopWindow() msg = strings.messages[self, 'selectMask'].format(overlay.name) title = strings.titles[ self, 'selectMask'].format(overlay.name) dlg = addmaskdataseries.MaskDialog( frame, [o.name for o in roiOptions], title=title, message=msg, checkbox=False) if dlg.ShowModal() != wx.ID_OK: return maskimg = roiOptions[dlg.GetChoice()] mask = maskimg[:] > 0 if overlay.ndim > 3: data = overlay[opts.index()][mask] else: data = overlay[mask] count = self.__plotPanel.histType == 'count' drange = (np.nanmin(data), np.nanmax(data)) nbins = histogramseries.autoBin(data, drange) xdata, ydata, _ = histogramseries.histogram(data, nbins, drange, drange, includeOutliers=False, count=count) ds = dataseries.DataSeries(overlay, self.overlayList, self.displayCtx, self.__plotPanel) ds.colour = self.__plotPanel.getOverlayPlotColour(overlay) ds.lineStyle = self.__plotPanel.getOverlayPlotStyle(overlay) ds.lineWidth = 2 ds.alpha = 1 ds.label = '{} [mask: {}]'.format(overlay.name, maskimg.name) # We have to run the data through # prepareDataSeries to preprocess # (e.g. smooth) it ds.setData(xdata, ydata) ds.setData(*self.__plotPanel.prepareDataSeries(ds)) self.__plotPanel.canvas.dataSeries.append(ds)