Skip to content

Commit

Permalink
slice: refactor plugin to decouple from cube (#2715)
Browse files Browse the repository at this point in the history
* refactor slice plugin

* allow tool to become default when first becoming visible
* allow downstream to override slice axis
* allow for multiple viewers with indicators by using mixins for WithSliceIndicator or WithSliceSelection
* decouple slice axis from cube and replace with optional "snap to slice" functionality

* initialize original slice location to middle of first found data layer

* re-implement play/increment functionality

* and add decrement since slider no longer exists

* slice indicator: use sci notation only if necessary

* initialize value_unit in cubeviz

* fix jittering indicator

* delay snap to slice while inputting number

* implement deprecated API access to slice

* changelog entry

* update docs

* support test data

* deprecate cubeviz_helper.select_slice

* edge checks and wrapping support in cube play functionality

* update tests

* reproduce previous logic for init slice

* do not allow disabling snapping in cubeviz

* but keep support for downstream

* avoid calls to viewer.data()

* ap phot: determine slice-index on the fly instead of relying on plugin

* update even more tests

* read slice component from x_att

to support wave/wavelength/freq/frequency/wavenumber/velocity/energy

* handle cubes passing int to slice value

* further support for flexible x_att handling

* more test updates

* fix support for slice axis given in integers

* remove comment

* fix play support when slices are integers

* allow initializing when slice axis is pixel

* always label as "value" in UI

* can always change to be more intelligent based on data and x-display-unit later

* don't allow starting playing if no slices

(this would have quite immediately after otherwise, but is hard to reliably test since that is threaded)

* DOC: Use new API in concept notebook
  • Loading branch information
kecnry authored Mar 8, 2024
1 parent 43487aa commit b4cdd08
Show file tree
Hide file tree
Showing 20 changed files with 528 additions and 334 deletions.
6 changes: 5 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ Cubeviz

- Live previews in spectral extraction plugin. [#2733]

- Slice plugin is refactored to rely on the spectral value instead of the slice index. This removes
both the slider and slice-index input. [#2715]

Imviz
^^^^^

Expand Down Expand Up @@ -67,7 +70,8 @@ Cubeviz
be removed in a future release. [#2664]

- Slice plugin's ``wavelength``, ``wavelength_unit``, and ``show_wavelength`` are deprecated in favor
of ``value``, ``value_unit``, and ``show_value``, respectively. [#2706]
of ``value``, ``value_unit``, and ``show_value``, respectively. ``slice`` is also deprecated
and should be replaced with accessing/setting ``value`` directly. [#2706, #2715]

Imviz
^^^^^
Expand Down
9 changes: 5 additions & 4 deletions docs/cubeviz/plugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ The slice plugin provides the ability to select the slice
of the cube currently visible in the image viewers, with the
corresponding wavelength highlighted in the spectrum viewer.

The slider can be grabbed to scrub through the cube. To choose
a specific slice, enter a slice number (integer) or an approximate
wavelength (in which case the nearest slice will be selected and
the wavelength entry will update to the exact value of that slice).
To choose a specific slice, enter an approximate wavelength (in which case the nearest slice will
be selected and the wavelength entry will "span" to the exact value of that slice). The snapping
behavior can be disabled in the plugin settings to allow for smooth scrubbing, in which case the
closest slice will still be displayed in the cube viewer.

The spectrum viewer also contains a tool to allow clicking and
dragging in the spectrum plot to choose the currently selected slice.
Expand All @@ -89,6 +89,7 @@ For your convenience, there are also player-style buttons with
the following functionality:

* Jump to first
* Previous slice
* Play/Pause
* Next slice
* Jump to last
Expand Down
11 changes: 6 additions & 5 deletions jdaviz/components/toolbar_nested.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,17 @@ def __init__(self, viewer, tools_nested, default_tool_priority=[]):
primary=i == 0,
visible=True)

# handle logic for tool visibilities (which will also handle setting the primary
# to something other than the first entry, if necessary)
self._update_tool_visibilities()

# default_tool_priority allows falling back on an existing tool
# if its the primary tool. If no items in default_tool_priority
# are currently "primary", then either no tool will be selected
# or will fallback on BasicJupyterToolbar's handling of
# viewer._default_mouse_mode_cls (which will not show that tool as active).
self.default_tool_priority = default_tool_priority
self._handle_default_tool()

# handle logic for tool visibilities (which will also handle setting the primary
# to something other than the first entry, if necessary)
# NOTE: this will also call _handle_default_tool
self._update_tool_visibilities()

# toolbars in the main app viewers need to respond to the data-collection, etc,
# but those in plugins do not
Expand Down Expand Up @@ -132,6 +132,7 @@ def _update_tool_visibilities(self):
self.send_state("tools_data")
if needs_deactivate_active:
self.active_tool_id = None
self._handle_default_tool()

def _handle_default_tool(self):
# default to the first item in the default_tool_priority list that is currently
Expand Down
14 changes: 9 additions & 5 deletions jdaviz/configs/cubeviz/helper.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import numpy as np
from astropy.io import fits
from astropy.io import registry as io_registry
from astropy.utils.decorators import deprecated
from glue.core import BaseData
from specutils import Spectrum1D
from specutils.io.registers import _astropy_has_priorities
Expand All @@ -14,6 +15,10 @@
__all__ = ['Cubeviz']


_spectral_axis_names = ["Wave", "Wavelength", "Freq", "Frequency",
"Wavenumber", "Velocity", "Energy"]


class Cubeviz(ImageConfigHelper, LineListMixin):
"""Cubeviz Helper class"""
_default_configuration = 'cubeviz'
Expand All @@ -36,8 +41,7 @@ def _set_spectrum_x_axis(self, msg):
return
ref_data = viewer.state.reference_data
if ref_data and ref_data.ndim == 3:
for att_name in ["Wave", "Wavelength", "Freq", "Frequency",
"Wavenumber", "Velocity", "Energy"]:
for att_name in _spectral_axis_names:
if att_name in ref_data.component_ids():
if viewer.state.x_att != ref_data.id[att_name]:
viewer.state.x_att = ref_data.id[att_name]
Expand Down Expand Up @@ -76,6 +80,7 @@ def load_data(self, data, data_label=None, override_cube_limit=False, **kwargs):

super().load_data(data, parser_reference="cubeviz-data-parser", **kwargs)

@deprecated(since="3.9", alternative="select_wavelength")
def select_slice(self, slice):
"""
Select a slice by index.
Expand All @@ -89,8 +94,7 @@ def select_slice(self, slice):
raise TypeError("slice must be an integer")
if slice < 0:
raise ValueError("slice must be positive")
msg = SliceSelectSliceMessage(slice=slice, sender=self)
self.app.hub.broadcast(msg)
self.plugins['Slice'].slice = slice

def select_wavelength(self, wavelength):
"""
Expand All @@ -100,7 +104,7 @@ def select_wavelength(self, wavelength):
----------
wavelength : float
Wavelength to select in units of the x-axis of the spectrum. The nearest slice will
be selected.
be selected if "snap to slice" is enabled in the slice plugin.
"""
if not isinstance(wavelength, (int, float)):
raise TypeError("wavelength must be a float or int")
Expand Down
Loading

0 comments on commit b4cdd08

Please sign in to comment.