Skip to content

Commit

Permalink
mouseover display to warn when outside original bounding box
Browse files Browse the repository at this point in the history
  • Loading branch information
kecnry committed Dec 13, 2022
1 parent 94e00d6 commit c10cfb7
Show file tree
Hide file tree
Showing 9 changed files with 33 additions and 14 deletions.
3 changes: 2 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ Cubeviz
Imviz
^^^^^

- Fixes cropped image layer with WCS-linking without fast-approximation. [#1908]
- Fixes cropped image layer with WCS-linking without fast-approximation, mouseover display
now shows when information is outside original reference data bounding box. [#1908]

Mosviz
^^^^^^
Expand Down
4 changes: 4 additions & 0 deletions docs/imviz/displayimages.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ cursor's location in pixel space (X and Y), the RA and Dec at that point, and th
of the data there. This information is displayed in the top bar of the UI, on the
middle-right side.

If the mouse is outside the original bounding-box of the reference data, the transformation
from pixels to sky coordinates is less reliable. This is indicated by "(est.)" and the sky
coordinates becoming gray.

Home
====

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ def vue_recenter_subset(self, *args):
# the reference data. However, Subset is always defined w.r.t.
# the reference data, so we need to convert back.
viewer = self.app._jdaviz_helper.default_viewer
x, y, _ = viewer._get_real_xy(
x, y, _, _ = viewer._get_real_xy(
data, phot_aperstats.xcentroid, phot_aperstats.ycentroid, reverse=True)
if not np.all(np.isfinite((x, y))):
raise ValueError(f'Invalid centroid ({x}, {y})')
Expand Down
6 changes: 4 additions & 2 deletions jdaviz/configs/imviz/plugins/coords_info/coords_info.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from traitlets import Unicode
from traitlets import Bool, Unicode

from jdaviz.core.registries import tool_registry
from jdaviz.core.template_mixin import TemplateMixin
Expand All @@ -19,6 +19,7 @@ class CoordsInfo(TemplateMixin):
world_dec = Unicode("").tag(sync=True)
world_ra_deg = Unicode("").tag(sync=True)
world_dec_deg = Unicode("").tag(sync=True)
within_bounding_box = Bool(True).tag(sync=True)

def reset_coords_display(self):
self.world_label_prefix = '\u00A0'
Expand All @@ -29,7 +30,7 @@ def reset_coords_display(self):
self.world_ra_deg = ''
self.world_dec_deg = ''

def set_coords(self, sky):
def set_coords(self, sky, within_bounding_box=True):
celestial_coordinates = sky.to_string('hmsdms', precision=4, pad=True).split()
celestial_coordinates_deg = sky.to_string('decimal', precision=10, pad=True).split()
world_ra = celestial_coordinates[0]
Expand All @@ -47,3 +48,4 @@ def set_coords(self, sky):
self.world_dec = world_dec
self.world_ra_deg = world_ra_deg
self.world_dec_deg = world_dec_deg
self.within_bounding_box = within_bounding_box
6 changes: 3 additions & 3 deletions jdaviz/configs/imviz/plugins/coords_info/coords_info.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@
<b v-if="pixel">Pixel </b>{{ pixel }}&nbsp;&nbsp;<b v-if="value">Value </b>{{ value }}
</td>
</tr>
<tr>
<tr :style="within_bounding_box ? '' : 'color: gray'">
<td width="42"><b>{{ world_label_prefix }}</b></td>
<td width="115">{{ world_ra }}</td>
<td width="120">{{ world_dec }}</td>
<td>{{ world_label_icrs }}</td>
</tr>
<tr>
<td width="42"></td>
<tr :style="within_bounding_box ? '' : 'color: gray'">
<td width="42">{{ within_bounding_box ? '' : '(est.)' }}</td>
<td width="115">{{ world_ra_deg }}</td>
<td width="120">{{ world_dec_deg }}</td>
<td>{{ world_label_deg }}</td>
Expand Down
4 changes: 4 additions & 0 deletions jdaviz/configs/imviz/plugins/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ def _parse_image(app, file_obj, data_label, ext=None):

for data, data_label in data_iter:
if data.coords is not None:
# keep a copy of the original bounding box so we can detect
# when extrapolating beyond, but then remove the bounding box
# so that image layers are not cropped.
data.coords._orig_bounding_box = data.coords.bounding_box
data.coords.bounding_box = None
data_label = app.return_data_label(data_label, alt_name="image_data")
app.add_data(data, data_label)
Expand Down
2 changes: 1 addition & 1 deletion jdaviz/configs/imviz/plugins/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def on_click(self, data):
y = data['domain']['y']
if x is None or y is None: # Out of bounds
return
x, y, _ = self.viewer._get_real_xy(image, x, y)
x, y, _, _ = self.viewer._get_real_xy(image, x, y)
self.viewer.center_on((x, y))


Expand Down
18 changes: 13 additions & 5 deletions jdaviz/configs/imviz/plugins/viewers.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def on_mouse_or_key_event(self, data):

maxsize = int(np.ceil(np.log10(np.max(image.shape)))) + 3
fmt = 'x={0:0' + str(maxsize) + '.1f} y={1:0' + str(maxsize) + '.1f}'
x, y, coords_status = self._get_real_xy(image, x, y)
x, y, coords_status, within_bounding_box = self._get_real_xy(image, x, y)
self.label_mouseover.pixel = (fmt.format(x, y))

if coords_status:
Expand All @@ -115,7 +115,7 @@ def on_mouse_or_key_event(self, data):
except Exception: # WCS might not be celestial
self.label_mouseover.reset_coords_display()
else:
self.label_mouseover.set_coords(coo)
self.label_mouseover.set_coords(coo, within_bounding_box=within_bounding_box)
else:
self.label_mouseover.reset_coords_display()

Expand Down Expand Up @@ -155,7 +155,7 @@ def on_mouse_or_key_event(self, data):
y = data['domain']['y']
if x is None or y is None: # Out of bounds
return
x, y, _ = self._get_real_xy(image, x, y)
x, y, _, _ = self._get_real_xy(image, x, y)
self.line_profile_xy.selected_x = x
self.line_profile_xy.selected_y = y
self.line_profile_xy.selected_viewer = self.reference_id
Expand Down Expand Up @@ -221,7 +221,9 @@ def on_limits_change(self, *args):
self.set_compass(self.state.layers[i].layer)

def _get_real_xy(self, image, x, y, reverse=False):
"""Return real (X, Y) position and status in case of dithering.
"""Return real (X, Y) position and status in case of dithering as well as whether the
results were within the bounding box of the reference data or required possibly inaccurate
extrapolation.
``coords_status`` is for ``self.label_mouseover`` coords handling only.
When `True`, it sets the coords, otherwise it resets.
Expand All @@ -234,10 +236,16 @@ def _get_real_xy(self, image, x, y, reverse=False):
# Convert these to a SkyCoord via WCS - note that for other datasets
# we aren't actually guaranteed to get a SkyCoord out, just for images
# with valid celestial WCS
within_bounding_box = True
try:
# Convert X,Y from reference data to the one we are actually seeing.
# world_to_pixel return scalar ndarray that we need to convert to float.
if self.get_link_type(image.label) == 'wcs':
bb = self.state.reference_data.coords._orig_bounding_box
if bb is not None:
ints = bb.intervals
within_bounding_box = (ints[0].lower <= x <= ints[0].upper and
ints[1].lower <= y <= ints[1].upper)
if not reverse:
x, y = list(map(float, image.coords.world_to_pixel(
self.state.reference_data.coords.pixel_to_world(x, y))))
Expand All @@ -250,7 +258,7 @@ def _get_real_xy(self, image, x, y, reverse=False):
else:
coords_status = False

return x, y, coords_status
return x, y, coords_status, within_bounding_box

def _get_zoom_limits(self, image):
"""Return a list of ``(x, y)`` that defines four corners of
Expand Down
2 changes: 1 addition & 1 deletion jdaviz/core/region_translators.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def _get_region_from_spatial_subset(plugin_obj, subset_label):
# not loaded in all the viewers, so use default viewer.
viewer = plugin_obj.app._jdaviz_helper.default_viewer

x, y, _ = viewer._get_real_xy(
x, y, _, _ = viewer._get_real_xy(
plugin_obj.app.data_collection[plugin_obj.dataset_selected],
reg.center.x, reg.center.y)
reg.center.x = x
Expand Down

0 comments on commit c10cfb7

Please sign in to comment.