diff --git a/jdaviz/configs/cubeviz/plugins/tests/test_parsers.py b/jdaviz/configs/cubeviz/plugins/tests/test_parsers.py index 4da5089072..b7453ede07 100644 --- a/jdaviz/configs/cubeviz/plugins/tests/test_parsers.py +++ b/jdaviz/configs/cubeviz/plugins/tests/test_parsers.py @@ -5,6 +5,8 @@ from astropy.wcs import WCS from specutils import Spectrum1D +from jdaviz.utils import PRIHDR_KEY + @pytest.fixture def image_hdu_obj(): @@ -58,6 +60,12 @@ def test_fits_image_hdu_parse_from_file(tmpdir, image_hdu_obj, cubeviz_helper): # 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' + for i in range(3): + assert cubeviz_helper.app.data_collection[i].meta[PRIHDR_KEY]['BITPIX'] == 8 + flux_viewer = cubeviz_helper.app.get_viewer('flux-viewer') flux_viewer.on_mouse_or_key_event({'event': 'mousemove', 'domain': {'x': 0, 'y': 0}}) assert flux_viewer.label_mouseover.pixel == 'x=00.0 y=00.0' @@ -114,6 +122,7 @@ def test_spectrum1d_parse(spectrum1d, cubeviz_helper): assert len(cubeviz_helper.app.data_collection) == 1 assert cubeviz_helper.app.data_collection[0].label.endswith('[FLUX]') + assert cubeviz_helper.app.data_collection[0].meta['uncertainty_type'] == 'std' # Coordinate display is only for spatial image, which is missing here. flux_viewer = cubeviz_helper.app.get_viewer('flux-viewer') diff --git a/jdaviz/configs/mosviz/plugins/parsers.py b/jdaviz/configs/mosviz/plugins/parsers.py index 3ffb3ece49..ee8bdf9e3a 100644 --- a/jdaviz/configs/mosviz/plugins/parsers.py +++ b/jdaviz/configs/mosviz/plugins/parsers.py @@ -221,8 +221,13 @@ def mos_spec1d_parser(app, data_obj, data_labels=None): with app.data_collection.delay_link_manager_update(): - for i in range(len(data_obj)): - app.add_data(data_obj[i], data_labels[i], notify_done=False) + for cur_data, cur_label in zip(data_obj, data_labels): + # Make metadata layout conform with other viz. + if 'header' in cur_data.meta: + cur_data.meta.update(cur_data.meta['header']) + del cur_data.meta['header'] + + app.add_data(cur_data, cur_label, notify_done=False) _add_to_table(app, data_labels, '1D Spectra') diff --git a/jdaviz/configs/mosviz/tests/test_data_loading.py b/jdaviz/configs/mosviz/tests/test_data_loading.py index 8dece712bd..15e23910a9 100644 --- a/jdaviz/configs/mosviz/tests/test_data_loading.py +++ b/jdaviz/configs/mosviz/tests/test_data_loading.py @@ -9,13 +9,17 @@ import pytest from specutils import Spectrum1D +from jdaviz.utils import PRIHDR_KEY + def test_load_spectrum1d(mosviz_helper, spectrum1d): label = "Test 1D Spectrum" mosviz_helper.load_1d_spectra(spectrum1d, data_labels=label) assert len(mosviz_helper.app.data_collection) == 2 - assert mosviz_helper.app.data_collection[0].label == label + dc_0 = mosviz_helper.app.data_collection[0] + assert dc_0.label == label + assert dc_0.meta['uncertainty_type'] == 'std' table = mosviz_helper.app.get_viewer('table-viewer') table.widget_table.vue_on_row_clicked(0) @@ -24,7 +28,7 @@ def test_load_spectrum1d(mosviz_helper, spectrum1d): assert isinstance(data[label], Spectrum1D) - with pytest.raises(TypeError): + with pytest.raises(AttributeError): mosviz_helper.load_1d_spectra([1, 2, 3]) @@ -34,7 +38,10 @@ def test_load_image(mosviz_helper, mos_image): mosviz_helper.load_images(mos_image, data_labels=label) assert len(mosviz_helper.app.data_collection) == 2 - assert mosviz_helper.app.data_collection[0].label == f"{label} 0" + dc_0 = mosviz_helper.app.data_collection[0] + assert dc_0.label == f"{label} 0" + assert PRIHDR_KEY not in dc_0.meta + assert dc_0.meta['RADESYS'] == 'ICRS' table = mosviz_helper.app.get_viewer('table-viewer') table.widget_table.vue_on_row_clicked(0) @@ -51,7 +58,9 @@ def test_load_spectrum_collection(mosviz_helper, spectrum_collection): mosviz_helper.load_1d_spectra(spectrum_collection, data_labels=labels) assert len(mosviz_helper.app.data_collection) == 6 - assert mosviz_helper.app.data_collection[0].label == labels[0] + dc_0 = mosviz_helper.app.data_collection[0] + assert dc_0.label == labels[0] + assert dc_0.meta['uncertainty_type'] == 'std' table = mosviz_helper.app.get_viewer('table-viewer') table.widget_table.vue_on_row_clicked(0) @@ -68,7 +77,9 @@ def test_load_list_of_spectrum1d(mosviz_helper, spectrum1d): mosviz_helper.load_1d_spectra(spectra, data_labels=labels) assert len(mosviz_helper.app.data_collection) == 4 - assert mosviz_helper.app.data_collection[0].label == labels[0] + dc_0 = mosviz_helper.app.data_collection[0] + assert dc_0.label == labels[0] + assert dc_0.meta['uncertainty_type'] == 'std' table = mosviz_helper.app.get_viewer('table-viewer') table.widget_table.vue_on_row_clicked(0) @@ -85,7 +96,9 @@ def test_load_mos_spectrum2d(mosviz_helper, mos_spectrum2d): mosviz_helper.load_2d_spectra(mos_spectrum2d, data_labels=label) assert len(mosviz_helper.app.data_collection) == 2 - assert mosviz_helper.app.data_collection[0].label == label + dc_0 = mosviz_helper.app.data_collection[0] + assert dc_0.label == label + assert dc_0.meta['INSTRUME'] == 'nirspec' table = mosviz_helper.app.get_viewer('table-viewer') table.widget_table.vue_on_row_clicked(0) @@ -140,7 +153,7 @@ def test_load_single_image_multi_spec(mosviz_helper, mos_image, spectrum1d, mos_ @pytest.mark.filterwarnings('ignore') @pytest.mark.remote_data -def test_nirpsec_loader(mosviz_helper, tmpdir): +def test_nirspec_loader(mosviz_helper, tmpdir): ''' Tests loading our default MosvizExample notebook data ''' @@ -157,12 +170,30 @@ def test_nirpsec_loader(mosviz_helper, tmpdir): mosviz_helper.load_data(directory=data_dir, instrument='nirspec') assert len(mosviz_helper.app.data_collection) == 16 - assert "MOS Table" in mosviz_helper.app.data_collection - assert "Image 4" in mosviz_helper.app.data_collection - assert "1D Spectrum 4" in mosviz_helper.app.data_collection - assert "2D Spectrum 4" in mosviz_helper.app.data_collection + + dc_0 = mosviz_helper.app.data_collection[0] + assert dc_0.label == "MOS Table" + assert len(dc_0.meta) == 0 + + dc_5 = mosviz_helper.app.data_collection[5] + assert dc_5.label == "Image 4" + assert PRIHDR_KEY not in dc_5.meta + assert dc_5.meta['WCSAXES'] == 2 + + dc_10 = mosviz_helper.app.data_collection[10] + assert dc_10.label == "1D Spectrum 4" + assert PRIHDR_KEY not in dc_10.meta + assert 'header' not in dc_10.meta + assert dc_10.meta['TARGNAME'] == 'FOO' + + dc_15 = mosviz_helper.app.data_collection[15] + assert dc_15.label == "2D Spectrum 4" + assert PRIHDR_KEY not in dc_15.meta + assert 'header' not in dc_15.meta + assert dc_15.meta['SOURCEID'] == 2315 +# This is another version of test_niriss_parser in test_parsers.py @pytest.mark.remote_data def test_niriss_loader(mosviz_helper, tmpdir): @@ -183,7 +214,7 @@ def test_niriss_loader(mosviz_helper, tmpdir): @pytest.mark.remote_data -def test_nirpsec_fallback(mosviz_helper, tmpdir): +def test_nirspec_fallback(mosviz_helper, tmpdir): ''' When no instrument is provided, mosviz.load_data is expected to fallback to the nirspec loader. Naturally, the nirspec dataset should then work without any instrument keyword diff --git a/jdaviz/configs/mosviz/tests/test_parsers.py b/jdaviz/configs/mosviz/tests/test_parsers.py index 42284cde60..b8ede93f58 100644 --- a/jdaviz/configs/mosviz/tests/test_parsers.py +++ b/jdaviz/configs/mosviz/tests/test_parsers.py @@ -1,10 +1,13 @@ -import pytest from zipfile import ZipFile import pathlib +import pytest from astropy.utils.data import download_file +from jdaviz.utils import PRIHDR_KEY + +# This is another version of test_niriss_loader in test_data_loading.py @pytest.mark.remote_data def test_niriss_parser(mosviz_helper, tmpdir): @@ -20,5 +23,23 @@ def test_niriss_parser(mosviz_helper, tmpdir): mosviz_helper.load_niriss_data(data_dir) assert len(mosviz_helper.app.data_collection) == 80 - assert mosviz_helper.app.data_collection[0].label == "Image canucs F150W" - assert mosviz_helper.app.data_collection[-1].label == "MOS Table" + + dc_0 = mosviz_helper.app.data_collection[0] + assert dc_0.label == "Image canucs F150W" + assert PRIHDR_KEY not in dc_0.meta + assert dc_0.meta['bunit_data'] == 'MJy/sr' # ASDF metadata + + dc_1 = mosviz_helper.app.data_collection[1] + assert dc_1.label == 'F150W Source 1 spec2d C' + assert PRIHDR_KEY not in dc_1.meta + assert dc_1.meta['SOURCEID'] == 1 + + dc_40 = mosviz_helper.app.data_collection[40] + assert dc_40.label == 'F150W Source 1 spec1d C' + assert PRIHDR_KEY not in dc_40.meta + assert 'header' not in dc_40.meta + assert dc_40.meta['FILTER'] == 'GR150C' + + dc_tab = mosviz_helper.app.data_collection[-1] + assert dc_tab.label == "MOS Table" + assert len(dc_tab.meta) == 0 diff --git a/jdaviz/configs/specviz/tests/test_helper.py b/jdaviz/configs/specviz/tests/test_helper.py index 6b71db428e..68fb8dc408 100644 --- a/jdaviz/configs/specviz/tests/test_helper.py +++ b/jdaviz/configs/specviz/tests/test_helper.py @@ -26,7 +26,9 @@ def setup_class(self, specviz_helper, spectrum1d): def test_load_spectrum1d(self): assert len(self.spec_app.app.data_collection) == 1 - assert self.spec_app.app.data_collection[0].label == self.label + dc_0 = self.spec_app.app.data_collection[0] + assert dc_0.label == self.label + assert dc_0.meta['uncertainty_type'] == 'std' data = self.spec_app.app.get_data_from_viewer('spectrum-viewer') @@ -248,9 +250,12 @@ def test_load_spectrum_list_directory(tmpdir, specviz_helper): with pytest.warns(UserWarning, match='SRCTYPE is missing or UNKNOWN in JWST x1d loader'): specviz_helper.load_spectrum(data_path) assert len(specviz_helper.app.data_collection) == 3 - for element in specviz_helper.app.data_collection: - assert element.data.main_components[0] in ['flux'] - assert element.data.main_components[1] in ['uncertainty'] + for data in specviz_helper.app.data_collection: + assert data.main_components[:2] == ['flux', 'uncertainty'] + + dc_0 = specviz_helper.app.data_collection[0] + assert 'header' not in dc_0.meta + assert dc_0.meta['SPORDER'] == 1 def test_plot_uncertainties(specviz_helper, spectrum1d): diff --git a/jdaviz/configs/specviz2d/tests/__init__.py b/jdaviz/configs/specviz2d/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/jdaviz/configs/specviz2d/tests/test_parsers.py b/jdaviz/configs/specviz2d/tests/test_parsers.py new file mode 100644 index 0000000000..8cb6cccc81 --- /dev/null +++ b/jdaviz/configs/specviz2d/tests/test_parsers.py @@ -0,0 +1,33 @@ +import pytest +from asdf.asdf import AsdfWarning +from astropy.utils.data import download_file + +from jdaviz.utils import PRIHDR_KEY + + +@pytest.mark.remote_data +def test_2d_parser(specviz2d_helper): + fn = download_file('https://stsci.box.com/shared/static/exnkul627fcuhy5akf2gswytud5tazmw.fits', cache=True) # noqa + + with pytest.warns(AsdfWarning, match='jwextension'): + specviz2d_helper.load_data(spectrum_2d=fn) + assert len(specviz2d_helper.app.data_collection) == 2 + + dc_0 = specviz2d_helper.app.data_collection[0] + assert dc_0.label == 'Spectrum 2D' + assert PRIHDR_KEY not in dc_0.meta + assert 'header' not in dc_0.meta + assert dc_0.meta['DETECTOR'] == 'MIRIMAGE' + + dc_1 = specviz2d_helper.app.data_collection[1] + assert dc_1.label == 'Spectrum 1D' + assert 'header' not in dc_1.meta + assert dc_1.meta['NAXIS'] == 2 + + +def test_1d_parser(specviz2d_helper, spectrum1d): + specviz2d_helper.load_data(spectrum_1d=spectrum1d) + assert len(specviz2d_helper.app.data_collection) == 1 + dc_0 = specviz2d_helper.app.data_collection[0] + assert dc_0.label == 'Spectrum 1D' + assert dc_0.meta['uncertainty_type'] == 'std' diff --git a/jdaviz/conftest.py b/jdaviz/conftest.py index c9ea41783d..1643adc27d 100644 --- a/jdaviz/conftest.py +++ b/jdaviz/conftest.py @@ -99,9 +99,7 @@ def spectrum1d_cube(): "CRPIX1": 0, "CRPIX2": 0, "CRPIX3": 0} w = WCS(wcs_dict) - spec = Spectrum1D(flux=flux, wcs=w) - - return spec + return Spectrum1D(flux=flux, wcs=w) @pytest.fixture @@ -116,6 +114,7 @@ def mos_spectrum1d(): Unless linking the two is required, try to use the global spectrum1d fixture. ''' spec_axis = np.linspace(6000, 8000, 1024) * u.AA + np.random.seed(42) flux = (np.random.randn(len(spec_axis.value)) + 10*np.exp(-0.001*(spec_axis.value-6563)**2) + spec_axis.value/500) * u.Jy @@ -132,78 +131,36 @@ def mos_spectrum2d(): TODO: This should be reformed to match the global Spectrum1D defined above so that we may deprecate the mos-specific spectrum1d. ''' - header = """ -WCSAXES = 2 / Number of coordinate axes -CRPIX1 = 0.0 / Pixel coordinate of reference point -CRPIX2 = 1024.5 / Pixel coordinate of reference point -CDELT1 = 1E-06 / [m] Coordinate increment at reference point -CDELT2 = 2.9256727777778E-05 / [deg] Coordinate increment at reference point -CUNIT1 = 'm' / Units of coordinate increment and value -CUNIT2 = 'deg' / Units of coordinate increment and value -CTYPE1 = 'WAVE' / Vacuum wavelength (linear) -CTYPE2 = 'OFFSET' / Spatial offset -CRVAL1 = 0.0 / [m] Coordinate value at reference point -CRVAL2 = 5.0 / [deg] Coordinate value at reference point -RADESYS = 'ICRS' / Equatorial coordinate system -SPECSYS = 'BARYCENT' / Reference frame of spectral coordinates -""" - new_hdr = {} - - for line in header.split('\n'): - try: - key, value = line.split('=') - key = key.strip() - value, _ = value.split('/') - value = value.strip() - value = value.strip("'") - except ValueError: - continue - - new_hdr[key] = value - - wcs = WCS(new_hdr) + header = { + 'WCSAXES': 2, + 'CRPIX1': 0.0, 'CRPIX2': 1024.5, + 'CDELT1': 1E-06, 'CDELT2': 2.9256727777778E-05, + 'CUNIT1': 'm', 'CUNIT2': 'deg', + 'CTYPE1': 'WAVE', 'CTYPE2': 'OFFSET', + 'CRVAL1': 0.0, 'CRVAL2': 5.0, + 'RADESYS': 'ICRS', 'SPECSYS': 'BARYCENT'} + wcs = WCS(header) + np.random.seed(42) data = np.random.sample((1024, 15)) * u.one - return Spectrum1D(data, wcs=wcs) + return Spectrum1D(data, wcs=wcs, meta=header) @pytest.fixture def mos_image(): - header = """ -WCSAXES = 2 / Number of coordinate axes -CRPIX1 = 937.0 / Pixel coordinate of reference point -CRPIX2 = 696.0 / Pixel coordinate of reference point -CDELT1 = -1.5182221158397E-05 / [deg] Coordinate increment at reference point -CDELT2 = 1.5182221158397E-05 / [deg] Coordinate increment at reference point -CUNIT1 = 'deg' / Units of coordinate increment and value -CUNIT2 = 'deg' / Units of coordinate increment and value -CTYPE1 = 'RA---TAN' / Right ascension, gnomonic projection -CTYPE2 = 'DEC--TAN' / Declination, gnomonic projection -CRVAL1 = 5.0155198140981 / [deg] Coordinate value at reference point -CRVAL2 = 5.002450989248 / [deg] Coordinate value at reference point -LONPOLE = 180.0 / [deg] Native longitude of celestial pole -LATPOLE = 5.002450989248 / [deg] Native latitude of celestial pole -DATEREF = '1858-11-17' / ISO-8601 fiducial time -MJDREFI = 0.0 / [d] MJD of fiducial time, integer part -MJDREFF = 0.0 / [d] MJD of fiducial time, fractional part -RADESYS = 'ICRS' / Equatorial coordinate system -""" - new_hdr = {} - - for line in header.split('\n'): - try: - key, value = line.split('=') - key = key.strip() - value, _ = value.split('/') - value = value.strip() - value = value.strip("'") - except ValueError: - continue - - new_hdr[key] = value - - wcs = WCS(new_hdr) + header = { + 'WCSAXES': 2, + 'CRPIX1': 937.0, 'CRPIX2': 696.0, + 'CDELT1': -1.5182221158397e-05, 'CDELT2': 1.5182221158397e-05, + 'CUNIT1': 'deg', 'CUNIT2': 'deg', + 'CTYPE1': 'RA---TAN', 'CTYPE2': 'DEC--TAN', + 'CRVAL1': 5.0155198140981, 'CRVAL2': 5.002450989248, + 'LONPOLE': 180.0, 'LATPOLE': 5.002450989248, + 'DATEREF': '1858-11-17', 'MJDREFI': 0.0, 'MJDREFF': 0.0, + 'RADESYS': 'ICRS'} + wcs = WCS(header) + np.random.seed(42) data = np.random.sample((55, 55)) - return CCDData(data, wcs=wcs, unit='Jy') + return CCDData(data, wcs=wcs, unit='Jy', meta=header) try: diff --git a/jdaviz/utils.py b/jdaviz/utils.py index 26f088f3df..5a3521f716 100644 --- a/jdaviz/utils.py +++ b/jdaviz/utils.py @@ -4,7 +4,6 @@ import os from ipyvue import watch - __all__ = [] # For Metadata Viewer plugin internal use only.