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

BUG: Gaussian smooth plugin incompatible with unreleased upstream package #821

Closed
pllim opened this issue Aug 30, 2021 · 4 comments · Fixed by glue-viz/glue-astronomy#40
Closed
Labels
bug Something isn't working Upstream fix required

Comments

@pllim
Copy link
Contributor

pllim commented Aug 30, 2021

This started happening over the weekend in dev job, so must have been some recent unreleased upstream changes (probably glue-viz/glue-astronomy#36). We need to fix this incompatibility before it is too late.

Example log: https://github.com/spacetelescope/jdaviz/runs/3460019342?check_suite_focus=true

Package versions: 
Numpy: 1.22.0.dev0+949.ga90677a0b
Scipy: 1.7.1
Matplotlib: 3.4.3
h5py: 3.4.0
Pandas: 1.3.2
astropy: 5.0.dev702+g5942ac3a2
pyyaml: 5.4.1
scikit-image: 0.18.3
specutils: 1.3.1
spectral-cube: 0.5.1.dev215+gc3a9ece
asteval: 0.9.25
click: 8.0.1
echo: 0.5
idna: 2.10
traitlets: 5.0.5
bqplot: 0.12.30
bqplot-image-gl: 1.4.4
glue-core: 1.2.1
glue-jupyter: 0.8
glue-astronomy: 0.3.dev6+g03e439a
ipyvue: 1.5.0
ipyvuetify: 1.8.1
ipysplitpanes: 0.2.0
ipygoldenlayout: 0.4.0
voila: 0.2.10
vispy: 0.8.1
gwcs: 0.16.2a1.dev31+g0f3d750
asdf: 2.9.0.dev11+g9e64fbe

______________________ test_linking_after_spectral_smooth ______________________

spectral_cube_wcs = WCS Keywords

Number of WCS axes: 3
CTYPE : 'RA---TAN'  'DEC--TAN'  'FREQ'  
CRVAL : 0.0  0.0  0.0  
CRPIX : 0.0  0.0 ...0  0.0  
PC2_1 PC2_2 PC2_3  : 0.0  1.0  0.0  
PC3_1 PC3_2 PC3_3  : 0.0  0.0  1.0  
CDELT : 1.0  1.0  1.0  
NAXIS : 0  0

    def test_linking_after_spectral_smooth(spectral_cube_wcs):
    
        app = Application(configuration="cubeviz")
        dc = app.data_collection
        dc.append(Data(x=np.ones((3, 4, 5)), label='test', coords=spectral_cube_wcs))
    
        gs = GaussianSmooth(app=app)
    
        gs._on_data_selected({'new': 'test'})
        gs.stddev = '3.2'
>       gs.vue_spectral_smooth()

../../.tox/py38-test-devdeps/lib/python3.8/site-packages/jdaviz/configs/default/plugins/gaussian_smooth/tests/test_gaussian_smooth.py:20: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../.tox/py38-test-devdeps/lib/python3.8/site-packages/jdaviz/configs/default/plugins/gaussian_smooth/gaussian_smooth.py:64: in vue_spectral_smooth
    spec = self._selected_data.get_object(cls=Spectrum1D)
../../.tox/py38-test-devdeps/lib/python3.8/site-packages/glue/core/data.py:289: in get_object
    return handler.to_object(self, **kwargs)
../../.tox/py38-test-devdeps/lib/python3.8/site-packages/glue_astronomy/translators/spectrum1d.py:168: in to_object
    return Spectrum1D(**data_kwargs, **kwargs)
../../.tox/py38-test-devdeps/lib/python3.8/site-packages/specutils/spectra/spectrum1d.py:252: in __init__
    spec_axis = self.wcs.pixel_to_world(np.arange(self.flux.shape[-1]))
../../.tox/py38-test-devdeps/lib/python3.8/site-packages/astropy/wcs/wcsapi/high_level_api.py:239: in pixel_to_world
    world = self.low_level_wcs.pixel_to_world_values(*pixel_arrays)
../../.tox/py38-test-devdeps/lib/python3.8/site-packages/astropy/wcs/wcsapi/fitswcs.py:322: in pixel_to_world_values
    world = self.all_pix2world(*pixel_arrays, 0)
../../.tox/py38-test-devdeps/lib/python3.8/site-packages/astropy/wcs/wcs.py:1347: in all_pix2world
    return self._array_converter(
../../.tox/py38-test-devdeps/lib/python3.8/site-packages/astropy/wcs/wcs.py:1323: in _array_converter
    return _return_list_of_arrays([xy], origin)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

axes = [array([0, 1, 2])], origin = 0

    def _return_list_of_arrays(axes, origin):
        if any([x.size == 0 for x in axes]):
            return axes
    
        try:
            axes = np.broadcast_arrays(*axes)
        except ValueError:
            raise ValueError(
                "Coordinate arrays are not broadcastable to each other")
    
        xy = np.hstack([x.reshape((x.size, 1)) for x in axes])
    
        if ra_dec_order and sky == 'input':
            xy = self._denormalize_sky(xy)
>       output = func(xy, origin)
E       ValueError: Wrong number of dimensions in input array.  Expected 2.

../../.tox/py38-test-devdeps/lib/python3.8/site-packages/astropy/wcs/wcs.py:1291: ValueError
----------------------------- Captured stderr call -----------------------------
WARNING:specutils.spectra.spectrum1d:Input WCS indicates that the spectral axis is not last. Reshaping arrays to put spectral axis last.
------------------------------ Captured log call -------------------------------
WARNING  specutils.spectra.spectrum1d:spectrum1d.py:188 Input WCS indicates that the spectral axis is not last. Reshaping arrays to put spectral axis last.
@pllim
Copy link
Contributor Author

pllim commented Sep 2, 2021

Minimally reproducible code snippet as follows. Must have dev version of glue-astronomy installed:

import numpy as np
from astropy.wcs import WCS
from glue.config import data_translator
from glue.core import Data
from specutils import Spectrum1D

# This indirectly enables the necessary data translator
from jdaviz.configs.default.plugins.gaussian_smooth.gaussian_smooth import GaussianSmooth

wcs = WCS(naxis=3)
wcs.wcs.ctype = 'RA---TAN', 'DEC--TAN', 'FREQ'
wcs.wcs.set()
data = Data(x=np.ones((3, 4, 5)), label='test', coords=wcs)
handler, _ = data_translator.get_handler_for(Spectrum1D)
spec = data.get_object(cls=Spectrum1D)  # See traceback
.../glue/core/data.py in get_object(self, cls, **kwargs)
    287         handler, _ = data_translator.get_handler_for(cls)
    288
--> 289         return handler.to_object(self, **kwargs)
    290
    291     @property

.../glue_astronomy/translators/spectrum1d.py in to_object(self, data_or_subset, attribute, statistic)
    168         return Spectrum1D(**data_kwargs, **kwargs)

.../specutils/spectra/spectrum1d.py in __init__(self, flux, spectral_axis, wcs, velocity_convention, rest_value, redshift, radial_velocity, bin_specification, **kwargs)
    250             # If spectral_axis wasn't provided, set _spectral_axis based on
    251             # the WCS
--> 252             spec_axis = self.wcs.pixel_to_world(np.arange(self.flux.shape[-1]))
    253
    254             if spec_axis.unit.is_equivalent(u.one):

.../astropy/wcs/wcsapi/high_level_api.py in pixel_to_world(self, *pixel_arrays)
    237
    238         # Compute the world coordinate values
--> 239         world = self.low_level_wcs.pixel_to_world_values(*pixel_arrays)
    240
    241         if self.world_n_dim == 1:

.../astropy/wcs/wcsapi/fitswcs.py in pixel_to_world_values(self, *pixel_arrays)
    320
    321     def pixel_to_world_values(self, *pixel_arrays):
--> 322         world = self.all_pix2world(*pixel_arrays, 0)
    323         return world[0] if self.world_n_dim == 1 else tuple(world)
    324

..../astropy/wcs/wcs.py in all_pix2world(self, *args, **kwargs)
   1345
   1346     def all_pix2world(self, *args, **kwargs):
-> 1347         return self._array_converter(
   1348             self._all_pix2world, 'output', *args, **kwargs)
   1349     all_pix2world.__doc__ = """

.../astropy/wcs/wcs.py in _array_converter(self, func, sky, ra_dec_order, *args)
   1321                     "(coords[N][{}], origin)".format(self.naxis))
   1322             if xy.shape == () or len(xy.shape) == 1:
-> 1323                 return _return_list_of_arrays([xy], origin)
   1324             return _return_single_array(xy, origin)
   1325

.../astropy/wcs/wcs.py in _return_list_of_arrays(axes, origin)
   1289             if ra_dec_order and sky == 'input':
   1290                 xy = self._denormalize_sky(xy)
-> 1291             output = func(xy, origin)
   1292             if ra_dec_order and sky == 'output':
   1293                 output = self._normalize_sky(output)

ValueError: Wrong number of dimensions in input array.  Expected 2.

which narrows down to:

from astropy import units as u

flux = np.ones((3, 4, 5)) * u.dimensionless_unscaled
spec = Spectrum1D(flux=flux, mask=None, wcs=wcs)  # traceback

which narrows down to:

wcs.pixel_to_world([0, 1, 2, 3, 4])  # traceback

@pllim
Copy link
Contributor Author

pllim commented Sep 2, 2021

I traced this error to statistic set to None instead of 'mean'. See glue-viz/glue-astronomy#40

@astrofrog
Copy link
Collaborator

I think the change of default of None in glue-astronomy actually makes sense, however the exception we are running into here is a bug in specutils: astropy/specutils#857 - so for now I think reverting the default in glue-astronomy makes sense.

@pllim
Copy link
Contributor Author

pllim commented Sep 3, 2021

Thanks! I opened glue-viz/glue-astronomy#43 upstream as a follow-up. I don't think there is anything Jdaviz can do in this matter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Upstream fix required
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants