From f85ec71bebbc1a4d229a99bd3c9419a7aa9fe299 Mon Sep 17 00:00:00 2001 From: Pey Lian Lim <2090236+pllim@users.noreply.github.com> Date: Mon, 29 Jan 2024 22:30:40 -0500 Subject: [PATCH] Implement slice in output table and do not display slice for cubeviz 2D data, as requested. --- jdaviz/configs/cubeviz/plugins/slice/slice.py | 1 + .../plugins/tests/test_cubeviz_aperphot.py | 22 ++++++++-------- .../aper_phot_simple/aper_phot_simple.py | 25 +++++++++++++++---- .../aper_phot_simple/aper_phot_simple.vue | 2 +- jdaviz/core/events.py | 3 ++- 5 files changed, 35 insertions(+), 18 deletions(-) diff --git a/jdaviz/configs/cubeviz/plugins/slice/slice.py b/jdaviz/configs/cubeviz/plugins/slice/slice.py index 1b98e6458c..54b57246fe 100644 --- a/jdaviz/configs/cubeviz/plugins/slice/slice.py +++ b/jdaviz/configs/cubeviz/plugins/slice/slice.py @@ -220,6 +220,7 @@ def _on_slider_updated(self, event): self.hub.broadcast(SliceWavelengthUpdatedMessage(slice=value, wavelength=self.wavelength, + wavelength_unit=self.wavelength_unit, sender=self)) def vue_goto_first(self, *args): diff --git a/jdaviz/configs/cubeviz/plugins/tests/test_cubeviz_aperphot.py b/jdaviz/configs/cubeviz/plugins/tests/test_cubeviz_aperphot.py index 984f2525ec..2ac9d2a9df 100644 --- a/jdaviz/configs/cubeviz/plugins/tests/test_cubeviz_aperphot.py +++ b/jdaviz/configs/cubeviz/plugins/tests/test_cubeviz_aperphot.py @@ -1,5 +1,7 @@ +import numpy as np import pytest from astropy import units as u +from astropy.tests.helper import assert_quantity_allclose from astropy.utils.exceptions import AstropyUserWarning from numpy.testing import assert_allclose from regions import RectanglePixelRegion, PixCoord @@ -33,7 +35,7 @@ def test_cubeviz_aperphot_cube_orig_flux(cubeviz_helper, image_cube_hdu_obj_micr assert_allclose(row["sum"], 75 * flux_unit) # 3 (w) x 5 (h) x 5 (v) assert_allclose(row["sum_aper_area"], 15 * (u.pix * u.pix)) # 3 (w) x 5 (h) assert_allclose(row["mean"], 5 * flux_unit) - assert row["slice"] == 4 + assert_quantity_allclose(row["slice"], 4.894499866699333 * u.um) # Move slider and make sure it recomputes for a new slice automatically. cube_slice_plg = cubeviz_helper.plugins["Slice"]._obj @@ -50,27 +52,21 @@ def test_cubeviz_aperphot_cube_orig_flux(cubeviz_helper, image_cube_hdu_obj_micr assert_allclose(row["sum"], 15 * flux_unit) # 3 (w) x 5 (h) x 1 (v) assert_allclose(row["sum_aper_area"], 15 * (u.pix * u.pix)) # 3 (w) x 5 (h) assert_allclose(row["mean"], 1 * flux_unit) - assert row["slice"] == 0 - - -def test_cubeviz_aperphot_generated_2d_collapse(cubeviz_helper, image_cube_hdu_obj_microns): - cubeviz_helper.load_data(image_cube_hdu_obj_microns, data_label="test") - flux_unit = u.Unit("1E-17 erg*s^-1*cm^-2*Angstrom^-1") + assert_quantity_allclose(row["slice"], 4.8904998665093435 * u.um) + # We continue on with test_cubeviz_aperphot_generated_2d_collapse here + # because we want to make sure the result would append properly between 3D and 2D. collapse_plg = cubeviz_helper.plugins["Collapse"]._obj collapse_plg.vue_collapse() # Need this to make it available for photometry data drop-down. cubeviz_helper.app.add_data_to_viewer("uncert-viewer", "test[FLUX] collapsed") - aper = RectanglePixelRegion(center=PixCoord(x=1, y=2), width=3, height=5) - cubeviz_helper.load_regions(aper) - plg = cubeviz_helper.plugins["Aperture Photometry"]._obj plg.dataset_selected = "test[FLUX] collapsed" plg.aperture_selected = "Subset 1" plg.vue_do_aper_phot() - row = cubeviz_helper.get_aperture_photometry_results()[0] + row = cubeviz_helper.get_aperture_photometry_results()[2] # Basically, we should recover the input rectangle here. assert_allclose(row["xcenter"], 1 * u.pix) @@ -81,6 +77,7 @@ def test_cubeviz_aperphot_generated_2d_collapse(cubeviz_helper, image_cube_hdu_o assert_allclose(row["sum"], 540 * flux_unit) # 3 (w) x 5 (h) x 36 (v) assert_allclose(row["sum_aper_area"], 15 * (u.pix * u.pix)) # 3 (w) x 5 (h) assert_allclose(row["mean"], 36 * flux_unit) + assert np.isnan(row["slice"]) def test_cubeviz_aperphot_generated_2d_moment(cubeviz_helper, image_cube_hdu_obj_microns): @@ -111,6 +108,7 @@ def test_cubeviz_aperphot_generated_2d_moment(cubeviz_helper, image_cube_hdu_obj assert_allclose(row["sum"], 540 * flux_unit) # 3 (w) x 5 (h) x 36 (v) assert_allclose(row["sum_aper_area"], 15 * (u.pix * u.pix)) # 3 (w) x 5 (h) assert_allclose(row["mean"], 36 * flux_unit) + assert np.isnan(row["slice"]) # Moment 1 has no compatible unit, so should not be available for photometry. moment_plg.n_moment = 1 @@ -152,6 +150,7 @@ def test_cubeviz_aperphot_generated_3d_gaussian_smooth(cubeviz_helper, image_cub assert_allclose(row["sum"], 48.54973 * flux_unit) # 3 (w) x 5 (h) x <5 (v) assert_allclose(row["sum_aper_area"], 15 * (u.pix * u.pix)) # 3 (w) x 5 (h) assert_allclose(row["mean"], 3.236648941040039 * flux_unit) + assert_quantity_allclose(row["slice"], 4.894499866699333 * u.um) def test_cubeviz_aperphot_cube_orig_flux_mjysr(cubeviz_helper, spectrum1d_cube_custom_fluxunit): @@ -182,3 +181,4 @@ def test_cubeviz_aperphot_cube_orig_flux_mjysr(cubeviz_helper, spectrum1d_cube_c assert_allclose(row["pixarea_tot"], 2.350443053909789e-13 * u.sr) assert_allclose(row["aperture_sum_mag"], 23.72476627732448 * u.mag) assert_allclose(row["mean"], 5 * (u.MJy / u.sr)) + assert_quantity_allclose(row["slice"], 0.46236 * u.um) diff --git a/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.py b/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.py index a3ff328bfa..307b31a8fd 100644 --- a/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.py +++ b/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.py @@ -70,7 +70,9 @@ class SimpleAperturePhotometry(PluginTemplateMixin, ApertureSubsetSelectMixin, fit_radial_profile = Bool(False).tag(sync=True) fit_results = List().tag(sync=True) - cube_slice = Any(0).tag(sync=True) # Cubeviz only + # Cubeviz only + cube_slice = Any(0).tag(sync=True) + is_cube = Bool(False).tag(sync=True) icon_radialtocheck = Unicode(read_icon(os.path.join(ICON_DIR, 'radialtocheck.svg'), 'svg+xml')).tag(sync=True) # noqa icon_checktoradial = Unicode(read_icon(os.path.join(ICON_DIR, 'checktoradial.svg'), 'svg+xml')).tag(sync=True) # noqa @@ -139,6 +141,17 @@ def _on_slice_changed(self, msg): if self.config != "cubeviz": return self.cube_slice = msg.slice + self._cube_wave = u.Quantity(msg.wavelength, msg.wavelength_unit) + + @observe("dataset_selected") + def _on_dataset_selected_changed(self, event={}): + if self.config != "cubeviz": + return + # self.dataset might not exist when app is setting itself up. + if hasattr(self, "dataset") and self.dataset.selected_dc_item.ndim > 2: + self.is_cube = True + else: + self.is_cube = False def _get_defaults_from_metadata(self, dataset=None): defaults = {} @@ -439,9 +452,7 @@ def calculate_photometry(self, dataset=None, aperture=None, background=None, if hasattr(reg, 'to_pixel'): sky_center = reg.center if self.config == "cubeviz" and data.ndim > 2: - cube_slice_plg = self.app._jdaviz_helper.plugins["Slice"]._obj - ycenter, xcenter = w.world_to_pixel( - u.Quantity(cube_slice_plg.wavelength, cube_slice_plg.wavelength_unit), sky_center)[1] # noqa: E501 + ycenter, xcenter = w.world_to_pixel(self._cube_wave, sky_center)[1] else: # "imviz" xcenter, ycenter = w.world_to_pixel(sky_center) else: @@ -528,7 +539,11 @@ def calculate_photometry(self, dataset=None, aperture=None, background=None, indexes=[1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 18, 18, 18]) if self.config == "cubeviz": - phot_table.add_column(int(self.cube_slice), name="slice", index=29) + if data.ndim > 2: + slice_val = self._cube_wave + else: + slice_val = u.Quantity(np.nan, self._cube_wave.unit) + phot_table.add_column(slice_val, name="slice", index=29) if add_to_table: try: diff --git a/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.vue b/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.vue index 023c180cc6..bbac067cd9 100644 --- a/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.vue +++ b/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.vue @@ -32,7 +32,7 @@ hint="Select the data for photometry." /> -
+