-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor mouseover coords info display #1976
Conversation
2c59039
to
e5fa123
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic route is more complicated now per mousemove. Any performance penalty?
I don't think it is - the callback goes directly to the method in the plugin to handle mousemove events. There is an if-statement there to check whether the viewer is an image or spectrum viewer... if that has any performance implications, we could move the if-statement to creating the callbacks instead but that just makes testing a little clunkier. There are a few other isinstance checks after that to determine the behavior (again, could be brought higher up if its a concern), but this also gets rid of if-statements for the event type since only mouse events (and not keypress or click events) are processed here. But if you don't like the code move or find any performance decreases, we can also split that part out and just keep the changes to the traitlets. |
(I think this should pass tests, but will leave in draft until #1975 is resolved) |
e5fa123
to
39ad22d
Compare
If we go this route (moving event-logic into the plugin), this would also allow us to merge this functionality into the marker plugin (#1953), so the same codebase would show the mouseover display and allow logging that same information to an exportable table with a keypress. As far as I know, we can't have a single plugin have vue files for both the tray and toolbar, so we'll need to decide where this code ultimately belongs and how to share it between the two plugins. I'm trying to use the same callback infrastructure there as in this PR, so hopefully moving that logic around should be straightforward 🤞 |
bca282c
to
e415dd1
Compare
Codecov ReportBase: 91.95% // Head: 92.04% // Increases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## main #1976 +/- ##
==========================================
+ Coverage 91.95% 92.04% +0.08%
==========================================
Files 140 140
Lines 15333 15148 -185
==========================================
- Hits 14100 13943 -157
+ Misses 1233 1205 -28
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran out of time, so this is just partial review. I will continue from test_linking.py
when I come back.
@@ -185,6 +186,17 @@ def _on_subset_create(self, msg): | |||
if msg.subset.label not in self._expected_subset_layers and msg.subset.label: | |||
self._expected_subset_layers.append(msg.subset.label) | |||
|
|||
@property | |||
def active_image_layer(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This really only applies to Imviz, is it correct to have it so high up in JdavizViewerMixin
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's applicable to any image viewer. This will just return None for a viewer without a valid image layer. But would you prefer either putting this in the AstrowidgetsImageViewerMixin
or creating a new mixin for non-astrowidgets image-viewer-specific methods/properties?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just leave it here then. This is not part of Astrowidgets API anyway. Thanks for the clarification.
@@ -122,10 +122,6 @@ def deactivate(self): | |||
def on_click(self, data): | |||
self.viewer.blink_once(reversed=data['event']=='contextmenu') # noqa: E225 | |||
|
|||
# Also update the coordinates display. | |||
data['event'] = 'mousemove' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was here so blink without moving cursor would update. Is this still the case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is handled by the _layers_changed
callback method now
key_pressed = data['key'] | ||
|
||
if key_pressed in ('b', 'B'): | ||
self.blink_once(reversed=key_pressed=='B') # noqa: E225 | ||
|
||
# Also update the coordinates display. | ||
data['event'] = 'mousemove' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to check if blink without moving cursor still correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(same as above - this should work, but please feel free to test and confirm or let me know if any case doesn't act as expected)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like it works to me.
1e0c3cc
to
eb7409d
Compare
e98c955
to
506f709
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm ok with deferring efforts toward allowing customization, approved.
{'event': 'mousemove', 'domain': {'x': -1, 'y': 0}}) | ||
assert label_mouseover.as_text() == ('Pixel x=-1.0 y=00.0', # Out of bounds | ||
'World 13h41m45.5759s +27d00m12.3044s (ICRS)', | ||
'205.4398995981 27.0034178810 (deg)') # noqa |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This RA and Dec should have changed because X is now -1. Only the value should not shown. The old test does not check for sky coordinates so I cannot tell you what it is supposed to be but you should double check. This does not look right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A simple way to check is to create that same WCS object locally and then call its pixel_to_world
method as per https://github.com/astropy/astropy-APEs/blob/main/APE14.rst#high-level-api
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went back to main and added debugging print statements to the original test and they gave these same values (that's not to say that they're necessarily correct). I'll need to think about the exact scenario here to see what would be expected, or I guess we could always file as a separate follow-up and only include as_text()[0]
in the test coverage so that we don't suggest these values are validated as correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... But theoretically, this is what should happen. I wonder if I omitted the sky coordinates on purpose or this was an oversight. Past Self ™️ strikes again!
from astropy.wcs import WCS
w = WCS({
'WCSAXES': 3, 'CRPIX1': 38.0, 'CRPIX2': 38.0, 'CRPIX3': 1.0,
'CRVAL1': 205.4384, 'CRVAL2': 27.004754, 'CRVAL3': 4.890499866509344,
'CTYPE1': 'RA---TAN', 'CTYPE2': 'DEC--TAN', 'CTYPE3': 'WAVE',
'CUNIT1': 'deg', 'CUNIT2': 'deg', 'CUNIT3': 'um',
'CDELT1': 3.61111097865634E-05, 'CDELT2': 3.61111097865634E-05, 'CDELT3': 0.001000000047497451, # noqa
'PC1_1 ': -1.0, 'PC1_2 ': 0.0, 'PC1_3 ': 0,
'PC2_1 ': 0.0, 'PC2_2 ': 1.0, 'PC2_3 ': 0,
'PC3_1 ': 0, 'PC3_2 ': 0, 'PC3_3 ': 1,
'DISPAXIS': 2, 'VELOSYS': -2538.02,
'SPECSYS': 'BARYCENT', 'RADESYS': 'ICRS', 'EQUINOX': 2000.0,
'LONPOLE': 180.0, 'LATPOLE': 27.004754,
'MJDREFI': 0.0, 'MJDREFF': 0.0, 'DATE-OBS': '2014-03-30'})
>>> w.pixel_to_world(0, 0, 0)
[<SkyCoord (ICRS): (ra, dec) in deg
(205.4398996, 27.00341788)>,
<SpectralCoord
(target: <ICRS Coordinate: (ra, dec, distance) in (deg, deg, kpc)
(205.4384, 27.004754, 1000.)
(pm_ra_cosdec, pm_dec, radial_velocity) in (mas / yr, mas / yr, km / s)
(0., 0., 0.)>)
4.89049987e-06 m>]
>>> w.pixel_to_world(-1, 0, 0)
[<SkyCoord (ICRS): (ra, dec) in deg
(205.43994013, 27.00341788)>,
<SpectralCoord
(target: <ICRS Coordinate: (ra, dec, distance) in (deg, deg, kpc)
(205.4384, 27.004754, 1000.)
(pm_ra_cosdec, pm_dec, radial_velocity) in (mas / yr, mas / yr, km / s)
(0., 0., 0.)>)
4.89049987e-06 m>]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So it turns out when you load that test case into Cubeviz, the flux cube WCS becomes a PaddedSpectrumWCS
but the uncert cube retained the original FITS WCS. If you do this, you can recreate the weird results this test is seeing.
>>> cubeviz_helper.app.data_collection[1].coords.pixel_to_world(0, 0, 3)
[<SpectralCoord
(target: <ICRS Coordinate: (ra, dec, distance) in (deg, deg, kpc)
(205.4384, 27.004754, 1000.)
(pm_ra_cosdec, pm_dec, radial_velocity) in (mas / yr, mas / yr, km / s)
(0., 0., 0.)>)
4.89049987e-06 m>,
<SkyCoord (ICRS): (ra, dec) in deg
(205.43977801, 27.00341788)>]
>>> cubeviz_helper.app.data_collection[1].coords.pixel_to_world(-1, 0, 3)
[<SpectralCoord
(target: <ICRS Coordinate: (ra, dec, distance) in (deg, deg, kpc)
(205.4384, 27.004754, 1000.)
(pm_ra_cosdec, pm_dec, radial_velocity) in (mas / yr, mas / yr, km / s)
(0., 0., 0.)>)
4.89149987e-06 m>,
<SkyCoord (ICRS): (ra, dec) in deg
(205.43977801, 27.00341788)>]
It makes no sense but (1) it is unrelated to this PR, and (2) it is not real data. So, my recommendation is that you retain the old test behavior by not comparing the sky coordinates at all. I'd rather we do that than to say in the test we expect non-sensible result.
I thought uncert would have the same WCS as flux cube... maybe @bmorris3 cube work would naturally fix this. 🤷
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, my recommendation is that you retain the old test behavior by not comparing the sky coordinates at all.
ok, good idea, I like that plan for now.
17d98d0
to
d9e0a92
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tests LGTM now. Some minor comments.
I'll approve soon if quick manual testing don't break anything.
@@ -185,6 +186,17 @@ def _on_subset_create(self, msg): | |||
if msg.subset.label not in self._expected_subset_layers and msg.subset.label: | |||
self._expected_subset_layers.append(msg.subset.label) | |||
|
|||
@property | |||
def active_image_layer(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just leave it here then. This is not part of Astrowidgets API anyway. Thanks for the clarification.
if isinstance(viewer, | ||
(SpecvizProfileView, | ||
ImvizImageView, | ||
CubevizImageView, | ||
MosvizImageView, | ||
MosvizProfile2DView)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a follow-up issue to make this plugin somewhat working for custom config?
self.row2_title = 'Wave' | ||
self.row2_text = f'{closest_wave.value:10.5e} {closest_wave.unit.to_string()}' | ||
if closest_wave.unit != u.pix: | ||
self.row2_text += f' ({int(closest_i)} pix)' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if the int
casting is still needed here now that we only display if it is within bounds of spectral axis.
(The above screenshot was when using |
Re: #1976 (comment) I see same behavior on
|
I think the "(est.)" is now gone from mouseover text, so https://jdaviz--1976.org.readthedocs.build/en/1976/imviz/displayimages.html#notes-on-gwcs needs to be updated to remove mention of "(est.)". |
This one is definitely related (i.e., not happening in
|
* refactored to bring mouseover logic into the plugin itself * traitlets for information are now based on their position in the UI rather than their meaning for imviz (which was then "stretched" to apply to other viewers)
Co-authored-by: P. L. Lim <[email protected]>
Co-authored-by: P. L. Lim <[email protected]>
158d3b9
to
996c2e9
Compare
Fixed, good catch! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM now. Thanks!
Description
This pull request refactors/renames the logic in the coordinates info display so that:
The behavior should essentially be the same as in #1894, except that the top line in specviz now reads "Cursor" instead of the previously hard-coded "Pixel".
Fix #1645
Change log entry
CHANGES.rst
? If you want to avoid merge conflicts,list the proposed change log here for review and add to
CHANGES.rst
before merge. If no, maintainershould add a
no-changelog-entry-needed
label.Checklist for package maintainer(s)
This checklist is meant to remind the package maintainer(s) who will review this pull request of some common things to look for. This list is not exhaustive.
trivial
label.