def read_spectra_file(data_or_file, format=None, config_dict=None): """Read a FITS file of a spectrum into a SpectrumList Parameters ---------- data_or_file : HDUList, Path or file object The FITS data to load format : str, optional The format of the FITS file, by default None config_dict : dict, optional Used to specify the format of the FITS file, if the format string doesn't work, by default None Returns ------- specutils.SpectrumList Data from the FITS file in a SpectrumList object """ if data_or_file is None: return None if format: return SpectrumList.read(data_or_file, format=format) elif config_dict: return SpectrumList.read(data_or_file, **config_dict) else: # Try to resolve ambiguous loaders formats = ssv.ssvloaders.whatformat(data_or_file) if len(formats) > 1: for i in range(len(formats) - 1): ssv.ssvloaders.unregister(formats[i]) spectra = SpectrumList.read(data_or_file, format=formats[-1]) ssv.ssvloaders.restore_registered_loaders() return spectra
def fromMarzJSON(json_spectrum): from astropy.nddata import ( VarianceUncertainty, StdDevUncertainty, InverseVariance, ) wavelength = Quantity(json_spectrum["wavelength"], u.Angstrom) spectrum = SpectrumList() uncertainty = None if "variance" in json_spectrum.keys(): uncertainty = StdDevUncertainty( Quantity(np.array(json_spectrum["variance"], dtype=np.float))) for key in json_spectrum.keys(): if key != 'wavelength' and key != 'variance': flux = Quantity(np.array(json_spectrum[key], dtype=np.float)) if key == 'intensity' and uncertainty: aspectrum = Spectrum1D(flux=flux, spectral_axis=wavelength, uncertainty=uncertainty, mask=np.isnan(flux), meta={'purpose': 'reduced'}) else: aspectrum = Spectrum1D(flux=flux, spectral_axis=wavelength, mask=np.isnan(flux), meta={'purpose': key}) spectrum.append(aspectrum) return spectrum
def test_jwst_reader_fail(tmpdir, x1d_single, srctype): """Check that the reader fails when SRCTYPE is not set or is UNKNOWN""" tmpfile = str(tmpdir.join('jwst.fits')) hdulist = x1d_single # Add a spectrum with bad SRCTYPE (mutate the fixture) hdulist.append(create_spectrum_hdu(100, srctype, ver=2)) hdulist.writeto(tmpfile) with pytest.raises(RuntimeError, match="^Keyword"): SpectrumList.read(tmpfile, format='JWST x1d multi')
def marz_loader(fname): try: spectra = SpectrumList.read(fname, format=SINGLE_SPLIT_LABEL, **MARZ_CONFIG_NEXT) except: # fallback (to not having support for "fallback_header"!) spectra = SpectrumList.read(fname, format=SINGLE_SPLIT_LABEL, **MARZ_CONFIG) return spectra
def test_gama_gama(self, shared_datadir): spectra = SpectrumList.read( shared_datadir / GAMA_GAMA_TEST_FILENAME, format=loaders.MULTILINE_SINGLE_LABEL, **GAMA_GAMA_CONFIG ) assert len(spectra) == 3 assert spectra[0].flux.unit == u.Unit("10^-17 erg/s/cm^2/A") assert spectra[0].spectral_axis.unit == u.Angstrom assert spectra[1].flux.unit == u.count assert spectra[1].spectral_axis.unit == u.Angstrom assert spectra[2].flux.unit == u.count assert spectra[2].spectral_axis.unit == u.Angstrom assert isinstance(spectra[0].uncertainty, StdDevUncertainty) assert isinstance(spectra[1].uncertainty, StdDevUncertainty) assert spectra[2].uncertainty is None assert spectra[0].meta.get("label") is not None assert spectra[0].meta.get("header") is not None assert spectra[1].meta.get("label") is not None assert spectra[1].meta.get("header") is not None assert spectra[2].meta.get("label") is not None assert spectra[2].meta.get("header") is not None
def test_ozdes_guess(self, shared_datadir): spectra = SpectrumList.read(shared_datadir / OZDES_TEST_FILENAME) # The test file has the combined obs, and 4 other sets assert len(spectra) == 5 assert spectra[0].flux.unit == u.count / u.Angstrom assert spectra[0].spectral_axis.unit == u.Angstrom assert isinstance(spectra[0].uncertainty, VarianceUncertainty) assert spectra[0].meta.get("label") is None assert spectra[0].meta.get("header") is not None assert spectra[1].flux.unit == u.count / u.Angstrom assert spectra[1].spectral_axis.unit == u.Angstrom assert isinstance(spectra[1].uncertainty, VarianceUncertainty) assert spectra[1].meta.get("label") is not None assert spectra[1].meta.get("header") is not None assert spectra[2].flux.unit == u.count / u.Angstrom assert spectra[2].spectral_axis.unit == u.Angstrom assert isinstance(spectra[2].uncertainty, VarianceUncertainty) assert spectra[2].meta.get("label") is not None assert spectra[2].meta.get("header") is not None assert spectra[3].flux.unit == u.count / u.Angstrom assert spectra[3].spectral_axis.unit == u.Angstrom assert isinstance(spectra[3].uncertainty, VarianceUncertainty) assert spectra[3].meta.get("label") is not None assert spectra[3].meta.get("header") is not None assert spectra[4].flux.unit == u.count / u.Angstrom assert spectra[4].spectral_axis.unit == u.Angstrom assert isinstance(spectra[4].uncertainty, VarianceUncertainty) assert spectra[4].meta.get("label") is not None assert spectra[4].meta.get("header") is not None
def test_galah_guess(self, shared_datadir): spectra = SpectrumList.read(shared_datadir / GALAH_TEST_FILENAME) # Should be main spectra, without sky, and normalised assert len(spectra) == 3 assert spectra[0].flux.unit == u.count assert spectra[1].flux.unit == u.Unit('') # dimensionless assert spectra[2].flux.unit == u.count assert spectra[0].spectral_axis.unit == u.Angstrom assert spectra[1].spectral_axis.unit == u.Angstrom assert spectra[2].spectral_axis.unit == u.Angstrom assert isinstance(spectra[0].uncertainty, StdDevUncertainty) assert spectra[1].uncertainty is None assert isinstance(spectra[2].uncertainty, StdDevUncertainty) assert spectra[0].meta.get("label") is not None assert spectra[0].meta.get("header") is not None assert spectra[1].meta.get("label") is None assert spectra[1].meta.get("header") is not None assert spectra[2].meta.get("label") is not None assert spectra[2].meta.get("header") is not None
def test_guess_all(self, shared_datadir, filename): formats = ssv.ssvloaders.whatformat(shared_datadir / filename) spectra = SpectrumList.read(shared_datadir / filename) print("format for {0} is {1} and number of spectra is {2}".format( filename, formats, len(spectra))) for spectrum in spectra: print(spectrum)
def read_data_file(self, file_path, file_loader=None): """ Read spectral data from file given file path and loader. Parameters ---------- file_path : str Path to location of the spectrum file. file_loader : str Format specified for the astropy io interface. Returns ------- : :class:`~specutils.SpectrumList` A `~specutils.SpectrumList` instance containing the spectra loaded from the file """ # In the case that the user has selected auto load, loop through every # available loader and choose the one that 1) the registry identifier # function allows, and 2) is the highest priority. try: if file_loader: if file_loader not in self._get_matching_formats(file_path): msg = 'Given file can not be processed as specified file format ({})' raise IOError(msg.format(file_loader)) speclist = SpectrumList.read(file_path, format=file_loader) except IORegistryError as e: # In this case, assume that the registry has found several # loaders that fit the same identifier, choose the highest # priority one. speclist = self._try_priority_file_loaders(file_path) return speclist
def sixdfgs_combined_fits_loader(file_obj, **kwargs): """ Load the combined variant of a 6dF Galaxy Survey (6dFGS) file. 6dFGS used the Six-degree Field instrument on the UK Schmidt Telescope (UKST) at the Siding Spring Observatory (SSO) near Coonabarabran, Australia. Further details can be found at http://www.6dfgs.net/, or https://docs.datacentral.org.au/6dfgs/. Catalogues and spectra were produced, with the spectra being provided as both fits tables and as fits images. This loads the combined variant of the spectra. Parameters ---------- file_obj: str, file-like or HDUList FITS file name, object (provided from name by Astropy I/O Registry), or HDUList (as resulting from astropy.io.fits.open()). Returns ------- data: SpectrumList The 6dF spectra that are represented by the data in this file. """ if isinstance(file_obj, fits.hdu.hdulist.HDUList): hdulist = file_obj else: hdulist = fits.open(file_obj, **kwargs) specs = SpectrumList([_load_single_6dfgs_hdu(hdu) for hdu in hdulist[5:]]) if not isinstance(file_obj, fits.hdu.hdulist.HDUList): hdulist.close() return specs
def setup_class(self, specviz_helper, spectrum1d): self.spec_app = specviz_helper self.spec = spectrum1d self.spec_list = SpectrumList([spectrum1d] * 3) self.label = "Test 1D Spectrum" self.spec_app.load_spectrum(spectrum1d, data_label=self.label)
def load_sdss_mastar(path, hdu=1, **kwargs): r""" Read a list of spectrum from a path that is described by the SDSS MaNGA MaStar data model, which actually describes a collection of spectra of different sources: https://data.sdss.org/datamodel/files/MANGA_SPECTRO_MASTAR/DRPVER/MPROCVER/mastar-goodspec-DRPVER-MPROCVER.html :param path: The local path of the spectrum. :returns: A `specutils.Spectrum1D` object. """ spectra = [] units = u.Unit("1e-17 erg / (Angstrom cm2 s)") with fits.open(path, **kwargs) as image: _hdu = image[hdu] for i in range(_hdu.header["NAXIS2"]): meta = OrderedDict(zip(_hdu.data.dtype.names, _hdu.data[i])) spectral_axis = meta.pop("WAVE") * u.Angstrom flux = np.atleast_2d(meta.pop("FLUX") * units) uncertainty = InverseVariance(meta.pop("IVAR").reshape(flux.shape)) spectra.append(Spectrum1D(spectral_axis=spectral_axis, flux=flux, uncertainty=uncertainty, meta=meta)) return SpectrumList(spectra)
def smooth_spectra(spectra, *, filter="box", **kwargs): """ Smooth spectra via a given filter. """ if filter == "box" and not kwargs: kwargs["width"] = DEFAULT_BOX_FILTER_WIDTH if filter in NAMED_FILTERS: filter = NAMED_FILTERS[filter] if isinstance(spectra, Spectrum1D): return convolution_smooth(spectra, filter(**kwargs)) if isinstance(spectra, SpectrumList): return SpectrumList([ convolution_smooth(spectrum, filter(**kwargs)) for spectrum in spectra ]) if isinstance(spectra, SpectrumCollection): return SpectrumCollection([ convolution_smooth(spectrum, filter(**kwargs)) for spectrum in spectra ]) try: spectra_iter = iter(spectra) except TypeError: raise TypeError( "Must be a specutils spectrum object or an iterable object") return [ convolution_smooth(spectrum, filter(**kwargs)) for spectrum in spectra_iter ]
def test_ozdes_prefer_combined(self, shared_datadir): spectra = SpectrumList.read(shared_datadir / OZDES_TEST_FILENAME, format=loaders.SINGLE_SPLIT_LABEL, **OZDES_CONFIG) tables = specutils_spectra_to_table_spectra(spectra, prefer_combined=True) len(tables) == 1
def gama_lt_obscore_loader(fname): spectra = SpectrumList.read(fname, format="GAMA-LT") for spec in spectra: spec.meta["obscore"] = {} obscore = spec.meta["obscore"] if spec.meta["purpose"] == "reduced": hdr = spec.meta["header"] t1, t2 = gama_lt_get_times(hdr) if t1 is not None: obscore["t_min"] = t1.to_value('mjd',subfmt='float') if t2 is not None: obscore["t_max"] = t2.to_value('mjd',subfmt='float') obscore["s_ra"] = hdr["RA"] obscore["s_dec"] = hdr["DEC"] if "ESTSEE" in hdr: obscore["s_seeing"] = hdr["ESTSEE"] # obscore["obs_collection"] = "gama_dr2" # obscore["facility_name"] = "gama_lt" obscore["dataproduct_subtype"] = "science" obscore["calib_level"] = 2 if "EXPTIME" in hdr: obscore["t_exptime"] = hdr["EXPTIME"] nspecpix = len(spec.spectral_axis) obscore["em_xel"] = nspecpix obscore["em_ucd"] = "em.wl" obscore["em_unit"] = "angstrom" obscore["s_xel1"] = nspecpix obscore["s_xel2"] = 1 obscore["t_xel"] = 1 obscore["em_min"] = spec.spectral_axis[0].meter obscore["em_max"] = ( spec.spectral_axis[nspecpix - 1].meter ) obscore["o_ucd"] = "phot.count" obscore["instrument_name"] = "FrodoSpec" obscore["s_fov"] = 9.84 / 3600 obscore["em_calib_status"] = "calibrated" if "GAMANAME" in hdr: obscore["target_name"] = hdr["GAMANAME"] if "OBJECT" in hdr: obscore["alt_target_name"] = hdr["OBJECT"] if "WAVRESOL" in hdr: obscore["em_resolution"] = hdr["WAVRESOL"] * 1e-10 # if('SN' in hdr): # obscore['em_snr'] = hdr['SN'] # alternative name: OBJECT if "SPECID" in hdr: obscore["obs_id"] = hdr["SPECID"] if "Z" in hdr: obscore["redshift"] = hdr["Z"] return spectra
def gama_mgc_obscore_loader(fname): spectra = SpectrumList.read(fname, format="GAMA-MGC") for spec in spectra: spec.meta["obscore"] = {} obscore = spec.meta["obscore"] if spec.meta["purpose"] == "reduced": hdr = spec.meta["header"] t1, t2 = get_times( hdr, date_kw="DATE-OBS", start_kw="UT", duration_kw="EXPTIME" ) if t1 is not None: obscore["t_min"] = t1.to_value('mjd',subfmt='float') if t2 is not None: obscore["t_max"] = t2.to_value('mjd',subfmt='float') obscore["s_ra"] = hdr["RA"] obscore["s_dec"] = hdr["DEC"] obscore["s_fov"] = 2.1 / 3600 if "SEEING" in hdr: obscore["s_seeing"] = hdr["SEEING"] # obscore["obs_collection"] = "gama_dr2" # obscore["facility_name"] = "mgc" obscore["dataproduct_subtype"] = "science" obscore["calib_level"] = 2 if "EXPTIME" in hdr: obscore["t_exptime"] = hdr["EXPTIME"] nspecpix = len(spec.spectral_axis) obscore["em_xel"] = nspecpix obscore["em_ucd"] = "em.wl" obscore["em_unit"] = "angstrom" obscore["s_xel1"] = nspecpix obscore["s_xel2"] = 1 obscore["t_xel"] = 1 obscore["em_min"] = spec.spectral_axis[0].meter obscore["em_max"] = ( spec.spectral_axis[nspecpix - 1].meter ) obscore["o_ucd"] = "phot.count" obscore["instrument_name"] = "2dF" obscore["em_calib_status"] = "calibrated" if "GAMANAME" in hdr: obscore["target_name"] = hdr["GAMANAME"] if "OBJECT" in hdr: obscore["alt_target_name"] = hdr["OBJECT"] if "SN" in hdr: obscore["em_snr"] = hdr["SN"] # alternative name: OBJECT if "SPECID" in hdr: obscore["obs_id"] = hdr["SPECID"] if "Z" in hdr: obscore["redshift"] = hdr["Z"] return spectra
def test_without_rwss_guess(self, shared_datadir): spectra = SpectrumList.read(shared_datadir / AAOMEGA_WITHOUT_RWSS, ) assert len(spectra) == 153 for spec in spectra: assert spec.meta.get("label") is not None assert spec.meta.get("header") is not None assert spec.meta.get("purpose") is not None assert spec.meta.get("fibre_index") is not None
def galah_loader(filename): with read_fileobj_or_hdulist(filename) as hdulist: if len(hdulist) == 5: spectra = SpectrumList.read( hdulist, format=SINGLE_SPLIT_LABEL, **GALAH_5EXT_CONFIG ) spectra[0].meta["galah_hdu_format"] = 5 elif len(hdulist) == 4: spectra = SpectrumList.read( hdulist, format=SINGLE_SPLIT_LABEL, **GALAH_4EXT_CONFIG ) spectra[0].meta["galah_hdu_format"] = 4 else: raise RuntimeError( "Unknown GALAH format, has {} extensions".format(len(hdulist)) ) return spectra
def test_2dfgrs(self, shared_datadir): spectra = SpectrumList.read( shared_datadir / TWODFGRS_TEST_FILENAME, format="2dFGRS obscore", ) spec = spectra[0] obscore = spec.meta.get("obscore") assert obscore is not None assert obscore.get("calib_level") == 2 assert obscore.get("t_xel") == 1
def test_jwst_s2d_multi_reader(tmpdir, s2d_multi): path = str(tmpdir.join("test.fits")) model = s2d_multi model.save(path) speclist = SpectrumList.read(path, format="JWST s2d multi") assert len(speclist) == 2 assert hasattr(speclist[0], "spectral_axis") assert speclist[1].unit == u.Jy
def test_galah(self, shared_datadir): spectra = SpectrumList.read( shared_datadir / GALAH_TEST_FILENAME, format="GALAH obscore", ) spec = spectra[0] obscore = spec.meta.get("obscore") assert obscore is not None assert obscore.get("calib_level") == 2 assert obscore.get("t_xel") == 1
def test_jwst_x1d_multi_reader_check_units(tmpdir, x1d_multi): """Test units for Spectrum1D.read for JWST x1d data""" tmpfile = str(tmpdir.join('jwst.fits')) x1d_multi.writeto(tmpfile) data = SpectrumList.read(tmpfile) assert data[0].unit == u.Jy assert data[1].unit == u.MJy / u.sr assert data[2].unit == u.Jy
def test_ozdes(self, shared_datadir): spectra = SpectrumList.read( shared_datadir / OZDES_TEST_FILENAME, format="OzDES obscore", ) spec = spectra[0] obscore = spec.meta.get("obscore") assert obscore is not None assert obscore.get("calib_level") == 3 assert obscore.get("t_xel") == 4
def test_marz_guess_1(self, shared_datadir): formats = loaders.whatformat(shared_datadir / "marz/quasarLinearSkyAirNoHelio.fits") if len(formats) > 1: loaders.unregister(formats[0]) spectra = SpectrumList.read( shared_datadir / "marz/quasarLinearSkyAirNoHelio.fits" ) # Should be main spectra, with sky, and normalised assert len(spectra) == 2
def test_marz_guess_2(self, shared_datadir): formats = ssv.ssvloaders.whatformat( shared_datadir / "marz/alldata_combined_runz_x12_b02.fits") if len(formats) > 1: ssv.ssvloaders.unregister(formats[0]) spectra = SpectrumList.read(shared_datadir / "marz/alldata_combined_runz_x12_b02.fits") # Should be main spectra, with sky, and normalised assert len(spectra) == 2
def test_not_marz_guess_1(self, shared_datadir): formats = ssv.ssvloaders.whatformat(shared_datadir / "OBJ0032red.fits") if len(formats) > 1: ssv.ssvloaders.unregister(formats[0]) spectra = SpectrumList.read(shared_datadir / "OBJ0032red.fits") # Should be main spectra, with sky, and normalised assert len(spectra) > 0 assert spectra[0].spectral_axis.unit == u.Angstrom assert spectra[0].meta.get("header") is not None
def test_2slaq_qso(self, shared_datadir): spectra = SpectrumList.read( shared_datadir / GAMA_2SLAQ_QSO_TEST_FILENAME, format="GAMA-2SLAQ-QSO obscore", ) spec = spectra[0] obscore = spec.meta.get("obscore") assert obscore is not None assert obscore.get("calib_level") == 2 assert obscore.get("t_xel") == 1
def test_6dfgs_table(self, shared_datadir): spectra = SpectrumList.read( shared_datadir / SIXDFGS_TABLE_TEST_FILENAME, format="6dFGS-tabular obscore", ) spec = spectra[0] obscore = spec.meta.get("obscore") assert obscore is not None assert obscore.get("calib_level") == 2 assert obscore.get("t_xel") == 1
def test_6dfgs_combined(self, shared_datadir): spectra = SpectrumList.read( shared_datadir / SIXDFGS_COMBINED_TEST_FILENAME, format="6dFGS-combined obscore", ) spec = spectra[0] obscore = spec.meta.get("obscore") assert obscore is not None assert obscore.get("calib_level") == 2 assert obscore.get("t_xel") == 4
def test_gama_wigglez(self, shared_datadir): spectra = SpectrumList.read( shared_datadir / GAMA_WIGGLEZ_TEST_FILENAME, format="GAMA-WiggleZ obscore", ) spec = spectra[0] obscore = spec.meta.get("obscore") assert obscore is not None assert obscore.get("calib_level") == 2 assert obscore.get("t_xel") == 1
def _try_priority_file_loaders(self, file_path): fmts = self._get_matching_formats(file_path) logging.warning("Loaders for '%s' matched for this data set. " "Iterating based on priority." "", ', '.join(fmts)) for fmt in fmts: try: speclist = SpectrumList.read(file_path, format=fmt) return speclist except IORegistryError: logging.warning("Attempted load with '%s' failed, " "trying next loader.", fmt) raise IOError('Could not find appropriate loader for given file')