diff options
Diffstat (limited to 'silx/gui/data/_VolumeWindow.py')
-rw-r--r-- | silx/gui/data/_VolumeWindow.py | 148 |
1 files changed, 0 insertions, 148 deletions
diff --git a/silx/gui/data/_VolumeWindow.py b/silx/gui/data/_VolumeWindow.py deleted file mode 100644 index 03b6876..0000000 --- a/silx/gui/data/_VolumeWindow.py +++ /dev/null @@ -1,148 +0,0 @@ -# coding: utf-8 -# /*########################################################################## -# -# Copyright (c) 2019 European Synchrotron Radiation Facility -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# -# ###########################################################################*/ -"""This module provides a widget to visualize 3D arrays""" - -__authors__ = ["T. Vincent"] -__license__ = "MIT" -__date__ = "22/03/2019" - - -import numpy - -from .. import qt -from ..plot3d.SceneWindow import SceneWindow -from ..plot3d.items import ScalarField3D, ComplexField3D, ItemChangedType - - -class VolumeWindow(SceneWindow): - """Extends SceneWindow with a convenient API for 3D array - - :param QWidget: parent - """ - - def __init__(self, parent): - super(VolumeWindow, self).__init__(parent) - self.__firstData = True - # Hide global parameter dock - self.getGroupResetWidget().parent().setVisible(False) - - def setAxesLabels(self, xlabel=None, ylabel=None, zlabel=None): - """Set the text labels of the axes. - - :param Union[str,None] xlabel: Label of the X axis - :param Union[str,None] ylabel: Label of the Y axis - :param Union[str,None] zlabel: Label of the Z axis - """ - sceneWidget = self.getSceneWidget() - sceneWidget.getSceneGroup().setAxesLabels( - 'X' if xlabel is None else xlabel, - 'Y' if ylabel is None else ylabel, - 'Z' if zlabel is None else zlabel) - - def clear(self): - """Clear any currently displayed data""" - sceneWidget = self.getSceneWidget() - items = sceneWidget.getItems() - if (len(items) == 1 and - isinstance(items[0], (ScalarField3D, ComplexField3D))): - items[0].setData(None) - else: # Safety net - sceneWidget.clearItems() - - @staticmethod - def __computeIsolevel(data): - """Returns a suitable isolevel value for data - - :param numpy.ndarray data: - :rtype: float - """ - data = data[numpy.isfinite(data)] - if len(data) == 0: - return 0 - else: - return numpy.mean(data) + numpy.std(data) - - def setData(self, data, offset=(0., 0., 0.), scale=(1., 1., 1.)): - """Set the 3D array data to display. - - :param numpy.ndarray data: 3D array of float or complex - :param List[float] offset: (tx, ty, tz) coordinates of the origin - :param List[float] scale: (sx, sy, sz) scale for each dimension - """ - sceneWidget = self.getSceneWidget() - dataMaxCoords = numpy.array(list(reversed(data.shape))) - 1 - - previousItems = sceneWidget.getItems() - if (len(previousItems) == 1 and - isinstance(previousItems[0], (ScalarField3D, ComplexField3D)) and - numpy.iscomplexobj(data) == isinstance(previousItems[0], ComplexField3D)): - # Reuse existing volume item - volume = sceneWidget.getItems()[0] - volume.setData(data, copy=False) - # Make sure the plane goes through the dataset - for plane in volume.getCutPlanes(): - point = numpy.array(plane.getPoint()) - if numpy.any(point < (0, 0, 0)) or numpy.any(point > dataMaxCoords): - plane.setPoint(dataMaxCoords // 2) - else: - # Add a new volume - sceneWidget.clearItems() - volume = sceneWidget.addVolume(data, copy=False) - volume.setLabel('Volume') - for plane in volume.getCutPlanes(): - # Make plane going through the center of the data - plane.setPoint(dataMaxCoords // 2) - plane.setVisible(False) - plane.sigItemChanged.connect(self.__cutPlaneUpdated) - volume.addIsosurface(self.__computeIsolevel, '#FF0000FF') - - # Expand the parameter tree - model = self.getParamTreeView().model() - index = qt.QModelIndex() # Invalid index for top level - while 1: - rowCount = model.rowCount(parent=index) - if rowCount == 0: - break - index = model.index(rowCount - 1, 0, parent=index) - self.getParamTreeView().setExpanded(index, True) - if not index.isValid(): - break - - volume.setTranslation(*offset) - volume.setScale(*scale) - - if self.__firstData: # Only center for first dataset - self.__firstData = False - sceneWidget.centerScene() - - def __cutPlaneUpdated(self, event): - """Handle the change of visibility of the cut plane - - :param event: Kind of update - """ - if event == ItemChangedType.VISIBLE: - plane = self.sender() - if plane.isVisible(): - self.getSceneWidget().selection().setCurrentItem(plane) |