From 3b276273c3d93165eacd118e9d8ce445ea9d3a0d Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Mon, 11 Nov 2024 14:02:09 -0500 Subject: [PATCH] WIP: RequiresWCSLinking plugin component mixin TODO: * styling should be different for orientation and footprints, but re-using as much of the logic as possible * test coverage --- jdaviz/app.py | 1 + .../plugin_requires_wcs_linking.vue | 78 ++++++++++++++++++ .../imviz/plugins/footprints/footprints.py | 4 +- .../imviz/plugins/footprints/footprints.vue | 25 +++--- .../imviz/plugins/orientation/orientation.py | 73 ++--------------- .../imviz/plugins/orientation/orientation.vue | 54 ++----------- jdaviz/core/template_mixin.py | 80 ++++++++++++++++++- 7 files changed, 184 insertions(+), 131 deletions(-) create mode 100644 jdaviz/components/plugin_requires_wcs_linking.vue diff --git a/jdaviz/app.py b/jdaviz/app.py index 007f907d37..0aa9bf2e1c 100644 --- a/jdaviz/app.py +++ b/jdaviz/app.py @@ -153,6 +153,7 @@ def to_unit(self, data, cid, values, original_units, target_units): 'plugin-slider': 'components/plugin_slider.vue', 'plugin-color-picker': 'components/plugin_color_picker.vue', 'plugin-input-header': 'components/plugin_input_header.vue', + 'plugin-requires-wcs-linking': 'components/plugin_requires_wcs_linking.vue', 'glue-state-sync-wrapper': 'components/glue_state_sync_wrapper.vue', 'data-menu-add-data': 'components/data_menu_add_data.vue', 'data-menu-remove': 'components/data_menu_remove.vue', diff --git a/jdaviz/components/plugin_requires_wcs_linking.vue b/jdaviz/components/plugin_requires_wcs_linking.vue new file mode 100644 index 0000000000..5f95cbc3f7 --- /dev/null +++ b/jdaviz/components/plugin_requires_wcs_linking.vue @@ -0,0 +1,78 @@ + + + diff --git a/jdaviz/configs/imviz/plugins/footprints/footprints.py b/jdaviz/configs/imviz/plugins/footprints/footprints.py index 4340494998..259f39de71 100644 --- a/jdaviz/configs/imviz/plugins/footprints/footprints.py +++ b/jdaviz/configs/imviz/plugins/footprints/footprints.py @@ -10,6 +10,7 @@ from jdaviz.core.region_translators import regions2roi from jdaviz.core.registries import tray_registry from jdaviz.core.template_mixin import (PluginTemplateMixin, ViewerSelectMixin, + RequiresWCSLinkingMixin, EditableSelectPluginComponent, FileImportSelectPluginComponent, HasFileImportSelect) from jdaviz.core.user_api import PluginUserApi @@ -21,7 +22,8 @@ @tray_registry('imviz-footprints', label="Footprints") -class Footprints(PluginTemplateMixin, ViewerSelectMixin, HasFileImportSelect): +class Footprints(PluginTemplateMixin, ViewerSelectMixin, + RequiresWCSLinkingMixin, HasFileImportSelect): """ See the :ref:`Footprints Plugin Documentation ` for more details. diff --git a/jdaviz/configs/imviz/plugins/footprints/footprints.vue b/jdaviz/configs/imviz/plugins/footprints/footprints.vue index d652926c8b..03d21672d1 100644 --- a/jdaviz/configs/imviz/plugins/footprints/footprints.vue +++ b/jdaviz/configs/imviz/plugins/footprints/footprints.vue @@ -27,22 +27,17 @@ > - - cannot plot footprint when aligned by pixels (see Orientation plugin). - - - link by WCS - - - - - no valid viewers (with necessary WCS information) to show footprint overlay. - - + :wcs_linking_available="wcs_linking_available" + :need_clear_astrowidget_markers="need_clear_astrowidget_markers" + :need_clear_subsets="need_clear_subsets" + :api_hints_enabled="false" + :show_link_by_wcs_button="true" + @delete-subsets="delete_subsets" + @reset-astrowidget-markers="reset_astrowidget_markers" + /> +
Display Options diff --git a/jdaviz/configs/imviz/plugins/orientation/orientation.py b/jdaviz/configs/imviz/plugins/orientation/orientation.py index 5b963f03a3..794f1f9202 100644 --- a/jdaviz/configs/imviz/plugins/orientation/orientation.py +++ b/jdaviz/configs/imviz/plugins/orientation/orientation.py @@ -2,9 +2,6 @@ from astropy.utils import deprecated from astropy.wcs.wcsapi import BaseHighLevelWCS from glue.core.link_helpers import LinkSame -from glue.core.message import ( - DataCollectionAddMessage, SubsetCreateMessage, SubsetDeleteMessage -) from glue.core.subset import Subset from glue.core.subset_group import GroupedSubset from glue.plugins.wcs_autolinking.wcs_autolinking import WCSLink, NoAffineApproximation @@ -15,14 +12,14 @@ ) from jdaviz.core.custom_traitlets import FloatHandleEmpty from jdaviz.core.events import ( - ExitBatchLoadMessage, ChangeRefDataMessage, - AstrowidgetMarkersChangedMessage, MarkersPluginUpdate, + ChangeRefDataMessage, SnackbarMessage, ViewerAddedMessage, AddDataMessage, LinkUpdatedMessage ) from jdaviz.core.registries import tray_registry from jdaviz.core.template_mixin import ( - PluginTemplateMixin, SelectPluginComponent, LayerSelect, ViewerSelectMixin, AutoTextField + PluginTemplateMixin, + RequiresWCSLinkingMixin, SelectPluginComponent, LayerSelect, ViewerSelectMixin, AutoTextField ) from jdaviz.core.user_api import PluginUserApi from jdaviz.utils import get_reference_image_data, layer_is_2d, _wcs_only_label @@ -34,7 +31,7 @@ @tray_registry('imviz-orientation', label="Orientation", viewer_requirements="image") -class Orientation(PluginTemplateMixin, ViewerSelectMixin): +class Orientation(PluginTemplateMixin, RequiresWCSLinkingMixin, ViewerSelectMixin): """ See the :ref:`Orientation Plugin Documentation ` for more details. @@ -66,12 +63,8 @@ class Orientation(PluginTemplateMixin, ViewerSelectMixin): align_by_selected = Unicode().tag(sync=True) wcs_use_fallback = Bool(True).tag(sync=True) wcs_fast_approximation = Bool(True).tag(sync=True) - wcs_linking_available = Bool(False).tag(sync=True) - need_clear_astrowidget_markers = Bool(False).tag(sync=True) - plugin_markers_exist = Bool(False).tag(sync=True) linking_in_progress = Bool(False).tag(sync=True) - need_clear_subsets = Bool(False).tag(sync=True) # rotation angle, counterclockwise [degrees] rotation_angle = FloatHandleEmpty(0).tag(sync=True) @@ -108,27 +101,9 @@ def __init__(self, *args, **kwargs): self, 'new_layer_label', 'new_layer_label_default', 'new_layer_label_auto', None ) - self.hub.subscribe(self, DataCollectionAddMessage, - handler=self._on_new_app_data) - - self.hub.subscribe(self, ExitBatchLoadMessage, - handler=self._on_new_app_data) - - self.hub.subscribe(self, AstrowidgetMarkersChangedMessage, - handler=self._on_astrowidget_markers_changed) - - self.hub.subscribe(self, MarkersPluginUpdate, - handler=self._on_markers_plugin_update) - self.hub.subscribe(self, ChangeRefDataMessage, handler=self._on_refdata_change) - self.hub.subscribe(self, SubsetCreateMessage, - handler=self._on_subset_change) - - self.hub.subscribe(self, SubsetDeleteMessage, - handler=self._on_subset_change) - self.hub.subscribe(self, ViewerAddedMessage, handler=self._on_viewer_added) @@ -187,32 +162,9 @@ def _link_image_data(self): finally: self.linking_in_progress = False - def _check_if_data_with_wcs_exists(self): - for data in self.app.data_collection: - if hasattr(data.coords, 'pixel_to_world'): - self.wcs_linking_available = True - return - self.wcs_linking_available = False - def _on_new_app_data(self, msg): - if self.app._jdaviz_helper._in_batch_load > 0: - return - if isinstance(msg, DataCollectionAddMessage): - components = [str(comp) for comp in msg.data.main_components] - if "ra" in components or "Lon" in components: - # linking currently removes any markers, so we want to skip - # linking immediately after new markers are added. - # Eventually we'll probably want to support linking WITH markers, - # at which point this if-statement should be removed. - return + super()._on_new_app_data(msg) self._link_image_data() - self._check_if_data_with_wcs_exists() - - def _on_astrowidget_markers_changed(self, msg): - self.need_clear_astrowidget_markers = msg.has_markers - - def _on_markers_plugin_update(self, msg): - self.plugin_markers_exist = msg.table_length > 0 @observe('align_by_selected', 'wcs_use_fallback', 'wcs_fast_approximation') def _update_link(self, msg={}): @@ -277,21 +229,6 @@ def _update_link(self, msg={}): for v in self.app._viewer_store.values(): v._prev_limits = None - def _on_subset_change(self, msg): - self.need_clear_subsets = len(self.app.data_collection.subset_groups) > 0 - - def delete_subsets(self): - # subsets will be deleted on changing link type: - for subset_group in self.app.data_collection.subset_groups: - self.app.data_collection.remove_subset_group(subset_group) - - def vue_delete_subsets(self, *args): - self.delete_subsets() - - def vue_reset_astrowidget_markers(self, *args): - for viewer in self.app._viewer_store.values(): - viewer.reset_markers() - def _get_wcs_angles(self, first_loaded_image=None): if first_loaded_image is None: first_loaded_image = self.viewer.selected_obj.first_loaded_data diff --git a/jdaviz/configs/imviz/plugins/orientation/orientation.vue b/jdaviz/configs/imviz/plugins/orientation/orientation.vue index 1f0a4a6f5e..c527bb05c9 100644 --- a/jdaviz/configs/imviz/plugins/orientation/orientation.vue +++ b/jdaviz/configs/imviz/plugins/orientation/orientation.vue @@ -13,52 +13,14 @@
Align Layers - - Please add at least one data with valid WCS to align by sky (WCS). - - - - Switching alignment will reset zoom. - - - - Marker positions may not be pixel-perfect when changing alignment/linking options. - - - - Astrowidget markers must be cleared before changing alignment/linking options. - - Clear Markers - - - - - - Existing subsets must be deleted before changing alignment/linking options. - - - {{ api_hints_enabled ? - 'plg.delete_subsets()' - : - 'Clear Subsets' - }} - - - + 0 + + def _on_subset_change(self, msg): + self.need_clear_subsets = len(self.app.data_collection.subset_groups) > 0 + + def _check_if_data_with_wcs_exists(self): + for data in self.app.data_collection: + if hasattr(data.coords, 'pixel_to_world'): + self.wcs_linking_available = True + return + self.wcs_linking_available = False + + def _on_new_app_data(self, msg): + if self.app._jdaviz_helper._in_batch_load > 0: + return + if isinstance(msg, DataCollectionAddMessage): + components = [str(comp) for comp in msg.data.main_components] + if "ra" in components or "Lon" in components: + # linking currently removes any markers, so we want to skip + # linking immediately after new markers are added. + # Eventually we'll probably want to support linking WITH markers, + # at which point this if-statement should be removed. + return + self._check_if_data_with_wcs_exists() + + def delete_subsets(self): + # subsets will be deleted on changing link type: + for subset_group in self.app.data_collection.subset_groups: + self.app.data_collection.remove_subset_group(subset_group) + + def vue_delete_subsets(self, *args): + self.delete_subsets() + + def vue_reset_astrowidget_markers(self, *args): + for viewer in self.app._viewer_store.values(): + viewer.reset_markers() + + class EditableSelectPluginComponent(SelectPluginComponent): """ Plugin select with support for renaming, adding, and deleting items (by the user).