Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable contour unit conversion #3149

Merged
merged 14 commits into from
Aug 23, 2024
2 changes: 1 addition & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import numpy as np
from astropy import units as u
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)
Expand Down Expand Up @@ -92,6 +93,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')
Expand Down Expand Up @@ -269,13 +273,41 @@ 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)

Comment on lines +277 to +280
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if _find_and_convert_contour_units just observed sb_unit_selected which already handles this logic?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we discussed that unit conversion probably needs some code moving soon anyways, so I'm fine deferring this until then

# for displaying message that PIXAR_SR = 1 if it is not found in the FITS header
if (
len(self.app.data_collection) > 0
and not self.app.data_collection[0].meta.get('PIXAR_SR')
):
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 = [viewer._obj for _, viewer in self._app._jdaviz_helper.viewers.items()]

rosteen marked this conversation as resolved.
Show resolved Hide resolved
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:
continue
if hasattr(layer, 'attribute_display_unit'):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing masks don't either.... could we instead check the units on the layer to make sure they're surface brightness? Eventually we might need to generalize this method to also set display units for images in velocity, etc (from moment maps), but that isn't enabled in unit conversion yet, so is probably safe to ignore.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a second check below for surface brightness - we know DQ doesn't work, so might as well do the fast check first for that still?

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':
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Loading