Skip to content

Commit

Permalink
better viewer zoom/center sync with different refdata
Browse files Browse the repository at this point in the history
  • Loading branch information
bmorris3 committed Oct 25, 2023
1 parent 842c5d0 commit ed8890d
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 26 deletions.
19 changes: 1 addition & 18 deletions jdaviz/configs/imviz/plugins/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,7 @@ class _ImvizMatchedZoomMixin(_MatchedZoomMixin):

def _is_matched_viewer(self, viewer):
# only match zooms in viewers that share reference data
return (
isinstance(viewer, BqplotImageView) and
viewer.state.reference_data == self.viewer.state.reference_data
)

def _post_activate(self):
# NOTE: For Imviz only.
# Set the reference data in other viewers to be the same as the current viewer.
# If adding the data to the viewer, make sure it is not actually shown since the
# user didn't request it.
for viewer in self._iter_matched_viewers(include_self=False):
if self.viewer.state.reference_data not in viewer.state.layers_data:
viewer.add_data(self.viewer.state.reference_data)
for layer in viewer.state.layers:
if layer.layer is self.viewer.state.reference_data:
layer.visible = False
break
viewer.state.reference_data = self.viewer.state.reference_data
return isinstance(viewer, BqplotImageView)


@viewer_tool
Expand Down
8 changes: 5 additions & 3 deletions jdaviz/configs/imviz/plugins/viewers.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,12 @@ def _get_zoom_limits(self, image):
they are linked by WCS.
"""
if self.state.reference_data.meta.get('_WCS_ONLY', False):
# Convert X,Y from reference data to the one we are actually seeing.
x = image.coords.world_to_pixel(self.state.reference_data.coords.pixel_to_world(
corner_world_coords = self.state.reference_data.coords.pixel_to_world(
(self.state.x_min, self.state.x_min, self.state.x_max, self.state.x_max),
(self.state.y_min, self.state.y_max, self.state.y_max, self.state.y_min)))
(self.state.y_min, self.state.y_max, self.state.y_max, self.state.y_min)
)
# Convert X,Y from reference data to the one we are actually seeing.
x = image.coords.world_to_pixel(corner_world_coords)
zoom_limits = np.array(list(zip(x[0], x[1])))
else:
zoom_limits = np.array(((self.state.x_min, self.state.y_min),
Expand Down
25 changes: 20 additions & 5 deletions jdaviz/core/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,6 @@ def _iter_matched_viewers(self, include_self=False):
def _map_limits(self, from_viewer, to_viewer, limits={}):
return limits

def _post_activate(self):
return

@property
def match_keys(self):
keys = []
Expand All @@ -80,8 +77,6 @@ def activate(self):
for k in self.match_keys:
self.viewer.state.add_callback(k, self.on_limits_change)

self._post_activate()

# Trigger a sync so the initial limits match
self.on_limits_change()

Expand All @@ -94,12 +89,32 @@ def deactivate(self):
def on_limits_change(self, *args):
# from_lims: limits in the viewer belonging to the tool
from_lims = {k: getattr(self.viewer.state, k) for k in self.match_keys}
orig_refdata = self.viewer.state.reference_data

for viewer in self._iter_matched_viewers(include_self=False):
# orig_lims: limits in this "matched" viewer
# to_lims: proposed new limits for this "matched" viewer
orig_lims = {k: getattr(viewer.state, k) for k in self.match_keys}
to_lims = self._map_limits(self.viewer, viewer, from_lims)

to_refdata = viewer.state.reference_data

if orig_refdata != to_refdata and hasattr(self.viewer, '_get_fov'):
# if the viewers have different reference data,
# rescale the zoom and center allowing for different
# viewer rotations:
orig_fov_sky = self.viewer._get_fov(orig_refdata)
to_fov_sky = viewer._get_fov(orig_refdata)
sky_cen = self.viewer._get_center_skycoord(orig_refdata)

viewer.zoom(
float(to_fov_sky / orig_fov_sky)
)
viewer.center_on(sky_cen)
continue

# if the viewers have the same reference data,
# make their limits match as usual:
with delay_callback(viewer.state, *self.match_keys):
for ax in self.match_axes:
# to avoid recursion we'll only update the state if there is a change
Expand Down

0 comments on commit ed8890d

Please sign in to comment.