Skip to content

Commit

Permalink
specviz2d/mosviz: matched mouseover markers (#2575)
Browse files Browse the repository at this point in the history
* specviz2d/mosviz matched mouseover markers
* update tests to include wave in mouseover info
* update tests for extra mouseover mark
  • Loading branch information
kecnry authored Nov 28, 2023
1 parent 9ecfec6 commit 2746b72
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 17 deletions.
4 changes: 4 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,16 @@ Imviz
Mosviz
^^^^^^

- Matched mouseover indicator to show same position in 1d and 2d spectral viewers. [#2575]

Specviz
^^^^^^^

Specviz2d
^^^^^^^^^

- Matched mouseover indicator to show same position in 1d and 2d spectral viewers. [#2575]

API Changes
-----------

Expand Down
78 changes: 69 additions & 9 deletions jdaviz/configs/imviz/plugins/coords_info/coords_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@
from traitlets import Bool, Unicode, observe

from astropy import units as u
from bqplot import LinearScale
from glue.core import BaseData
from glue.core.subset_group import GroupedSubset
from glue_jupyter.bqplot.image.layer_artist import BqplotImageSubsetLayerArtist

from jdaviz.configs.cubeviz.plugins.viewers import CubevizImageView
from jdaviz.configs.imviz.plugins.viewers import ImvizImageView
from jdaviz.configs.mosviz.plugins.viewers import MosvizImageView, MosvizProfile2DView
from jdaviz.configs.mosviz.plugins.viewers import (MosvizImageView, MosvizProfileView,
MosvizProfile2DView)
from jdaviz.configs.specviz.plugins.viewers import SpecvizProfileView
from jdaviz.core.events import ViewerAddedMessage
from jdaviz.core.helpers import data_has_valid_wcs
from jdaviz.core.marks import PluginScatter
from jdaviz.core.marks import PluginScatter, PluginLine
from jdaviz.core.registries import tool_registry
from jdaviz.core.template_mixin import TemplateMixin, DatasetSelectMixin
from jdaviz.utils import get_subset_type
Expand All @@ -31,7 +33,7 @@ class CoordsInfo(TemplateMixin, DatasetSelectMixin):
MosvizImageView,
MosvizProfile2DView)

_viewer_classes_with_marker = (SpecvizProfileView,)
_viewer_classes_with_marker = (SpecvizProfileView, MosvizProfile2DView)

dataset_icon = Unicode("").tag(sync=True) # option for layer (auto, none, or specific layer)
icon = Unicode("").tag(sync=True) # currently exposed layer
Expand Down Expand Up @@ -79,9 +81,25 @@ def _create_marks_for_viewer(self, viewer, id=None):
id = viewer.reference_id
if id in self._marks:
return
self._marks[id] = PluginScatter(viewer,
marker='rectangle', stroke_width=1,
visible=False)
if isinstance(viewer, MosvizProfile2DView):
self._marks[id] = PluginLine(viewer,
x=[0, 0], y=[0, 1],
scales={'x': viewer.scales['x'],
'y': LinearScale(min=0, max=1)},
visible=False)
else:
self._marks[id] = PluginScatter(viewer,
marker='rectangle', stroke_width=1,
visible=False)
if isinstance(viewer, MosvizProfileView):
matched_id = f"{id}:matched"
self._marks[matched_id] = PluginLine(viewer,
x=[0, 0], y=[0, 1],
scales={'x': viewer.scales['x'],
'y': LinearScale(min=0, max=1)},
visible=False)
viewer.figure.marks = viewer.figure.marks + [self._marks[matched_id]]

viewer.figure.marks = viewer.figure.marks + [self._marks[id]]

def _create_viewer_callbacks(self, viewer):
Expand Down Expand Up @@ -112,6 +130,16 @@ def marks(self):
self._create_marks_for_viewer(viewer, id)
return self._marks

@property
def _matched_markers(self):
if self.app.config == 'specviz2d':
return {'specviz2d-0': ['specviz2d-1:matched'],
'specviz2d-1': ['specviz2d-0']}
if self.app.config == 'mosviz':
return {'mosviz-1': ['mosviz-2:matched'],
'mosviz-2': ['mosviz-1']}
return {}

def as_text(self):
return (f"{self.row1a_title} {self.row1a_text} {self.row1b_title} {self.row1b_text}".strip(), # noqa
f"{self.row2_title} {self.row2_text}".strip(),
Expand Down Expand Up @@ -140,9 +168,11 @@ def reset_coords_display(self):

def _viewer_mouse_clear_event(self, viewer, data=None):
self.reset_coords_display()
marks = self.marks.get(viewer._reference_id)
if marks is not None:
marks.visible = False
marker_ids = [viewer._reference_id] + self._matched_markers.get(viewer._reference_id, [])
for marker_id in marker_ids:
marks = self.marks.get(marker_id)
if marks is not None:
marks.visible = False

def _viewer_mouse_event(self, viewer, data):
if data['event'] in ('mouseleave', 'mouseenter'):
Expand Down Expand Up @@ -336,6 +366,17 @@ def _image_viewer_update(self, viewer, x, y):
# TODO: use sky directly, but need to figure out how to have a compatible "blank" entry
self._dict['world'] = (sky.ra.value, sky.dec.value)
self._dict['world:unreliable'] = unreliable_world
elif isinstance(viewer, MosvizProfile2DView) and hasattr(getattr(image, 'coords', None),
'pixel_to_world_values'):
# use WCS to expose the wavelength for a 2d spectrum shown in pixel space
wave, pixel = image.coords.pixel_to_world(x, y)
self.row2_title = 'Wave'
self.row2_text = f'{wave.value:10.5e} {wave.unit.to_string()}'
self.row2_unreliable = False

self.row3_title = '\u00A0'
self.row3_text = ""
self.row3_unreliable = False
else:
self.row2_title = '\u00A0'
self.row2_text = ""
Expand Down Expand Up @@ -397,6 +438,20 @@ def _image_viewer_update(self, viewer, x, y):
self.row1b_title = ''
self.row1b_text = ''

if isinstance(viewer, MosvizProfile2DView):
self.marks[viewer._reference_id].update_xy([x, x], [0, 1])
self.marks[viewer._reference_id].visible = True

for matched_marker_id in self._matched_markers.get(viewer._reference_id, []):
if hasattr(getattr(image, 'coords', None), 'pixel_to_world_values'):
# should already have wave computed from setting the coords-info
matched_viewer = self.app.get_viewer(matched_marker_id.split(':matched')[0])
wave = wave.to_value(matched_viewer.state.x_display_unit)
self.marks[matched_marker_id].update_xy([wave, wave], [0, 1])
self.marks[matched_marker_id].visible = True
else:
self.marks[matched_marker_id].visible = False

def _spectrum_viewer_update(self, viewer, x, y):
def _cursor_fallback():
self._dict['axes_x'] = x
Expand Down Expand Up @@ -541,4 +596,9 @@ def _copy_axes_to_spectral():

self.marks[viewer._reference_id].update_xy([closest_wave], [closest_flux])
self.marks[viewer._reference_id].visible = True
for matched_marker_id in self._matched_markers.get(viewer._reference_id, []):
# NOTE: this currently assumes the the matched marker is a vertical line with a
# normalized y-scale
self.marks[matched_marker_id].update_xy([closest_i, closest_i], [0, 1])
self.marks[matched_marker_id].visible = True
_copy_axes_to_spectral()
3 changes: 2 additions & 1 deletion jdaviz/configs/mosviz/tests/test_data_loading.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,8 @@ def test_load_single_image_multi_spec(mosviz_helper, mos_image, spectrum1d, mos_

label_mouseover._viewer_mouse_event(spec2d_viewer,
{'event': 'mousemove', 'domain': {'x': 10, 'y': 100}})
assert label_mouseover.as_text() == ('Pixel x=00010.0 y=00100.0 Value +8.12986e-01', '', '')
assert label_mouseover.as_text() == ('Pixel x=00010.0 y=00100.0 Value +8.12986e-01',
'Wave 1.10000e-05 m', '')
assert label_mouseover.icon == 'c'

# need to trigger a mouseleave or mouseover to reset the traitlets
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ def test_plugin(specviz2d_helper):

# test trace marks - won't be created until after opening the plugin
sp2dv = specviz2d_helper.app.get_viewer('spectrum-2d-viewer')
assert len(sp2dv.figure.marks) == 2
assert len(sp2dv.figure.marks) == 3

pext.keep_active = True
assert len(sp2dv.figure.marks) == 11
assert len(sp2dv.figure.marks) == 12
assert pext.marks['trace'].visible is True
assert len(pext.marks['trace'].x) > 0

Expand Down Expand Up @@ -66,7 +66,7 @@ def test_plugin(specviz2d_helper):
# TODO: Investigate extra hidden mark from glue-jupyter, see
# https://github.com/spacetelescope/jdaviz/pull/2478#issuecomment-1731864411
# 3 new trace objects should have been loaded and plotted in the spectrum-2d-viewer
assert len(sp2dv.figure.marks) == 15
assert len(sp2dv.figure.marks) == 16

# interact with background section, check marks
pext.trace_trace_selected = 'New Trace'
Expand Down
5 changes: 3 additions & 2 deletions jdaviz/configs/specviz2d/tests/test_parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def test_2d_parser_jwst(specviz2d_helper):
label_mouseover._viewer_mouse_event(viewer_2d,
{'event': 'mousemove', 'domain': {'x': 350, 'y': 30}})
assert label_mouseover.as_text() == ('Pixel x=0350.0 y=0030.0 Value +3.22142e+04 MJy / sr',
'', '')
'Wave 6.24985e+00 um', '')


@pytest.mark.remote_data
Expand Down Expand Up @@ -72,7 +72,8 @@ def test_2d_parser_no_unit(specviz2d_helper, mos_spectrum2d):
label_mouseover = specviz2d_helper.app.session.application._tools['g-coords-info']
label_mouseover._viewer_mouse_event(viewer_2d,
{'event': 'mousemove', 'domain': {'x': 0, 'y': 0}})
assert label_mouseover.as_text() == ('Pixel x=00000.0 y=00000.0 Value +3.74540e-01', '', '')
assert label_mouseover.as_text() == ('Pixel x=00000.0 y=00000.0 Value +3.74540e-01',
'Wave 1.00000e-06 m', '')
assert label_mouseover.icon == 'a'

viewer_1d = specviz2d_helper.app.get_viewer('spectrum-viewer')
Expand Down
4 changes: 2 additions & 2 deletions jdaviz/core/marks.py
Original file line number Diff line number Diff line change
Expand Up @@ -581,15 +581,15 @@ def __init__(self, viewer, x=[], y=[], **kwargs):
self.viewer = viewer
# color is same blue as import button
kwargs.setdefault('colors', [accent_color])
super().__init__(x=x, y=y, scales=viewer.scales, **kwargs)
super().__init__(x=x, y=y, scales=kwargs.pop('scales', viewer.scales), **kwargs)


class PluginScatter(Scatter, PluginMark, HubListener):
def __init__(self, viewer, x=[], y=[], **kwargs):
self.viewer = viewer
# default color is same blue as import button
kwargs.setdefault('colors', [accent_color])
super().__init__(x=x, y=y, scales=viewer.scales, **kwargs)
super().__init__(x=x, y=y, scales=kwargs.pop('scales', viewer.scales), **kwargs)


class LineAnalysisContinuum(PluginLine):
Expand Down

0 comments on commit 2746b72

Please sign in to comment.