diff --git a/CHANGES.rst b/CHANGES.rst index 1816bca251..5a5eae3c97 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,7 @@ New Features ------------ - Added flux/surface brightness translation and surface brightness - unit conversion in Cubeviz and Specviz. [#2781, #2940, #3088, #3111, #3113, #3129, #3139, #3155] + unit conversion in Cubeviz and Specviz. [#2781, #2940, #3088, #3111, #3113, #3129, #3139, #3149, #3155] - Plugin tray is now open by default. [#2892] diff --git a/jdaviz/configs/specviz/plugins/unit_conversion/tests/test_unit_conversion.py b/jdaviz/configs/specviz/plugins/unit_conversion/tests/test_unit_conversion.py index 4380599b02..3089a84a6b 100644 --- a/jdaviz/configs/specviz/plugins/unit_conversion/tests/test_unit_conversion.py +++ b/jdaviz/configs/specviz/plugins/unit_conversion/tests/test_unit_conversion.py @@ -251,3 +251,22 @@ def test_sb_unit_conversion(cubeviz_helper): la = cubeviz_helper.plugins['Line Analysis']._obj assert la.dataset.get_selected_spectrum(use_display_units=True) + + +def test_contour_unit_conversion(cubeviz_helper, spectrum1d_cube_fluxunit_jy_per_steradian): + # custom cube to have Surface Brightness units + cubeviz_helper.load_data(spectrum1d_cube_fluxunit_jy_per_steradian, data_label="test") + + uc_plg = cubeviz_helper.plugins['Unit Conversion'] + uc_plg.open_in_tray() + + po_plg = cubeviz_helper.plugins['Plot Options'] + # Make sure that the contour values get updated + po_plg.contour_visible = True + + assert np.allclose(po_plg.contour_max.value, 199) + + uc_plg._obj.flux_or_sb_selected = 'Surface Brightness' + uc_plg.flux_unit = 'MJy' + + assert np.allclose(po_plg.contour_max.value, 1.99e-4) diff --git a/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.py b/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.py index 34e19145ff..9605de6849 100644 --- a/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.py +++ b/jdaviz/configs/specviz/plugins/unit_conversion/unit_conversion.py @@ -1,8 +1,10 @@ -import numpy as np from astropy import units as u +from glue.core.subset_group import GroupedSubset +from glue_jupyter.bqplot.image import BqplotImageView +import numpy as np from traitlets import List, Unicode, observe, Bool -from jdaviz.core.events import GlobalDisplayUnitChanged +from jdaviz.core.events import GlobalDisplayUnitChanged, AddDataToViewerMessage from jdaviz.core.registries import tray_registry from jdaviz.core.template_mixin import (PluginTemplateMixin, UnitSelectPluginComponent, SelectPluginComponent, PluginUserApi) @@ -92,6 +94,9 @@ def __init__(self, *args, **kwargs): self.spectrum_viewer.state.add_callback('y_display_unit', self._on_glue_y_display_unit_changed) + self.session.hub.subscribe(self, AddDataToViewerMessage, + handler=self._find_and_convert_contour_units) + self.spectral_unit = UnitSelectPluginComponent(self, items='spectral_unit_items', selected='spectral_unit_selected') @@ -269,6 +274,11 @@ def _on_flux_unit_changed(self, msg): else: self.flux_or_sb_selected = 'Surface Brightness' + # Always send a surface brightness unit to contours + if self.flux_or_sb_selected == 'Flux': + yunit = self._append_angle_correctly(yunit, self.angle_unit.selected) + self._find_and_convert_contour_units(yunit=yunit) + # for displaying message that PIXAR_SR = 1 if it is not found in the FITS header if ( len(self.app.data_collection) > 0 @@ -276,6 +286,32 @@ def _on_flux_unit_changed(self, msg): ): self.pixar_sr_exists = False + def _find_and_convert_contour_units(self, msg=None, yunit=None): + if not yunit: + yunit = self.sb_unit_selected + + if msg is not None: + viewers = [self.app.get_viewer(msg.viewer_reference)] + else: + viewers = self._app._viewer_store.values() + + if self.angle_unit_selected is None or self.angle_unit_selected == '': + # Can't do this before the plugin is initialized completely + return + + for viewer in viewers: + if not isinstance(viewer, BqplotImageView): + continue + for layer in viewer.state.layers: + + # DQ layer doesn't play nicely with this attribute + if "DQ" in layer.layer.label or isinstance(layer.layer, GroupedSubset): + continue + elif u.Unit(layer.layer.get_component("flux").units).physical_type != 'surface brightness': # noqa + continue + if hasattr(layer, 'attribute_display_unit'): + layer.attribute_display_unit = yunit + def _translate(self, flux_or_sb=None): # currently unsupported, can be supported with a scale factor if self.app.config == 'specviz': diff --git a/pyproject.toml b/pyproject.toml index db3d4bad9b..090f46100b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ dependencies = [ "bqplot>=0.12.37", "bqplot-image-gl>=1.4.11", "glue-core>=1.20.0", - "glue-jupyter>=0.21.0", + "glue-jupyter>=0.22.1", "echo>=0.5.0", "ipykernel>=6.19.4", "ipyvue>=1.6",