def load_vega(vegafile=None, **kwargs): """Convenience function to load Vega spectrum that is used throughout `stsynphot`. Parameters ---------- vegafile : str or `None`, optional Vega spectrum filename. If `None`, use ``synphot.config.conf.vega_file``. kwargs : dict Keywords acceptable by :func:`synphot.specio.read_remote_spec`. Returns ------- sp : `synphot.spectrum.SourceSpectrum` or `None` Vega spectrum. `None` if failed. """ global Vega if vegafile is None: vegafile = synconf.vega_file with synconf.set_temp('vega_file', vegafile): try: Vega = SourceSpectrum.from_vega(**kwargs) except Exception as e: Vega = None warnings.warn( 'Failed to load Vega spectrum from {0}; Functionality ' 'involving Vega will be cripped: {1}'.format( vegafile, str(e)), AstropyUserWarning)
def rescale_normalized_spectra(spectra, catalog_info, magnitude_system, bandpass_file, gain_value): """Rescale any input spectra that are normalized Parameters ---------- spectra : OrderedDict Dictionary containing spectra for some/all targets. Dictionary keys are the object indexes (such as from the index column in the catalog_file. Entries must be e.g. d[1] = {"wavelengths": <wavelength_list>, "fluxes": <List of spectral flux densities>} Wavelengths and fluxes can be lists, or lists with astropy units attached. If no units are supplied, Mirage assumes wavelengths in microns and flux densities in Flambda units. catalog_info : astropy.table.Table Index column and magnitude column to use for rescaling. Extracted from the original input catalog. magnitude_system : str Magnitude system corresponding to the input magnitudes (e.g. 'abmag') bandpass_file : str Name of ascii file containing filter throughput curve. (Generally retrieved from config directory) gain_value : float Gain value (e-/ADU) to use to adjust any rescaled spectra to produce given countrates in ADU/sec rather than e-/sec. This is needed because the flux calibration info (e.g. photflam, photfnu) were created such that they translate from magnitudes to ADU/sec rather than to e-/sec Returns ------- spec : OrderedDict Input dictionary, with flux values rescaled (in FLAM units) to the requested magnitude, only for spectra where the flux units are astropy.units.pct """ logger = logging.getLogger( 'mirage.catalogs.spectra_from_catalog.rescale_normalized_spectra') # Get the Vega spectrum from synphot. Use the version that was used # to create the photom reference files and filter zeropoints with syn_conf.set_temp( 'vega_file', 'http://ssb.stsci.edu/cdbs/calspec/alpha_lyr_stis_008.fits'): vegaspec = SourceSpectrum.from_vega() mag_colname = [col for col in catalog_info.colnames if 'index' not in col][0] instrument = mag_colname.split('_')[0].lower() # Make a copy so we aren't modifying spec in place, which seems to be passed # by reference back to the calling function spec = copy.deepcopy(spectra) for dataset in spec: waves = spec[dataset]['wavelengths'] flux = spec[dataset]['fluxes'] flux_units = flux.unit if (flux_units == u.pct): logger.info( 'SED for source {} is normalized. Rescaling.'.format(dataset)) match = catalog_info['index'] == dataset if not any(match): #raise ValueError(('WARNING: No matching target in ascii catalog for normalized source ' # 'number {}. Unable to rescale.').format(dataset)) continue magnitude = catalog_info[mag_colname].data[match][0] # Create a synphot source spectrum fake_flux_units = units.FLAM source_spectrum = SourceSpectrum(Empirical1D, points=waves, lookup_table=flux.value * fake_flux_units) # Create a synphot SpectralElement containing the filter bandpass filter_tp = ascii.read(bandpass_file) bp_waves = filter_tp['Wavelength_microns'].data * u.micron bp_waves = bp_waves.to(u.Angstrom) thru = filter_tp['Throughput'].data bandpass = SpectralElement(Empirical1D, points=bp_waves.value, lookup_table=thru) / gain_value # Renormalize magnitude_system = magnitude_system.lower() if magnitude_system == 'vegamag': magunits = units.VEGAMAG vega_spec = vegaspec elif magnitude_system == 'abmag': magunits = u.ABmag vega_spec = None elif magnitude_system == 'stmag': magunits = u.STmag vega_spec = None elif magnitude_system == 'counts': raise ValueError( 'ERROR: normalization to a given countrate not yet supported.' ) if magnitude_system != 'vegamag': renorm = source_spectrum.normalize(magnitude * magunits, bandpass, vegaspec=vega_spec) else: if instrument == 'nircam': # NIRCam vegamag zeropoints are based on synphot's Vega spectrum renorm = source_spectrum.normalize(magnitude * magunits, bandpass, vegaspec=vega_spec) elif instrument == 'niriss': # NIRISS vegamag zeropoints are based on Vega having a # magnitude of 0.02 in all filters renorm = source_spectrum.normalize( (magnitude - 0.02) * units.VEGAMAG, bandpass, vegaspec=vega_spec) elif instrument == 'fgs': # FGS vegamag zeropoints are based on a Sirius spectrum # rather than Vega raise NotImplementedError( "Source spectrum rescaling for FGS not yet supported") sirius_file = 'sirius_mod_003.txt' sirius_tab = ascii.read(sirius_file) sirius_waves = sirius_tab['Wavelength'] * u.Angstrom sirius_flux = sirius_tab['Flux'] * units.FLAM sirius_spectrum = SourceSpectrum(Empirical1D, points=sirius_waves, lookup_table=sirius_flux) #sirius_spec_norm = sirius_spectrum.normalize(0. * units.VEGAMAG, bandpass, vegaspec=sirius_spectrum) renorm = source_spectrum.normalize( magnitude * units.VEGAMAG, bandpass, vegaspec=sirius_spectrum) spec[dataset]['fluxes'] = renorm(waves, flux_unit='flam') else: logger.info( 'SED for source {} is already in physical units. NOT RESCALING' .format(dataset)) return spec