Skip to content

Commit

Permalink
moved equivalencies to new file
Browse files Browse the repository at this point in the history
  • Loading branch information
cshanahan1 committed Nov 20, 2024
1 parent 88d82f9 commit 7f9e561
Show file tree
Hide file tree
Showing 32 changed files with 1,162 additions and 547 deletions.
8 changes: 4 additions & 4 deletions jdaviz/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@
from jdaviz.utils import (SnackbarQueue, alpha_index, data_has_valid_wcs, layer_is_table_data,
MultiMaskSubsetState, _wcs_only_label, flux_conversion,
spectral_axis_conversion)
from jdaviz.core.custom_units import SPEC_PHOTON_FLUX_DENSITY_UNITS
from jdaviz.core.validunits import (check_if_unit_is_per_solid_angle,
combine_flux_and_angle_units,
supported_sq_angle_units)
from jdaviz.core.custom_units_and_equivs import SPEC_PHOTON_FLUX_DENSITY_UNITS
from jdaviz.core.unit_conversion_utils import (check_if_unit_is_per_solid_angle,
combine_flux_and_angle_units,
supported_sq_angle_units)

__all__ = ['Application', 'ALL_JDAVIZ_CONFIGS', 'UnitConverterWithSpectral']

Expand Down
14 changes: 13 additions & 1 deletion jdaviz/configs/cubeviz/plugins/moment_maps/moment_maps.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
SpectralContinuumMixin,
skip_if_no_updates_since_last_active,
with_spinner)
from jdaviz.core.unit_conversion_utils import flux_conversion_general
from jdaviz.core.user_api import PluginUserApi

__all__ = ['MomentMap']
Expand Down Expand Up @@ -324,7 +325,18 @@ def calculate_moment(self, add_data=True):
# convert units for moment 0, which is the only currently supported
# moment for using converted units.
if n_moment == 0:
self.moment = self.moment.to(self.moment_zero_unit)
x_unit = u.Unit(self.spectrum_viewer.state.x_display_unit)
# only flux<> flux conversions will occur, so we only
# need the spectral_density equivalency. should I just
# be using the mean wavelength here?
eqv = u.spectral_density(np.mean(slab.spectral_axis))

self.moment = flux_conversion_general(self.moment.value,
u.Unit(self.moment.unit) / x_unit,
u.Unit(self.moment_zero_unit) / x_unit,
eqv, with_unit=True)

self.moment *= x_unit

