Exemple #1
0
def test_clone_wcs_link():

    # Make sure that WCSLink can be serialized/deserialized

    wcs1 = WCS(naxis=2)
    wcs1.wcs.ctype = 'DEC--TAN', 'RA---TAN'
    wcs1.wcs.set()

    data1 = Data(label='Data 1')
    data1.coords = WCSCoordinates(wcs=wcs1)
    data1['x'] = np.ones((2, 3))

    wcs2 = WCS(naxis=3)
    wcs2.wcs.ctype = 'GLON-CAR', 'FREQ', 'GLAT-CAR'
    wcs2.wcs.set()

    data2 = Data(label='Data 2')
    data2.coords = WCSCoordinates(wcs=wcs2)
    data2['x'] = np.ones((2, 3, 4))

    link1 = WCSLink(data1, data2)
    link2 = clone(link1)

    assert isinstance(link2, WCSLink)
    assert link2.data1.label == 'Data 1'
    assert link2.data2.label == 'Data 2'
Exemple #2
0
    def setup_method(self, method):

        # Set up simple spectral WCS
        wcs_1d = WCS(naxis=1)
        wcs_1d.wcs.ctype = ['VELO-LSR']
        wcs_1d.wcs.set()

        # Set up a spectral cube WCS
        wcs_3d = WCS(naxis=3)
        wcs_3d.wcs.ctype = ['RA---TAN', 'DEC--TAN', 'VELO-LSR']
        wcs_3d.wcs.set()

        # Set up glue Coordinates object
        coords_1d = WCSCoordinates(wcs=wcs_1d)
        coords_3d = WCSCoordinates(wcs=wcs_3d)

        self.data_1d = Data(label='spectrum', coords=coords_1d)
        self.data_3d = Data(label='spectrum', coords=coords_3d)

        # FIXME: there should be an easier way to do this in glue
        x = np.array([3.4, 2.3, -1.1, 0.3])
        y = np.array([3.2, 3.3, 3.4, 3.5])
        self.data_1d.add_component(Component(x, units='Jy'), 'x')
        self.data_1d.add_component(Component(y, units='Jy'), 'y')
        self.data_3d.add_component(Component(np.broadcast_to(x, (6, 5, 4)), units='Jy'), 'x')
        self.data_3d.add_component(Component(np.broadcast_to(x, (6, 5, 4))), 'y')

        self.app = GlueApplication()
        self.session = self.app.session
        self.hub = self.session.hub

        self.data_collection = self.session.data_collection
        self.data_collection.append(self.data_1d)
        self.data_collection.append(self.data_3d)
Exemple #3
0
def test_link_editor():

    # Make sure that the WCSLink works property in the link editor and is
    # returned unmodified. The main way to check that is just to make sure that
    # the link round-trips when going through EditableLinkFunctionState.

    wcs1 = WCS(naxis=2)
    wcs1.wcs.ctype = 'DEC--TAN', 'RA---TAN'
    wcs1.wcs.set()

    data1 = Data(label='Data 1')
    data1.coords = WCSCoordinates(wcs=wcs1)
    data1['x'] = np.ones((2, 3))

    wcs2 = WCS(naxis=3)
    wcs2.wcs.ctype = 'GLON-CAR', 'FREQ', 'GLAT-CAR'
    wcs2.wcs.set()

    data2 = Data(label='Data 2')
    data2.coords = WCSCoordinates(wcs=wcs2)
    data2['x'] = np.ones((2, 3, 4))

    link1 = WCSLink(data1, data2)

    link2 = EditableLinkFunctionState(link1).link

    assert isinstance(link2, WCSLink)
    assert link2.data1.label == 'Data 1'
    assert link2.data2.label == 'Data 2'
    def setup_method(self, method):

        self.coords = MyCoords()
        self.image1 = Data(label='image1', x=[[1, 2], [3, 4]], y=[[4, 5], [2, 3]])
        self.image2 = Data(label='image2', a=[[3, 3], [2, 2]], b=[[4, 4], [3, 2]],
                           coords=self.coords)
        self.catalog = Data(label='catalog', c=[1, 3, 2], d=[4, 3, 3])
        self.hypercube = Data(label='hypercube', x=np.arange(120).reshape((2, 3, 4, 5)))

        # Create data versions with WCS coordinates
        self.image1_wcs = Data(label='image1_wcs', x=self.image1['x'],
                               coords=WCSCoordinates(wcs=WCS(naxis=2)))
        self.hypercube_wcs = Data(label='hypercube_wcs', x=self.hypercube['x'],
                                  coords=WCSCoordinates(wcs=WCS(naxis=4)))

        self.application = GlueApplication()

        self.session = self.application.session

        self.hub = self.session.hub

        self.data_collection = self.session.data_collection
        self.data_collection.append(self.image1)
        self.data_collection.append(self.image2)
        self.data_collection.append(self.catalog)
        self.data_collection.append(self.hypercube)
        self.data_collection.append(self.image1_wcs)
        self.data_collection.append(self.hypercube_wcs)

        self.viewer = self.application.new_data_viewer(ImageViewer)

        self.data_collection.register_to_hub(self.hub)
        self.viewer.register_to_hub(self.hub)

        self.options_widget = self.viewer.options_widget()
