diff --git a/jdaviz/configs/imviz/helper.py b/jdaviz/configs/imviz/helper.py index 65fd8418f4..b1d293bbea 100644 --- a/jdaviz/configs/imviz/helper.py +++ b/jdaviz/configs/imviz/helper.py @@ -220,7 +220,7 @@ def zoom_level(self): """ viewer = self.app.get_viewer("viewer-1") - if viewer.shape is None: + if viewer.shape is None: # pragma: no cover raise ValueError('Viewer is still loading, try again later') screenx = viewer.shape[1] @@ -240,7 +240,7 @@ def zoom_level(self, val): viewer = self.app.get_viewer("viewer-1") image = viewer.state.reference_data if (image is None or viewer.shape is None or - viewer.state.x_att is None or viewer.state.y_att is None): + viewer.state.x_att is None or viewer.state.y_att is None): # pragma: no cover return # Zoom on X and Y will auto-adjust. diff --git a/jdaviz/configs/imviz/tests/test_astrowidgets_api.py b/jdaviz/configs/imviz/tests/test_astrowidgets_api.py index 7c534acea8..f5f8331301 100644 --- a/jdaviz/configs/imviz/tests/test_astrowidgets_api.py +++ b/jdaviz/configs/imviz/tests/test_astrowidgets_api.py @@ -65,6 +65,59 @@ def test_center_offset_sky(self): self.imviz.offset_by(dsky, dsky) +class TestZoom(BaseImviz_WCS_NoWCS): + + @pytest.mark.parametrize('val', (0, -0.1, 'foo', [1, 2])) + def test_invalid_zoom_level(self, val): + with pytest.raises(ValueError, match='Unsupported zoom level'): + self.imviz.zoom_level = val + + def test_invalid_zoom(self): + with pytest.raises(ValueError, match='zoom only accepts int or float'): + self.imviz.zoom('fit') + + def assert_zoom_results(self, zoom_level, x_min, x_max, y_min, y_max, dpix): + assert_allclose(self.imviz.zoom_level, zoom_level) + assert_allclose((self.viewer.state.x_min, self.viewer.state.x_max, + self.viewer.state.y_min, self.viewer.state.y_max), + (x_min + dpix, x_max + dpix, + y_min + dpix, y_max + dpix)) + + @pytest.mark.parametrize('is_offcenter', (False, True)) + def test_zoom(self, is_offcenter): + if is_offcenter: + self.imviz.center_on((0, 0)) + dpix = -4.5 + else: + self.imviz.center_on((4.5, 4.5)) + dpix = 0 + + self.assert_zoom_results(10, -0.5, 9.5, -0.5, 9.5, dpix) + + # NOTE: Not sure why X/Y min/max not exactly the same as aspect ratio 1 + self.imviz.zoom_level = 1 + self.assert_zoom_results(1, -46, 54, -45.5, 54.5, dpix) + + self.imviz.zoom_level = 2 + self.assert_zoom_results(2, -21.5, 28.5, -20.5, 29.5, dpix) + + self.imviz.zoom(2) + self.assert_zoom_results(4, -9.5, 15.5, -8.0, 17.0, dpix) + + self.imviz.zoom(0.5) + self.assert_zoom_results(2, -22.5, 27.5, -20.5, 29.5, dpix) + + self.imviz.zoom_level = 0.5 + self.assert_zoom_results(0.5, -98, 102, -95.5, 104.5, dpix) + + # This fits the whole image on screen, regardless. + # NOTE: But somehow Y min/max auto-adjust does not work properly + # in the unit test when off-center. Works in notebook though. + if not is_offcenter: + self.imviz.zoom_level = 'fit' + self.assert_zoom_results(10, -0.5, 9.5, -0.5, 9.5, 0) + + class TestMarkers(BaseImviz_WCS_NoWCS): def test_invalid_markers(self): diff --git a/jdaviz/configs/imviz/tests/utils.py b/jdaviz/configs/imviz/tests/utils.py index 28cf0531ad..a69bb386a8 100644 --- a/jdaviz/configs/imviz/tests/utils.py +++ b/jdaviz/configs/imviz/tests/utils.py @@ -1,38 +1,42 @@ -import numpy as np -import pytest -from astropy.io import fits -from astropy.wcs import WCS - -__all__ = ['BaseImviz_WCS_NoWCS'] - - -class BaseImviz_WCS_NoWCS: - @pytest.fixture(autouse=True) - def setup_class(self, imviz_app): - hdu = fits.ImageHDU(np.zeros((10, 10)), name='SCI') - - # Apply some celestial WCS from - # https://learn.astropy.org/rst-tutorials/celestial_coords1.html - hdu.header.update({'CTYPE1': 'RA---TAN', - 'CUNIT1': 'deg', - 'CDELT1': -0.0002777777778, - 'CRPIX1': 1, - 'CRVAL1': 337.5202808, - 'NAXIS1': 10, - 'CTYPE2': 'DEC--TAN', - 'CUNIT2': 'deg', - 'CDELT2': 0.0002777777778, - 'CRPIX2': 1, - 'CRVAL2': -20.833333059999998, - 'NAXIS2': 10}) - - # Data with WCS - imviz_app.load_data(hdu, data_label='has_wcs') - - # Data without WCS - imviz_app.load_data(hdu, data_label='no_wcs') - imviz_app.app.data_collection[1].coords = None - - self.wcs = WCS(hdu.header) - self.imviz = imviz_app - self.viewer = imviz_app.app.get_viewer('viewer-1') +import numpy as np +import pytest +from astropy.io import fits +from astropy.wcs import WCS + +__all__ = ['BaseImviz_WCS_NoWCS'] + + +class BaseImviz_WCS_NoWCS: + @pytest.fixture(autouse=True) + def setup_class(self, imviz_app): + hdu = fits.ImageHDU(np.zeros((10, 10)), name='SCI') + + # Apply some celestial WCS from + # https://learn.astropy.org/rst-tutorials/celestial_coords1.html + hdu.header.update({'CTYPE1': 'RA---TAN', + 'CUNIT1': 'deg', + 'CDELT1': -0.0002777777778, + 'CRPIX1': 1, + 'CRVAL1': 337.5202808, + 'NAXIS1': 10, + 'CTYPE2': 'DEC--TAN', + 'CUNIT2': 'deg', + 'CDELT2': 0.0002777777778, + 'CRPIX2': 1, + 'CRVAL2': -20.833333059999998, + 'NAXIS2': 10}) + + # Data with WCS + imviz_app.load_data(hdu, data_label='has_wcs') + + # Data without WCS + imviz_app.load_data(hdu, data_label='no_wcs') + imviz_app.app.data_collection[1].coords = None + + self.wcs = WCS(hdu.header) + self.imviz = imviz_app + self.viewer = imviz_app.app.get_viewer('viewer-1') + + # Since we are not really displaying, need this to test zoom. + self.viewer.shape = (100, 100) + self.viewer.state._set_axes_aspect_ratio(1)