diff --git a/CHANGES.rst b/CHANGES.rst index c651c91ebd..74ad53eab5 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,7 +6,7 @@ New Features - Added flux/surface brightness translation and surface brightness unit conversion in Cubeviz and Specviz. [#2781, #2940, #3088, #3111, #3113, #3129, - #3139, #3149, #3155, #3178, #3185, #3187, #3190, #3156] + #3139, #3149, #3155, #3178, #3185, #3187, #3190, #3156, #3200] - Plugin tray is now open by default. [#2892] diff --git a/jdaviz/configs/cubeviz/plugins/parsers.py b/jdaviz/configs/cubeviz/plugins/parsers.py index 95410f239b..ae2113ab63 100644 --- a/jdaviz/configs/cubeviz/plugins/parsers.py +++ b/jdaviz/configs/cubeviz/plugins/parsers.py @@ -178,7 +178,7 @@ def _get_celestial_wcs(wcs): return wcs.celestial if hasattr(wcs, 'celestial') else None -def _return_spectrum_with_correct_units(flux, wcs, metadata, data_type, +def _return_spectrum_with_correct_units(flux, wcs, metadata, data_type=None, target_wave_unit=None, hdulist=None, uncertainty=None, mask=None, apply_pix2=False): """Upstream issue of WCS not using the correct units for data must be fixed here. @@ -199,6 +199,10 @@ def _return_spectrum_with_correct_units(flux, wcs, metadata, data_type, if uncertainty is not None: uncertainty = uncertainty / (u.pix * u.pix) + # handle scale factors when they are included in the unit + if not np.isclose(flux.unit.scale, 1.0, rtol=1e-5): + flux = flux.to(flux.unit / flux.unit.scale) + sc = Spectrum1D(flux=flux, wcs=wcs, uncertainty=uncertainty, mask=mask) if target_wave_unit is None and hdulist is not None: @@ -461,7 +465,7 @@ def _parse_spectrum1d_3d(app, file_obj, data_label=None, if hasattr(file_obj, 'wcs'): meta['_orig_spatial_wcs'] = _get_celestial_wcs(file_obj.wcs) - s1d = Spectrum1D(flux=flux, wcs=file_obj.wcs, meta=meta) + s1d = _return_spectrum_with_correct_units(flux, wcs=file_obj.wcs, metadata=meta) # convert data loaded in flux units to a per-square-pixel surface # brightness unit (e.g Jy to Jy/pix**2) diff --git a/jdaviz/configs/cubeviz/plugins/spectral_extraction/tests/test_spectral_extraction.py b/jdaviz/configs/cubeviz/plugins/spectral_extraction/tests/test_spectral_extraction.py index 084bbca5bf..07e75f884a 100644 --- a/jdaviz/configs/cubeviz/plugins/spectral_extraction/tests/test_spectral_extraction.py +++ b/jdaviz/configs/cubeviz/plugins/spectral_extraction/tests/test_spectral_extraction.py @@ -432,12 +432,12 @@ def test_cube_extraction_with_nan(cubeviz_helper, image_cube_hdu_obj): cubeviz_helper.load_data(image_cube_hdu_obj, data_label="with_nan") extract_plg = cubeviz_helper.plugins['Spectral Extraction'] sp = extract_plg.extract() # Default settings (sum) - assert_allclose(sp.flux.value, 96) # (10 x 10) - 4 + assert_allclose(sp.flux.value, 9.6E-16) # (10 x 10) - 4 cubeviz_helper.load_regions(RectanglePixelRegion(PixCoord(1.5, 1.5), width=4, height=4)) extract_plg.aperture = 'Subset 1' sp_subset = extract_plg.extract() # Default settings but on Subset - assert_allclose(sp_subset.flux.value, 12) # (4 x 4) - 4 + assert_allclose(sp_subset.flux.value, 1.2E-16) # (4 x 4) - 4 def test_autoupdate_results(cubeviz_helper, spectrum1d_cube_largest): diff --git a/jdaviz/configs/cubeviz/plugins/tests/test_parsers.py b/jdaviz/configs/cubeviz/plugins/tests/test_parsers.py index 40aa0c8efd..912bf47ae8 100644 --- a/jdaviz/configs/cubeviz/plugins/tests/test_parsers.py +++ b/jdaviz/configs/cubeviz/plugins/tests/test_parsers.py @@ -45,10 +45,17 @@ def test_fits_image_hdu_with_microns(image_cube_hdu_obj_microns, cubeviz_helper) label_mouseover = cubeviz_helper.app.session.application._tools['g-coords-info'] label_mouseover._viewer_mouse_event(flux_viewer, {'event': 'mousemove', 'domain': {'x': 0, 'y': 0}}) + + # This secondarily tests a scale factor embedded in a unit at parse-time to make sure it + # is applied to the values, then it is removed from the actual display unit flux_unit_str = "erg / (Angstrom s cm2 pix2)" - assert label_mouseover.as_text() == (f'Pixel x=00.0 y=00.0 Value +5.00000e+00 1e-17 {flux_unit_str}', # noqa + assert label_mouseover.as_text() == (f'Pixel x=00.0 y=00.0 Value +5.00000e-17 {flux_unit_str}', # noqa 'World 13h41m45.5759s +27d00m12.3044s (ICRS)', '205.4398995981 27.0034178810 (deg)') # noqa + + # verify that scale factor embedded in unit is removed + assert np.allclose(flux_cube.unit.scale, 1.0) + unc_viewer = cubeviz_helper.app.get_viewer('uncert-viewer') label_mouseover._viewer_mouse_event(unc_viewer, {'event': 'mousemove', 'domain': {'x': -1, 'y': 0}}) @@ -87,7 +94,6 @@ def test_fits_image_hdu_parse_from_file(tmpdir, image_cube_hdu_obj, cubeviz_help assert cubeviz_helper.app.data_collection[0].label == "test_fits_image.fits[FLUX]" # This tests the same data as test_fits_image_hdu_parse above. - cubeviz_helper.app.data_collection[0].meta['EXTNAME'] == 'FLUX' cubeviz_helper.app.data_collection[1].meta['EXTNAME'] == 'MASK' cubeviz_helper.app.data_collection[2].meta['EXTNAME'] == 'ERR' @@ -99,7 +105,7 @@ def test_fits_image_hdu_parse_from_file(tmpdir, image_cube_hdu_obj, cubeviz_help label_mouseover._viewer_mouse_event(flux_viewer, {'event': 'mousemove', 'domain': {'x': 0, 'y': 0}}) flux_unit_str = "erg / (Angstrom s cm2 pix2)" - assert label_mouseover.as_text() == (f'Pixel x=00.0 y=00.0 Value +1.00000e+00 1e-17 {flux_unit_str}', # noqa + assert label_mouseover.as_text() == (f'Pixel x=00.0 y=00.0 Value +1.00000e-17 {flux_unit_str}', # noqa 'World 13h41m46.5994s +26d59m58.6136s (ICRS)', '205.4441642302 26.9996148973 (deg)') @@ -129,12 +135,11 @@ def test_spectrum3d_parse(image_cube_hdu_obj, cubeviz_helper): label_mouseover._viewer_mouse_event(flux_viewer, {'event': 'mousemove', 'domain': {'x': 0, 'y': 0}}) flux_unit_str = "erg / (Angstrom s cm2 pix2)" - assert label_mouseover.as_text() == (f'Pixel x=00.0 y=00.0 Value +1.00000e+00 1e-17 {flux_unit_str}', # noqa + assert label_mouseover.as_text() == (f'Pixel x=00.0 y=00.0 Value +1.00000e-17 {flux_unit_str}', # noqa 'World 13h41m46.5994s +26d59m58.6136s (ICRS)', '205.4441642302 26.9996148973 (deg)') # These viewers have no data. - unc_viewer = cubeviz_helper.app.get_viewer(cubeviz_helper._default_uncert_viewer_reference_name) label_mouseover._viewer_mouse_event(unc_viewer, {'event': 'mousemove', 'domain': {'x': -1, 'y': 0}})