Skip to content

Commit

Permalink
Moment map compat with specutils dev
Browse files Browse the repository at this point in the history
  • Loading branch information
pllim committed Jun 3, 2024
1 parent 4c17521 commit ea71dfc
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 18 deletions.
12 changes: 9 additions & 3 deletions jdaviz/configs/cubeviz/plugins/moment_maps/moment_maps.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import os
from pathlib import Path

import numpy as np
import specutils
from astropy import units as u
from astropy.nddata import CCDData
import numpy as np

from astropy.utils import minversion
from traitlets import Bool, List, Unicode, observe
from specutils import manipulation, analysis, Spectrum1D

Expand All @@ -24,6 +25,7 @@

__all__ = ['MomentMap']

SPECUTILS_LT_1_15_1 = not minversion(specutils, "1.15.1.dev")

spaxel = u.def_unit('spaxel', 1 * u.Unit(""))
u.add_enabled_units([spaxel])
Expand Down Expand Up @@ -350,7 +352,11 @@ def calculate_moment(self, add_data=True):

# convert unit string to u.Unit so moment map data can be converted
flux_or_sb_display_unit = u.Unit(flux_sb_unit)
self.moment = self.moment.to(flux_or_sb_display_unit)
if SPECUTILS_LT_1_15_1:
moment_new_unit = flux_or_sb_display_unit
else:
moment_new_unit = flux_or_sb_display_unit * self.spectrum_viewer.state.x_display_unit # noqa: E501

Check warning on line 358 in jdaviz/configs/cubeviz/plugins/moment_maps/moment_maps.py

View check run for this annotation

Codecov / codecov/patch

jdaviz/configs/cubeviz/plugins/moment_maps/moment_maps.py#L358

Added line #L358 was not covered by tests
self.moment = self.moment.to(moment_new_unit)

