Skip to content

Commit

Permalink
Merge pull request #2486 from meeseeksmachine/auto-backport-of-pr-243…
Browse files Browse the repository at this point in the history
…1-on-v3.7.x

Backport PR #2431 on branch v3.7.x (BUG: Moment map retains WCS on write)
  • Loading branch information
pllim authored Sep 27, 2023
2 parents c049540 + 84061df commit fc17771
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Bug Fixes
Cubeviz
^^^^^^^

- Fixed moment map losing WCS when being written out to FITS file. [#2431]

Imviz
^^^^^

Expand Down
8 changes: 6 additions & 2 deletions jdaviz/configs/cubeviz/plugins/moment_maps/moment_maps.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from astropy.nddata import CCDData

from traitlets import Unicode, Bool, observe
from specutils import Spectrum1D, manipulation, analysis
from specutils import manipulation, analysis

from jdaviz.core.custom_traitlets import IntHandleEmpty
from jdaviz.core.events import SnackbarMessage
Expand Down Expand Up @@ -101,7 +101,11 @@ def calculate_moment(self, add_data=True):
Whether to add the resulting data object to the app according to ``add_results``.
"""
# Retrieve the data cube and slice out desired region, if specified
cube = self.dataset.get_object(cls=Spectrum1D, statistic=None)
if "_orig_spec" in self.dataset.selected_obj.meta:
cube = self.dataset.selected_obj.meta["_orig_spec"]
else:
cube = self.dataset.selected_obj

spec_min, spec_max = self.spectral_subset.selected_min_max(cube)
slab = manipulation.spectral_slab(cube, spec_min, spec_max)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import os
import warnings
from pathlib import Path

import pytest
from astropy.io import fits
from astropy.nddata import CCDData
from astropy.wcs import WCS
from astroquery.mast import Observations
from numpy.testing import assert_allclose

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


@pytest.mark.filterwarnings('ignore:No observer defined on WCS')
def test_moment_calculation(cubeviz_helper, spectrum1d_cube, tmpdir):
dc = cubeviz_helper.app.data_collection
cubeviz_helper.load_data(spectrum1d_cube, data_label='test')
with warnings.catch_warnings():
warnings.filterwarnings("ignore", message="No observer defined on WCS.*")
cubeviz_helper.load_data(spectrum1d_cube, data_label='test')
flux_viewer = cubeviz_helper.app.get_viewer(cubeviz_helper._default_flux_viewer_reference_name)

# Since we are not really displaying, need this to trigger GUI stuff.
Expand Down Expand Up @@ -95,7 +99,6 @@ def test_moment_calculation(cubeviz_helper, spectrum1d_cube, tmpdir):
"204.9998877673 27.0001000000 (deg)")


@pytest.mark.filterwarnings('ignore:No observer defined on WCS')
def test_write_momentmap(cubeviz_helper, spectrum1d_cube, tmp_path):
''' Test writing a moment map out to a FITS file on disk '''

Expand All @@ -105,7 +108,9 @@ def test_write_momentmap(cubeviz_helper, spectrum1d_cube, tmp_path):
existing_sentinel_text = "This is a simulated, existing file on disk"
test_file.write_text(existing_sentinel_text)

cubeviz_helper.load_data(spectrum1d_cube, data_label='test')
with warnings.catch_warnings():
warnings.filterwarnings("ignore", message="No observer defined on WCS.*")
cubeviz_helper.load_data(spectrum1d_cube, data_label='test')
plugin = cubeviz_helper.plugins['Moment Maps']
moment = plugin.calculate_moment()

Expand Down Expand Up @@ -135,3 +140,24 @@ def test_write_momentmap(cubeviz_helper, spectrum1d_cube, tmp_path):
plugin._obj.filename = "fake_path/test_file.fits"
with pytest.raises(ValueError, match="Invalid path"):
plugin._obj.vue_save_as_fits()


@pytest.mark.remote_data
def test_momentmap_nirspec_prism(cubeviz_helper, tmp_path):
uri = "mast:jwst/product/jw02732-o003_t002_nirspec_prism-clear_s3d.fits"
download_path = str(tmp_path / Path(uri).name)
Observations.download_file(uri, local_path=download_path)

with warnings.catch_warnings():
warnings.simplefilter("ignore")
cubeviz_helper.load_data(download_path)
plugin = cubeviz_helper.plugins['Moment Maps']
plugin.calculate_moment()
assert isinstance(plugin._obj.moment.wcs, WCS)

# Because cube axes order is re-arranged by specutils on load, this gets confusing.
# There is a swapaxes within Moment Map WCS calculation.
sky_moment = plugin._obj.moment.wcs.pixel_to_world(50, 30)
sky_cube = cubeviz_helper.app.data_collection[0].meta["_orig_spec"].wcs.celestial.pixel_to_world(30, 50) # noqa: E501
assert_allclose((sky_moment.ra.deg, sky_moment.dec.deg),
(sky_cube.ra.deg, sky_cube.dec.deg))

0 comments on commit fc17771

Please sign in to comment.