# Reattach the WCS so we can load the result
self.moment = CCDData(self.moment, wcs=data_wcs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from numpy.testing import assert_allclose
from specutils import SpectralRegion

from jdaviz.core.custom_units_and_equivs import PIX2, SPEC_PHOTON_FLUX_DENSITY_UNITS


@pytest.mark.parametrize("cube_type", ["Surface Brightness", "Flux"])
def test_user_api(cubeviz_helper, spectrum1d_cube, spectrum1d_cube_sb_unit, cube_type):
Expand Down Expand Up @@ -350,3 +352,75 @@ def test_correct_output_spectral_y_units(cubeviz_helper, spectrum1d_cube_custom_

mm.calculate_moment()
assert mm.moment.unit == moment_unit.replace('m', 'um')


@pytest.mark.parametrize("flux_angle_unit", [(u.Unit(x), u.sr) for x in SPEC_PHOTON_FLUX_DENSITY_UNITS] + [(u.Unit(x), PIX2) for x in SPEC_PHOTON_FLUX_DENSITY_UNITS]) # noqa
def test_moment_zero_unit_flux_conversions(cubeviz_helper,
spectrum1d_cube_custom_fluxunit,
flux_angle_unit):
"""
Test the calculation of the 0th moment and all possible flux unit conversions.
Tests all units in SPEC_PHOTON_FLUX_DENSITY_UNITS against one another, since
they are all valid selections in the unit conversion plugin.
"""
flux_unit, angle_unit = flux_angle_unit
cube_unit = flux_unit / angle_unit

sb_cube = spectrum1d_cube_custom_fluxunit(fluxunit=cube_unit)

# load surface brigtness cube
with warnings.catch_warnings():
warnings.filterwarnings("ignore", message="No observer defined on WCS.*")
cubeviz_helper.load_data(sb_cube, data_label='test')

# get plugins
uc = cubeviz_helper.plugins["Unit Conversion"]
mm = cubeviz_helper.plugins['Moment Maps']._obj

# and flux viewer for mouseover info
flux_viewer = cubeviz_helper.app.get_viewer(cubeviz_helper._default_flux_viewer_reference_name)
label_mouseover = cubeviz_helper.app.session.application._tools['g-coords-info']

for new_flux_unit in SPEC_PHOTON_FLUX_DENSITY_UNITS:
if new_flux_unit != flux_unit: # dont compare same units
# first set back to original flux unit, so we're not converting from
# the unit set during the last iteration
uc.flux_unit.selected = flux_unit.to_string()

# then convert to new flux unit
uc.flux_unit.selected = new_flux_unit

new_mm_unit = (u.Unit(new_flux_unit) * u.m / u.Unit(angle_unit)).to_string()
assert mm.output_unit_items[0]['label'] == 'Surface Brightness'
assert mm.output_unit_items[0]['unit_str'] == new_mm_unit

# calculate moment with new output label and plot in flux viewer
mm.add_results.label = new_flux_unit
mm.add_results.viewer.selected = cubeviz_helper._default_flux_viewer_reference_name
mm.calculate_moment()

assert mm.moment.unit == new_mm_unit

# make sure mouseover info in flux unit is new moment map unit
# which should be flux/sb unit times spectral axis unit (e.g. MJy m / sr)
label_mouseover._viewer_mouse_event(flux_viewer,
{'event': 'mousemove',
'domain': {'x': 0, 'y': 0}})
m_orig = label_mouseover.as_text()[0]
assert (u.Unit(new_flux_unit / angle_unit) * u.m).to_string() in m_orig

# 'jiggle' mouse so we can move it back
label_mouseover._viewer_mouse_event(flux_viewer,
{'event': 'mousemove',
'domain': {'x': 1, 'y': 1}})

# when flux unit is changed, the mouseover unit conversion should be
# skipped so that the plotted moment map remains in its original
# unit. setting back to the original flux unit also ensures that
# each iteration begins on the same unit so that every comparison
# is tested
uc.flux_unit.selected = new_flux_unit
label_mouseover._viewer_mouse_event(flux_viewer,
{'event': 'mousemove',
'domain': {'x': 0, 'y': 0}})
assert m_orig == label_mouseover.as_text()[0]
7 changes: 3 additions & 4 deletions jdaviz/configs/cubeviz/plugins/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@
from astropy.wcs import WCS
from specutils import Spectrum1D

from jdaviz.core.custom_units import PIX2
from jdaviz.core.custom_units_and_equivs import PIX2, _eqv_flux_to_sb_pixel
from jdaviz.core.registries import data_parser_registry
from jdaviz.core.validunits import check_if_unit_is_per_solid_angle
from jdaviz.utils import (standardize_metadata, PRIHDR_KEY, download_uri_to_path,
_eqv_flux_to_sb_pixel)
from jdaviz.core.unit_conversion_utils import check_if_unit_is_per_solid_angle
from jdaviz.utils import standardize_metadata, PRIHDR_KEY, download_uri_to_path

__all__ = ['parse_data']

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@
skip_if_no_updates_since_last_active,
with_spinner, with_temp_disable)
from jdaviz.core.user_api import PluginUserApi
from jdaviz.core.validunits import check_if_unit_is_per_solid_angle
from jdaviz.core.unit_conversion_utils import (all_flux_unit_conversion_equivs,
flux_conversion_general,
check_if_unit_is_per_solid_angle)
from jdaviz.configs.cubeviz.plugins.parsers import _return_spectrum_with_correct_units
from jdaviz.configs.cubeviz.plugins.viewers import WithSliceIndicator
from jdaviz.utils import _eqv_pixar_sr


__all__ = ['SpectralExtraction']
Expand Down Expand Up @@ -562,9 +563,18 @@ def _preview_x_from_extracted(self, extracted):
return extracted.spectral_axis

def _preview_y_from_extracted(self, extracted):
# TODO: use extracted.meta.get('PIXAR_SR') once populated
return extracted.flux.to(self.spectrum_y_units,
equivalencies=_eqv_pixar_sr(self.dataset.selected_obj.meta.get('PIXAR_SR', 1.0))) # noqa:
"""Convert y-axis units of extraction preview to display units,
if necessary."""

if extracted.flux.unit != self.spectrum_y_units:

eqv = all_flux_unit_conversion_equivs(self.dataset.selected_obj.meta.get('PIXAR_SR', 1.0), # noqa
self.dataset.selected_obj.spectral_axis)

return flux_conversion_general(extracted.flux.value, extracted.flux.unit,
self.spectrum_y_units, eqv)

return extracted.flux

@with_spinner()
def extract(self, return_bg=False, add_data=True, **kwargs):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,17 @@
from astropy.table import QTable
from astropy.tests.helper import assert_quantity_allclose
from astropy.utils.exceptions import AstropyUserWarning

from glue.core.roi import CircularROI, RectangularROI
from numpy.testing import assert_allclose, assert_array_equal
from regions import (CirclePixelRegion, CircleAnnulusPixelRegion, EllipsePixelRegion,
RectanglePixelRegion, PixCoord)
from specutils import Spectrum1D
from specutils.manipulation import FluxConservingResampler

from jdaviz.core.custom_units_and_equivs import PIX2, SPEC_PHOTON_FLUX_DENSITY_UNITS
from jdaviz.core.unit_conversion_utils import (all_flux_unit_conversion_equivs,
flux_conversion_general)

calspec_url = "https://archive.stsci.edu/hlsps/reference-atlases/cdbs/current_calspec/"


Expand Down Expand Up @@ -650,3 +653,68 @@ def test_spectral_extraction_scientific_validation(
).to_value(u.dimensionless_unscaled) - 1
))
assert median_abs_relative_dev < expected_rtol


