diff --git a/CHANGES.rst b/CHANGES.rst index 42ea4afcec..95b05a0a40 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -72,6 +72,9 @@ Bug Fixes - Fixed broken histogram pan/zoom in Plot Options plugin. [#3361] +- Fixed bug with Plot Options select_all when data is float32. [#3366] + + Cubeviz ^^^^^^^ - Removed the deprecated ``save as fits`` option from the Collapse, Moment Maps, and Spectral Extraction plugins; use the Export plugin instead. [#3256] diff --git a/jdaviz/configs/default/plugins/plot_options/tests/test_plot_options.py b/jdaviz/configs/default/plugins/plot_options/tests/test_plot_options.py index 0d0781ae57..db18a7e16b 100644 --- a/jdaviz/configs/default/plugins/plot_options/tests/test_plot_options.py +++ b/jdaviz/configs/default/plugins/plot_options/tests/test_plot_options.py @@ -431,3 +431,30 @@ def test_segmentation_image(imviz_helper): assert plot_opts.stretch_function.value == 'linear' assert plot_opts.image_bias.value == 0.5 assert plot_opts.image_contrast.value == 1.0 + + +def test_imviz_select_all_layers(imviz_helper): + """ + Test to catch a (fixed) bug that was revealed when trying to select + all layers when data is float32. This was caused when trying to set + `stretch_vmin_value`. + """ + + arr = np.arange(36.).reshape(6, 6).astype(np.float32) + + # load three images in one viewer + with imviz_helper.batch_load(): + for i in range(3): + imviz_helper.load_data(arr, data_label=f"data_{i}") + + plot_options = imviz_helper.plugins['Plot Options'] + + plot_options.layer.multiselect = True + plot_options.select_all() + + # all layers selected, set stretch function to log for all + plot_options.stretch_function = 'log' + + # and make sure each layer picked up this change + for layer in plot_options.image_colormap.linked_states: + assert layer.as_dict()['stretch'] == 'log' diff --git a/jdaviz/core/template_mixin.py b/jdaviz/core/template_mixin.py index 47229c0a04..09fced569c 100644 --- a/jdaviz/core/template_mixin.py +++ b/jdaviz/core/template_mixin.py @@ -4413,9 +4413,9 @@ def _update_mixed_state(self): # change to one of the linked_states changes the value that will be adopted when # unmixing something in mixed state and results in more consistent and predictable # behavior - self._processing_change_from_glue = True - self.value = current_glue_values[0] - self._processing_change_from_glue = False + if len(current_glue_values) and current_glue_values[0] is not None: + self._on_glue_value_changed(current_glue_values[0], + update_mixed_state=False) self.sync = {**self.sync, 'mixed': mixed} @@ -4478,7 +4478,7 @@ def _on_glue_layer_visible_changed(self, value): self._processing_change_from_glue = False self._update_mixed_state() - def _on_glue_value_changed(self, value): + def _on_glue_value_changed(self, value, update_mixed_state=True): if self._glue_name in ('color_mode', 'linewidth'): # then we need to force updates to the layer-icon colors # NOTE: this will only trigger when the change to color_mode was handled @@ -4513,8 +4513,10 @@ def _on_glue_value_changed(self, value): # it is not skipped if it has already been called since an actual traitlet change) self.plugin._update_stretch_curve() - # need to recompute mixed state - self._update_mixed_state() + if update_mixed_state: + # recompute mixed state + self._update_mixed_state() + self._processing_change_from_glue = False def unmix_state(self, new_value=None):