From 4b7188acb0cab601d966b91a4156cf1c6e9b0d4e Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Tue, 30 Jan 2024 15:12:40 -0500 Subject: [PATCH] lcviz cube support (#2678) * lcviz-case for cube mouseover * stretch histogram - use layer attribute instead of assuming first * refactor coords info so downstream can override * downstream implementation in https://github.com/spacetelescope/lcviz/pull/83 --- jdaviz/components/viewer_data_select.vue | 11 ++++-- .../plugins/plot_options/plot_options.py | 7 ++-- .../imviz/plugins/coords_info/coords_info.py | 34 ++++++++++++------- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/jdaviz/components/viewer_data_select.vue b/jdaviz/components/viewer_data_select.vue index 0bc734e7bf..29e65c65c4 100644 --- a/jdaviz/components/viewer_data_select.vue +++ b/jdaviz/components/viewer_data_select.vue @@ -127,6 +127,10 @@ module.exports = { if (this.$props.viewer.reference === 'spectrum-2d-viewer') { multi_select = false } + } else if (this.$props.viewer.config === 'lcviz') { + if (this.$props.viewer.reference.startsWith('image')) { + multi_select = false + } } return { // default to passed values, whenever value or uncertainty are changed @@ -193,14 +197,17 @@ module.exports = { } } else if (this.$props.viewer.config === 'lcviz') { // TODO: generalize itemIsVisible so downstream apps can provide their own customized filters + if (this.$props.viewer.reference.startsWith('image')) { + return (item.ndims === 3 && this.dataItemInViewer(item, returnExtraItems)) + } if (item.meta._LCVIZ_EPHEMERIS !== undefined) { if (!this.$props.viewer.reference.startsWith('flux-vs-phase:')) { return false } var viewer_ephem_comp = this.$props.viewer.reference.split('flux-vs-phase:')[1].split('[')[0] - return item.meta._LCVIZ_EPHEMERIS.ephemeris == viewer_ephem_comp && this.dataItemInViewer(item, returnExtraItems) + return item.ndims === 1 && item.meta._LCVIZ_EPHEMERIS.ephemeris == viewer_ephem_comp && this.dataItemInViewer(item, returnExtraItems) } - return this.dataItemInViewer(item, returnExtraItems) + return item.ndims === 1 && this.dataItemInViewer(item, returnExtraItems) } else if (this.$props.viewer.config === 'imviz') { return this.dataItemInViewer(item, returnExtraItems && !this.wcsOnlyItem(item)) } diff --git a/jdaviz/configs/default/plugins/plot_options/plot_options.py b/jdaviz/configs/default/plugins/plot_options/plot_options.py index 4b8d6c6d6e..3dceddb5c4 100644 --- a/jdaviz/configs/default/plugins/plot_options/plot_options.py +++ b/jdaviz/configs/default/plugins/plot_options/plot_options.py @@ -878,15 +878,16 @@ def _update_stretch_histogram(self, msg={}): if not len(self.layer.selected_obj[0]): return # multiselect case (but we won't check multiselect since the selection can lag behind) - data = self.layer.selected_obj[0][0].layer + layer = self.layer.selected_obj[0][0] else: - data = self.layer.selected_obj[0].layer + layer = self.layer.selected_obj[0] + data = layer.layer if isinstance(data, GroupedSubset): # don't update histogram for subsets: return - comp = data.get_component(data.main_components[0]) + comp = data.get_component(layer.state.attribute) # TODO: further optimization could be done by caching sub_data if self.stretch_hist_zoom_limits and (not self.layer_multiselect or len(self.layer_selected) == 1): # noqa diff --git a/jdaviz/configs/imviz/plugins/coords_info/coords_info.py b/jdaviz/configs/imviz/plugins/coords_info/coords_info.py index b76e64e09a..5ec7fbfbe4 100644 --- a/jdaviz/configs/imviz/plugins/coords_info/coords_info.py +++ b/jdaviz/configs/imviz/plugins/coords_info/coords_info.py @@ -226,6 +226,25 @@ def update_display(self, viewer, x, y): (ImvizImageView, CubevizImageView, MosvizImageView, MosvizProfile2DView)): self._image_viewer_update(viewer, x, y) + def _image_shape_inds(self, image): + # return the indices in image.shape for the x and y dimension, respectively + if image.ndim == 3: + # cubeviz case + return (0, 1) # (ix_shape, iy_shape) + elif image.ndim == 2: + return (1, 0) # (ix_shape, iy_shape) + else: # pragma: no cover + raise ValueError(f'does not support ndim={image.ndim}') + + def _get_cube_value(self, image, arr, x, y, viewer): + if image.ndim == 3: + # cubeviz case: + return arr[int(round(x)), int(round(y)), viewer.state.slices[-1]] + elif image.ndim == 2: + return arr[int(round(y)), int(round(x))] + else: # pragma: no cover + raise ValueError(f'does not support ndim={image.ndim}') + def _image_viewer_update(self, viewer, x, y): # Display the current cursor coordinates (both pixel and world) as # well as data values. For now we use the first dataset in the @@ -406,15 +425,7 @@ def _image_viewer_update(self, viewer, x, y): # Extract data values at this position. # Check if shape is [x, y, z] or [y, x] and show value accordingly. - if image.ndim == 3: - # needed for cubeviz - ix_shape = 0 - iy_shape = 1 - elif image.ndim == 2: - ix_shape = 1 - iy_shape = 0 - else: # pragma: no cover - raise ValueError(f'does not support ndim={image.ndim}') + ix_shape, iy_shape = self._image_shape_inds(image) if (-0.5 < x < image.shape[ix_shape] - 0.5 and -0.5 < y < image.shape[iy_shape] - 0.5 and hasattr(active_layer, 'attribute')): @@ -425,10 +436,7 @@ def _image_viewer_update(self, viewer, x, y): elif isinstance(viewer, CubevizImageView): arr = image.get_component(attribute).data unit = image.get_component(attribute).units - if image.ndim == 3: - value = arr[int(round(x)), int(round(y)), viewer.state.slices[-1]] - else: # 2 - value = arr[int(round(y)), int(round(x))] + value = self._get_cube_value(image, arr, x, y, viewer) self.row1b_title = 'Value' self.row1b_text = f'{value:+10.5e} {unit}' self._dict['value'] = float(value)