@pytest.mark.parametrize("flux_angle_unit", [(u.Unit(x), u.sr) for x in SPEC_PHOTON_FLUX_DENSITY_UNITS] # noqa
+ [(u.Unit(x), PIX2) for x in SPEC_PHOTON_FLUX_DENSITY_UNITS]) # noqa
def test_spectral_extraction_flux_unit_conversions(cubeviz_helper,
spectrum1d_cube_custom_fluxunit,
flux_angle_unit):
"""
Test that cubeviz spectral extraction plugin works with all possible
flux unit conversions for a cube loaded in units spectral/photon flux
density. The spectral extraction result will remain in the native
data unit, but the extraction preview should be converted to the
display unit.
"""

flux_unit, angle_unit = flux_angle_unit

sb_cube = spectrum1d_cube_custom_fluxunit(fluxunit=flux_unit / angle_unit,
shape=(5, 4, 4),
with_uncerts=True)
cubeviz_helper.load_data(sb_cube)

spectrum_viewer = cubeviz_helper.app.get_viewer(
cubeviz_helper._default_spectrum_viewer_reference_name)

uc = cubeviz_helper.plugins["Unit Conversion"]
se = cubeviz_helper.plugins['Spectral Extraction']
se.keep_active = True # keep active for access to preview markers

# equivalencies for unit conversion, for comparison of outputs
equivs = all_flux_unit_conversion_equivs(se.dataset.selected_obj.meta.get('PIXAR_SR', 1.0),
se.dataset.selected_obj.spectral_axis)

for new_flux_unit in SPEC_PHOTON_FLUX_DENSITY_UNITS:
if new_flux_unit != flux_unit:

uc.flux_unit.selected = flux_unit.to_string()
uc.spectral_y_type.selected = 'Flux'

# and set back to sum initially so units will always be flux not sb
se.function.selected = 'Sum'
se.extract()

original_sum_y_values = se._obj.marks['extract'].y

# set to new unit
uc.flux_unit.selected = new_flux_unit
assert spectrum_viewer.state.y_display_unit == new_flux_unit

# still using 'sum', results should be in flux
collapsed = se.extract()

# make sure extraction preview was translated to new display units
new_sum_y_values = se._obj.marks['extract'].y
new_converted_to_old_unit = flux_conversion_general(new_sum_y_values,
u.Unit(new_flux_unit),
u.Unit(flux_unit),
equivs, with_unit=False)
np.testing.assert_allclose(original_sum_y_values, new_converted_to_old_unit)

# collapsed result will still have the native data flux unit
assert uc.spectral_y_type.selected == 'Flux'
assert collapsed.flux.unit == collapsed.uncertainty.unit == flux_unit
# but display units in spectrum viewer should reflect new flux unit selection
assert se._obj.spectrum_y_units == se._obj.results_units == new_flux_unit
Loading

0 comments on commit 7f9e561

Please sign in to comment.