diff --git a/glue/core/data.py b/glue/core/data.py index 7bcb9fe4f..77359b96c 100644 --- a/glue/core/data.py +++ b/glue/core/data.py @@ -71,6 +71,8 @@ def __init__(self): self.style = VisualAttributes(parent=self) + self.uuid = str(uuid.uuid4()) + @property def label(self): """ @@ -773,11 +775,6 @@ def __init__(self, label="", coords=None, **kwargs): self._key_joins = {} - # To avoid circular references when saving objects with references to - # the data, we make sure that all Data objects have a UUID that can - # uniquely identify them. - self.uuid = str(uuid.uuid4()) - @property def coords(self): """ diff --git a/glue/viewers/histogram/tests/test_viewer.py b/glue/viewers/histogram/tests/test_viewer.py index b3fedb578..82eb34439 100644 --- a/glue/viewers/histogram/tests/test_viewer.py +++ b/glue/viewers/histogram/tests/test_viewer.py @@ -7,6 +7,7 @@ from glue.viewers.histogram.viewer import SimpleHistogramViewer from glue.core.application_base import Application from glue.core.data import Data +from glue.core.data_derived import IndexedData @visual_test @@ -119,3 +120,29 @@ def test_reset_limits(): assert_allclose(viewer.state.hist_x_min, 49.95) assert_allclose(viewer.state.hist_x_max, 949.05) + + +def test_indexed_data(): + + # Make sure that the scatter viewer works properly with IndexedData objects + + data_4d = Data(label='hypercube', + x=np.random.random((3, 5, 4, 3)), + y=np.random.random((3, 5, 4, 3))) + + data_2d = IndexedData(data_4d, (2, None, 3, None)) + + application = Application() + + session = application.session + + hub = session.hub + + data_collection = session.data_collection + data_collection.append(data_4d) + data_collection.append(data_2d) + + viewer = application.new_data_viewer(SimpleHistogramViewer) + viewer.add_data(data_2d) + + assert viewer.state.x_att is data_2d.main_components[0] diff --git a/glue/viewers/image/state.py b/glue/viewers/image/state.py index 194650c93..9258646b9 100644 --- a/glue/viewers/image/state.py +++ b/glue/viewers/image/state.py @@ -620,6 +620,7 @@ def reset_contrast_bias(self): def _update_attribute_display_unit_choices(self, *args): + # NOTE: only Data and its subclasses support specifying units if self.layer is None or self.attribute is None or not isinstance(self.layer, Data): ImageLayerState.attribute_display_unit.set_choices(self, []) return diff --git a/glue/viewers/profile/state.py b/glue/viewers/profile/state.py index 7d08aff20..bd096693d 100644 --- a/glue/viewers/profile/state.py +++ b/glue/viewers/profile/state.py @@ -3,7 +3,7 @@ import numpy as np -from glue.core import Subset +from glue.core import Subset, Data from echo import delay_callback from glue.viewers.matplotlib.state import (MatplotlibDataViewerState, MatplotlibLayerState, @@ -11,7 +11,6 @@ DeferredDrawSelectionCallbackProperty as DDSCProperty) from glue.core.data_combo_helper import ManualDataComboHelper, ComponentIDComboHelper from glue.utils import defer_draw, avoid_circular -from glue.core.data import BaseData from glue.core.link_manager import is_convertible_to_single_pixel_cid from glue.core.exceptions import IncompatibleDataException from glue.core.message import SubsetUpdateMessage @@ -264,7 +263,8 @@ def _layers_changed(self, *args): def _update_x_display_unit_choices(self): - if self.reference_data is None: + # NOTE: only Data and its subclasses support specifying units + if self.reference_data is None or not isinstance(self.reference_data, Data): ProfileViewerState.x_display_unit.set_choices(self, []) return @@ -280,7 +280,8 @@ def _update_y_display_unit_choices(self): component_units = set() for layer_state in self.layers: - if isinstance(layer_state.layer, BaseData): + # NOTE: only Data and its subclasses support specifying units + if isinstance(layer_state.layer, Data): component = layer_state.layer.get_component(layer_state.attribute) if component.units: component_units.add((layer_state.layer, layer_state.attribute, component.units)) diff --git a/glue/viewers/profile/tests/test_viewer.py b/glue/viewers/profile/tests/test_viewer.py index eb6f8e866..b57c6b5d5 100644 --- a/glue/viewers/profile/tests/test_viewer.py +++ b/glue/viewers/profile/tests/test_viewer.py @@ -11,6 +11,7 @@ from glue.config import settings, unit_converter from glue.plugins.wcs_autolinking.wcs_autolinking import WCSLink from glue.core.roi import XRangeROI +from glue.core.data_derived import IndexedData @visual_test @@ -171,3 +172,29 @@ def test_unit_conversion(): viewer.state.reference_data = d2 viewer.state.y_display_unit = 'mJy' + + +def test_indexed_data(): + + # Make sure that the profile viewer works properly with IndexedData objects + + data_4d = Data(label='hypercube_wcs', + x=np.random.random((3, 5, 4, 3)), + coords=WCS(naxis=4)) + + data_2d = IndexedData(data_4d, (2, None, 3, None)) + + application = Application() + + session = application.session + + hub = session.hub + + data_collection = session.data_collection + data_collection.append(data_4d) + data_collection.append(data_2d) + + viewer = application.new_data_viewer(SimpleProfileViewer) + viewer.add_data(data_2d) + + assert viewer.state.x_att is data_2d.world_component_ids[0] diff --git a/glue/viewers/scatter/tests/test_viewer.py b/glue/viewers/scatter/tests/test_viewer.py index e622b213d..ad0a3080c 100644 --- a/glue/viewers/scatter/tests/test_viewer.py +++ b/glue/viewers/scatter/tests/test_viewer.py @@ -9,6 +9,7 @@ from glue.core.application_base import Application from glue.core.data import Data from glue.core.link_helpers import LinkSame +from glue.core.data_derived import IndexedData @visual_test @@ -103,3 +104,30 @@ def test_reset_limits(): assert_allclose(viewer.state.y_min, 1000 + 67.932) assert_allclose(viewer.state.y_max, 1000 + 931.068) + + +def test_indexed_data(): + + # Make sure that the scatter viewer works properly with IndexedData objects + + data_4d = Data(label='hypercube', + x=np.random.random((3, 5, 4, 3)), + y=np.random.random((3, 5, 4, 3))) + + data_2d = IndexedData(data_4d, (2, None, 3, None)) + + application = Application() + + session = application.session + + hub = session.hub + + data_collection = session.data_collection + data_collection.append(data_4d) + data_collection.append(data_2d) + + viewer = application.new_data_viewer(SimpleScatterViewer) + viewer.add_data(data_2d) + + assert viewer.state.x_att is data_2d.main_components[0] + assert viewer.state.y_att is data_2d.main_components[1]