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

implement unit conversion in specviz2d #3253

Open
wants to merge 25 commits into
base: main
Choose a base branch
from

Conversation

gibsongreen
Copy link
Contributor

@gibsongreen gibsongreen commented Oct 24, 2024

Description

This pull request is to address implementing the Unit Conversion plugin in Specviz2d.

Change log entry

  • Is a change log needed? If yes, is it added to 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, maintainer
    should 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.

  • Are two approvals required? Branch protection rule does not check for the second approval. If a second approval is not necessary, please apply the trivial label.
  • Do the proposed changes actually accomplish desired goals? Also manually run the affected example notebooks, if necessary.
  • Do the proposed changes follow the STScI Style Guides?
  • Are tests added/updated as required? If so, do they follow the STScI Style Guides?
  • Are docs added/updated as required? If so, do they follow the STScI Style Guides?
  • Did the CI pass? If not, are the failures related?
  • Is a milestone set? Set this to bugfix milestone if this is a bug fix and needs to be released ASAP; otherwise, set this to the next major release milestone. Bugfix milestone also needs an accompanying backport label.
  • After merge, any internal documentations need updating (e.g., JIRA, Innerspace)?

Copy link

codecov bot commented Dec 19, 2024

Codecov Report

Attention: Patch coverage is 95.83333% with 2 lines in your changes missing coverage. Please review.

Project coverage is 88.81%. Comparing base (cf9664f) to head (98f2852).
Report is 13 commits behind head on main.

Files with missing lines Patch % Lines
jdaviz/core/helpers.py 87.50% 1 Missing ⚠️
jdaviz/core/marks.py 92.30% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##             main    #3253    +/-   ##
========================================
  Coverage   88.80%   88.81%            
========================================
  Files         125      125            
  Lines       19155    19268   +113     
========================================
+ Hits        17010    17112   +102     
- Misses       2145     2156    +11     

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

@gibsongreen gibsongreen marked this pull request as ready for review December 19, 2024 15:37
Comment on lines +240 to +241
self.has_angle = False
self.has_sb = False
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We don't append an angle unit in Specviz right now, see the screenshot when the native unit is Jy. This hides both from displaying in the UI and unexposes them from the API.

Screenshot 2024-12-19 at 4 40 57 PM

