def get_normalized_star_spectrum(spectral_type, magnitude, filter_name): """ spec_data = get_normalized_star_spectrum(spectral_type, magnitude, filter_name) Returns a structure containing the synthetic spectrum of the star having the spectral type and magnitude in the specified input filter. Magnitude is in VEGAMAG-F(lambda) system. Spectra are from PICKLES, PASP, 110, 863 (1998) Absolute flux spectra, no effect of atmospheric and instrument transmission Parameters ---------- r0AtZenith: float overall r0 at zenith [m] spectral_type: string. spectral type and luminosity class (e.g. G2V or M4III) or 'vega' magnitude: float. magnitude in the filter_name filter filter_name: string. Name of the filter. See Filters.get() for the list of available filters Returns ------- spectrum: synphot.SourceSpectrum object defining the spectrum Examples -------- Plot the spectrum of a vega, A0V, G2V stars of mag=8 defined on JohnsonR filter >>> sp= get_normalized_star_spectrum('vega', 8, Filters.JOHNSON_R) >>> spA0V= get_normalized_star_spectrum('A0V', 8, Filters.JOHNSON_R) >>> spG2V= get_normalized_star_spectrum('G2V', 8, Filters.JOHNSON_R) >>> plt.plot(sp.waveset, sp(sp.waveset), label='Vega') >>> plt.plot(spA0V.waveset, spA0V(spA0V.waveset), label='A0V') >>> plt.plot(spG2V.waveset, spG2V(spG2V.waveset), label='G2V') >>> plt.grid(True) >>> plt.xlabel('nm') >>> plt.ylabel('FLAM') >>> plt.xlim(0, 10000) >>> plt.legend() """ # read the sourcespectrum if spectral_type == 'vega': spectrum = SourceSpectrum.from_vega() else: spectrum = SourceSpectrum.from_file( PickelsLibrary.filename(spectral_type)) bandpass = Filters.get(filter_name) spectrum_norm = spectrum.normalize( magnitude * synphot.units.VEGAMAG, bandpass, vegaspec=SourceSpectrum.from_vega()) return spectrum_norm
def calculate_values(detector, filt, mjd, aper): # parameters can be removed from obsmode as needed obsmode = 'wfc3,{},{},mjd#{},aper#{}'.format(detector, filt, mjd, aper) bp = stsyn.band(obsmode) # STMag photflam = bp.unit_response(stsyn.conf.area) # inverse sensitivity in flam stmag = -21.1 - 2.5 * log10(photflam.value) # Pivot Wavelength and bandwidth photplam = bp.pivot() # pivot wavelength in angstroms bandwidth = bp.photbw() # bandwidth in angstroms # ABMag abmag = stmag - 5 * log10(photplam.value) + 18.6921 # Vegamag #for some reason stsyn.Vega doesn't load so we redefine it stsyn.Vega = SourceSpectrum.from_vega() obs = Observation( stsyn.Vega, bp, binset=bp.binset ) # synthetic observation of vega in bandpass using vega spectrum vegamag = -obs.effstim(flux_unit='obmag', area=stsyn.conf.area) return obsmode, photplam.value, bandwidth.value, photflam.value, stmag, abmag, vegamag.value
def filter_vega_zp(filterfile, filterzero): ''' ###################################################### # Input # # -------------------------------------------------- # # filterfile: file containing filter function # # filterzero: flux corresponding to mag=0 # # -------------------------------------------------- # # Output # # -------------------------------------------------- # # mag_0: magnitude of Vega in filter system. # ###################################################### ''' from synphot import SourceSpectrum, SpectralElement, Observation #load Vega spectrum spec = SourceSpectrum.from_vega() #Load ascii filter function if filterfile.split('/')[-1][:6] == 'Bessel': filt = SpectralElement.from_file(filterfile, wave_unit='nm') else: filt = SpectralElement.from_file(filterfile, wave_unit='AA') wave = filt.waveset #Synthetic observation obs = Observation(spec, filt) flux = obs.effstim(flux_unit='jy', waverange=(wave[0],wave[-1])) #Calibrate to zero point (zp) mag_0 = -2.512*np.log10(flux/filterzero) return mag_0
def Scorr_vega(filt1,filt2, zerof1,zerof2): from synphot import SourceSpectrum #load Vega spectrum spec = SourceSpectrum.from_vega() #Scorr = -2.5log(flux2/flux1) such that mag2 = mag1 + Scorr mag1 = filter_mag(filt1, zerof1, spec) mag2 = filter_mag(filt2, zerof2, spec) scorr = mag2 - mag1 return scorr
def __init__(self): self.verbose = False self.telescope_area = 25.326 * 10000. #JWST primary area in cm^2 self.wave_bins = np.arange(0.5, 5, 0.1) * u.micron self.vega = SourceSpectrum.from_vega() self.g2v = STS.grid_to_spec('ck04models', 5860, 0., 4.40) self.kband = SpectralElement.from_filter('bessel_k') self.bpdir = './' self.bpfile = os.path.join( self.bpdir, 'F335M_nircam_plus_ote_throughput_moda_sorted.txt') self.bp = SpectralElement.from_file(self.bpfile, wave_unit=u.micron)
def misc(): # get_vega() downloads this one synphot.specio.read_remote_spec( 'http://ssb.stsci.edu/cdbs/calspec/alpha_lyr_stis_008.fits') # G5V of UVKLIB subset of Pickles library # see http://www.stsci.edu/hst/instrumentation/reference-data-for-calibration-and-tools/astronomical-catalogs/pickles-atlas.html synphot.specio.read_remote_spec( 'http://ssb.stsci.edu/cdbs/grid/pickles/dat_uvk/pickles_uk_27.fits') # read the sourcespectrum spG5V = SourceSpectrum.from_file( 'http://ssb.stsci.edu/cdbs/grid/pickles/dat_uvk/pickles_uk_27.fits') spG2V = SourceSpectrum.from_file( 'http://ssb.stsci.edu/cdbs/grid/pickles/dat_uvk/pickles_uk_26.fits') filtR = SpectralElement.from_filter('johnson_r') spG2V_19r = spG2V.normalize(19 * synphot.units.VEGAMAG, filtR, vegaspec=SourceSpectrum.from_vega()) bp = SpectralElement(Box1D, x_0=700 * u.nm, width=600 * u.nm) obs = Observation(spG2V_19r, bp) obs.countrate(area=50 * u.m**2) bp220 = SpectralElement(Box1D, x_0=800 * u.nm, width=400 * u.nm) bpCRed = SpectralElement(Box1D, x_0=1650 * u.nm, width=300 * u.nm) * 0.8 Observation(spG2V_19r, bp220).countrate(area=50 * u.m**2) Observation(spG2V_19r, bpCRed).countrate(area=50 * u.m**2) spM0V_8R = get_normalized_star_spectrum('M0V', 8.0, 'johnson_r') uPhotonSecM2Micron = u.photon / (u.s * u.m**2 * u.micron) spG2V_8R = get_normalized_star_spectrum("G2V", 8.0, 'johnson_r') plt.plot(spG2V_8R.waveset, spG2V_8R(spG2V_8R.waveset).to(uPhotonSecM2Micron)) # compare with Armando's spG2V_19R = get_normalized_star_spectrum("G2V", 19, 'johnson_r') bp = SpectralElement(Box1D, x_0=700 * u.nm, width=600 * u.nm) obs = Observation(spG2V_19R, bp) obs.countrate(area=50 * u.m**2) # zeropoint in filtro r in erg/s/cm2/A Observation(get_normalized_star_spectrum('A0V', 0, 'johnson_r'), SpectralElement.from_filter('johnson_r')).effstim('flam') # zeropoint in ph/s/m2 Observation(get_normalized_star_spectrum('A0V', 0, 'johnson_r'), SpectralElement.from_filter('johnson_r')).countrate(area=1 * u.m**2)
def __init__(self): """ Set up NIRCam-specific information """ self.verbose = True self.imaging_throughput_files = None #total sys. throughput: include JWST+NIRCam+filter self.grism_throughput_files = None #assume these include JWST+NIRCam+grism+crossing filter self.detector = None #'A1-A5, B1-B5' self.telescope_area = 25.326 * 10000. #JWST primary area in cm^2 self.detector_width = 2040 #pixels self.detector_length = 2040 #pixels self.xcoeffs = None self.ycoeffs = None self.pixel_area_a2 = None self.pixel_area_sr = None self.vega = SourceSpectrum.from_vega() self.maxlen = 3000 #wavelength and relresponse arrays have to be 3000 elements long self.resolving_power = 1525 #for NIRCam at 4.0 microns #dictionary of pupil wheel filter:filter wheel filter self.filter_dict = { 'F164N': '150W2', 'F323N': 'F322W2', 'F405N': 'F444W', 'F466N': 'F444W', 'F470N': 'F444W' } self.crossing_filters = [ 'F250M', 'F277W', 'F300M', 'F322W2', 'F335W', 'F356W', 'F360M', 'F410M', 'F430M', 'F444W', 'F460M', 'F480M' ] self.disp = {'1': 10.04, '2': 5.02} #angstroms/pixel - from Nor's code self.zeropoint_base = 'NIRCam_zeropoints' self.photom_base = 'NIRCam_photom' self.grism_thruput = '/grp/jwst/wit/nircam/reference_files/SpectralResponse_2015-Final/Grisms/NIRCam_LW_grism_efficiencies_from_Tom_Greene.csv' self.model = NircamPhotomModel() self.pam_outfile = None self.photom_outfile = None self.author = 'Nircam Team' self.useafter = '2017-01-01' self.pam_descrip = 'NIRCam Pixel Area Map' self.photom_descrip = 'NIRCam flux conversion reference file' self.pedigree = 'GROUND' self.pam_history = None self.photom_history = None
def __init__(self, mag, magsystem='VEGAMAG', filt_range=None, sed=None, temp=5778): # Define the magnitude system. if filt_range is None: filt_range = [5000, 6000] if magsystem.lower() == 'vegamag': sys = units.VEGAMAG elif magsystem.lower() == 'stmag': sys = u.STmag elif magsystem.lower() == 'abnu': sys = u.ABmag # Get Vega's spectrum. vega = SourceSpectrum.from_vega() # Set attributes. self.mag = mag self.SED = sed self.temp = temp self.inputFlux = units.convert_flux(filt_range, mag * sys, units.FLAM, vegaspec=vega) self.range = filt_range self.F_lambda = self.starF_lambda()
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
def vega_spectrum(mag=0): vega = SourceSpectrum.from_vega(cache=True) return vega * 10**(-0.4 * mag)
ensure_dir_exists(output_data_dir) tsdir = '/home/anadkarni/NIRCam_AZ_TSO_Data_Challenge/GJ436_LC_TS_Params/' # ---------- Prepare Inputs ---------- xml_file = os.path.join(input_data_path, 'GJ436.xml') pointing_file = xml_file.replace('.xml', '.pointing') # ---------- Stellar Spectrum ---------- t_eff = 3500 # surface temperature metallicity = 0.02 # Fe/H log_g = 5.0 # surface gravity = 182 m/s^2 sp = stsyn.grid_to_spec('ck04models', t_eff, metallicity, log_g) bp = SpectralElement.from_filter('johnson_k') vega = SourceSpectrum.from_vega() sp_norm = sp.normalize(6.073 * units.VEGAMAG, bp, vegaspec=vega) wavelengths = sp_norm.waveset.to(u.micron) fluxes = sp_norm(wavelengths, flux_unit='flam') wavelength_units = 'microns' flux_units = 'flam' sed_file = os.path.join(output_dir, 'GJ436_stellar_spectrum.hdf5') fluxes = [fluxes] wavelengths = [wavelengths] with h5py.File(sed_file, "w") as file_obj: for i in range(len(fluxes)): dset = file_obj.create_dataset( str(i + TSO_GRISM_INDEX), data=[wavelengths[i].value, fluxes[i].value], dtype='f', compression="gzip",
def flux2ABmag(wave, flux, band, mag, plot=False): # "band" should be either "sdss_g" or "V" for the moment # The input "wave" should be in nm # Define bandpass: if band == "sdss_g": bp = SpectralElement.from_file('../utility/photometry/g.dat') magvega = -0.08 elif band == "V": bp = SpectralElement.from_filter('johnson_v') magvega = 0.03 # SDSS g-band magnitude of Vega #gmagvega=-0.08 # Read the spectrum of Vega sp_vega = SourceSpectrum.from_vega() wv_vega = sp_vega.waveset fl_vega = sp_vega(wv_vega, flux_unit=units.FLAM) ## Convolve with the bandpass obs_vega = Observation(sp_vega, bp) ## Integrated flux fluxtot_vega = obs_vega.integrate() # Read the synthetic spectrum sp = SourceSpectrum(Empirical1D, points = wave * 10., \ lookup_table=flux*units.FLAM) wv = sp.waveset fl = sp(wv, flux_unit=units.FLAM) ## Convolve with the bandpass obs = Observation(sp, bp, force='extrap') ## Integrated g-band flux fluxtot = obs.integrate() # Scaling factor to make the flux compatible with the desired magnitude dm = mag - magvega const = fluxtot_vega * 10**(-0.4 * dm) / fluxtot # Scale the original flux by const fl_scale = const * fl # Convert to ABmag fl_scale_mag = units.convert_flux(wv, fl_scale, out_flux_unit='abmag') sp_scaled_mag = SourceSpectrum(Empirical1D, points=wv, lookup_table=fl_scale_mag) # Plot if plot == True: fig, ax = plt.subplots(2, 1, sharex=True) ax[0].plot(wave * 10., flux, linestyle="-", marker="") ax[1].plot(wv[1:-1], sp_scaled_mag(wv, flux_unit=u.ABmag)[1:-1], linestyle="-", marker="") ax[1].set_xlabel("Angstrom") ax[0].set_ylabel("$F_{\lambda}$") ax[1].set_ylabel("ABmag") ax[1].set_ylim(mag + 3., mag - 2.0) #plt.show() return (wv[1:-1] / 10., sp_scaled_mag(wv, flux_unit=u.ABmag)[1:-1])