Skip to content
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

View spectrum from single spaxel on hover #2647

Merged
merged 14 commits into from
Jan 22, 2024

Conversation

rosteen
Copy link
Collaborator

@rosteen rosteen commented Jan 5, 2024

Now shows spectrum and auto-scales spectrum viewer when hovering with the single-spaxel subset tool activated, see demo:

Screen.Recording.2024-01-05.at.11.59.02.AM.mov

Opened as draft since I still need to add tests and update docs. Outstanding question: do we want to reset the spectrum viewer limits to the default when deactivating the tool/leaving the viewer area?

@github-actions github-actions bot added cubeviz plugin Label for plugins common to multiple configurations labels Jan 5, 2024
@kecnry
Copy link
Member

kecnry commented Jan 5, 2024

Outstanding question: do we want to reset the spectrum viewer limits to the default when deactivating the tool/leaving the viewer area?

What if instead we just have it overlay with a normalized y-axis (the values would no longer match the left y-axis, but you would be able to see the shape of the spectrum at the pixel) 🤔 ?

@rosteen
Copy link
Collaborator Author

rosteen commented Jan 5, 2024

What if instead we just have it overlay with a normalized y-axis (the values would no longer match the left y-axis, but you would be able to see the shape of the spectrum at the pixel) 🤔 ?

Interesting idea, definitely has some pros and cons. Probably a question for the POs on their preference.

@kecnry
Copy link
Member

kecnry commented Jan 5, 2024

Interesting idea, definitely has some pros and cons. Probably a question for the POs on their preference.

Agreed.

Either way... I definitely think that:

  • we probably want to respect user-set x-limits
  • we definitely want the spectrum-viewer to return to exactly as it was before any hovering (i.e. not end up resetting limits or anything like that just because of a hover event)

@rosteen rosteen added this to the 3.9 milestone Jan 5, 2024
Copy link
Contributor

@pllim pllim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this smart enough to know when it is hovering over something that isn't a flux cube or does it not matter?

What if you have it active, and then do unit conversion? Is that possible yet?

@rosteen
Copy link
Collaborator Author

rosteen commented Jan 5, 2024

Is this smart enough to know when it is hovering over something that isn't a flux cube or does it not matter?

What if you have it active, and then do unit conversion? Is that possible yet?

Right now it just grabs the first visible layer in the viewer, I should add a check to make sure it's 3D at least. And unit conversion is not available in Cubeviz currently.

@kecnry
Copy link
Member

kecnry commented Jan 5, 2024

Is this smart enough to know when it is hovering over something that isn't a flux cube or does it not matter?

Hmmm, that's a good point though, you could in theory have the uncertainty or mask cube in that viewer, and so maybe we should use the logic from #2646 to always use the flux-cube, since that is what creating the subset will end up doing anyways (I think).

@rosteen
Copy link
Collaborator Author

rosteen commented Jan 8, 2024

* we probably want to respect user-set x-limits

* we definitely want the spectrum-viewer to return to exactly as it was before any hovering (i.e. not end up resetting limits or anything like that just because of a hover event)

