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

TST: SpectralGWCS failures using specutils 1.3.1 and glue-astronomy dev #837

Closed
pllim opened this issue Sep 3, 2021 · 6 comments · Fixed by glue-viz/glue-astronomy#45 or #733
Closed
Labels
bug Something isn't working 🔥 Critical mosviz specviz

Comments

@pllim
Copy link
Contributor

pllim commented Sep 3, 2021

Example log: https://github.com/spacetelescope/jdaviz/runs/3508608981?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.dev786+g0fd7ae818
pyyaml: 5.4.1
scikit-image: 0.18.3
specutils: 1.3.1
spectral-cube: 0.5.1.dev227+g8d07dc9
asteval: 0.9.25
click: 8.0.1
echo: 0.5
idna: 2.10
traitlets: 5.1.0
bqplot: 0.12.30
bqplot-image-gl: 1.4.4
glue-core: 1.2.1
glue-jupyter: 0.8
glue-astronomy: 0.3.dev15+g312e959
ipyvue: 1.5.0
ipyvuetify: 1.8.1
ipysplitpanes: 0.2.0
ipygoldenlayout: 0.4.0
voila: 0.2.11
vispy: 0.8.1
gwcs: 0.16.2a1.dev32+g464e55f
asdf: 2.9.0.dev11+g9e64fbe
____________________________ test_viewer_axis_link _____________________________

mosviz_app = <jdaviz.configs.mosviz.helper.MosViz object at 0x7f623bc65e20>
spectrum1d = <Spectrum1D(flux=<Quantity [ 9.29172181, 11.92673337, 13.19606653, ..., 16.03141721,
           15.67835212, 17.780023...tralAxis [6000.        , 6001.95503421, 6003.91006843, ..., 7996.08993157,
   7998.04496579, 8000.        ] Angstrom>)>
spectrum2d = SpectralCube with shape=(15, 1, 1024):
 n_x:   1024  type_x: RA---TAN  unit_x: deg    range:     0.999898 deg:   86.79...:     0.055866 deg:    0.999746 deg
 n_s:     15  type_s: WAVE      unit_s: m      range:        1.000 m:      15.000 m

    def test_viewer_axis_link(mosviz_app, spectrum1d, spectrum2d):
        label1d = "Test 1D Spectrum"
        mosviz_app.load_1d_spectra(spectrum1d, data_labels=label1d)
    
        label2d = "Test 2D Spectrum"
        mosviz_app.load_2d_spectra(spectrum2d, data_labels=label2d)
    
        table = mosviz_app.app.get_viewer('table-viewer')
        table.widget_table.vue_on_row_clicked(0)
    
        scale_2d = mosviz_app.app.get_viewer('spectrum-2d-viewer').scales['x']
        scale_1d = mosviz_app.app.get_viewer('spectrum-viewer').scales['x']
    
        scale_2d.min = 200.0
>       assert scale_1d.min == spectrum1d.spectral_axis.value[200]
E       assert 6000.0 == 6391.006842619746
E        +  where 6000.0 = LinearScale(allow_padding=False, max=6000.0, min=6000.0).min

../../.tox/py39-test-devdeps/lib/python3.9/site-packages/jdaviz/configs/mosviz/tests/test_helper.py:261: AssertionError
________________________ test_get_spectral_regions_unit ________________________

specviz_app = <jdaviz.configs.specviz.helper.SpecViz object at 0x7f623a348eb0>
spectrum1d = <Spectrum1D(flux=<Quantity [12.49671415, 12.30618014, 13.53658529, 14.85657834, 13.5436244 ,
           13.98808527, 1...28024,
                   1.72491783, 0.56228753, 1.01283112, 0.31424733,
                   0.90802408, 1.4123037 ]))>

    def test_get_spectral_regions_unit(specviz_app, spectrum1d):
        # Ensure units we put in are the same as the units we get out
        specviz_app.load_spectrum(spectrum1d)
        specviz_app.app.get_viewer("spectrum-viewer").apply_roi(XRangeROI(1, 3.5))
    
>       subsets = specviz_app.get_spectral_regions()

../../.tox/py39-test-devdeps/lib/python3.9/site-packages/jdaviz/configs/specviz/tests/test_helper.py:88: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../.tox/py39-test-devdeps/lib/python3.9/site-packages/jdaviz/configs/specviz/helper.py:78: in get_spectral_regions
    regions = self.app.get_subsets_from_viewer("spectrum-viewer", subset_type="spectral")
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = Application(components={'g-viewer-tab': '<template>\n  <component :is="stack.container">\n    <g-viewer-tab\n      v-f...lbackList with 1 elements>
  tool_items: <CallbackList with 3 elements>
  tray_items: <CallbackList with 5 elements>
>)
viewer_reference = 'spectrum-viewer', data_label = None
subset_type = 'spectral'

    def get_subsets_from_viewer(self, viewer_reference, data_label=None, subset_type=None):
        """
        Returns the subsets of a specified viewer converted to astropy regions
        objects.
    
        It should be noted that the subset translation machinery lives in the
        glue-astronomy repository. Currently, the machinery only works on 2D
        data for cases like range selection. For e.g. a profile viewer that is
        ostensibly just a view into a 3D data set, it is necessary to first
        reduce the dimensions of the data, then retrieve the subset information
        as a regions object. This means that the returned y extents in the
        region are not strictly representative of the subset range in y.
    
        Parameters
        ----------
        viewer_reference : str
            The reference to the viewer defined with the ``reference`` key
            in the yaml configuration file.
        data_label : str, optional
            Optionally provide a label to retrieve a specific data set from the
            viewer instance.
        subset_type : str, optional
            Optionally specify either "spectral" or "spatial" to return only
            subsets created in a profile (spectrum) viewer or image viewer,
            respectively.
    
        Returns
        -------
        data : dict
            A dict of the transformed Glue subset objects, with keys
            representing the subset name and values as astropy regions
            objects.
        """
        viewer = self.get_viewer(viewer_reference)
        data = self.get_data_from_viewer(viewer_reference,
                                         data_label,
                                         cls=None)
        regions = {}
    
        if data_label is not None:
            data = {data_label: data}
    
        for key, value in data.items():
            if isinstance(value, Subset):
                # Skip spatial or spectral subsets if only the other is wanted
                if subset_type == "spectral" and isinstance(value.subset_state, RoiSubsetState):
                    continue
                elif subset_type == "spatial" and isinstance(value.subset_state, RangeSubsetState):
                    continue
    
                # Range selection on a profile is currently not supported in
                #  the glue translation machinery for astropy regions, so we
                #  have to do it manually. Only data that is 2d is supported,
                #  therefore, if the data is already 2d, simply use as is.
                if value.data.ndim == 2:
                    region = value.data.get_selection_definition(
                        subset_id=key, format='astropy-regions')
                    regions[key] = region
                    continue
                # There is a special case for 1d data (which is also not
                #  supported currently). We now eschew the use of the
                #  translation machinery entirely and construct the astropy
                #  region ourselves.
                elif value.data.ndim == 1:
                    # Grab the data units from the glue-astronomy spectral axis
                    # TODO: this needs to be much simpler; i.e. data units in
                    #  the glue component objects
>                   unit = value.data.coords.spectral_axis.unit
E                   AttributeError: 'SpectralGWCS' object has no attribute 'spectral_axis'

../../.tox/py39-test-devdeps/lib/python3.9/site-packages/jdaviz/app.py:523: AttributeError
__________________ test_get_spectral_regions_unit_conversion ___________________

specviz_app = <jdaviz.configs.specviz.helper.SpecViz object at 0x7f623a28c250>
spectrum1d = <Spectrum1D(flux=<Quantity [12.49671415, 12.30618014, 13.53658529, 14.85657834, 13.5436244 ,
           13.98808527, 1...28024,
                   1.72491783, 0.56228753, 1.01283112, 0.31424733,
                   0.90802408, 1.4123037 ]))>

    def test_get_spectral_regions_unit_conversion(specviz_app, spectrum1d):
        # If the reference (visible) data changes via unit conversion,
        # check that the region's units convert too
        specviz_app.load_spectrum(spectrum1d)
        specviz_app.app.get_viewer("spectrum-viewer").apply_roi(XRangeROI(1, 3.5))
    
        # Convert the wavelength axis to microns
        new_spectral_axis = "micron"
        conv_func = uc.UnitConversion.process_unit_conversion
        converted_spectrum = conv_func(specviz_app.app, spectrum=spectrum1d,
                                       new_spectral_axis=new_spectral_axis)
    
        # Add this new data and clear the other, making the converted spectrum our reference
        specviz_app.app.add_data(converted_spectrum, "Converted Spectrum")
        specviz_app.app.add_data_to_viewer("spectrum-viewer",
                                           "Converted Spectrum",
                                           clear_other_data=True)
    
        # Retrieve the Subset
>       subsets = specviz_app.get_spectral_regions()

