-
Notifications
You must be signed in to change notification settings - Fork 74
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
add pixel scale factor to metadata and API translation #2752
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #2752 +/- ##
==========================================
- Coverage 88.70% 88.70% -0.01%
==========================================
Files 108 108
Lines 16305 16374 +69
==========================================
+ Hits 14464 14524 +60
- Misses 1841 1850 +9 ☔ View full report in Codecov by Sentry. |
jdaviz/configs/cubeviz/plugins/spectral_extraction/spectral_extraction.py
Outdated
Show resolved
Hide resolved
CHANGES.rst
Outdated
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 far, none of the diff is user-facing, so it does not need a change log.
@@ -159,7 +160,7 @@ def user_api(self): | |||
expose = ['function', 'spatial_subset', 'aperture', | |||
'add_results', 'collapse_to_spectrum', | |||
'wavelength_dependent', 'reference_wavelength', | |||
'aperture_method'] | |||
'aperture_method', 'translate_units'] |
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'd vote to not expose this to the user yet.
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 list name makes more sense now, will do and make a note of it.
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.
@kecnry how do I hide it from the user, but still enable it to be callable?
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.
remove it from this list, and either access the plugin object directly (if you already have the user API object, just call ._obj
on it to get to the actual plugin object).
collapsed_spec._data *= 10e6 | ||
|
||
# spectral_cube.meta['_pixel_scale_factor'] / 1, where 1 = default scale factor | ||
collapsed_spec._data *= spectral_cube.meta['_pixel_scale_factor'] |
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 think the scale factors will need to be stored in collapsed_spec
instead of spectral_cube
, since a single spectral cube can be used to extract multiple spectra with different subsets/apertures.
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.
You are right, that makes a lot more sense instead of the flux data!
elif collapsed_spec._unit != u.Jy / u.pix and collapsed_spec._unit != u.MJy / u.sr: | ||
raise ValueError(f"Units '{collapsed_spec._unit}' are not MJy/sr nor Jy/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.
can this not be generalized to any flux or surface brightness units?
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.
Should be doable and generalizing here is a better idea
# per https://jwst-docs.stsci.edu/jwst-near-infrared-camera/nircam-performance/nircam-absolute-flux-calibration-and-zeropoints # noqa | ||
# MJy/sr is default, to measure photometry in MJy, convert the image to units | ||
# of MJy/pixel by multiplying by the average area of a pixel in sr, a constant | ||
# provided in the FITS header keyword PIXAR_SR | ||
collapsed_spec._data *= spectral_cube.meta['PIXAR_SR'] |
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.
should this, and the original unit, be absorbed into the scale factor so we can just multiply or divide by a quantity?
@@ -343,6 +345,11 @@ def collapse_to_spectrum(self, add_data=True, **kwargs): | |||
sender=self) | |||
self.hub.broadcast(snackbar_message) | |||
|
|||
# per https://jwst-docs.stsci.edu/jwst-near-infrared-camera/nircam-performance/nircam-absolute-flux-calibration-and-zeropoints # noqa | |||
if 'PIXAR_SR' in spectral_cube.meta: | |||
pix_scale_factor = self.aperture.scale_factor * 10e6 * spectral_cube.meta['PIXAR_SR'] |
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.
where does the 10^6 come from? Does that make assumptions on units (converting between MJy and Jy maybe)?
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 had made the assumption based on conversations from the hack day and the meetings with Patrick that yes MJy to Jy would need scientific notation conversion, I'll remove it from here and the specification in the translate_units()
function
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 would, but we're going to want to have the flexibility to change between any prefix. Ideally this would take the new units, but if that's too difficult, we can do that as a followup and just assume the same units (except the sr) otherwise.
# MJy/sr -> Jy/pix | ||
if collapsed_spec._unit == u.MJy / u.sr: | ||
collapsed_spec._data *= collapsed_spec.meta['_pixel_scale_factor'] | ||
collapsed_spec._unit = u.Jy / u.pix | ||
# Jy/pix -> MJy/sr | ||
elif collapsed_spec._unit == u.Jy / u.pix: | ||
collapsed_spec._data /= collapsed_spec.meta['_pixel_scale_factor'] | ||
collapsed_spec._unit = u.MJy / u.sr |
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 still think we want this to be generalized to any surface brightness -> flux units, basically just adding or removing the steradians but keeping the same base units otherwise (which probably means we don't need the 10^6 in the factor).
u.MJy / u.sr: u.MJy / u.pix, | ||
u.Jy / u.sr: u.Jy / u.pix, | ||
u.erg / (u.cm**2*u.s*u.AA*u.sr): u.erg / (u.cm**2*u.s*u.AA), | ||
u.erg / (u.s*u.cm**2*u.sr): u.erg / (u.s*u.cm**2), | ||
u.W / (u.m**2*u.Hz*u.sr): u.W / (u.m**2*u.Hz) |
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 dictionary will probably have to go when translating to any sb/flux. If there's eventually a drop down for the user to select their desired units, the path forward for this becomes clear.
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.
can we just multiply or divide by u.sr
directly?
@@ -343,6 +345,11 @@ def collapse_to_spectrum(self, add_data=True, **kwargs): | |||
sender=self) | |||
self.hub.broadcast(snackbar_message) | |||
|
|||
# per https://jwst-docs.stsci.edu/jwst-near-infrared-camera/nircam-performance/nircam-absolute-flux-calibration-and-zeropoints # noqa | |||
if 'PIXAR_SR' in spectral_cube.meta: |
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.
what happens when 'PIXAR_SR' does not exist? What if instead we just use spectral_cube.meta.get('PIXAR_SR', 1.0)
?
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 updated this instead of the if statement, I think we'd need to calculate the average area of a pixel if PIXAR_SR doesn't exist
u.MJy / u.sr: u.MJy / u.pix, | ||
u.Jy / u.sr: u.Jy / u.pix, | ||
u.erg / (u.cm**2*u.s*u.AA*u.sr): u.erg / (u.cm**2*u.s*u.AA), | ||
u.erg / (u.s*u.cm**2*u.sr): u.erg / (u.s*u.cm**2), | ||
u.W / (u.m**2*u.Hz*u.sr): u.W / (u.m**2*u.Hz) |
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.
can we just multiply or divide by u.sr
directly?
# per https://jwst-docs.stsci.edu/jwst-near-infrared-camera/nircam-performance/nircam-absolute-flux-calibration-and-zeropoints # noqa | ||
pix_scale_factor = self.aperture.scale_factor * spectral_cube.meta.get('PIXAR_SR', 1.0) | ||
collapsed_spec.meta['_pixel_scale_factor'] = pix_scale_factor |
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 torn whether this belong in or outside of the if add_data
... but might be useful for comparing if its outside (and then just in case anyone passes that data back into jdaviz)
# per https://jwst-docs.stsci.edu/jwst-near-infrared-camera/nircam-performance/nircam-absolute-flux-calibration-and-zeropoints # noqa | |
pix_scale_factor = self.aperture.scale_factor * spectral_cube.meta.get('PIXAR_SR', 1.0) | |
collapsed_spec.meta['_pixel_scale_factor'] = pix_scale_factor | |
# per https://jwst-docs.stsci.edu/jwst-near-infrared-camera/nircam-performance/nircam-absolute-flux-calibration-and-zeropoints # noqa | |
pix_scale_factor = self.aperture.scale_factor * spectral_cube.meta.get('PIXAR_SR', 1.0) | |
collapsed_spec.meta['_pixel_scale_factor'] = pix_scale_factor |
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.
oh but this needs to be done before add_results_from_plugin
, right now the metadata entry isn't showing up when accessing through viz.get_data(...)
.
@@ -519,3 +524,13 @@ def _live_update(self, event={}): | |||
for mark in self.marks.values(): | |||
mark.update_xy(sp.spectral_axis.value, sp.flux.value) | |||
mark.visible = True | |||
|
|||
def translate_units(self, collapsed_spec): |
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 is probably fine for this PR to demonstrate the translation, but when we connect a switch, we'll want to have the ability to change the entry already loaded in the data-collection (preferably in-place without having to re-parse).
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 - definitely will want science verification on a real workflow but that can be done once the whole thing is functional (in the planned follow-up efforts). Thanks!
I most definitely agree, thank you for all of your productive input! |
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 good to me! Thanks for your work!
…r with scale factor
f10c122
to
bf012bd
Compare
Description
This pull request is to address storing the scale factor in metadata so that data can be "translated" between surface brightness and flux units. In addition, to add internal API functionality to translate from MJy/sr <-> Jy/pix.
Screen.Recording.2024-03-19.at.1.30.07.PM.mov
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.