Exemple #5
0
    def on_finished(self, data, unit=None):
        """
        Called when the `QThread` has finished performing the operation on the
        `SpectralCube` object.

        Parameters
        ----------
        data : ndarray
            The result of the operation performed on the `SpectralCube` object.
        """
        component_name = "{} {}".format(self._component_id,
                                        self._operation_name)

        comp_count = len([x for x in self._data.component_ids()
                          if component_name in str(x)])

        if comp_count > 0:
            component_name = "{} {}".format(component_name, comp_count)

        if data.ndim == 2:
            coords = WCSCoordinates(wcs=self._data.coords.wcs.celestial)

            self._data.container_2d = Data(label=self._data.label + " [2d]",
                                           coords=coords)
            self._data.container_2d.add_component(data, component_name)

            # self._layout.session.data_collection.append(self._data.container_2d)
            self._layout.add_overlay(data, component_name, display_now=True)
        else:
            component = Component(data, units=unit)
            self._data.add_component(component, component_name)

        super(SpectralOperationHandler, self).accept()
Exemple #6
0
 def load_stacked_sequence(self, raster_data):
     for window, window_data in raster_data.items():
         w_data = Data(label=f"{window.replace(' ', '_')}")
         w_data.coords = WCSCoordinates(wcs=window_data.wcs)
         w_data.add_component(Component(window_data.data),
                              f"{window}")
         self.datasets.append(w_data)
Exemple #7
0
def import_iris_obs():

    caption = "Select a directory containing files from one IRIS OBS, and stack all raster scans."

    data_path = Path(pick_directory(caption))
    rasters = list(data_path.glob("*raster*"))
    sji = list(data_path.glob("*SJI*"))

    sji_data = []

    for s in sji:
        sji_data.append(load_sji_fits(s))

    raster_data = read_iris_spectrograph_level2_fits(rasters,
                                                     spectral_windows=['Mg II k 2796'],
                                                     memmap=False, uncertainty=False)

    raster_data = {window: stack_spectrogram_sequence(seq)
                   for window, seq in raster_data.data.items()}

    result = []
    for window, window_data in raster_data.items():
        w_data = Data(label=f"{window.replace(' ', '_')}")
        w_data.coords = WCSCoordinates(wcs=window_data.wcs)
        w_data.add_component(Component(window_data.data),
                             f"{window}")
        result.append(w_data)

    return result + sji_data
def test_to_spectrum1d():

    # Set up simple spectral WCS
    wcs = WCS(naxis=1)
    wcs.wcs.ctype = ['VELO-LSR']
    wcs.wcs.set()

    coords = WCSCoordinates(wcs=wcs)

    data = Data(label='spectrum', coords=coords)
    data.add_component(Component(np.array([3.4, 2.3, -1.1, 0.3]), units='Jy'),
                       'x')

    spec = data.get_object(Spectrum1D, attribute=data.id['x'])

    assert_quantity_allclose(spec.spectral_axis, [1, 2, 3, 4] * u.m / u.s)
    assert_quantity_allclose(spec.flux, [3.4, 2.3, -1.1, 0.3] * u.Jy)

    data.add_subset(data.id['x'] > 1, label='bright')

    spec_subset = data.get_subset_object(cls=Spectrum1D,
                                         subset_id=0,
                                         attribute=data.id['x'])

    assert_quantity_allclose(spec_subset.spectral_axis,
                             [1, 2, 3, 4] * u.m / u.s)
    assert_quantity_allclose(spec_subset.flux,
                             [3.4, 2.3, np.nan, np.nan] * u.Jy)
    assert_equal(spec_subset.mask, [1, 1, 0, 0])
Exemple #9
0
def test_wcs_autolink_emptywcs():

    # No links should be found because the WCS don't actually have well defined
    # physical types.

    data1 = Data()
    data1.coords = WCSCoordinates(wcs=WCS(naxis=1))
    data1['x'] = [1, 2, 3]

    data2 = Data()
    data2.coords = WCSCoordinates(wcs=WCS(naxis=1))
    data2['x'] = [4, 5, 6]

    dc = DataCollection([data1, data2])
    links = wcs_autolink(dc)
    assert len(links) == 0
Exemple #10
0
def test_component_unit_header(tmpdir):
    from astropy import units as u
    filename = tmpdir.join('test3.fits').strpath

    data = Data(x=np.arange(6).reshape(2, 3),
                y=(np.arange(6) * 2).reshape(2, 3),
                z=(np.arange(6) * 2).reshape(2, 3))

    wcs = WCS()
    data.coords = WCSCoordinates(wcs=wcs)

    unit1 = data.get_component("x").units = u.m / u.s
    unit2 = data.get_component("y").units = u.Jy
    unit3 = data.get_component("z").units = ""

    fits_writer(filename, data)

    with fits.open(filename) as hdulist:
        assert len(hdulist) == 3
        bunit = hdulist['x'].header.get('BUNIT')
        assert u.Unit(bunit) == unit1

        bunit = hdulist['y'].header.get('BUNIT')
        assert u.Unit(bunit) == unit2

        bunit = hdulist['z'].header.get('BUNIT')
        assert bunit == unit3
Exemple #11
0
 def load_sequence(self, raster_data):
     for window, window_data in raster_data.items():
         for i, scan_data in enumerate(window_data):
             w_data = Data(label=f"{window.replace(' ', '_')}-scan-{i}")
             w_data.coords = WCSCoordinates(wcs=scan_data.wcs)
             w_data.add_component(Component(scan_data.data),
                                  f"{window}-scan-{i}")
             w_data.meta = scan_data.meta
             self.datasets.append(w_data)
Exemple #12
0
 def to_data(self, obj):
     if obj.wcs is None:
         coords = None
     else:
         coords = WCSCoordinates(wcs=obj.wcs)
     data = Data(coords=coords)
     data['data'] = obj.data
     data.get_component('data').units = str(obj.unit)
     data.meta.update(obj.meta)
     return data
Exemple #13
0
    def load_sji(self, sji):
        with fits.open(sji) as hdul:
            hdul.verify("fix")
            label = hdul[0].header['TDESC1']
            data = Data(label=label)
            data.coords = WCSCoordinates(hdul[0].header)
            data.meta = hdul[0].header
            data.add_component(Component(hdul[0].data), label)

            self.datasets.append(data)
Exemple #14
0
def _parse_iris_raster(data, label):
    result = []
    for window, window_data in data.data.items():
        for i, scan_data in enumerate(window_data):
            w_data = Data(label=f"{window.replace(' ', '_')}-scan-{i}")
            w_data.coords = WCSCoordinates(wcs=scan_data.wcs)
            w_data.add_component(Component(scan_data.data),
                                 f"{window}-scan-{i}")
            w_data.meta = scan_data.meta
            result.append(w_data)
    return result
Exemple #15
0
def load_sji_fits(filename):
    with fits.open(filename) as hdul:
        hdul.verify("fix")
        sji = hdul[0]
        label = sji.header['TDESC1']
        data = Data(label=label)
        data.coords = WCSCoordinates(sji.header)
        data.meta = sji.header
        data.add_component(Component(sji.data), label)

    return data
Exemple #16
0
    def test_hypercube_world(self):

        # Check defaults when we add data

        wcs = WCS(naxis=4)
        hypercube2 = Data()
        hypercube2.coords = WCSCoordinates(wcs=wcs)
        hypercube2.add_component(np.random.random((2, 3, 4, 5)), 'a')

        self.data_collection.append(hypercube2)

        self.viewer.add_data(hypercube2)
Exemple #17
0
def _parse_iris_raster(data, label):
    result = []
    for window, window_data in data.items():
        for i, scan_data in enumerate(window_data):
            w_data = Data(label=f"{window.replace(' ', '_')}-scan-{i}")
            w_data.coords = WCSCoordinates(scan_data.header)
            w_data.add_component(Component(scan_data.data),
                                 f"{window}-scan-{i}")
            w_data.meta = scan_data.meta
            w_data.style = VisualAttributes(color='#5A4FCF')
            result.append(w_data)
    return result
Exemple #18
0
def test_wcs_autolink_spectral_cube():

    # This should link all coordinates

    wcs1 = WCS(naxis=3)
    wcs1.wcs.ctype = 'DEC--TAN', 'FREQ', 'RA---TAN'
    wcs1.wcs.set()

    data1 = Data()
    data1.coords = WCSCoordinates(wcs=wcs1)
    data1['x'] = np.ones((2, 3, 4))
    pz1, py1, px1 = data1.pixel_component_ids

    wcs2 = WCS(naxis=3)
    wcs2.wcs.ctype = 'GLON-CAR', 'GLAT-CAR', 'FREQ'
    wcs2.wcs.set()

    data2 = Data()
    data2.coords = WCSCoordinates(wcs=wcs2)
    data2['x'] = np.ones((2, 3, 4))
    pz2, py2, px2 = data2.pixel_component_ids

    dc = DataCollection([data1, data2])
    links = wcs_autolink(dc)
    assert len(links) == 1
    link = links[0]
    assert isinstance(link, MultiLink)
    assert len(link) == 6
    assert link[0].get_to_id() == pz2
    assert link[0].get_from_ids() == [pz1, py1, px1]
    assert link[1].get_to_id() == py2
    assert link[1].get_from_ids() == [pz1, py1, px1]
    assert link[2].get_to_id() == px2
    assert link[2].get_from_ids() == [pz1, py1, px1]
    assert link[3].get_to_id() == pz1
    assert link[3].get_from_ids() == [pz2, py2, px2]
    assert link[4].get_to_id() == py1
    assert link[4].get_from_ids() == [pz2, py2, px2]
    assert link[5].get_to_id() == px1
    assert link[5].get_from_ids() == [pz2, py2, px2]
Exemple #19
0
    def load_sji(self, sji):
        with fits.open(sji) as hdul:
            hdul.verify("fix")
            label = hdul[0].header['TDESC1'] + hdul[0].header['OBSID']
            data = Data(label=label)
            data.coords = WCSCoordinates(hdul[0].header)
            data.meta = hdul[0].header
            preferred_cmap_name = 'IRIS ' + hdul[0].header['TDESC1'].replace(
                '_', ' ')
            data.style = VisualAttributes(preferred_cmap=preferred_cmap_name)
            data.add_component(Component(hdul[0].data), label)

            self.datasets.append(data)
Exemple #20
0
def test_celestial_with_unknown_axes():

    # Regression test for a bug that caused n-d datasets with celestial axes
    # and axes with unknown physical types to not even be linked by celestial
    # axes.

    wcs1 = WCS(naxis=3)
    wcs1.wcs.ctype = 'DEC--TAN', 'RA---TAN', 'SPAM'
    wcs1.wcs.set()

    data1 = Data()
    data1.coords = WCSCoordinates(wcs=wcs1)
    data1['x'] = np.ones((2, 3, 4))
    pz1, py1, px1 = data1.pixel_component_ids

    wcs2 = WCS(naxis=3)
    wcs2.wcs.ctype = 'GLON-CAR', 'FREQ', 'GLAT-CAR'
    wcs2.wcs.set()

    data2 = Data()
    data2.coords = WCSCoordinates(wcs=wcs2)
    data2['x'] = np.ones((2, 3, 4))
    pz2, py2, px2 = data2.pixel_component_ids

    dc = DataCollection([data1, data2])
    links = wcs_autolink(dc)
    assert len(links) == 1
    link = links[0]
    assert isinstance(link, MultiLink)
    assert len(link) == 4
    assert link[0].get_to_id() == px2
    assert link[0].get_from_ids() == [px1, py1]
    assert link[1].get_to_id() == pz2
    assert link[1].get_from_ids() == [px1, py1]
    assert link[2].get_to_id() == px1
    assert link[2].get_from_ids() == [px2, pz2]
    assert link[3].get_to_id() == py1
    assert link[3].get_from_ids() == [px2, pz2]
Exemple #21
0
def _parse_iris_raster(data, label):
    """
    Parse IRIS Level 2 raster files so that it can be loaded by glue.
    """
    w_dataset = []
    for window, window_data in data.items():
        for i, scan_data in enumerate(window_data):
            w_data = Data(label=f"{window.replace(' ', '_')}-{scan_data.meta['OBSID']}-scan-{i}")
            w_data.coords = WCSCoordinates(scan_data.wcs.to_header())
            w_data.add_component(Component(scan_data.data), f"{window.replace(' ', '_')}-{scan_data.meta['OBSID']}-scan-{i}")
            w_data.meta = scan_data.meta
            w_data.style = VisualAttributes(color='#5A4FCF')
            w_dataset.append(w_data)

    return w_dataset
