def main(): colnames = ("ID", "Name", "M_sun Vega", "M_sun AB", "lambda_eff (Å)", "Description") filters = [fsps.get_filter(name) for name in fsps.list_filters()] filter_list = make_filter_list(filters) txt = make_table(filter_list, colnames) print(txt)
def _set_filter(self, filt): #fetch filter transmission curve from FSPS #this sets the wavelength grid, so no rebinning needed #lookup for filter number given name fsps_filts = fsps.list_filters() filt_lookup = dict(zip(fsps_filts, range(1, len(fsps_filts) + 1))) #reference in case given a spitzer or mips filter...probably not an issue right now. mips_dict = {90: 23.68 * 1e4, 91: 71.42 * 1e4, 92: 155.9 * 1e4} spitzer_dict = { 53: 3.550 * 1e4, 54: 4.493 * 1e4, 55: 5.731 * 1e4, 56: 7.872 * 1e4 } #pull information for this filter fobj = fsps.get_filter(filt) filter_num = filt_lookup[filt] fwl, ftrans = fobj.transmission ftrans = np.maximum(ftrans, 0.) trans_interp = np.asarray(np.interp(self.inst_wavelength, fwl / 1e4, ftrans, left=0., right=0.), dtype=np.float) #normalize transmission ttrans = np.trapz( np.copy(trans_interp) / self.inst_wavelength, self.inst_wavelength) if ttrans < self.small_num: ttrans = 1. ntrans = np.maximum(trans_interp / ttrans, 0.0) if filter_num in mips_dict: td = np.trapz( ((self.inst_wavelength / mips_dict[filter_num])**(-2.)) * ntrans / self.inst_wavelength, self.inst_wavelength) ntrans = ntrans / max(1e-70, td) if filter_num in spitzer_dict: td = np.trapz( ((self.inst_wavelength / spitzer_dict[filter_num])**(-1.0)) * ntrans / self.inst_wavelength, self.inst_wavelength) ntrans = ntrans / max(1e-70, td) #stupid, but re-normalize to peak of 1 (since all other throughput terms #are included in the instrument throughput self.trans_norm = np.copy(ntrans) / ntrans.max() self.transmission = ntrans self.pivot = fobj.lambda_eff return
def sfr(fuv, fuv_err, dist, N): mfuv = fuv + 5 - 5 * np.log10(dist * 1e6) flux = 10**-((mfuv + mab0) / 2.5) flux_err = np.log(10) * flux * fuv_err / 2.5 Lfuv = flux * 4 * np.pi * (10 * 3.086e18)**2 Lfuv_err = flux_err * 4 * np.pi * (10 * 3.086e18)**2 fil = fsps.get_filter('galex_fuv') nu_eff = 2.9979e18 / fil.lambda_eff sfr = nu_eff * Lfuv / (10**C_fuv) sfr_err = nu_eff * Lfuv_err / (10**C_fuv) logsfr_err = sfr_err / (np.log(10) * sfr) return np.log10(sfr), logsfr_err
def table(self): """An :class:`astropy.table.Table` with the chain.""" msuns = np.array([fsps.get_filter(n).msun_ab for n in self._model.computed_bands]) theta_f_accept = json.dumps(dict(zip(self._model.theta_params, self.median_theta_faccept))) phi_f_accept = json.dumps(dict(zip(self._model.phi_params, self.phi_faccept))) meta = OrderedDict(( ('theta_f_accept', theta_f_accept), ('phi_f_accept', phi_f_accept), ('observed_bands', self._model.observed_bands), ('instruments', self._model.instruments), ('computed_bands', self._model.computed_bands), ('msun_ab', msuns), ('band_indices', self._model.band_indices), ('theta_params', self._model.theta_params), ('phi_params', self._model.phi_params), ('theta_proposal_sigma', self._theta_prop), ('phi_proposal_sigma', self._theta_prop), ('sed', self._model._seds), ('sed_err', self._model._errs), ('pixels', self._model.pixel_metadata), ('area', self._model._areas))) # Make tables for individual chains; stack later # FIXME should axis order be changed for theta throughout the sampler? # or I can just continue to swarp aces here theta_table = Table(np.swapaxes(self.theta, 1, 2), names=self._model.theta_params, meta=meta) phi_table = Table(self.phi, names=self._model.phi_params) background_names = ["B__{0}__{1}".format(n, b) for n, b in zip(self._model.instruments, self._model.observed_bands)] B_table = Table(self.B, names=background_names) blob_table = Table(self.blobs) tbl = MultiPixelChain(hstack((theta_table, phi_table, B_table, blob_table))) # Add M/L computations for each computed band. for i, (band_name, msun) in enumerate(zip(self._model.computed_bands, msuns)): logLsol = micro_jy_to_luminosity(tbl['model_sed'][:, :, i], msun, np.atleast_2d(tbl['d']).T) ml = tbl['logMstar'] - logLsol colname = "logML_{0}".format(band_name) tbl.add_column(Column(name=colname, data=ml)) return tbl
def sfr(fuv, fuv_err, dist, N): """Converts the Galex FUV filter luminosity into an estimate of the SFR of the galaxy. The errors in measurement of FUV magnitude are propagated to the errors in SFR estimated. Returns: Logarithm of the SFR and the log error in sfr for all the galaxies in the sample. """ mfuv = fuv + 5 - 5 * np.log10(dist * 1e6) flux = 10**-((mfuv + mab0) / 2.5) flux_err = np.log(10) * flux * fuv_err / 2.5 Lfuv = flux * 4 * np.pi * (10 * 3.086e18)**2 Lfuv_err = flux_err * 4 * np.pi * (10 * 3.086e18)**2 fil = fsps.get_filter('galex_fuv') nu_eff = 2.9979e18 / fil.lambda_eff sfr = nu_eff * Lfuv / (10**C_fuv) sfr_err = nu_eff * Lfuv_err / (10**C_fuv) logsfr_err = sfr_err / (np.log(10) * sfr) return np.log10(sfr), logsfr_err
def _set_filter(self, filt): #fetch filter transmission curves from FSPS #normalize and interpolate onto template grid #lookup for filter number given name fsps_filts = fsps.list_filters() filt_lookup = dict(zip(fsps_filts, range(1,len(fsps_filts)+1))) #reference in case given a spitzer or mips filter...probably not an issue right now. mips_dict = {90:23.68*1e4, 91:71.42*1e4, 92:155.9*1e4} spitzer_dict = {53:3.550*1e4, 54:4.493*1e4, 55:5.731*1e4, 56:7.872*1e4} #pull information for this filter fobj = fsps.get_filter(filt) filter_num = filt_lookup[filt] fwl, ftrans = fobj.transmission ftrans = np.maximum(ftrans, 0.) trans_interp = np.asarray(np.interp(self.red_wavelength, fwl/1e4, ftrans, left=0., right=0.), dtype=np.float) #normalize transmission ttrans = np.trapz(np.copy(trans_interp)/self.red_wavelength, self.red_wavelength) if ttrans < self.small_num: ttrans = 1. ntrans = np.maximum(trans_interp / ttrans, 0.0) if filter_num in mips_dict: td = np.trapz(((self.red_wavelength/mips_dict[filter_num])**(-2.))*ntrans/self.red_wavelength, self.red_wavelength) ntrans = ntrans/max(1e-70,td) if filter_num in spitzer_dict: td = np.trapz(((self.red_wavelength/spitzer_dict[filter_num])**(-1.0))*ntrans/self.red_wavelength, self.red_wavelength) ntrans = ntrans/max(1e-70,td) self.transmission = ntrans return
else: cloud = 'smc' #Choose bands for which you want to predict images. bands = ['irac_1'] # Cloud SFHs if cloud == 'smc': dm = 18.89 elif cloud == 'lmc': dm=18.49 mass, rnames, mets, esfh = load_data(cloud) # Band information ab_to_vega = np.atleast_1d(np.squeeze([f.msun_ab-f.msun_vega for b in bands for f in [fsps.get_filter(b)] ])) norm = 10**(-0.4 * (dm + ab_to_vega)) #SPS sps = fsps.StellarPopulation(compute_vega_mags=True) sps.params['sfh'] = 0 sps.params['imf_type'] = 0 sps.params['tpagb_norm_type'] = 2 #VCJ sps.params['add_agb_dust_model'] = True sps.params['agb_dust'] = 1.0 if len(sps.ssp_ages) == 107: isocname = 'MIST_VW' else: isocname = 'Padova2007' # Produce SEDs for each age and Z
Demonstration of plotting FSPS's un-normalized filter transmission tables (i.e., contents of $SPS_HOME/data/all_filters.dat). """ import fsps from matplotlib.figure import Figure from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas import matplotlib.gridspec as gridspec names = ['sdss_u', 'sdss_g', 'sdss_r', 'sdss_i', '2mass_J', '2mass_H', '2mass_Ks'] shortnames = ['u', 'g', 'r', 'i', 'J', 'H', 'Ks'] colors = ['violet', 'dodgerblue', 'maroon', 'black', 'c', 'm', 'y'] filters = [fsps.get_filter(n) for n in names] fig = Figure(figsize=(3.5, 3.5)) canvas = FigureCanvas(fig) gs = gridspec.GridSpec( 1, 1, left=0.17, right=0.95, bottom=0.15, top=0.95, wspace=None, hspace=None, width_ratios=None, height_ratios=None) ax = fig.add_subplot(gs[0]) for name, fltr, c, shortname in zip(names, filters, colors, shortnames): lmbd, trans = fltr.transmission lambda_eff = fltr.lambda_eff / 10000. # µm ax.plot(lmbd / 10000., trans, ls='-', lw=1., c=c) ax.annotate(shortname, (lambda_eff, trans.max()), textcoords='offset points', xytext=(0., 5.),
## To select the UV filters plot each one to pick the ones you ## like. Picking manually. uv = fsps.find_filter('uv') # for fil in uv: # plt.figure() # plt.plot(wlinv,10*attenuation.conroy(wl,f_bump=0.5),'-') # f = fsps.get_filter(fil) # plt.plot((f.transmission[0]*1e-4)**-1,f.transmission[1],label=f.name) # plt.legend() ## Amplify all the HST (WFC3) filters: wfc3 = fsps.find_filter('wfc3_uvis') for fil in wfc3: plt.figure() plt.plot(wlinv, attenuation.conroy(wl, f_bump=0.5) / 10, '-') f = fsps.get_filter(fil) plt.plot((f.transmission[0] * 1e-4)**-1, f.transmission[1], label=f.name) plt.legend() plt.plot(wlinv, attenuation.conroy(wl, f_bump=0.5), '-') f = fsps.get_filter('wfc3_uvis_f218w') plt.plot((f.transmission[0] * 1e-4)**-1, 100 * f.transmission[1], label=f.name) f = fsps.get_filter('wfc3_uvis_f225w') plt.plot((f.transmission[0] * 1e-4)**-1, 100 * f.transmission[1], label=f.name) plt.legend()
def compute_library_seds(self, bands, age=13.7, default_pset=None): """Compute an SED for each library model instance. Model SEDs are stored as absolute fluxes (µJy at d=10pc), normalized to a 1 Solar mass stellar population. .. todo:: Support parallel computation. Parameters ---------- bands : list List of `FSPS bandpass names <http://dan.iel.fm/python-fsps/current/filters/>`_. default_pset : dict Default Python-FSPS parameters. """ if default_pset is None: default_pset = {} # ALWAYS compute AB mags default_pset['compute_vega_mags'] = False # Solar magnitude in each bandpass solar_mags = [fsps.get_filter(n).msun_ab for n in bands] # Add bands and AB solar mags to the group attr metadata self.group.attrs['bands'] = bands self.group.attrs['msun_ab'] = solar_mags # Build the SED table table_names = ['seds', 'mass_light', 'meta'] for name in table_names: if name in self.group: del self.group[name] # Table for SEDs n_models = len(self.group["params"]) dtype = np.dtype([(n, np.float) for n in bands]) sed_table = self.group.create_dataset("seds", (n_models,), dtype=dtype) # Table for M/L ratios in each bandpass dtype = np.dtype([(n, np.float) for n in bands]) ml_table = self.group.create_dataset("mass_light", (n_models,), dtype=dtype) # Table for metadata (stellar mass, dust mass, etc..) meta_cols = ('logMstar', 'logMdust', 'logLbol', 'logSFR', 'logAge') dtype = np.dtype([(n, np.float) for n in meta_cols]) meta_table = self.group.create_dataset("meta", (n_models,), dtype=dtype) # Iterate on each model # TODO eventually split this work between processors sp_param_names = self.group['params'].dtype.names sp = fsps.StellarPopulation(**default_pset) for i, row in enumerate(self.group["params"]): for n, p in zip(sp_param_names, row): sp.params[n] = float(p) mags = sp.get_mags(tage=age, bands=bands) fluxes = abs_ab_mag_to_micro_jy(mags, 10.) # Fill in SED and ML tables for n, msun, flux in zip(bands, solar_mags, fluxes): # interesting slicing syntax for structured array assignment sed_table[n, i] = flux logL = micro_jy_to_luminosity(flux, msun, 10.) log_ml = np.log10(sp.stellar_mass) - logL ml_table[n, i] = log_ml # Fill in meta data table meta_table['logMstar', i] = np.log10(sp.stellar_mass) meta_table['logMdust', i] = np.log10(sp.dust_mass) meta_table['logLbol', i] = np.log10(sp.log_lbol) meta_table['logSFR', i] = np.log10(sp.sfr) meta_table['logAge', i] = sp.log_age
def table(self): """An :class:`astropy.table.Table` with the chain.""" if self.sampler is None: return None msuns = np.array([fsps.get_filter(n).msun_ab for n in self.model.computed_bands]) meta = OrderedDict(( ('observed_bands', self.model.observed_bands), ('instruments', self.model.instruments), ('computed_bands', self.model.computed_bands), ('msun_ab', msuns), ('d', self.model.d), # expected distance in parsecs ('band_indices', self.model.band_indices), ('theta_params', self.model.param_names), ('compute_time', self._run_time), ('step_time', self._call_time), ('sed', self.model._sed), ('sed_err', self.model._err), ('pixels', self.model.pixel_metadata), ('area', self.model._area), ('n_walkers', self.n_walkers), ("f_accept", self.sampler.acceptance_fraction), ("acor", self.sampler.acor))) # Convert flatchain into a structured array nwalkers, nsteps, ndim = self.sampler.chain.shape flatchain_arr = self.sampler.chain[:, :, :].reshape((-1, ndim)) dt = [(n, np.float) for n in self.model.param_names] flatchain = np.empty(flatchain_arr.shape[0], dtype=np.dtype(dt)) for i, n in enumerate(self.model.param_names): flatchain[n][:] = flatchain_arr[:, i] # Flatten the blob list and make a structured array blobs = self.sampler.blobs blobchain = np.empty(nwalkers * nsteps, self.model.blob_dtype) blobchain.fill(np.nan) for i in xrange(nsteps): for j in xrange(nwalkers): for k in self.model.blob_dtype.names: blobchain[k][i * self.n_walkers + j] = blobs[i][j][k] chain_table = Table(flatchain, meta=meta) blob_table = Table(blobchain) tbl = SinglePixelChain(hstack((chain_table, blob_table), join_type='exact')) # Add M/L computations for each computed band. for i, (band_name, msun) in enumerate(zip(self.model.computed_bands, msuns)): # Either use expected distance or the chain distance # FIXME fragile code if 'd' in self.model.param_names: d = np.array(tbl['d']) else: d = self.model.d logLsol = micro_jy_to_luminosity(tbl['model_sed'][:, i], msun, d) ml = tbl['logMstar'] - logLsol colname = "logML_{0}".format(band_name) tbl.add_column(Column(name=colname, data=ml)) return tbl
import fsps from sedbot.photconv import sb_to_mass, ab_mag_to_mjy, mjy_to_ab_sb from sedbot.probf import LnUniform, LnNormal from sedbot.ensemble_multipix.gibbsbg import MultiPixelGibbsBgModeller from sedbot.ensemble_multipix.threeparam_lnprob import ThreeParamLnProb, \ GlobalThreeParamLnProb N_PIXELS = 5 BANDS = ['sdss_u', 'sdss_g', 'sdss_r', 'sdss_i', '2mass_J', '2mass_Ks'] D0 = 785. * 1000. # distance in parsecs (McConnachie 2005) D0_SIGMA = 25. * 1000. PIX_AREA = 1. # arcsec-sq MSUN_I = fsps.get_filter('sdss_i').msun_ab BKG_AMPLITUDE = 1e-10 # units of janksy per sq arcsec # Hard limits on parameters LIMITS = {'logmass': (sb_to_mass(30., MSUN_I, PIX_AREA, 0.4, D0), sb_to_mass(12., MSUN_I, PIX_AREA, 0.4, D0)), 'logtau': (-1., 2.), 'const': (0., 1.0), 'sf_start': (0.5, 10.), 'tburst': (10.0, 13.8), 'fburst': (0., 1.0), 'logZZsol': (-1.98, 0.2), 'd': (D0 - 3. * D0_SIGMA, D0 + 3. * D0_SIGMA), 'dust1': (0., 5.), 'dust2': (0., 3.), 'ml': (-0.5, 1.5)}
nbins = 100 alpha = 0.5 lw = 2 color = 'blue' histtype = 'step' ax = np.ravel(axes) # setup filters ssc_filters = ['irac1','irac2','irac3','irac4'] fsps_filters = ['irac_1','irac_2','irac_3','irac_4'] sedpy_filters = ['spitzer_irac_ch1','spitzer_irac_ch2','spitzer_irac_ch3','spitzer_irac_ch4'] name = ['IRAC1','IRAC2','IRAC3','IRAC4'] for ii in xrange(len(fsps_filters)): firac = fsps.get_filter(fsps_filters[ii]) sirac = sedpy.observate.Filter(sedpy_filters[ii]) ax[ii].plot(sirac.wavelength/1e4, sirac.transmission / sirac.transmission.max(), label='sedpy',lw=1.5) ax[ii].plot(firac.transmission[0]/1e4, firac.transmission[1] / firac.transmission[1].max(), label='FSPS',lw=1.5) nirac = load_ssc_curve(ssc_filters[ii]+'.txt') ax[ii].plot(nirac['lambda'], nirac['transmission'] / nirac['transmission'].max(), label='new',lw=1.5) if ii == 0: ax[ii].legend(frameon=False) ax[ii].set_xlabel(r'wavelength [$\mu$m]') ax[ii].set_ylabel(r'filter response '+name[ii]) outfile = 'irac_response_comparison.png'
cloud = 'smc' #Choose bands for which you want to predict images. bands = ['irac_1'] # Cloud SFHs if cloud == 'smc': dm = 18.89 elif cloud == 'lmc': dm = 18.49 mass, rnames, mets, esfh = load_data(cloud) # Band information ab_to_vega = np.atleast_1d( np.squeeze([ f.msun_ab - f.msun_vega for b in bands for f in [fsps.get_filter(b)] ])) norm = 10**(-0.4 * (dm + ab_to_vega)) #SPS sps = fsps.StellarPopulation(compute_vega_mags=True) sps.params['sfh'] = 0 sps.params['imf_type'] = 0 sps.params['tpagb_norm_type'] = 2 #VCJ sps.params['add_agb_dust_model'] = True sps.params['agb_dust'] = 1.0 if len(sps.ssp_ages) == 107: isocname = 'MIST_VW' else: isocname = 'Padova2007'
Demonstration of plotting FSPS's un-normalized filter transmission tables (i.e., contents of $SPS_HOME/data/all_filters.dat). """ import fsps from matplotlib.figure import Figure from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas import matplotlib.gridspec as gridspec names = [ 'sdss_u', 'sdss_g', 'sdss_r', 'sdss_i', '2mass_J', '2mass_H', '2mass_Ks' ] shortnames = ['u', 'g', 'r', 'i', 'J', 'H', 'Ks'] colors = ['violet', 'dodgerblue', 'maroon', 'black', 'c', 'm', 'y'] filters = [fsps.get_filter(n) for n in names] fig = Figure(figsize=(3.5, 3.5)) canvas = FigureCanvas(fig) gs = gridspec.GridSpec(1, 1, left=0.17, right=0.95, bottom=0.15, top=0.95, wspace=None, hspace=None, width_ratios=None, height_ratios=None) ax = fig.add_subplot(gs[0])