summaryrefslogtreecommitdiff
path: root/silx/gui/data/_VolumeWindow.py
diff options
context:
space:
mode:
Diffstat (limited to 'silx/gui/data/_VolumeWindow.py')
-rw-r--r--silx/gui/data/_VolumeWindow.py148
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)