diff --git a/CHANGES.rst b/CHANGES.rst
index fa93ac5f59..03c1db06d5 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -45,6 +45,9 @@ API Changes
Cubeviz
^^^^^^^
+- ``spatial_subset`` in the spectral extraction plugin is now renamed to ``aperture`` and will
+ be removed in a future release. [#2664]
+
Imviz
^^^^^
diff --git a/docs/dev/ui_style_guide.rst b/docs/dev/ui_style_guide.rst
index e970b72da2..f1709b03f5 100644
--- a/docs/dev/ui_style_guide.rst
+++ b/docs/dev/ui_style_guide.rst
@@ -22,7 +22,7 @@ try to adhere to the following principles:
components are necessary in a single row. Always emphasize readability at the default/minimum
width of the plugin tray, rather than using columns that result in a ton of text overflow.
* Use ```` to align content to the right (such as action buttons).
-* Action buttons should use ``text``
+* Action buttons should use ``text``
to control the color depending on whether the button affects things outside the plugin itself
(adding/modifying data collection or subset entries, etc) or are isolated to within the plugin
(adding model components in model fitting, etc). These buttons can be wrapped in tooltip components
diff --git a/jdaviz/configs/cubeviz/plugins/slice/slice.py b/jdaviz/configs/cubeviz/plugins/slice/slice.py
index 425afbafa6..1b98e6458c 100644
--- a/jdaviz/configs/cubeviz/plugins/slice/slice.py
+++ b/jdaviz/configs/cubeviz/plugins/slice/slice.py
@@ -11,7 +11,8 @@
from specutils.spectra.spectrum1d import Spectrum1D
from jdaviz.core.events import (AddDataMessage, SliceToolStateMessage,
- SliceSelectSliceMessage, GlobalDisplayUnitChanged)
+ SliceSelectSliceMessage, SliceWavelengthUpdatedMessage,
+ GlobalDisplayUnitChanged)
from jdaviz.core.registries import tray_registry
from jdaviz.core.template_mixin import PluginTemplateMixin
from jdaviz.core.user_api import PluginUserApi
@@ -217,6 +218,10 @@ def _on_slider_updated(self, event):
for viewer in self._indicator_viewers:
viewer._update_slice_indicator(value)
+ self.hub.broadcast(SliceWavelengthUpdatedMessage(slice=value,
+ wavelength=self.wavelength,
+ sender=self))
+
def vue_goto_first(self, *args):
if self.is_playing:
return
diff --git a/jdaviz/configs/cubeviz/plugins/spectral_extraction/spectral_extraction.py b/jdaviz/configs/cubeviz/plugins/spectral_extraction/spectral_extraction.py
index acaee9a9ed..4cc1424fa9 100644
--- a/jdaviz/configs/cubeviz/plugins/spectral_extraction/spectral_extraction.py
+++ b/jdaviz/configs/cubeviz/plugins/spectral_extraction/spectral_extraction.py
@@ -5,17 +5,19 @@
import numpy as np
import astropy
import astropy.units as u
+from astropy.utils.decorators import deprecated
from astropy.nddata import (
NDDataArray, StdDevUncertainty, NDUncertainty
)
-from traitlets import Bool, List, Unicode, observe
+from traitlets import Bool, Float, List, Unicode, observe
-from jdaviz.core.events import SnackbarMessage
+from jdaviz.core.custom_traitlets import FloatHandleEmpty
+from jdaviz.core.events import SnackbarMessage, SliceWavelengthUpdatedMessage
from jdaviz.core.registries import tray_registry
from jdaviz.core.template_mixin import (PluginTemplateMixin,
DatasetSelectMixin,
SelectPluginComponent,
- SpatialSubsetSelectMixin,
+ ApertureSubsetSelectMixin,
AddResultsMixin,
with_spinner)
from jdaviz.core.user_api import PluginUserApi
@@ -31,7 +33,7 @@
'cubeviz-spectral-extraction', label="Spectral Extraction", viewer_requirements='spectrum'
)
class SpectralExtraction(PluginTemplateMixin, DatasetSelectMixin,
- SpatialSubsetSelectMixin, AddResultsMixin):
+ ApertureSubsetSelectMixin, AddResultsMixin):
"""
See the :ref:`Spectral Extraction Plugin Documentation ` for more details.
@@ -41,12 +43,20 @@ class SpectralExtraction(PluginTemplateMixin, DatasetSelectMixin,
* :meth:`~jdaviz.core.template_mixin.PluginTemplateMixin.show`
* :meth:`~jdaviz.core.template_mixin.PluginTemplateMixin.open_in_tray`
* :meth:`~jdaviz.core.template_mixin.PluginTemplateMixin.close_in_tray`
- * ``spatial_subset`` (:class:`~jdaviz.core.template_mixin.SubsetSelect`):
- Subset to use for the spectral extraction, or ``No Subset``.
+ * ``aperture`` (:class:`~jdaviz.core.template_mixin.SubsetSelect`):
+ Subset to use for the spectral extraction, or ``Entire Cube``.
* ``add_results`` (:class:`~jdaviz.core.template_mixin.AddResults`)
* :meth:`collapse`
"""
template_file = __file__, "spectral_extraction.vue"
+ uses_active_status = Bool(True).tag(sync=True)
+
+ # feature flag for cone support
+ dev_cone_support = Bool(False).tag(sync=True)
+ wavelength_dependent = Bool(False).tag(sync=True)
+ reference_wavelength = FloatHandleEmpty().tag(sync=True)
+ slice_wavelength = Float().tag(sync=True)
+
function_items = List().tag(sync=True)
function_selected = Unicode('Sum').tag(sync=True)
filename = Unicode().tag(sync=True)
@@ -68,6 +78,12 @@ def __init__(self, *args, **kwargs):
self.extracted_spec = None
+ # TODO: in the future this could be generalized with support in SelectPluginComponent
+ self.aperture._default_text = 'Entire Cube'
+ self.aperture._manual_options = ['Entire Cube']
+ self.aperture.items = [{"label": "Entire Cube"}]
+ self.aperture.select_default()
+
self.function = SelectPluginComponent(
self,
items='function_items',
@@ -77,6 +93,9 @@ def __init__(self, *args, **kwargs):
self._set_default_results_label()
self.add_results.viewer.filters = ['is_spectrum_viewer']
+ self.session.hub.subscribe(self, SliceWavelengthUpdatedMessage,
+ handler=self._on_slice_changed)
+
if ASTROPY_LT_5_3_2:
self.disabled_msg = "Spectral Extraction in Cubeviz requires astropy>=5.3.2"
@@ -95,11 +114,46 @@ def user_api(self):
return PluginUserApi(
self,
expose=(
- 'function', 'spatial_subset',
+ 'function', 'spatial_subset', 'aperture',
'add_results', 'collapse_to_spectrum'
)
)
+ @property
+ @deprecated(since="3.9", alternative="aperture")
+ def spatial_subset(self):
+ return self.user_api.aperture
+
+ @property
+ def slice_plugin(self):
+ return self.app._jdaviz_helper.plugins['Slice']
+
+ @observe('wavelength_dependent')
+ def _wavelength_dependent_changed(self, *args):
+ if self.wavelength_dependent:
+ self.reference_wavelength = self.slice_plugin.wavelength
+ # NOTE: this can be redundant in the case where reference_wavelength changed and triggers
+ # the observe, but we need to ensure it is updated if reference_wavelength is unchanged
+ self._update_mark_scale()
+
+ def _on_slice_changed(self, msg):
+ self.slice_wavelength = msg.wavelength
+
+ def vue_goto_reference_wavelength(self, *args):
+ self.slice_plugin.wavelength = self.reference_wavelength
+ # TODO: can we get rid of this extra call after properly observing wavelength?
+# self._update_mark_scale()
+
+ def vue_adopt_slice_as_reference(self, *args):
+ self.reference_wavelength = self.slice_plugin.wavelength
+
+ @observe('reference_wavelength', 'slice_wavelength')
+ def _update_mark_scale(self, *args):
+ if not self.wavelength_dependent:
+ self.aperture.scale_factor = 1.0
+ return
+ self.aperture.scale_factor = self.slice_wavelength/self.reference_wavelength
+
@with_spinner()
def collapse_to_spectrum(self, add_data=True, **kwargs):
"""
@@ -121,12 +175,12 @@ def collapse_to_spectrum(self, add_data=True, **kwargs):
# defaults to ``No Subset``). Since the Cubeviz parser puts the fluxes
# and uncertainties in different glue Data objects, we translate the spectral
# cube and its uncertainties into separate NDDataArrays, then combine them:
- if self.spatial_subset_selected != self.spatial_subset.default_text:
+ if self.aperture.selected != self.spatial_subset.default_text:
nddata = spectral_cube.get_subset_object(
- subset_id=self.spatial_subset_selected, cls=NDDataArray
+ subset_id=self.aperture.selected, cls=NDDataArray
)
uncertainties = uncert_cube.get_subset_object(
- subset_id=self.spatial_subset_selected, cls=StdDevUncertainty
+ subset_id=self.aperture.selected, cls=StdDevUncertainty
)
else:
nddata = spectral_cube.get_object(cls=NDDataArray)
@@ -242,15 +296,15 @@ def _save_extracted_spec_to_fits(self, overwrite=False, *args):
f"Extracted spectrum saved to {os.path.abspath(filename)}",
sender=self, color="success"))
- @observe('spatial_subset_selected')
+ @observe('aperture_selected')
def _set_default_results_label(self, event={}):
label = "Spectral extraction"
if (
- hasattr(self, 'spatial_subset') and
- self.spatial_subset.selected != self.spatial_subset.default_text
+ hasattr(self, 'aperture') and
+ self.aperture.selected != self.aperture.default_text
):
- label += f' ({self.spatial_subset_selected})'
+ label += f' ({self.aperture_selected})'
self.results_label_default = label
diff --git a/jdaviz/configs/cubeviz/plugins/spectral_extraction/spectral_extraction.vue b/jdaviz/configs/cubeviz/plugins/spectral_extraction/spectral_extraction.vue
index 553945daa8..41695b4510 100644
--- a/jdaviz/configs/cubeviz/plugins/spectral_extraction/spectral_extraction.vue
+++ b/jdaviz/configs/cubeviz/plugins/spectral_extraction/spectral_extraction.vue
@@ -2,6 +2,9 @@
@@ -18,13 +21,53 @@
+
+
cone support is under active development and hidden from users
+
+
+
+
+
+
+
+
+ Adopt Current Slice
+
+
+
+
+
+
+
+
+
+ Slice to Reference Wavelength
+
+
+
+
+
+
+