Unverified Commit 029a7ea6 authored by Peterson, Peter's avatar Peterson, Peter Committed by GitHub
Browse files

Merge pull request #32053 from mantidproject/scd238_sliceviewer_fix

Sliceviewer cursor tracking fix for MDHistograms ornl-next
parents 444e8798 4311c131
......@@ -55,5 +55,6 @@ Improvements
Bugfixes
########
- Fix cursor tracking from getting stuck and displaying incorrect signals when viewing MDHistogram workspaces in :ref:`sliceviewer`.
:ref:`Release 6.2.0 <v6.2.0>`
\ No newline at end of file
......@@ -13,6 +13,7 @@ import numpy as np
from mantidqt.utils.qt import import_qt
from matplotlib.collections import QuadMesh
from matplotlib.image import AxesImage
from matplotlib.transforms import Bbox
from .lineplots import CursorTracker, cursor_info
from .transform import NonOrthogonalTransform
......@@ -25,18 +26,25 @@ ImageInfoWidget = import_qt('.._common', 'mantidqt.widgets', 'ImageInfoWidget')
class ImageInfoTracker(CursorTracker):
def __init__(self, image: Union[AxesImage, QuadMesh], transform: NonOrthogonalTransform,
do_transform: bool, widget: ImageInfoWidget):
do_transform: bool, widget: ImageInfoWidget, cursor_transform: tuple = None):
"""
Update the image that the widget refers too.
:param: An AxesImage or Mesh instance to track
:param: transpose_xy: If true the cursor position should be transposed
before sending to the table update
:param do_transform: Flag to perform transform for QuadMesh images
:param widget: ImageInfoWidget instance
:param cursor_transform: Full axes limits to use for mouse coord transform to use instead of image extents
"""
super().__init__(image_axes=image.axes, autoconnect=False)
self._image = image
self.transform = transform
self.do_transform = do_transform
self._widget = widget
self._cursor_transform = None
if cursor_transform is not None:
self._cursor_transform = Bbox([[cursor_transform[1][0], cursor_transform[0][0]],
[cursor_transform[1][1], cursor_transform[0][1]]])
if hasattr(image, 'get_extent'):
self.on_cursor_at = self._on_cursor_at_axesimage
......@@ -59,7 +67,7 @@ class ImageInfoTracker(CursorTracker):
if self._image is None:
return
cinfo = cursor_info(self._image, xdata, ydata)
cinfo = cursor_info(self._image, xdata, ydata, full_bbox=self._cursor_transform)
if cinfo is not None:
arr, _, (i, j) = cinfo
if (0 <= i < arr.shape[0]) and (0 <= j < arr.shape[1]) and not np.ma.is_masked(arr[i, j]):
......
......@@ -397,12 +397,13 @@ CursorInfo = namedtuple("CursorInfo", ("array", "extent", "point"))
@lru_cache(maxsize=32)
def cursor_info(image: AxesImage, xdata: float, ydata: float) -> Optional[CursorInfo]:
def cursor_info(image: AxesImage, xdata: float, ydata: float, full_bbox: Bbox = None) -> Optional[CursorInfo]:
"""Return information on the image for the given position in
data coordinates.
:param image: An instance of an image type
:param xdata: X data coordinate of cursor
:param xdata: Y data coordinate of cursor
:param full_bbox: Bbox of full workspace dimension to use for transforming mouse position
:return: None if point is not valid on the image else return CursorInfo type
"""
extent = image.get_extent()
......@@ -410,7 +411,14 @@ def cursor_info(image: AxesImage, xdata: float, ydata: float) -> Optional[Cursor
arr = image.get_array()
data_extent = Bbox([[ymin, xmin], [ymax, xmax]])
array_extent = Bbox([[0, 0], arr.shape[:2]])
trans = BboxTransform(boxin=data_extent, boxout=array_extent)
if full_bbox is None:
trans = BboxTransform(boxin=data_extent, boxout=array_extent)
else:
# If the view is zoomed in and the slice is changed, then the image extents
# and data extents change. This causes the cursor to be transformed to the
# wrong point for certain MDH workspaces (since it cannot be dynamically rebinned).
# This will use the full WS data dimensions to do the transformation
trans = BboxTransform(boxin=full_bbox, boxout=array_extent)
point = trans.transform_point([ydata, xdata])
if any(np.isnan(point)):
return None
......
......@@ -65,6 +65,7 @@ class SliceViewerDataView(QWidget):
self._line_plots = None
self._image_info_tracker = None
self._region_selection_on = False
self._orig_lims = None
# Dimension widget
self.dimensions_layout = QGridLayout()
......@@ -253,8 +254,6 @@ class SliceViewerDataView(QWidget):
transpose=self.dimensions.transpose,
norm=self.colorbar.get_norm(),
**kwargs)
self.on_track_cursor_state_change(self.track_cursor_checked())
# ensure the axes data limits are updated to match the
# image. For example if the axes were zoomed and the
# swap dimensions was clicked we need to restore the
......@@ -262,6 +261,11 @@ class SliceViewerDataView(QWidget):
extent = self.image.get_extent()
self.ax.set_xlim(extent[0], extent[1])
self.ax.set_ylim(extent[2], extent[3])
# Set the original data limits which get passed to the ImageInfoWidget so that
# the mouse projection to data space is correct for MDH workspaces when zoomed/changing slices
self._orig_lims = self.get_axes_limits()
self.on_track_cursor_state_change(self.track_cursor_checked())
self.draw_plot()
......@@ -384,7 +388,8 @@ class SliceViewerDataView(QWidget):
self._image_info_tracker = ImageInfoTracker(image=self.image,
transform=self.nonortho_transform,
do_transform=self.nonorthogonal_mode,
widget=self.image_info_widget)
widget=self.image_info_widget,
cursor_transform=self._orig_lims)
if state:
self._image_info_tracker.connect()
......@@ -463,7 +468,6 @@ class SliceViewerDataView(QWidget):
else:
return None
def set_axes_limits(self, xlim, ylim):
"""
Set the view limits on the image axes to the given extents. Assume the
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment