diff --git a/CHANGES.rst b/CHANGES.rst index be0501a337..270d17759c 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -36,6 +36,9 @@ Imviz - Added Gaia catalog to Catalog plugin. [#3090] +- Updated ``link_type`` to ``align_by`` and ``wcs_use_affine`` to ``wcs_fast_approximation`` in + Orientation plugin API to better match UI text. [#3128] + Mosviz ^^^^^^ diff --git a/jdaviz/app.py b/jdaviz/app.py index 775d9169c0..47f7a9646d 100644 --- a/jdaviz/app.py +++ b/jdaviz/app.py @@ -325,9 +325,9 @@ def __init__(self, configuration=None, *args, **kwargs): self.auto_link = kwargs.pop('auto_link', True) # Imviz linking - self._link_type = 'pixels' + self._align_by = 'pixels' if self.config == "imviz": - self._wcs_use_affine = None + self._wcs_fast_approximation = None # Subscribe to messages indicating that a new viewer needs to be # created. When received, information is passed to the application @@ -1938,7 +1938,7 @@ def _reparent_subsets(self, old_parent, new_parent=None): # Translate bounds through WCS if needed if (self.config == "imviz" and - self._jdaviz_helper.plugins["Orientation"].link_type == "WCS"): + self._jdaviz_helper.plugins["Orientation"].align_by == "WCS"): # Default shape for WCS-only layers is 10x10, but it doesn't really matter # since we only need the angles. @@ -2219,7 +2219,7 @@ def vue_data_item_remove(self, event): # Make sure the data isn't loaded in any viewers and isn't the selected orientation for viewer_id, viewer in self._viewer_store.items(): - if orientation_plugin is not None and self._link_type == 'wcs': + if orientation_plugin is not None and self._align_by == 'wcs': if viewer.state.reference_data.label == data_label: self._change_reference_data(base_wcs_layer_label, viewer_id) self.remove_data_from_viewer(viewer_id, data_label) @@ -2506,12 +2506,12 @@ def _on_new_viewer(self, msg, vid=None, name=None, add_layers_to_viewer=False, msg.cls, data=msg.data, show=False) viewer.figure_widget.layout.height = '100%' - linked_by_wcs = self._link_type == 'wcs' + linked_by_wcs = self._align_by == 'wcs' if hasattr(viewer.state, 'linked_by_wcs'): orientation_plugin = self._jdaviz_helper.plugins.get('Orientation', None) if orientation_plugin is not None: - linked_by_wcs = orientation_plugin.link_type.selected == 'WCS' + linked_by_wcs = orientation_plugin.align_by.selected == 'WCS' elif len(self._viewer_store) and hasattr(self._jdaviz_helper, 'default_viewer'): # The plugin would only not exist for instances of Imviz where the user has # intentionally removed the Orientation plugin, but in that case we will diff --git a/jdaviz/configs/default/plugins/export/export.py b/jdaviz/configs/default/plugins/export/export.py index f62fd8cb6c..5734e63f66 100644 --- a/jdaviz/configs/default/plugins/export/export.py +++ b/jdaviz/configs/default/plugins/export/export.py @@ -728,12 +728,12 @@ def save_subset_as_region(self, selected_subset_label, filename): """ # type of region saved depends on link type - link_type = getattr(self.app, '_link_type', None) + align_by = getattr(self.app, '_align_by', None) region = self.app.get_subsets(subset_name=selected_subset_label, - include_sky_region=link_type == 'wcs') + include_sky_region=align_by == 'wcs') - region = region[0][f'{"sky_" if link_type == "wcs" else ""}region'] + region = region[0][f'{"sky_" if align_by == "wcs" else ""}region'] region.write(str(filename), overwrite=True) diff --git a/jdaviz/configs/default/plugins/export/tests/test_export.py b/jdaviz/configs/default/plugins/export/tests/test_export.py index 701f07aca9..ebec3820d9 100644 --- a/jdaviz/configs/default/plugins/export/tests/test_export.py +++ b/jdaviz/configs/default/plugins/export/tests/test_export.py @@ -105,7 +105,7 @@ def test_export_subsets_wcs(self, imviz_helper, spectral_cube_wcs): imviz_helper.load_data(data) # load data twice so we can link them imviz_helper.load_data(data) - imviz_helper.link_data(link_type='wcs') + imviz_helper.link_data(align_by='wcs') imviz_helper.app.get_viewer('imviz-0').apply_roi(CircularROI(xc=8, yc=6, diff --git a/jdaviz/configs/default/plugins/markers/markers.py b/jdaviz/configs/default/plugins/markers/markers.py index 59dc0067f3..8f3a27c749 100644 --- a/jdaviz/configs/default/plugins/markers/markers.py +++ b/jdaviz/configs/default/plugins/markers/markers.py @@ -129,7 +129,7 @@ def _recompute_mark_positions(self, viewer): orig_world_x = np.asarray(self.table._qtable['world_ra'][in_viewer]) orig_world_y = np.asarray(self.table._qtable['world_dec'][in_viewer]) - if self.app._link_type.lower() == 'wcs': + if self.app._align_by.lower() == 'wcs': # convert from the sky coordinates in the table to pixels via the WCS of the current # reference data new_wcs = viewer.state.reference_data.coords @@ -139,7 +139,7 @@ def _recompute_mark_positions(self, viewer): except Exception: # fail gracefully new_x, new_y = [], [] - elif self.app._link_type == 'pixels': + elif self.app._align_by == 'pixels': # we need to convert based on the WCS of the individual data layers on which each mark # was first created new_x, new_y = np.zeros_like(orig_world_x), np.zeros_like(orig_world_y) @@ -156,7 +156,7 @@ def _recompute_mark_positions(self, viewer): new_x, new_y = [], [] break else: - raise NotImplementedError(f"link_type {self.app._link_type} not implemented") + raise NotImplementedError(f"align_by {self.app._align_by} not implemented") # check for entries that do not correspond to a layer or only have pixel coordinates pixel_only_inds = data_labels == '' diff --git a/jdaviz/configs/default/plugins/plot_options/plot_options.py b/jdaviz/configs/default/plugins/plot_options/plot_options.py index d77aa30451..e457061fa1 100644 --- a/jdaviz/configs/default/plugins/plot_options/plot_options.py +++ b/jdaviz/configs/default/plugins/plot_options/plot_options.py @@ -741,7 +741,7 @@ def _on_global_display_unit_changed(self, *args): self.send_state('display_units') def _on_refdata_change(self, *args): - if self.app._link_type.lower() == 'wcs': + if self.app._align_by.lower() == 'wcs': self.display_units['image'] = 'deg' else: self.display_units['image'] = 'pix' diff --git a/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py b/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py index 891fb57846..d963bdd12d 100644 --- a/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py +++ b/jdaviz/configs/default/plugins/subset_plugin/subset_plugin.py @@ -90,8 +90,8 @@ def __init__(self, *args, **kwargs): self.subset_states = [] self.spectral_display_unit = None - link_type = getattr(self.app, '_link_type', None) - self.display_sky_coordinates = (link_type == 'wcs' and not self.multiselect) + align_by = getattr(self.app, '_align_by', None) + self.display_sky_coordinates = (align_by == 'wcs' and not self.multiselect) def _on_link_update(self, *args): """When linking is changed pixels<>wcs, change display units of the @@ -100,8 +100,8 @@ def _on_link_update(self, *args): to the UI upon link change by calling _get_subset_definition, which will re-determine how to display subset information.""" - link_type = getattr(self.app, '_link_type', None) - self.display_sky_coordinates = (link_type == 'wcs') + align_by = getattr(self.app, '_align_by', None) + self.display_sky_coordinates = (align_by == 'wcs') if self.subset_selected != self.subset_select.default_text: self._get_subset_definition(*args) diff --git a/jdaviz/configs/default/plugins/subset_plugin/tests/test_subset_plugin.py b/jdaviz/configs/default/plugins/subset_plugin/tests/test_subset_plugin.py index b9edeba99d..0c1e56df08 100644 --- a/jdaviz/configs/default/plugins/subset_plugin/tests/test_subset_plugin.py +++ b/jdaviz/configs/default/plugins/subset_plugin/tests/test_subset_plugin.py @@ -138,7 +138,7 @@ def test_circle_recenter_linking(roi_class, subset_info, imviz_helper, image_2d_ # remove subsets and change link type to wcs dc = imviz_helper.app.data_collection dc.remove_subset_group(dc.subset_groups[0]) - imviz_helper.link_data(link_type='wcs') + imviz_helper.link_data(align_by='wcs') assert plugin.display_sky_coordinates # linking change should trigger change to True # apply original subset. transform sky coord of original subset to new pixels diff --git a/jdaviz/configs/imviz/helper.py b/jdaviz/configs/imviz/helper.py index 92c7b93c6d..dbd97f369c 100644 --- a/jdaviz/configs/imviz/helper.py +++ b/jdaviz/configs/imviz/helper.py @@ -3,6 +3,7 @@ import warnings from copy import deepcopy +from astropy.utils import deprecated import numpy as np from glue.core.link_helpers import LinkSame @@ -190,7 +191,7 @@ def load_data(self, data, data_label=None, show_in_viewer=True, **kwargs): show_in_viewer = f"{self.app.config}-0" if show_in_viewer: - linked_by_wcs = self.app._link_type == 'wcs' + linked_by_wcs = self.app._align_by == 'wcs' if linked_by_wcs: for applied_label, visible, is_wcs_only, has_wcs in zip( applied_labels, applied_visible, layer_is_wcs_only, layer_has_wcs @@ -211,7 +212,7 @@ def load_data(self, data, data_label=None, show_in_viewer=True, **kwargs): else: if 'Orientation' not in self.plugins.keys(): # otherwise plugin will handle linking automatically with DataCollectionAddMessage - self.link_data(link_type='wcs') + self.link_data(align_by='wcs') # One input might load into multiple Data objects. # NOTE: If the batch_load context manager was used, it will @@ -223,35 +224,39 @@ def load_data(self, data, data_label=None, show_in_viewer=True, **kwargs): if (has_wcs and linked_by_wcs) or not linked_by_wcs: self.app.add_data_to_viewer(show_in_viewer, applied_label, visible=visible) - def link_data(self, link_type='pixels', wcs_fallback_scheme=None, wcs_use_affine=True): + def link_data(self, align_by='pixels', wcs_fallback_scheme=None, wcs_fast_approximation=True): """(Re)link loaded data in Imviz with the desired link type. All existing links will be replaced. Parameters ---------- - link_type : {'pixels', 'wcs'} + align_by : {'pixels', 'wcs'} Choose to link by pixels or WCS. wcs_fallback_scheme : {None, 'pixels'} If WCS linking failed, choose to fall back to linking by pixels or not at all. - This is only used when ``link_type='wcs'``. + This is only used when ``align_by='wcs'``. Choosing `None` may result in some Imviz functionality not working properly. - wcs_use_affine : bool + wcs_fast_approximation : bool Use an affine transform to represent the offset between images if possible (requires that the approximation is accurate to within 1 pixel with the full WCS transformations). If approximation fails, it will automatically - fall back to full WCS transformation. This is only used when ``link_type='wcs'``. + fall back to full WCS transformation. This is only used when ``align_by='wcs'``. Affine approximation is much more performant at the cost of accuracy. """ - from jdaviz.configs.imviz.plugins.orientation.orientation import link_type_msg_to_trait + from jdaviz.configs.imviz.plugins.orientation.orientation import align_by_msg_to_trait plg = self.plugins["Orientation"] plg._obj.wcs_use_fallback = wcs_fallback_scheme == 'pixels' - plg.wcs_use_affine = wcs_use_affine - plg.link_type = link_type_msg_to_trait[link_type] + plg.wcs_fast_approximation = wcs_fast_approximation + plg.align_by = align_by_msg_to_trait[align_by] + @deprecated(since="4.0", alternative="get_alignment_method") def get_link_type(self, data_label_1, data_label_2): + return self.get_alignment_method(data_label_1, data_label_2) + + def get_alignment_method(self, data_label_1, data_label_2): """Find the type of ``glue`` linking between the given data labels. A link is bi-directional. If there are more than 2 data in the collection, one of the given @@ -264,7 +269,7 @@ def get_link_type(self, data_label_1, data_label_2): Returns ------- - link_type : {'pixels', 'wcs', 'self'} + align_by : {'pixels', 'wcs', 'self'} One of the link types accepted by the Orientation plugin or ``'self'`` if the labels are identical. @@ -277,23 +282,23 @@ def get_link_type(self, data_label_1, data_label_2): if data_label_1 == data_label_2: return "self" - link_type = None + align_by = None for elink in self.app.data_collection.external_links: elink_labels = (elink.data1.label, elink.data2.label) if data_label_1 in elink_labels and data_label_2 in elink_labels: if isinstance(elink, LinkSame): # Assumes WCS link never uses LinkSame - link_type = 'pixels' + align_by = 'pixels' else: # If not pixels, must be WCS - link_type = 'wcs' + align_by = 'wcs' break # Might have duplicate, just grab first match - if link_type is None: + if align_by is None: avail_links = [f"({elink.data1.label}, {elink.data2.label})" for elink in self.app.data_collection.external_links] raise ValueError(f'{data_label_1} and {data_label_2} combo not found ' f'in data collection external links: {avail_links}') - return link_type + return align_by def get_aperture_photometry_results(self): """Return aperture photometry results, if any. diff --git a/jdaviz/configs/imviz/plugins/footprints/footprints.py b/jdaviz/configs/imviz/plugins/footprints/footprints.py index 6df321eef6..8e082ae60e 100644 --- a/jdaviz/configs/imviz/plugins/footprints/footprints.py +++ b/jdaviz/configs/imviz/plugins/footprints/footprints.py @@ -180,7 +180,7 @@ def _ensure_sky(region): return '', {path: region} def _on_link_type_updated(self, msg=None): - self.is_pixel_linked = (getattr(self.app, '_link_type', None) == 'pixels' and + self.is_pixel_linked = (getattr(self.app, '_align_by', None) == 'pixels' and len(self.app.data_collection) > 1) # toggle visibility as necessary self._on_is_active_changed() @@ -193,10 +193,10 @@ def _on_link_type_updated(self, msg=None): self._change_overlay(overlay_selected=choice, center_the_overlay=False) def vue_link_by_wcs(self, *args): - # call other plugin so that other options (wcs_use_affine, wcs_use_fallback) + # call other plugin so that other options (wcs_fast_approximation, wcs_use_fallback) # are retained. Remove this method if support for plotting footprints # when pixel-linked is reintroduced. - self.app._jdaviz_helper.plugins['Orientation'].link_type = 'WCS' + self.app._jdaviz_helper.plugins['Orientation'].align_by = 'WCS' def _ensure_first_overlay(self): if not len(self._overlays): diff --git a/jdaviz/configs/imviz/plugins/orientation/orientation.py b/jdaviz/configs/imviz/plugins/orientation/orientation.py index 2f1a36a7e8..5b963f03a3 100644 --- a/jdaviz/configs/imviz/plugins/orientation/orientation.py +++ b/jdaviz/configs/imviz/plugins/orientation/orientation.py @@ -1,4 +1,5 @@ from astropy import units as u +from astropy.utils import deprecated from astropy.wcs.wcsapi import BaseHighLevelWCS from glue.core.link_helpers import LinkSame from glue.core.message import ( @@ -29,7 +30,7 @@ __all__ = ['Orientation'] base_wcs_layer_label = 'Default orientation' -link_type_msg_to_trait = {'pixels': 'Pixels', 'wcs': 'WCS'} +align_by_msg_to_trait = {'pixels': 'Pixels', 'wcs': 'WCS'} @tray_registry('imviz-orientation', label="Orientation", viewer_requirements="image") @@ -50,8 +51,8 @@ class Orientation(PluginTemplateMixin, ViewerSelectMixin): * :meth:`~jdaviz.core.template_mixin.PluginTemplateMixin.show` * :meth:`~jdaviz.core.template_mixin.PluginTemplateMixin.open_in_tray` * :meth:`~jdaviz.core.template_mixin.PluginTemplateMixin.close_in_tray` - * ``link_type`` (`~jdaviz.core.template_mixin.SelectPluginComponent`) - * ``wcs_use_affine`` + * ``align_by`` (`~jdaviz.core.template_mixin.SelectPluginComponent`) + * ``wcs_fast_approximation`` * ``delete_subsets`` * ``viewer`` * ``orientation`` @@ -61,10 +62,10 @@ class Orientation(PluginTemplateMixin, ViewerSelectMixin): """ template_file = __file__, "orientation.vue" - link_type_items = List().tag(sync=True) - link_type_selected = Unicode().tag(sync=True) + align_by_items = List().tag(sync=True) + align_by_selected = Unicode().tag(sync=True) wcs_use_fallback = Bool(True).tag(sync=True) - wcs_use_affine = 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) @@ -94,10 +95,10 @@ def __init__(self, *args, **kwargs): self.icons = {k: v for k, v in self.app.state.icons.items()} - self.link_type = SelectPluginComponent(self, - items='link_type_items', - selected='link_type_selected', - manual_options=['Pixels', 'WCS']) + self.align_by = SelectPluginComponent(self, + items='align_by_items', + selected='align_by_selected', + manual_options=['Pixels', 'WCS']) self.orientation = LayerSelect( self, 'orientation_layer_items', 'orientation_layer_selected', 'viewer_selected', @@ -141,28 +142,48 @@ def user_api(self): return PluginUserApi( self, expose=( - 'link_type', 'wcs_use_affine', 'delete_subsets', - 'viewer', 'orientation', + 'align_by', 'link_type', 'wcs_fast_approximation', 'wcs_use_affine', + 'delete_subsets', 'viewer', 'orientation', 'rotation_angle', 'east_left', 'add_orientation' ) ) + @property + @deprecated(since="4.0", alternative="align_by") + def link_type(self): + return self.align_by + + @link_type.setter + @deprecated(since="4.0", alternative="align_by") + def link_type(self, link_type): + self.align_by = link_type + + @property + @deprecated(since="4.0", alternative="wcs_fast_approximation") + def wcs_use_affine(self): + return self.wcs_fast_approximation + + @wcs_use_affine.setter + @deprecated(since="4.0", alternative="wcs_fast_approximation") + def wcs_use_affine(self, wcs_use_affine): + self.wcs_fast_approximation = wcs_use_affine + def _link_image_data(self): self.linking_in_progress = True try: - link_type = self.link_type.selected.lower() + align_by = self.align_by.selected.lower() link_image_data( self.app, - link_type=link_type, + align_by=align_by, wcs_fallback_scheme='pixels' if self.wcs_use_fallback else None, - wcs_use_affine=self.wcs_use_affine, + wcs_fast_approximation=self.wcs_fast_approximation, error_on_fail=False) except Exception: # pragma: no cover raise else: # Only broadcast after success. self.app.hub.broadcast(LinkUpdatedMessage( - link_type, self.wcs_use_fallback, self.wcs_use_affine, sender=self.app)) + align_by, self.wcs_use_fallback, self.wcs_fast_approximation, sender=self.app)) finally: self.linking_in_progress = False @@ -193,14 +214,14 @@ def _on_astrowidget_markers_changed(self, msg): def _on_markers_plugin_update(self, msg): self.plugin_markers_exist = msg.table_length > 0 - @observe('link_type_selected', 'wcs_use_fallback', 'wcs_use_affine') + @observe('align_by_selected', 'wcs_use_fallback', 'wcs_fast_approximation') def _update_link(self, msg={}): """Run link_image_data with the selected parameters.""" - if not hasattr(self, 'link_type'): + if not hasattr(self, 'align_by'): # could happen before plugin is fully initialized return - if msg.get('name', None) == 'wcs_use_affine' and self.link_type.selected == 'Pixels': + if msg.get('name', None) == 'wcs_fast_approximation' and self.align_by.selected == 'Pixels': # noqa # approximation doesn't apply, avoid updating when not necessary! return @@ -222,8 +243,8 @@ def _update_link(self, msg={}): raise ValueError(f"cannot change linking with markers present (value reverted to " f"'{msg.get('old')}'), call viewer.reset_markers()") - if self.link_type.selected == 'Pixels': - self.wcs_use_affine = True + if self.align_by.selected == 'Pixels': + self.wcs_fast_approximation = True self.linking_in_progress = False self._link_image_data() @@ -231,7 +252,7 @@ def _update_link(self, msg={}): # load data into the viewer that are now compatible with the # new link type, remove data from the viewer that are now # incompatible: - wcs_linked = self.link_type.selected == 'WCS' + wcs_linked = self.align_by.selected == 'WCS' viewer_selected = self.app.get_viewer(self.viewer.selected) data_in_viewer = self.app.get_viewer(viewer_selected.reference).data() @@ -332,7 +353,7 @@ def add_orientation(self, rotation_angle=None, east_left=None, label=None, def _add_orientation(self, rotation_angle=None, east_left=None, label=None, set_on_create=True, wrt_data=None, from_ui=False): - if self.link_type_selected != 'WCS': + if self.align_by_selected != 'WCS': raise ValueError("must be aligned by WCS to add orientation options") if wrt_data is None: @@ -406,14 +427,14 @@ def _send_wcs_layers_to_all_viewers(self, *args, **kwargs): ) for viewer_ref in viewers_to_update: self.viewer.selected = viewer_ref - self.orientation.update_wcs_only_filter(wcs_only=self.link_type_selected == 'WCS') + self.orientation.update_wcs_only_filter(wcs_only=self.align_by_selected == 'WCS') for wcs_layer in wcs_only_layers: if wcs_layer not in self.viewer.selected_obj.layers: self.app.add_data_to_viewer(viewer_ref, wcs_layer) if ( self.orientation.selected not in self.viewer.selected_obj.state.wcs_only_layers and - self.link_type_selected == 'WCS' + self.align_by_selected == 'WCS' ): self.orientation.selected = base_wcs_layer_label @@ -448,11 +469,11 @@ def _on_refdata_change(self, msg): # don't select until reference data are available: if ref_data is not None: - link_type = viewer.get_link_type(ref_data.label) - if link_type != 'self': - self.link_type_selected = link_type_msg_to_trait[link_type] + align_by = viewer.get_alignment_method(ref_data.label) + if align_by != 'self': + self.align_by_selected = align_by_msg_to_trait[align_by] elif not len(viewer.data()): - self.link_type_selected = link_type_msg_to_trait['pixels'] + self.align_by_selected = align_by_msg_to_trait['pixels'] if msg.data.label not in self.orientation.choices: return @@ -545,7 +566,7 @@ def _update_layer_label_default(self, event={}): ) -def link_image_data(app, link_type='pixels', wcs_fallback_scheme=None, wcs_use_affine=True, +def link_image_data(app, align_by='pixels', wcs_fallback_scheme=None, wcs_fast_approximation=True, error_on_fail=False): """(Re)link loaded data in Imviz with the desired link type. @@ -561,19 +582,19 @@ def link_image_data(app, link_type='pixels', wcs_fallback_scheme=None, wcs_use_a app : `~jdaviz.app.Application` Application associated with Imviz, e.g., ``imviz.app``. - link_type : {'pixels', 'wcs'} + align_by : {'pixels', 'wcs'} Choose to link by pixels or WCS. wcs_fallback_scheme : {None, 'pixels'} If WCS linking failed, choose to fall back to linking by pixels or not at all. - This is only used when ``link_type='wcs'``. + This is only used when ``align_by='wcs'``. Choosing `None` may result in some Imviz functionality not working properly. - wcs_use_affine : bool + wcs_fast_approximation : bool Use an affine transform to represent the offset between images if possible (requires that the approximation is accurate to within 1 pixel with the full WCS transformations). If approximation fails, it will automatically - fall back to full WCS transformation. This is only used when ``link_type='wcs'``. + fall back to full WCS transformation. This is only used when ``align_by='wcs'``. Affine approximation is much more performant at the cost of accuracy. error_on_fail : bool @@ -588,15 +609,15 @@ def link_image_data(app, link_type='pixels', wcs_fallback_scheme=None, wcs_use_a Invalid inputs or reference data. """ - if len(app.data_collection) <= 1 and link_type != 'wcs': # No need to link, we are done. + if len(app.data_collection) <= 1 and align_by != 'wcs': # No need to link, we are done. return - if link_type not in ('pixels', 'wcs'): # pragma: no cover - raise ValueError(f"link_type must be 'pixels' or 'wcs', got {link_type}") - if link_type == 'wcs' and wcs_fallback_scheme not in (None, 'pixels'): # pragma: no cover + if align_by not in ('pixels', 'wcs'): # pragma: no cover + raise ValueError(f"align_by must be 'pixels' or 'wcs', got {align_by}") + if align_by == 'wcs' and wcs_fallback_scheme not in (None, 'pixels'): # pragma: no cover raise ValueError("wcs_fallback_scheme must be None or 'pixels', " f"got {wcs_fallback_scheme}") - if link_type == 'wcs': + if align_by == 'wcs': at_least_one_data_have_wcs = len([ hasattr(d, 'coords') and isinstance(d.coords, BaseHighLevelWCS) for d in app.data_collection @@ -604,15 +625,15 @@ def link_image_data(app, link_type='pixels', wcs_fallback_scheme=None, wcs_use_a if not at_least_one_data_have_wcs: # pragma: no cover if wcs_fallback_scheme is None: if error_on_fail: - raise ValueError("link_type can only be 'wcs' when wcs_fallback_scheme " + raise ValueError("align_by can only be 'wcs' when wcs_fallback_scheme " "is 'None' if at least one image has a valid WCS.") else: return else: # fall back on pixel linking - link_type = 'pixels' + align_by = 'pixels' - old_link_type = getattr(app, '_link_type', None) + old_align_by = getattr(app, '_align_by', None) # In WCS linking, changing orientation layer is done within Orientation plugin, # so here we assume viewer.state.reference_data is already the desired @@ -622,8 +643,8 @@ def link_image_data(app, link_type='pixels', wcs_fallback_scheme=None, wcs_use_a # # data1 = reference, data2 = actual data data_already_linked = [] - if (link_type == old_link_type and - (link_type == "pixels" or wcs_use_affine == app._wcs_use_affine)): + if (align_by == old_align_by and + (align_by == "pixels" or wcs_fast_approximation == app._wcs_fast_approximation)): # We are only here to link new data with existing configuration, # so no need to relink existing data. for link in app.data_collection.external_links: @@ -632,17 +653,17 @@ def link_image_data(app, link_type='pixels', wcs_fallback_scheme=None, wcs_use_a # Everything has to be relinked. for viewer in app._viewer_store.values(): if len(viewer._marktags): - raise ValueError(f"cannot change link_type (from '{app._link_type}' to " - f"'{link_type}') when markers are present. " + raise ValueError(f"cannot change align_by (from '{app._align_by}' to " + f"'{align_by}') when markers are present. " f" Clear markers with viewer.reset_markers() first") - # set internal tracking of link_type before changing reference data for anything that is + # set internal tracking of align_by before changing reference data for anything that is # subscribed to a change in reference data - app._link_type = link_type - app._wcs_use_affine = wcs_use_affine + app._align_by = align_by + app._wcs_fast_approximation = wcs_fast_approximation # wcs -> pixels: First loaded real data will be reference. - if link_type == 'pixels' and old_link_type == 'wcs': + if align_by == 'pixels' and old_align_by == 'wcs': # default reference layer is the first-loaded image in default viewer: refdata = app._jdaviz_helper.default_viewer._obj.first_loaded_data if refdata is None: # No data in viewer, just use first in collection # pragma: no cover @@ -656,7 +677,7 @@ def link_image_data(app, link_type='pixels', wcs_fallback_scheme=None, wcs_use_a app._change_reference_data(refdata.label, viewer_id=viewer_id) # pixels -> wcs: Always the default orientation - elif link_type == 'wcs' and old_link_type == 'pixels': + elif align_by == 'wcs' and old_align_by == 'pixels': # Have to create the default orientation first. if base_wcs_layer_label not in app.data_collection.labels: default_reference_layer = (app._jdaviz_helper.default_viewer._obj.first_loaded_data @@ -699,18 +720,18 @@ def link_image_data(app, link_type='pixels', wcs_fallback_scheme=None, wcs_use_a # 4. We are not touching fake WCS layers in pixel linking. # 5. We are not touching data without WCS in WCS linking. if ((i == iref) or (not layer_is_2d(data)) or (data in data_already_linked) or - (link_type == "pixels" and data.meta.get(_wcs_only_label)) or - (link_type == "wcs" and not hasattr(data.coords, 'pixel_to_world'))): + (align_by == "pixels" and data.meta.get(_wcs_only_label)) or + (align_by == "wcs" and not hasattr(data.coords, 'pixel_to_world'))): continue ids1 = data.pixel_component_ids new_links = [] try: - if link_type == 'pixels': + if align_by == 'pixels': new_links = [LinkSame(ids0[i], ids1[i]) for i in ndim_range] else: # wcs wcslink = WCSLink(data1=refdata, data2=data, cids1=ids0, cids2=ids1) - if wcs_use_affine: + if wcs_fast_approximation: try: new_links = [wcslink.as_affine_link()] except NoAffineApproximation: # pragma: no cover @@ -718,7 +739,7 @@ def link_image_data(app, link_type='pixels', wcs_fallback_scheme=None, wcs_use_a else: new_links = [wcslink] except Exception as e: # pragma: no cover - if link_type == 'wcs' and wcs_fallback_scheme == 'pixels': + if align_by == 'wcs' and wcs_fallback_scheme == 'pixels': try: new_links = [LinkSame(ids0[i], ids1[i]) for i in ndim_range] except Exception as e: # pragma: no cover @@ -750,7 +771,7 @@ def link_image_data(app, link_type='pixels', wcs_fallback_scheme=None, wcs_use_a 'Images successfully relinked', color='success', timeout=8000, sender=app)) for viewer in app._viewer_store.values(): - wcs_linked = link_type == 'wcs' + wcs_linked = align_by == 'wcs' # viewer-state needs to know link type for reset_limits behavior viewer.state.linked_by_wcs = wcs_linked # also need to store a copy in the viewer item for the data dropdown to access @@ -760,5 +781,5 @@ def link_image_data(app, link_type='pixels', wcs_fallback_scheme=None, wcs_use_a viewer_item['linked_by_wcs'] = wcs_linked # if changing from one link type to another, reset the limits: - if link_type != old_link_type: + if align_by != old_align_by: viewer.state.reset_limits() diff --git a/jdaviz/configs/imviz/plugins/orientation/orientation.vue b/jdaviz/configs/imviz/plugins/orientation/orientation.vue index 7299148f3d..dc3aa251e0 100644 --- a/jdaviz/configs/imviz/plugins/orientation/orientation.vue +++ b/jdaviz/configs/imviz/plugins/orientation/orientation.vue @@ -40,13 +40,13 @@ @@ -73,7 +73,7 @@ -
+
Orientation