../../.tox/py39-test-devdeps/lib/python3.9/site-packages/jdaviz/configs/specviz/tests/test_helper.py:114: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../.tox/py39-test-devdeps/lib/python3.9/site-packages/jdaviz/configs/specviz/helper.py:78: in get_spectral_regions
    regions = self.app.get_subsets_from_viewer("spectrum-viewer", subset_type="spectral")
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = Application(components={'g-viewer-tab': '<template>\n  <component :is="stack.container">\n    <g-viewer-tab\n      v-f...lbackList with 1 elements>
  tool_items: <CallbackList with 3 elements>
  tray_items: <CallbackList with 5 elements>
>)
viewer_reference = 'spectrum-viewer', data_label = None
subset_type = 'spectral'

    def get_subsets_from_viewer(self, viewer_reference, data_label=None, subset_type=None):
        """
        Returns the subsets of a specified viewer converted to astropy regions
        objects.
    
        It should be noted that the subset translation machinery lives in the
        glue-astronomy repository. Currently, the machinery only works on 2D
        data for cases like range selection. For e.g. a profile viewer that is
        ostensibly just a view into a 3D data set, it is necessary to first
        reduce the dimensions of the data, then retrieve the subset information
        as a regions object. This means that the returned y extents in the
        region are not strictly representative of the subset range in y.
    
        Parameters
        ----------
        viewer_reference : str
            The reference to the viewer defined with the ``reference`` key
            in the yaml configuration file.
        data_label : str, optional
            Optionally provide a label to retrieve a specific data set from the
            viewer instance.
        subset_type : str, optional
            Optionally specify either "spectral" or "spatial" to return only
            subsets created in a profile (spectrum) viewer or image viewer,
            respectively.
    
        Returns
        -------
        data : dict
            A dict of the transformed Glue subset objects, with keys
            representing the subset name and values as astropy regions
            objects.
        """
        viewer = self.get_viewer(viewer_reference)
        data = self.get_data_from_viewer(viewer_reference,
                                         data_label,
                                         cls=None)
        regions = {}
    
        if data_label is not None:
            data = {data_label: data}
    
        for key, value in data.items():
            if isinstance(value, Subset):
                # Skip spatial or spectral subsets if only the other is wanted
                if subset_type == "spectral" and isinstance(value.subset_state, RoiSubsetState):
                    continue
                elif subset_type == "spatial" and isinstance(value.subset_state, RangeSubsetState):
                    continue
    
                # Range selection on a profile is currently not supported in
                #  the glue translation machinery for astropy regions, so we
                #  have to do it manually. Only data that is 2d is supported,
                #  therefore, if the data is already 2d, simply use as is.
                if value.data.ndim == 2:
                    region = value.data.get_selection_definition(
                        subset_id=key, format='astropy-regions')
                    regions[key] = region
                    continue
                # There is a special case for 1d data (which is also not
                #  supported currently). We now eschew the use of the
                #  translation machinery entirely and construct the astropy
                #  region ourselves.
                elif value.data.ndim == 1:
                    # Grab the data units from the glue-astronomy spectral axis
                    # TODO: this needs to be much simpler; i.e. data units in
                    #  the glue component objects
>                   unit = value.data.coords.spectral_axis.unit
E                   AttributeError: 'SpectralGWCS' object has no attribute 'spectral_axis'

../../.tox/py39-test-devdeps/lib/python3.9/site-packages/jdaviz/app.py:523: AttributeError
=========================== short test summary info ============================
FAILED ../../.tox/py39-test-devdeps/lib/python3.9/site-packages/jdaviz/configs/mosviz/tests/test_helper.py::test_viewer_axis_link
FAILED ../../.tox/py39-test-devdeps/lib/python3.9/site-packages/jdaviz/configs/specviz/tests/test_helper.py::test_get_spectral_regions_unit
FAILED ../../.tox/py39-test-devdeps/lib/python3.9/site-packages/jdaviz/configs/specviz/tests/test_helper.py::test_get_spectral_regions_unit_conversion

🐱

@pllim pllim added bug Something isn't working testing labels Sep 3, 2021
@pllim pllim changed the title TST: SpectralGWCS failures using specutils 1.3.1 and glue-astropy dev TST: SpectralGWCS failures using specutils 1.3.1 and glue-astronomy dev Sep 3, 2021
@pllim
Copy link
Contributor Author

pllim commented Sep 3, 2021

Maybe specutils dev will fix this naturally but I cannot test it until astropy/specutils#858 is resolved.

@pllim
Copy link
Contributor Author

pllim commented Sep 3, 2021

@astrofrog said the fix for this falls to jdaviz to support GWCS for the affected code.

@astrofrog
Copy link
Collaborator

astrofrog commented Sep 3, 2021

The easiest fix might be to rely on APE14 API by replacing value.data.coords.spectral_axis.unit with value.data.coords.world_axis_units[-1] (I haven't tested this)

@astrofrog
Copy link
Collaborator

Did not mean to auto-close this - I didn't know this worked across repos!

@astrofrog astrofrog reopened this Sep 3, 2021
@pllim
Copy link
Contributor Author

pllim commented Sep 7, 2021

I didn't know this worked across repos!

But you knew back in 2014. 😉

astropy/package-template#81 (comment)

@pllim
Copy link
Contributor Author

pllim commented Sep 7, 2021

This issue can be closed by a PR to update minversion of glue-astronomy (0.3?) here once @astrofrog releases it upstream. I have opened glue-viz/glue-astronomy#46 to track the proper fix as "future work."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working 🔥 Critical mosviz specviz
Projects
None yet
3 participants