From e9147aa037161a8f84e3a667dd5b46104e57965d Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Fri, 31 May 2024 11:58:59 -0700 Subject: [PATCH] Fix unit conversion of limits from Fnu to Flam (#2889) * Fix unit conversion from flux to surface brightness * Fix case in to_unit where limits are converted from Fnu to Flam * change variable name to match PR, speclim->specvalues, value->values * readd accidentally deleted comment --------- Co-authored-by: gibsongreen --- jdaviz/app.py | 20 ++++++++++++++------ jdaviz/tests/test_app.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/jdaviz/app.py b/jdaviz/app.py index ee2bdcc67f..73f44c87a7 100644 --- a/jdaviz/app.py +++ b/jdaviz/app.py @@ -112,6 +112,15 @@ def to_unit(self, data, cid, values, original_units, target_units): eqv = [] else: eqv = [] + + # If there are only two values, this is likely the limits being converted, so then + # in case we need to use the spectral density equivalency, we need to provide only + # to spectral axis values. If there is only one value + if not np.isscalar(values) and len(values) == 2: + spectral_values = spec.spectral_axis[0] + else: + spectral_values = spec.spectral_axis + # Ensure a spectrum passed through Spectral Extraction plugin if '_pixel_scale_factor' in spec.meta and len(values) != 2: @@ -120,26 +129,25 @@ def to_unit(self, data, cid, values, original_units, target_units): # target_units dictate the conversion to take place. if (u.sr in u.Unit(original_units).bases) and \ - (u.sr not in u.Unit(target_units).bases): + (u.sr not in u.Unit(target_units).bases): # Surface Brightness -> Flux eqv = [(u.MJy / u.sr, u.MJy, lambda x: (x * np.array(spec.meta['_pixel_scale_factor'])), lambda x: x)] elif (u.sr not in u.Unit(original_units).bases) and \ - (u.sr in u.Unit(target_units).bases): + (u.sr in u.Unit(target_units).bases): # Flux -> Surface Brightness eqv = [(u.MJy, u.MJy / u.sr, lambda x: (x / np.array(spec.meta['_pixel_scale_factor'])), lambda x: x)] else: - eqv = u.spectral_density(spec.spectral_axis) + eqv = u.spectral_density(spectral_values) elif len(values) == 2: # Need this for setting the y-limits - spec_limits = [spec.spectral_axis[0].value, spec.spectral_axis[-1].value] - eqv = u.spectral_density(spec_limits * spec.spectral_axis.unit) + eqv = u.spectral_density(spectral_values) if '_pixel_scale_factor' in spec.meta: # get min and max scale factors, to use with min and max of spec for @@ -162,7 +170,7 @@ def to_unit(self, data, cid, values, original_units, target_units): lambda x: x)] else: - eqv = u.spectral_density(spec.spectral_axis) + eqv = u.spectral_density(spectral_values) else: # spectral axis eqv = u.spectral() + u.pixel_scale(1*u.pix) diff --git a/jdaviz/tests/test_app.py b/jdaviz/tests/test_app.py index 9327198695..08bb8451e9 100644 --- a/jdaviz/tests/test_app.py +++ b/jdaviz/tests/test_app.py @@ -233,3 +233,32 @@ def test_to_unit(cubeviz_helper): # will be a uniform array since not wavelength dependent # so test first value in array assert np.allclose(value[0], 4.800000041882413e-08) + + # Change from Fnu to Flam (with values shape matching spectral axis) + + values = np.ones(3001) + original_units = u.MJy + target_units = u.erg / u.cm**2 / u.s / u.AA + + new_values = uc.to_unit(cubeviz_helper, data, cid, values, original_units, target_units) + + assert np.allclose(new_values, + (values * original_units) + .to_value(target_units, + equivalencies=u.spectral_density(cube.spectral_axis))) + + # Change from Fnu to Flam (with a shape (2,) array of values indicating we + # are probably converting the limits) + + values = [1, 2] + original_units = u.MJy + target_units = u.erg / u.cm**2 / u.s / u.AA + + new_values = uc.to_unit(cubeviz_helper, data, cid, values, original_units, target_units) + + # In this case we do a regular spectral density conversion, but using the + # first value in the spectral axis for the equivalency + assert np.allclose(new_values, + ([1, 2] * original_units) + .to_value(target_units, + equivalencies=u.spectral_density(cube.spectral_axis[0])))