@@ -260,7 +260,7 @@ def _create_spectrum1d_cube_with_fluxunit(fluxunit=u.Jy, shape=(2, 2, 4), with_u
wcs_dict = {"CTYPE1": "RA---TAN", "CTYPE2": "DEC--TAN", "CTYPE3": "WAVE-LOG",
"CRVAL1": 205, "CRVAL2": 27, "CRVAL3": 4.622e-7,
"CDELT1": -0.0001, "CDELT2": 0.0001, "CDELT3": 8e-11,
"CRPIX1": 0, "CRPIX2": 0, "CRPIX3": 0,
"CRPIX1": 0, "CRPIX2": 0, "CRPIX3": 0, "PIXAR_SR": 10,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

With this update to the test fixture, in test_spectral_extraction_with_correct_sum_units, the scale factor is no longer the default value of 1, so we need to update the expected values in the test.

@@ -29,6 +29,8 @@ Specviz
Specviz2d
^^^^^^^^^

- Implement the Unit Conversion plugin the Specviz2D. [#3253]
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
- Implement the Unit Conversion plugin the Specviz2D. [#3253]
- Implement the Unit Conversion plugin in Specviz2D. [#3253]

Comment on lines +527 to +530
expected_flux_values = [190., 590., 990., 1390., 1790., 2190., 2590., 2990., 3390., 3790.]
# After collapsing, sr is removed via the scale factor and the extracted spectrum is in Jy
expected_flux_values = [flux * collapsed.meta.get('_pixel_scale_factor')
for flux in expected_flux_values]
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 be done with array math instead of a list comprehension?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have now made an update to make the expect_flux_values is an array instead of a list, this will remove the list comprehension all together

Comment on lines +228 to +232
if 'value' in row_info:
# format and cast flux value for Table
row_info['value'] = f"{row_info['value']:.5e}"
else:
row_info['value'] = ''
Copy link
Member

Choose a reason for hiding this comment

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

why is this necessary? Can/should we move it to as_dict instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There was an issue arising where the value column in the table couldn't be ready properly. This was happening when casting value when it was numpy.float32 to float in coords_info.py. I added a check to only cast if the value is not already float.

@@ -553,6 +553,7 @@ def _initialize_model_component(self, model_comp, comp_label, poly_order=None):
# equivs for spectral density and flux<>sb
pixar_sr = masked_spectrum.meta.get('_pixel_scale_factor', 1.0)
equivs = all_flux_unit_conversion_equivs(pixar_sr, init_x)
equivs += u.spectral_density(init_x)
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 be in all_flux_unit_conversion_equivs (or at least as an additional option)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it should already be handled by all_flux_unit_conversion_equivs, I was debugging an issue and threw it in there, just retested and it is able to be removed with no consequence.

spec = self.dataset.selected_spectrum
# Needs Attention:
# should conversion occur before or after call to _apply_subset_masks?
if spec.flux.unit.to_string != self.app._get_display_unit('flux'):
Copy link
Member

Choose a reason for hiding this comment

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

Isn't this a method? Is it cheaper to compare units instead of casting to string?

Suggested change
if spec.flux.unit.to_string != self.app._get_display_unit('flux'):
if spec.flux.unit.to_string() != self.app._get_display_unit('flux'):

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch! Is it worth converting the display units to astropy.Unit or keep to string comparison?

Comment on lines +909 to +914
# Needs Attention:
# should conversion occur before or after call to _apply_subset_masks?
if spec.flux.unit.to_string != self.app._get_display_unit('flux'):
equivalencies = u.spectral_density(self.dataset.selected_spectrum.spectral_axis)
spec = self.dataset.selected_spectrum.with_flux_unit(self.app._get_display_unit('flux'),
equivalencies=equivalencies)
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 all be moved into the DatasetSelect.selected_spectrum logic so its reusable and cached (and then the cache would need to be invalidated for a change in flux display units)?

Comment on lines +441 to +442
self._dict['spectral_axis'] = wave.value
self._dict['spectral_axis:unit'] = wave.unit.to_string()
Copy link
Member

Choose a reason for hiding this comment

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

where were these handled before (I don't see them in the else 🤔)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

X-axis conversions were not previously handled in Specviz2d, so they were previously always using the native units and value when mousing over

Comment on lines +226 to +227
# Note: spectra2d Wave loaded in meters, but we respect one spectral unit, so the meters in
# converted to Angstrom (the spectra1d spectral unit).
Copy link
Member

Choose a reason for hiding this comment

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

Can you explain this a little more? Is it that a previous data entry was in angstroms or just that that is the default spectral display unit?

Suggested change
# Note: spectra2d Wave loaded in meters, but we respect one spectral unit, so the meters in
# converted to Angstrom (the spectra1d spectral unit).
# Note: spectra2d Wave loaded in meters, but we respect one spectral unit, so the meters is
# converted to Angstrom (the spectra1d spectral unit).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So the loaded 1D and 2D spectra have different native spectral units, with one in meters and one in angstroms and app-wide we're respecting one choice for spectral unit.

Comment on lines 117 to 118
# TODO [specviz2d, mosviz] x_display_unit is not implemented in glue for image viewer
# used by spectrum-2d-viewer
Copy link
Member

Choose a reason for hiding this comment

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

is this still relevant?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For the MosvizImageView, I will make sure to update the comment to reflect this!

Comment on lines -240 to -242
# default to sr if input spectrum is not in surface brightness units
# TODO: for cubeviz, should we check the cube itself?
self.angle_unit.selected = 'sr'
Copy link
Member

Choose a reason for hiding this comment

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

why remove this? It doesn't seem to be replaced with any other logic to accomplish the same thing, except the else below which is defaulting to pix2 instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The logic just gets moved, not removed. So if the angle_unit is None and the config is not specviz nor specviz2d, then the angle_unit will still be set to sr. By updating the has_angle and has_sb if it is one of the 2 configs, it removes the sb_unit and angle_unit from the UI/API.

I can reintroduce the comments that previously exists about setting the angle_unit to sr.

@rosteen rosteen modified the milestones: 4.1, 4.2 Dec 23, 2024
Copy link
Contributor

@cshanahan1 cshanahan1 left a comment

Choose a reason for hiding this comment

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

When testing this with the specviz2d example notebook, the option to change flux unit disappears when you load the data. The screen shots below show an empty specviz instance, with the 'Flux' option appearing under the unit conversion plugin, and then after loading data when that dropdown disappears

Screenshot 2024-12-23 at 1 59 21 PM Screenshot 2024-12-23 at 2 08 54 PM

@cshanahan1
Copy link
Contributor

What is included in the scope here for surface brightness logic, including coercing flux units to surface brightness, handling square pixel, and toggling the spectral axis? (Are images of 2d spectra even typically or commonly in surface brightness units?)

@gibsongreen
Copy link
Contributor Author

gibsongreen commented Dec 23, 2024

What is included in the scope here for surface brightness logic, including coercing flux units to surface brightness, handling square pixel, and toggling the spectral axis? (Are images of 2d spectra even typically or commonly in surface brightness units?)

  • There will be no coercing for pix^2 in Specviz2d, but I think it will be applicable for the image viewers in Mosviz and Imviz.
  • We only apply the scale factor in Cubeviz since it is stored in the metadata when we extract the cube using the plugin (so no translations here)
  • I did some research into 2d spectra before starting and to my knowledge, they should only be in Flux units. Specviz2d will still be able to load surface brightness units in steradian, if applicable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cubeviz imviz plugin Label for plugins common to multiple configurations specviz specviz2d
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants