-
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
fix flux unit conversions in plugins #3228
base: main
Are you sure you want to change the base?
Conversation
jdaviz/configs/cubeviz/plugins/spectral_extraction/spectral_extraction.py
Outdated
Show resolved
Hide resolved
dc6fc9c
to
12c5b13
Compare
What is the warning about? Might be related.
|
Does this need a change log? |
# but I'm keeping them since they were already here. Background | ||
# should only be converted flux<>flux or sb<>sb so only a possible | ||
# u.spectral_density would be needed. explore removing these as a follow up | ||
equivs = u.spectral() +\ |
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 \
for continuation is discouraged in Python. Instead please use ()
.
@@ -308,7 +320,11 @@ def _get_defaults_from_metadata(self, dataset=None): | |||
# if display unit is different, translate | |||
if (self.config == 'cubeviz') and (self.display_unit != ''): | |||
disp_unit = u.Unit(self.display_unit) | |||
mjy2abmag = (mjy2abmag * u.Unit("MJy/sr")).to_value(disp_unit) | |||
mjy2abmag = flux_conversion_general(mjy2abmag, | |||
u.Unit("MJy/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.
This would save the overhead of string parsing.
u.Unit("MJy/sr"), | |
u.MJy / u.sr, |
Note: This is essentially a simplified version of the function utils.flux_conversion. | ||
The difference is that all required equivalencies must be passed in (rather than being | ||
generated from an input spectrum or slice value, and combined with input equivalences). | ||
I didn't want to replace calls to that function entirely because there is some extra | ||
logic there that i'm unsure of, but in theory we could/should. |
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 be rendered in API docstring? Looks like a note meant for internal devs only. Should this be moved to code comment instead?
Since this sounds like such an important function, please also document Parameters and Returns as laid out by numpydoc.
units appear in the aperture photometry output table in the variance columns. | ||
Units like (MJy / sr)**2 to (Jy / sr)**2 can convert directly using astropy | ||
units , but if an equivalency is required this conversion needs | ||
a workaround. |
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 comment about Parameters and Returns.
yes waiting until the end so I don't get conflicts to resolve |
y = flux_conversion_general(self.y, self.yunit, unit, eqv) | ||
else: | ||
y = (self.y * self.yunit).to_value(unit) | ||
y = flux_conversion_general(self.y, self.yunit, unit) |
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.
Good catch here, this originally was causing one of the tracebacks with some of the plugins in Specviz2d (in #3253), would only go away with this new flux_conversion_general
.
if 'PIXAR_SR' in self.app.data_collection[0].meta: | ||
# Need current slice value and associated unit to use to compute | ||
# spectral density equivalencies that enable Flux to Flux conversions. | ||
# This is needed for units that are not directly convertible/translatable. | ||
slice = viewer.slice_value * u.Unit(self.app._get_display_unit('spectral')) | ||
|
||
value = flux_conversion(value, unit, self.image_unit, | ||
eqv=_eqv_pixar_sr(self.app.data_collection[0].meta['PIXAR_SR']), # noqa: E501 | ||
slice=slice) | ||
unit = self.image_unit | ||
|
||
elif self.image_unit.is_equivalent(unit): | ||
value = (value * u.Unit(unit)).to_value(u.Unit(self.image_unit)) | ||
unit = self.image_unit | ||
pixar_sr = self.app.data_collection[0].meta | ||
else: | ||
pixar_sr = 1 | ||
eqv += _eqv_pixar_sr(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.
Is there a case here where we might need the _eqv_flux_to_sb_pixel
equivalencies? This applies to Specviz, Specviz2d, (and I'm assuming Mosviz). This is one outcome in Specviz without it in the image below. In #3253 I introduce 'un'-exposing the SB and angle unit so they don't display in the API/UI, so it might not need to be address but until that is in this is the current state in non-Cubeviz configs.
valid_types = ["spectral flux density", "surface brightness", | ||
"power density/spectral flux density wav", | ||
"photon flux density wav", | ||
"photon flux density"] | ||
if str(physical_type) not in valid_types: |
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.
Will make a note on the physical types JDAT-ticket and here (#3234).
equivs = _eqv_flux_to_sb_pixel() + u.spectral_density(init_x) | ||
init_y = init_y.to(self._units['y'], equivs) | ||
|
||
init_y = flux_conversion_general([init_y.value], init_y.unit, self._units['y'], equivs) |
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.
Leaving another note here to retest model fitting in Specviz2d following merging this PR (#3253). Bug was preexisting unit conversion plugin but still worth retesting.
eqv = _eqv_pixar_sr(self.dataset.selected_obj.meta.get('PIXAR_SR', 1.0)) | ||
eqv += _eqv_flux_to_sb_pixel() # for conversions between flux <> sb per pix2 | ||
eqv += u.spectral_density(self.dataset.selected_obj.spectral_axis) |
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.
eqv = _eqv_pixar_sr(self.dataset.selected_obj.meta.get('PIXAR_SR', 1.0)) | |
eqv += _eqv_flux_to_sb_pixel() # for conversions between flux <> sb per pix2 | |
eqv += u.spectral_density(self.dataset.selected_obj.spectral_axis) | |
eqv = ( | |
_eqv_pixar_sr(self.dataset.selected_obj.meta.get('PIXAR_SR', 1.0)) | |
+ _eqv_flux_to_sb_pixel() | |
+ u.spectral_density(self.dataset.selected_obj.spectral_axis) | |
) | |
def flux_conversion_general(values, original_unit, target_unit, | ||
equivalencies=None, with_unit=True): |
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 we keep the parameters the same here as in flux_conversion
? Originally adding spec
and slice
had to do with the image-viewers (the one case I explicitly remember testing for is working with the current state here) and eventually image data. I'll need to test this out a bit more to, might not be necessary but I will add a note about this on the Imviz implementation ticket.
Flux unit conversions done in plugins go through the 'flux_conversion_general' function that handles all equivalencies and special cases where the angle needs to be multiplied out before conversion. plugins that listen to unit conversion are tested with every combination of units to ensure all units that the spectral y axis can be translated to work in the plugin.