This already respected the user-set x-limits, I just implemented reverting to the previous zoom on mouseleave events or tool deactivation (in case it's deactivated from the API without mouse leaving the viewer).

Copy link

codecov bot commented Jan 8, 2024

Codecov Report

Attention: 9 lines in your changes are missing coverage. Please review.

Comparison is base (03edac6) 91.53% compared to head (2b2bd3e) 91.52%.
Report is 9 commits behind head on main.

Files Patch % Lines
jdaviz/configs/cubeviz/plugins/tools.py 87.50% 9 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2647      +/-   ##
==========================================
- Coverage   91.53%   91.52%   -0.01%     
==========================================
  Files         161      161              
  Lines       20056    20196     +140     
==========================================
+ Hits        18358    18485     +127     
- Misses       1698     1711      +13     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@rosteen
Copy link
Collaborator Author

rosteen commented Jan 9, 2024

This is what the other zoom option for the preview (overlaying it over current zoom) would look like. I was leaning toward zooming to the preview, but now I think this might be nicer so that you don't potentially have other spectra constantly moving around as the zoom changes. The downside is not being able to see what the flux values of the preview are.

Screen.Recording.2024-01-09.at.12.36.33.PM.mov

def activate(self):
self.viewer.add_event_callback(self.on_mouse_move, events=['mousemove', 'mouseleave'])
if self._spectrum_viewer is None:
self._spectrum_viewer = self.viewer.jdaviz_helper.app.get_viewer('spectrum-viewer')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we avoid hardcoding 'spectrum-viewer' here by using the helper attributes?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still think this might be worth doing to avoid future headache

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, grabs the first profile viewer now.

y = int(np.round(data['domain']['y']))

# Use first visible layer for now
cube_data = [layer.layer for layer in self.viewer.layers if layer.state.visible][0]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this use similar logic as #2646 to ensure its pulling from the flux cube? What happens when there are no visible layers (I'm guessing a traceback... we might want to just skip that case gracefully)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed this to return on an empty result, good catch.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic in 2646 might be useful, but I don't think it's worth holding this up for that to be merged. We could potentially do that if/when we change the axis handling.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, but the first visible layer now could still be a flat image, or the uncertainty or mask cubes, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a check to at least only use 3D data, avoiding a traceback if something like a collapsed image is displayed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thinking about this more... I think this should listen to the layer selection in mouseover itself, which also might fix the bug with the uncertainty cube failing to display. That or we just ALWAYS pull the flux cube, regardless of the viewer and whether it is an active layer in that viewer or not 🤷

jdaviz/configs/cubeviz/plugins/tools.py Outdated Show resolved Hide resolved
jdaviz/configs/cubeviz/plugins/tools.py Outdated Show resolved Hide resolved
jdaviz/configs/cubeviz/plugins/tools.py Show resolved Hide resolved
Copy link
Contributor

@javerbukh javerbukh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spectrum changing is so responsive, nice work!

if len(cube_data) == 0:
return
cube_data = cube_data[0]
spectrum = cube_data.get_object(statistic=None)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it worth caching this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about getting this on activation but was worried about data changing while the tool is active, and since it seems performant I didn't think it was worth the overhead of adding a hub listener or something along those lines.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might not be performant on large cubes (or anything where get_object is expensive), but haven't tested. I guess we can leave that for future improvement, since depending on the decision of how to handle layer selection, you may need to have a listener to invalidate the cache

@rosteen
Copy link
Collaborator Author

rosteen commented Jan 19, 2024

@kecnry This now tries to preview the same data as selected for the coords info hover, before falling back on any 3D data available if the selected layer isn't 3D. I also fixed the uncertainty preview. Mind giving this another look?

Comment on lines 137 to 144
else:
for layer in self.viewer.layers:
if layer.layer.label == coords_info_dataset and layer.visible:
if isinstance(layer, BqplotImageSubsetLayerArtist):
# cannot expose info for spatial subset layers
continue
cube_data = layer.layer
break
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this rely on dataset.selected_obj (which will then get caching for free)? Or do you need some layer info that isn't accessible there?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That also then might let you mouseover the uncertainty viewer but access the mouseover from the flux cube (if selected manually in the mouseover cycler) which would be super cool!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just copying the logic from coords_info, using selected_obj seems to work with an extra check for glue Data vs Spectrum1D. I do worry that it will be confusing for users rather than a good feature that if they select the hover option in a viewer, they might be seeing the data from another viewer if it's selected at the top level.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm true, I think most people don't even use the cycler though, so probably won't run into this except for advanced use-cases. Might be worth some user-testing or just see if anyone complains about confusion.

Copy link
Member

@kecnry kecnry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works well! Just a few comments above and I think this is good to go! (Although would be nice to get code coverage a little higher if that isn't too difficult - many of the uncovered lines are just different mouseout situations which probably don't need specific coverage)

@rosteen rosteen merged commit 8edbdf0 into spacetelescope:main Jan 22, 2024
14 of 15 checks passed
gibsongreen pushed a commit to gibsongreen/jdaviz that referenced this pull request Feb 12, 2024
* Working on adding spectrum-from-spaxel on hover

* First working version of spectrum on hover

* Handle NaNs properly

* Update docs and changelog

* Add simple test

Codestyle

Codestyle

* Revert zoom after preview view

* Address review comments

* Only use 3D data

* Fix preview spectrum for uncertainty cube

* Use the same layer selection as coords_info if possible

* Codestyle

* Use selected_obj and get first profile viewer rather than spectrum-viewer specifically

* Remove unused import

* Improve test coverage
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cubeviz plugin Label for plugins common to multiple configurations Ready for final review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants