From a73ab4c240040cd9095f1eb2e7de1ac6b87dc167 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Fri, 15 May 2020 11:48:37 +0100 Subject: [PATCH] Fix a bug where x_att and y_att could end up being out of sync in image viewer --- CHANGES.md | 2 ++ glue/viewers/image/state.py | 5 ++++ glue/viewers/image/tests/test_state.py | 37 ++++++++++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 4aa983699..0b0de5974 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -45,6 +45,8 @@ v0.16.0 (unreleased) v0.15.7 (2020-03-12) -------------------- +* Fix a bug where x_att and y_att could end up being out of sync in image viewer. [#2141] + * Fix bug that caused an infinite loop in the table viewer and caused glue to hang if too many incompatible subsets were in a table viewer. [#2105] diff --git a/glue/viewers/image/state.py b/glue/viewers/image/state.py index 4507e2962..40215b9f5 100644 --- a/glue/viewers/image/state.py +++ b/glue/viewers/image/state.py @@ -173,6 +173,11 @@ def _reference_data_changed(self, *args): self.yw_att_helper.world_coord = False self._update_combo_att() self._set_default_slices() + # We need to make sure that we update x_att and y_att + # at the same time before any other callbacks get called, + # so we do this here manually. + self._on_xatt_world_change() + self._on_yatt_world_change() def _layers_changed(self, *args): diff --git a/glue/viewers/image/tests/test_state.py b/glue/viewers/image/tests/test_state.py index 1b3180a61..b35540ef1 100644 --- a/glue/viewers/image/tests/test_state.py +++ b/glue/viewers/image/tests/test_state.py @@ -333,3 +333,40 @@ def test_too_many_dimensions(self): with pytest.raises(IncompatibleAttribute): self.viewer_state.layers[0].get_sliced_data() + + +def test_update_x_att_and_y_att(): + + # Regression test for a bug that caused y_att to not be updated before + # events were sent out about x_att changing. + + viewer_state = ImageViewerState() + + data1 = Data(x=np.ones((3, 4, 5))) + + layer_state1 = ImageLayerState(layer=data1, viewer_state=viewer_state) + viewer_state.layers.append(layer_state1) + + data2 = Data(x=np.ones((3, 4, 5))) + + layer_state2 = ImageLayerState(layer=data2, viewer_state=viewer_state) + viewer_state.layers.append(layer_state2) + + def check_consistency(*args, **kwargs): + # Make sure that x_att and y_att are always for same dataset + assert viewer_state.x_att.parent is viewer_state.y_att.parent + + viewer_state.add_global_callback(check_consistency) + viewer_state.add_callback('x_att', check_consistency) + viewer_state.add_callback('y_att', check_consistency) + viewer_state.add_callback('x_att_world', check_consistency) + viewer_state.add_callback('y_att_world', check_consistency) + viewer_state.add_callback('slices', check_consistency) + + viewer_state.reference_data = data1 + assert viewer_state.x_att is data1.pixel_component_ids[2] + assert viewer_state.y_att is data1.pixel_component_ids[1] + + viewer_state.reference_data = data2 + assert viewer_state.x_att is data2.pixel_component_ids[2] + assert viewer_state.y_att is data2.pixel_component_ids[1]