Exemple #22
0
def test_wcs_autolink_dimensional_mismatch():

    # No links should be found because the WCS don't actually have well defined
    # physical types.

    wcs1 = WCS(naxis=1)
    wcs1.wcs.ctype = ['FREQ']
    wcs1.wcs.set()

    data1 = Data()
    data1.coords = WCSCoordinates(wcs=wcs1)
    data1['x'] = [1, 2, 3]

    wcs2 = WCS(naxis=3)
    wcs2.wcs.ctype = 'DEC--TAN', 'FREQ', 'RA---TAN'
    wcs2.wcs.set()

    data2 = Data()
    data2.coords = WCSCoordinates(wcs=wcs2)
    data2['x'] = np.ones((2, 3, 4))

    dc = DataCollection([data1, data2])
    links = wcs_autolink(dc)
    assert len(links) == 0
def test_to_spectrum1d_from_3d_cube():

    # Set up simple spectral WCS
    wcs = WCS(naxis=3)
    wcs.wcs.ctype = ['RA---TAN', 'DEC--TAN', 'VELO-LSR']
    wcs.wcs.set()

    coords = WCSCoordinates(wcs=wcs)

    data = Data(label='spectral-cube', coords=coords)
    data.add_component(Component(np.ones((3, 4, 5)), units='Jy'), 'x')

    spec = data.get_object(Spectrum1D, attribute=data.id['x'], statistic='sum')

    assert_quantity_allclose(spec.spectral_axis, [1, 2, 3] * u.m / u.s)
    assert_quantity_allclose(spec.flux, [20, 20, 20] * u.Jy)
def test_to_spectrum1d_unitless():

    # Set up simple spectral WCS
    wcs = WCS(naxis=1)
    wcs.wcs.ctype = ['VELO-LSR']
    wcs.wcs.set()

    coords = WCSCoordinates(wcs=wcs)

    data = Data(label='spectrum', coords=coords)
    data.add_component(Component(np.array([3.4, 2.3, -1.1, 0.3])), 'x')

    spec = data.get_object(Spectrum1D, attribute=data.id['x'])

    assert_quantity_allclose(spec.spectral_axis, [1, 2, 3, 4] * u.m / u.s)
    assert_quantity_allclose(spec.flux, [3.4, 2.3, -1.1, 0.3] * u.one)
Exemple #25
0
def add_to_2d_container(cubeviz_layout, data, component_data, label):
    """
    Given the cubeviz layout, a data object, a new 2D layer and a label, add
    the 2D layer to the data object and update the cubeviz layout accordingly.
    This creates the 2D container dataset if needed.
    """

    # If the 2D container doesn't exist, we create it here. This container is
    # basically just a Data object but we keep it in an attribute
    # ``container_2d`` on its parent dataset.
    if getattr(data, 'container_2d', None) is None:

        # For now, we assume that the 2D maps are always computed along the
        # spectral axis, so that the resulting WCS is always celestial
        coords = WCSCoordinates(wcs=data.coords.wcs.celestial)
        data.container_2d = Data(label=data.label + " [2d]", coords=coords)

        data.container_2d.add_component(component_data, label)

        cubeviz_layout.session.data_collection.append(data.container_2d)

        # NOTE: the following is disabled for now but can be uncommented once
        # we are ready to use the glue overlay infrastructure.
        # Set up pixel links so that selections in the image plane propagate
        # between 1D and 2D views. Again this assumes as above that the
        # moments are computed along the spectral axis
        # link1 = LinkSame(data.pixel_component_ids[2],
        #                  data.container_2d.pixel_component_ids[1])
        # link2 = LinkSame(data.pixel_component_ids[1],
        #                  data.container_2d.pixel_component_ids[0])
        # cubeviz_layout.session.data_collection.add_link(link1)
        # cubeviz_layout.session.data_collection.add_link(link2)

        for helper in cubeviz_layout._viewer_combo_helpers:
            helper.append_data(data.container_2d)

        for viewer in cubeviz_layout.cube_views:
            viewer._widget.add_data(data.container_2d)

    else:
        # Make sure we don't add duplicate data components
        if label in data.container_2d.component_ids():
            raise ValueError("Data component with label '{}' already exists, "
                             "and cannot be created again".format(label))

        data.container_2d.add_component(component_data, label)