# Reattach the WCS so we can load the result
self.moment = CCDData(self.moment, wcs=data_wcs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
import warnings
from pathlib import Path

import numpy as np
import pytest
from astropy import units as u
from astropy.io import fits
from astropy.nddata import CCDData
from astropy.wcs import WCS
import astropy.units as u
import numpy as np
from numpy.testing import assert_allclose
from glue.core.roi import XRangeROI
from numpy.testing import assert_allclose

from jdaviz.configs.cubeviz.plugins.moment_maps.moment_maps import SPECUTILS_LT_1_15_1


def test_user_api(cubeviz_helper, spectrum1d_cube):
Expand Down Expand Up @@ -49,6 +51,13 @@ def test_user_api(cubeviz_helper, spectrum1d_cube):


def test_moment_calculation(cubeviz_helper, spectrum1d_cube, tmp_path):
if SPECUTILS_LT_1_15_1:
moment_unit = "Jy"
moment_value_str = "+8.00000e+00"
else:
moment_unit = "Jy m"
moment_value_str = "+6.40166e-10"

dc = cubeviz_helper.app.data_collection
with warnings.catch_warnings():
warnings.filterwarnings("ignore", message="No observer defined on WCS.*")
Expand Down Expand Up @@ -107,10 +116,11 @@ def test_moment_calculation(cubeviz_helper, spectrum1d_cube, tmp_path):
label_mouseover._viewer_mouse_event(flux_viewer, {'event': 'mousemove',
'domain': {'x': 0, 'y': 0}})

# Slice 0 has 8 pixels, this is Slice 1 # noqa
assert label_mouseover.as_text() == ("Pixel x=00.0 y=00.0 Value +8.00000e+00 Jy",
"World 13h39m59.9731s +27d00m00.3600s (ICRS)",
"204.9998877673 27.0001000000 (deg)")
# Slice 0 has 8 pixels, this is Slice 1
assert label_mouseover.as_text() == (
f"Pixel x=00.0 y=00.0 Value {moment_value_str} {moment_unit}",
"World 13h39m59.9731s +27d00m00.3600s (ICRS)",
"204.9998877673 27.0001000000 (deg)")

assert mm._obj.filename == 'moment0_test_FLUX.fits' # Auto-populated on calculate.
mm._obj.filename = str(tmp_path / mm._obj.filename) # But we want it in tmp_path for testing.
Expand All @@ -136,9 +146,10 @@ def test_moment_calculation(cubeviz_helper, spectrum1d_cube, tmp_path):
# Coordinate display should be unaffected.
label_mouseover._viewer_mouse_event(flux_viewer, {'event': 'mousemove',
'domain': {'x': 0, 'y': 0}})
assert label_mouseover.as_text() == ("Pixel x=00.0 y=00.0 Value +8.00000e+00 Jy",
"World 13h39m59.9731s +27d00m00.3600s (ICRS)",
"204.9998877673 27.0001000000 (deg)")
assert label_mouseover.as_text() == (
f"Pixel x=00.0 y=00.0 Value {moment_value_str} {moment_unit}",
"World 13h39m59.9731s +27d00m00.3600s (ICRS)",
"204.9998877673 27.0001000000 (deg)")


def test_moment_velocity_calculation(cubeviz_helper, spectrum1d_cube):
Expand Down Expand Up @@ -279,6 +290,10 @@ def test_momentmap_nirspec_prism(cubeviz_helper, tmp_path):


def test_correct_output_flux_or_sb_units(cubeviz_helper, spectrum1d_cube_custom_fluxunit):
if SPECUTILS_LT_1_15_1:
moment_unit = "Jy / sr"
else:
moment_unit = "Jy m / sr"

# test that the output unit labels in the moment map plugin reflect any
# changes made in the unit conversion plugin.
Expand All @@ -304,7 +319,7 @@ def test_correct_output_flux_or_sb_units(cubeviz_helper, spectrum1d_cube_custom_

# check that calculated moment has the correct units
mm.calculate_moment()
assert mm.moment.unit == 'MJy / sr'
assert mm.moment.unit == f'M{moment_unit}'

# now change surface brightness units in the unit conversion plugin
uc = cubeviz_helper.plugins["Unit Conversion"]
Expand All @@ -318,4 +333,4 @@ def test_correct_output_flux_or_sb_units(cubeviz_helper, spectrum1d_cube_custom_

# and that calculated moment has the correct units
mm.calculate_moment()
assert mm.moment.unit == 'Jy / sr'
assert mm.moment.unit == moment_unit
13 changes: 11 additions & 2 deletions jdaviz/configs/cubeviz/plugins/tests/test_cubeviz_aperphot.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from numpy.testing import assert_allclose
from regions import RectanglePixelRegion, PixCoord

from jdaviz.configs.cubeviz.plugins.moment_maps.moment_maps import SPECUTILS_LT_1_15_1


def test_cubeviz_aperphot_cube_orig_flux(cubeviz_helper, image_cube_hdu_obj_microns):
cubeviz_helper.load_data(image_cube_hdu_obj_microns, data_label="test")
Expand Down Expand Up @@ -100,14 +102,21 @@ def test_cubeviz_aperphot_generated_2d_moment(cubeviz_helper, image_cube_hdu_obj
row = cubeviz_helper.get_aperture_photometry_results()[0]

# Basically, we should recover the input rectangle here.
if SPECUTILS_LT_1_15_1:
moment_sum = 540 * flux_unit
moment_mean = 36 * flux_unit
else:
moment_unit = flux_unit * u.um
moment_sum = 0.54 * moment_unit
moment_mean = 0.036 * moment_unit
assert_allclose(row["xcenter"], 1 * u.pix)
assert_allclose(row["ycenter"], 2 * u.pix)
sky = row["sky_center"]
assert_allclose(sky.ra.deg, 205.43985906934287)
assert_allclose(sky.dec.deg, 27.003490103642033)
assert_allclose(row["sum"], 540 * flux_unit) # 3 (w) x 5 (h) x 36 (v)
assert_allclose(row["sum"], moment_sum) # 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_allclose(row["mean"], moment_mean)
assert np.isnan(row["slice_wave"])

# Moment 1 has no compatible unit, so should not be available for photometry.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ def valid_cubeviz_datasets(data):
acceptable_types = ['spectral flux density wav',
'photon flux density wav',
'spectral flux density',
'photon flux density']
'photon flux density',
'energy flux'] # Moment map 0
return ((data.ndim in (2, 3)) and
((img_unit == (u.MJy / u.sr)) or
(img_unit.physical_type in acceptable_types)))
Expand Down

0 comments on commit ea71dfc

Please sign in to comment.