Exemple #26
0
def test_conversion_utils_3d():

    # Set up simple spectral WCS
    wcs = WCS(naxis=3)
    wcs.wcs.ctype = ['RA---TAN', 'DEC--TAN', 'VELO-LSR']
    wcs.wcs.set()

    # Set up glue Coordinates object
    coords = WCSCoordinates(wcs=wcs)

    data = Data(label='spectral-cube', coords=coords)
    data.add_component(Component(np.ones((3, 4, 5)), units='Jy'), 'x')

    assert glue_data_has_spectral_axis(data)

    spec = glue_data_to_spectrum1d(data, data.id['x'], statistic='sum')
    assert_quantity_allclose(spec.spectral_axis, [1, 2, 3] * u.m / u.s)
    assert_quantity_allclose(spec.flux, [20, 20, 20] * u.Jy)
Exemple #27
0
def test_conversion_utils_1d():

    # Set up simple spectral WCS
    wcs = WCS(naxis=1)
    wcs.wcs.ctype = ['VELO-LSR']
    wcs.wcs.set()

    # Set up glue Coordinates object
    coords = WCSCoordinates(wcs=wcs)

    data = Data(label='spectrum', coords=coords)
    data.add_component(Component(np.array([3.4, 2.3, -1.1, 0.3]), units='Jy'),
                       'x')

    assert glue_data_has_spectral_axis(data)

    spec = glue_data_to_spectrum1d(data, data.id['x'])
    assert_quantity_allclose(spec.spectral_axis, [1, 2, 3, 4] * u.m / u.s)
    assert_quantity_allclose(spec.flux, [3.4, 2.3, -1.1, 0.3] * u.Jy)
Exemple #28
0
def add_to_2d_container(cubeviz_layout, data, component_data, label):
    """
    Given the cubeviz layout, a data object, a new 2D layer and a label, add
    the 2D layer to the data object and update the cubeviz layout accordingly.
    This creates the 2D container dataset if needed.
    """

    # If the 2D container doesn't exist, we create it here. This container is
    # basically just a Data object but we keep it in an attribute
    # ``container_2d`` on its parent dataset.
    if getattr(data, 'container_2d', None) is None:

        # For now, we assume that the 2D maps are always computed along the
        # spectral axis, so that the resulting WCS is always celestial
        coords = WCSCoordinates(wcs=data.coords.wcs.celestial)
        data.container_2d = Data(label=data.label + " [2d]", coords=coords)

        data.container_2d.add_component(component_data, label)

        cubeviz_layout.session.data_collection.append(data.container_2d)

        # Set up pixel links so that selections in the image plane propagate
        # between 1D and 2D views. Again this assumes as above that the
        # moments are computed along the spectral axis
        link1 = LinkSame(data.pixel_component_ids[2],
                         data.container_2d.pixel_component_ids[1])
        link2 = LinkSame(data.pixel_component_ids[1],
                         data.container_2d.pixel_component_ids[0])
        cubeviz_layout.session.data_collection.add_link(link1)
        cubeviz_layout.session.data_collection.add_link(link2)

        for helper in cubeviz_layout._viewer_combo_helpers:
            helper.append_data(data.container_2d)

        for viewer in cubeviz_layout.all_views:
            viewer._widget.add_data(data.container_2d)

    else:

        data.container_2d.add_component(component_data, label)
Exemple #29
0
    def put_data_cb(self):
        if self.glue_app is None:
            self.error_no_glue()
            return

        channel = self.fv.get_current_channel()
        if channel is None:
            self.fv.show_error("No active channel!")
            return

        image = channel.get_current_image()
        if image is None:
            self.fv.show_error("No data in channel '%s'" % (channel.name))
            return

        data_np = image.get_data()
        name = image.get('name', 'noname')
        kwargs = {name: data_np}

        try:
            # Pass in WCS for image.
            if isinstance(image, AstroImage.AstroImage):
                gdata = Data(**kwargs)
                h = image.get_header()
                w = WCS(h)
                gdata.coords = WCSCoordinates(h, wcs=w)
                self.glue_app.add_data(**{name: gdata})
            # Table data
            else:
                self.glue_app.add_data(**kwargs)

            self.glue_app.raise_()

        except Exception as e:
            self.fv.show_error("Error sending data to Glue: %s" % (str(e)))
            self.error_no_glue()