def grid(Nage=80, NZ=20, nebular=True, dust=False): """ Generate grid of spectra with FSPS Returns: spec (array, float) spectra, dimensions NZ*Nage metallicities (array, float) metallicity array, units Z / Zsol scale_factors (array, flota) age array in units of the scale factor wl (array, float) wavelength array in Angstroms """ if dust: sp = fsps.StellarPopulation(zcontinuous=1, sfh=0, logzsol=0.0, add_neb_emission=nebular, dust_type=2, dust2=0.2, cloudy_dust=True, dust1=0.0) else: sp = fsps.StellarPopulation(zcontinuous=1, sfh=0, cloudy_dust=True, logzsol=0.0, add_neb_emission=nebular) wl = np.array(sp.get_spectrum(tage=13, peraa=True)).T[:, 0] ages = np.logspace(-3.5, np.log10(cosmo.age(0).value - 0.4), num=Nage, base=10) scale_factors = cosmo.scale_factor( [z_at_value(cosmo.lookback_time, age * u.Gyr) for age in ages]) metallicities = np.linspace(-3, 1, num=NZ) # log(Z / Zsol) spec = np.zeros((len(metallicities), len(ages), len(wl))) for i, Z in enumerate(metallicities): for j, a in enumerate(ages): sp.params['logzsol'] = Z if nebular: sp.params['gas_logz'] = Z spec[i, j] = sp.get_spectrum(tage=a, peraa=True)[1] # Lsol / AA return spec, scale_factors, metallicities, wl
def hden_ascii(fileout, **kwargs): # change these parameters to modify the ionizing source grid # default mode is to produce an ascii grid in age and Z, # though different variables and more dimensions are possible. sp_dict = dict(zcontinuous=1, imf_type=2, sfh=0, const=0.0, sf_start=0.0) sp = fsps.StellarPopulation(**sp_dict) # all ages and Zs ages = 10.**sp.log_age logZs = np.log10(old_div(sp.zlegend, zsun)) print(ages, logZs) modpars = [(age, logZ) for age in ages for logZ in logZs] lam = sp.wavelengths all_fluxs = [] for logZ in logZs: sp.params['logzsol'] = logZ all_fluxs.append(sp.get_spectrum()[1]) #lsun per hz nmod = len(modpars) # flatten flux for writing flat_flux = np.array( [all_fluxs[j][i] for i in range(len(ages)) for j in range(len(logZs))]) # this function is flexible, ndim can be 3/4/n. # in this example, however, ndim is 2 (age, logz). writeASCII(fileout, lam, flat_flux, modpars, nx=len(lam), ndim=2, npar=2, nmod=nmod) return
def output_csf_spectra( taxis=np.arange(0.001, 0.011, 0.001), logz=0.0, sfr=1., emissionlines=True): starpop = fsps.StellarPopulation(zcontinuous=1, add_neb_emission=emissionlines, logzsol=logz, imf_type=1, sfh=3, dust_type=2) starpop.set_tabular_sfh(np.array([0, 10]), np.array([sfr, sfr])) spectra = [] wavelength = [] for t in tqdm(taxis): wavelength, spectrum = starpop.get_spectrum(tage=t) spectra.append(spectrum) table = np.vstack((wavelength, spectra)).T np.savetxt( './synth_spectra/spectra_%.1f_Z_CSF.txt' % np.exp(logz), table, header='# lambda, followed by CSF spectra going from 1 to 10 Myr')
def get_ssp(metallicity=0.0, dust=0.0): """Generates a stellar population model with the given parameters Parameters: metallicity (float): log(Z) in solar units (so 0.0 is solar metallicity) dust (float): dust parameter Returns: Saves a series of files for a given stellar population over a range of ages from 0.01 to 15 in steps of 0.5 """ sp = fsps.StellarPopulation(compute_vega_mags=False, zcontinuous=1, sfh=0, logzsol=metallicity, dust_type=2, dust2=dust, imf_type=0) for age in ages_allowed: sp_spectrum = sp.get_spectrum(tage=age)[1] sp_stellar_mass = sp.stellar_mass sp_df = pd.DataFrame(sp_spectrum, columns=['Spectrum']) sp_df['Stellar_mass'] = sp_stellar_mass filename = get_filename(metallicity=metallicity, dust=dust, age=age) sp_df.to_csv(ssp_folder + filename, index=False) if not os.path.exists(ssp_folder + 'wavelength.df'): wavelength = sp.get_spectrum(tage=2)[0] wavelength_df = pd.DataFrame(wavelength, columns=['Wavelength']) wavelength_df.to_csv(ssp_folder + 'wavelength.df', index=False)
def load_beams_and_trns(wv, field, galaxy_id, instr): ### Set transmission curve sp = fsps.StellarPopulation(imf_type = 0, tpagb_norm_type=0, zcontinuous = 1, logzsol = np.log10(0.002/0.019), sfh = 4, tau = 0.6, dust_type = 1) model_wave, model_flux = sp.get_spectrum(tage = 3.6, peraa = True) ### set beams BEAMS = [] blist = glob(beam_path + '*{}*_*{}*'.format(field[1], galaxy_id) ) for b in blist: mb = multifit.MultiBeam(b,**args) PAlist = [] for bm in mb.beams: if bm.grism.filter == instr: if bm.get_dispersion_PA() not in PAlist: PAlist.append(bm.get_dispersion_PA()) BEAMS.append(bm) TRANS = [] for i in BEAMS: W, F = forward_model_grism(i, model_wave, np.ones(len(model_wave))) trans = interp1d(W,F)(wv) TRANS.append(trans) return BEAMS, TRANS
def SF_spec_adjust(Gs, bestfits, spz): sp = fsps.StellarPopulation(zcontinuous=1, logzsol=0, sfh=3, dust_type=2) sp.params['dust1'] = 0 wvs, flxs, errs, beams, trans = Gather_grism_data_from_2d(Gs, sp) m, a, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, z, lm, d, bp1, rp1, ba, bb, bl, ra, rb, rl = BFS sp.params['dust2'] = d sp.params['logzsol'] = np.log10(m) print() time, sfr, tmax = convert_sfh(get_agebins(a, binnum=6), [m1, m2, m3, m4, m5, m6], maxage=a * 1E9) sp.set_tabular_sfh(time, sfr) wave, flux = sp.get_spectrum(tage=a, peraa=True) Gmfl, Pmfl = Full_forward_model( Gs, wave, F_lam_per_M(flux, wave * (1 + spz), spz, 0, sp.stellar_mass) * 10**lm, spz, wvs, flxs, errs, beams, trans) BFL, BER = Best_fit_scale(wvs[0], flxs[0], errs[0], Gmfl[0], bp1) RFL, RER = Best_fit_scale(wvs[1], flxs[1], errs[1], Gmfl[1], rp1) return BFL, BER, RFL, RER, Gmfl, wave, F_lam_per_M( flux, wave * (1 + spz), spz, 0, sp.stellar_mass) * 10**lm
def __init__(self, compute_vega_mags=False, zcontinuous=1, debug=False, safe=False, **kwargs): self.debug = debug self.safe = safe # This is a StellarPopulation object from fsps self.ssp = fsps.StellarPopulation(compute_vega_mags=compute_vega_mags, zcontinuous=zcontinuous) # This is the main state vector for the model self.params = { 'outwave': self.ssp.wavelengths.copy(), 'dust_tesc': 0.00, 'dust1': 0., 'dust2': 0., 'mass': np.array([1.0]), 'zmet': np.array([0.0]) } self.ssp_dirty = True # These are the parameters whose change will force a regeneration of # the basis from the SSPs (but will not force the SSPs to be # regenerated) if self.safe: self.basis_params = ['tage', 'logzsol', 'zmet'] else: self.basis_params = ['tage', 'zmet', 'logzsol'] self.basis_dirty = True
def test(): from sedpy import observate import fsps import matplotlib.pyplot as pl filters = [ 'galex_NUV', 'sdss_u0', 'sdss_r0', 'sdss_r0', 'sdss_i0', 'sdss_z0', 'bessell_U', 'bessell_B', 'bessell_V', 'bessell_R', 'bessell_I', 'twomass_J', 'twomass_H' ] flist = observate.load_filters(filters) sps = fsps.StellarPopulation(compute_vega_mags=False) wave, spec = sps.get_spectrum(tage=1.0, zmet=2, peraa=True) sed = observate.getSED(wave, spec, flist) sed_unc = np.abs(np.random.normal(1, 0.3, len(sed))) wgrid = np.linspace(2e3, 13e3, 1000) fgrid = np.linspace(-13, -9, 100) psed, sedpoints = sed_to_psed(flist, sed, sed_unc, wgrid, fgrid) pl.imshow(np.exp(psed).T, cmap='Greys_r', interpolation='nearest', origin='upper', aspect='auto')
def fbhb_ascii(fileout, **kwargs): # change these parameters to modify the ionizing source grid # default mode is to produce an ascii grid in age and Z, # though different variables and more dimensions are possible. fbhb_fracs = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0] sp_dict = dict(zcontinuous=1, imf_type=2, sfh=0) sp = fsps.StellarPopulation(**sp_dict) # all ages, default solar metallicity ages = 10.**sp.log_age modpars = [(age, fb) for age in ages for fb in fbhb_fracs] lam = sp.wavelengths all_fluxs = [] for fb in fbhb_fracs: sp.params["fbhb"] = fb all_fluxs.append(sp.get_spectrum()[1]) #lsun per hz nmod = len(modpars) # flatten flux for writing flat_flux = np.array([all_fluxs[j][i] for i in range(len(ages)) for j in range(len(fbhb_fracs))]) # this function is flexible, ndim can be 3/4/n. writeASCII(fileout, lam, flat_flux, modpars, nmod=nmod, ndim=2, npar=2, par1='age', par2='fbhb') return
def get_fsps_spec(self, **kwargs): sp = fsps.StellarPopulation(zcontinuous=1) sp.params['logzsol'] = self.logZ lam, spec = sp.get_spectrum(tage=self.age*1.0e-9) self.__setattr__('fsps_lam', lam) self.__setattr__('fsps_spec', spec) self.__setattr__('fsps_Q', calcQ(lam, spec*lsun, f_nu=True)) return
def _ssp_initiate(self): ''' initialize sps (FSPS StellarPopulaiton object) ''' if self.model_name == 'vanilla': ssp = fsps.StellarPopulation( zcontinuous=1, # interpolate metallicities sfh=4, # sfh type dust_type=2, # Calzetti et al. (2000) attenuation curve. imf_type=1) # chabrier elif self.model_name == 'dustless_vanilla': ssp = fsps.StellarPopulation( zcontinuous=1, # interpolate metallicities sfh=4, # sfh type imf_type=1) # chabrier else: raise NotImplementedError return ssp
def grid(Nage=80, NZ=20, nebular=True, dust=False): """ Generate grid of spectra with FSPS Returns: spec (array, float) spectra, dimensions NZ*Nage age (array, float) age array, Gyr metallicities (array, float) metallicity array, Z/Zsol wl (array, float) wavelength array in Angstroms """ if dust: sp = fsps.StellarPopulation( zcontinuous=1, sfh=0, logzsol=0.0, add_neb_emission=nebular, dust_type=2, dust2=0.2, cloudy_dust=True, dust1=0.0) # dust_type=1, dust2=0.2, dust1=0.2) else: sp = fsps.StellarPopulation(zcontinuous=1, sfh=0, cloudy_dust=True, add_neb_emission=nebular, logzsol=0.0) wl = np.array(sp.get_spectrum(tage=13, peraa=True)).T[:, 0] ages = np.logspace(-2, np.log10(15), num=Nage, base=10) metallicities = np.linspace(-2, 1, num=NZ) # log(Z / Zsol) spec = np.zeros((len(metallicities), len(ages), len(wl))) for i, Z in enumerate(metallicities): for j, a in enumerate(ages): sp.params['logzsol'] = Z if nebular: sp.params['gas_logz'] = Z spec[i, j] = sp.get_spectrum(tage=a, peraa=True)[1] # Lsol / AA return spec, ages, metallicities, wl
def generate_ssp_table(ssp_lookup_file, Zsol=Solar['total'], oversample=[2, 2], return_table=False, **fsps_options): ''' Generates an SPS lookup table, oversampling in [age,metallicity] by oversample ''' import fsps mylog.info('Generating SSP lookup table %s' % (ssp_lookup_file)) mylog.info('with FSPS options: %s' % (fsps_options)) fsps_opts = '' for key, value in fsps_options.items(): fsps_opts = fsps_opts + ("{0} = {1}, ".format(key, value)) fsps_opts = np.string_(fsps_opts) fsps_ssp = fsps.StellarPopulation(**fsps_options) wavelengths = fsps_ssp.wavelengths ssp_ages = [] mass_remaining = [] ssp_ages.append(fsps_ssp.ssp_ages[0]) mass_remaining.append(fsps_ssp.stellar_mass[0]) for i in range(len(fsps_ssp.ssp_ages) - 1): for j in range(i + 1, i + oversample[0]): ssp_ages.append((fsps_ssp.ssp_ages[j] - fsps_ssp.ssp_ages[j - 1]) * (j - i) / oversample[0] + fsps_ssp.ssp_ages[j - 1]) mass_remaining.append( (fsps_ssp.stellar_mass[j] - fsps_ssp.stellar_mass[j - 1]) * (j - i) / oversample[0] + fsps_ssp.stellar_mass[j - 1]) ssp_ages.append(fsps_ssp.ssp_ages[j]) mass_remaining.append(fsps_ssp.stellar_mass[j]) ssp_logZ = [] ssp_logZ.append(fsps_ssp.zlegend[0]) for i in range(len(fsps_ssp.zlegend) - 1): for j in range(i + 1, i + oversample[1]): ssp_logZ.append((fsps_ssp.zlegend[j] - fsps_ssp.zlegend[j - 1]) * (j - i) / oversample[1] + fsps_ssp.zlegend[j - 1]) ssp_logZ.append(fsps_ssp.zlegend[j]) ssp_logZ = np.log10(ssp_logZ) ssp_spectra = [] for age in ssp_ages: for Zmet in ssp_logZ: fsps_ssp.params["logzsol"] = Zmet - np.log10(Zsol) spectrum = fsps_ssp.get_spectrum(tage=10**(age - 9))[1] ssp_spectra.append(spectrum) with h5py.File(ssp_lookup_file, 'w') as hf: hf.create_dataset('fsps_options', data=fsps_opts) hf.create_dataset('ages', data=ssp_ages) hf.create_dataset('logZ', data=ssp_logZ) hf.create_dataset('mass_remaining', data=mass_remaining) hf.create_dataset('wavelengths', data=wavelengths) hf.create_dataset('spectra', data=ssp_spectra) memlog('Generated lookup table with %d ages and %d metallicities' % (len(ssp_ages), len(ssp_logZ))) if return_table: return ssp_ages, ssp_logZ, mass_remaining, wavelengths, ssp_spectra
def __init__(self, zcontinuous=1, reserved_params=['zred', 'sigma_smooth'], vactoair_flag=False, compute_vega_mags=False, **kwargs): # This is a StellarPopulation object from fsps self.ssp = fsps.StellarPopulation(compute_vega_mags=compute_vega_mags, zcontinuous=zcontinuous, vactoair_flag=vactoair_flag) self.reserved_params = reserved_params self.params = {} self.update(**kwargs)
def Get_mass(gwv, gfl, ger, Z, t, z, Av): sp = fsps.StellarPopulation(imf_type = 0, tpagb_norm_type = 0, zcontinuous = 1, logzsol = np.log10(Z/0.019), sfh = 4, tau = 0.6, dust_type = 1) wave,flux=np.array(sp.get_spectrum(tage=t,peraa=True)) fl_m = F_lam_per_M(flux, wave * (1 + z), z, Av, sp.stellar_mass) IDX = [U for U in range(len(gwv)) if 8000 < gwv[U] < 11300] return np.log10(Scale_model(gfl[IDX],ger[IDX],interp1d(wv,fl_m)(gwv[IDX])))
def make_clfs(cloud, tpagb_norm_type=2, select_function=None, sedfilters = None, **sps_kwargs): # These are the filters for integrated magnitudes of the object #sedfilters = ['galex_NUV', 'spitzer_irac_ch2', # 'spitzer_irac_ch4', 'spitzer_mips_24'] # These are the filters for which you want LFs lffilters = ['2mass_ks','irac_2','irac_4'] ######## # Get the SFH ######## import mcutils if cloud.lower() == 'lmc': print('doing lmc') dm = 18.5 regions = mcutils.lmc_regions() elif cloud.lower() == 'smc': print('doing smc') dm = 18.9 regions = mcutils.smc_regions() if 'header' in regions.keys(): rheader = regions.pop('header') #dump the header info from the reg. dict total_sfhs = None for n, dat in regions.iteritems(): total_sfhs = mcutils.sum_sfhs(total_sfhs, dat['sfhs']) total_zmet = dat['zmet'] ####### #Define SPS object ####### sps = fsps.StellarPopulation(compute_vega_mags=True) sps.params['add_agb_dust_model'] = True sps.params['tpagb_norm_type'] = tpagb_norm_type sps.params['sfh'] = 0 sps.params['imf_type'] = 0.0 #salpeter sps.params['agb_dust'] = 1.0 for k, v in sps_kwargs.iteritems(): try: sps.params[k] = v except(KeyError): pass # Go from SFH to LFs and SED sed, clfs = zsfh_to_obs(total_sfhs, total_zmet, lfbandnames=lffilters, bandnames=sedfilters, sps=sps, select_function=select_function, cloud=cloud, **sps_kwargs) return clfs
def __init__(self, compute_vega_mags=False, zcontinuous=1, vactoair_flag=False, **kwargs): # This is a StellarPopulation object from fsps self.csp = fsps.StellarPopulation(compute_vega_mags=compute_vega_mags, zcontinuous=zcontinuous, vactoair_flag=vactoair_flag) self.params = {}
def __init__(self, compute_vega_mags=False, zcontinuous=1, reserved_params=['zred', 'sigma_smooth'], **kwargs): # This is a StellarPopulation object from fsps self.csp = fsps.StellarPopulation(compute_vega_mags=compute_vega_mags, zcontinuous=zcontinuous) self.reserved_params = reserved_params self.params = {}
def save_temp( self, sfhtype='CSF', metallicity=1.0, time=0.001, renorm=True, savefp='/home/adam/Research/eazy-photoz/templates/AdamTemps/'): fname = savefp + sfhtype + '_%iMyr_Z_%.1f.dat' % (time * 1000, metallicity) if sfhtype == 'SSP': starpop = fsps.StellarPopulation( zcontinuous=1, add_neb_emission=True, imf_type=1, dust_type=2, sfh=0, logzsol=np.log10( metallicity)) # chabrier IMF and Calzetti dust elif sfhtype == 'CSF': starpop = fsps.StellarPopulation(zcontinuous=1, add_neb_emission=True, imf_type=1, dust_type=2, sfh=3, logzsol=np.log10(metallicity)) starpop.set_tabular_sfh(np.array([0, 1]), np.array([1, 1])) wavelength, l_nu = self.find_spectrum(starpop, time) if renorm: l_nu = 2 * l_nu / max( l_nu ) # Templates in EAZY seem to be normalized so they peak around 2, so maybe this will help? with open(fname, 'w') as writefile: for x in range(len(wavelength)): writefile.write(('%.5e' % wavelength[x]).ljust(20)) writefile.write('%.5e' % l_nu[x] + '\n')
def gen_data(filters, sigma): print('Initializing Stellar Population..') ssp = fsps.StellarPopulation(zmet=2, dust_type=1) print('Computing magnitude in the V and I bands..') V, I = ssp.get_mags(tage=14, bands=f) mags = [V, I] mags += -5 + 5 * np.log10(8.2e3) + np.random.normal( loc=0, scale=sigma, size=2) return mags
def selftest_broaden(): import fsps sps = fsps.StellarPopulation() ages = [1., 2., 3., 4., 5., 6., 7.] allspec = np.zeros([len(ages), len(sps.wavelengths)]) for i,tage in enumerate(ages): wave, spec = sps.get_spectrum(peraa=True, tage=tage) allspec[i,:] = spec outwave = wave[(wave > 1e3) & (wave < 1e4)] vbflux = vel_broaden(wave, allspec, 150., outwave=outwave) wbflux = wave_broaden(wave, allspec, 5., outwave=outwave)
def agn_templates(): import fsps import eazy import matplotlib.pyplot as plt sp = fsps.StellarPopulation() res = eazy.filters.FilterFile(path=None) jfilt = res[161] sp.params['dust_type'] = 2 sp.params['dust2'] = 0 sp.params['agn_tau'] = 10 sp.params['fagn'] = 0 wave, f0 = sp.get_spectrum(tage=0.5, peraa=True) fig = plt.figure(figsize=(6, 4)) ax = fig.add_subplot(111) sp.params['fagn'] = 1. for tau in [5, 10, 20, 50, 80, 120]: sp.params['agn_tau'] = tau wave, f1 = sp.get_spectrum(tage=0.5, peraa=True) label = 'agn_tau{0:03d}'.format(sp.params['agn_tau']) ax.plot(wave / 1.e4, f1 - f0, label=label, alpha=0.5) #fnorm = np.trapz(f1-f0, wave) templ = templates.Template(arrays=(wave, f1 - f0), name=label, meta={'agn_tau': sp.params['agn_tau']}) fnorm = templ.integrate_filter(jfilt, flam=True) / jfilt.pivot templ.flux *= fnorm file = 'templates/agn_tau/{0}.fits'.format(templ.name) print(tau, file) tab = templ.to_table() tab.write(file, overwrite=True) ax.legend() ax.loglog() ax.grid() ax.set_ylim(1.e-7, 1.e-3) ax.set_xlim(90 / 1.e4, 200) ax.set_xlabel(r'$\lambda$, $\mu$m') ax.set_ylabel(r'$f_\lambda$') fig.tight_layout(pad=0.1) fig.savefig('templates/agn_tau/fsps_agn.png')
def generate_spectra(params): """ This function allows the user to generate many spectra for a defined SFR at given ages, at user defined time steps and metallicities. INPUT: :sfr: The SFRs defined at each age for any number of sfhs, H. Shape (H, SFR) GLOBAL PARAMETERS: :ages: The times at which the sfr is defined for any number of sfhs, H. Shape (H, SFR). :time_steps: An array of time values for which a spectrum with the given sfr is returned. Shape (T,) :zmets: An array of model metallicity values (range 1-22, see FSPS details) for which a spectrum with the given sfr is returned. Shape (Z,) RETURNS: :fsps_flux: Fluxes at each manga wavelength, M for the number of sfhs input at each time_step and zmet combination. Shape (H*T*Z, M). """ time_step = [params[0]] zmets = params[1] ages = params[2] sfr = params[3] sp = fsps.StellarPopulation(compute_vega_mags=False, zcontinuous=0, zmet=18, sfh=3, dust_type=2, dust2=0.2, add_neb_emission=True, add_neb_continuum=False, imf_type=1, add_dust_emission=True, min_wave_smooth=3600, max_wave_smooth=7500, smooth_velocity=True, sigma_smooth=77.) sp.set_tabular_sfh(age = ages, sfr=sfr) def time_spec(params): sps = sp.get_spectrum(tage=params[0], zmet=params[1])[1] return sps fsps_wave = sp.get_spectrum()[0] fsps_spec = np.array(list(map(time_spec, list(product(time_step, zmets))))) manga_wave = np.load("manga_wavelengths_AA.npy") manga_hz = c*(un.km/un.s).to(un.AA/un.s)/manga_wave f = interpolate.interp1d(fsps_wave, fsps_spec) fluxes = f(manga_wave)*(manga_hz/manga_wave) # Fluxes returned by FSPS are in units L_sol/Hz - MaNGA DAP needs fluxes in per AA flux units return fluxes
def extract_cols(filters=our_filters, outfile='mist_ssp_feh'): # construct header for output file file_header = 'logt_yr ' for f in filters: file_header = file_header + f[-5:] + ' ' # generate SSP - this can take a while sp = fsps.StellarPopulation(compute_vega_mags=True, add_neb_emission=True, cloudy_dust=True, sfh=0, zmet=10) ages = sp.log_age # modify SSP with different metallicity values, extract mags, write to file for met in met_vals.keys(): output_file = outfile+met mags = sp.get_mags(zmet = met_vals[met], bands = filters) alldat = np.vstack((ages.T,mags.T)).T # transposing makes the stacking work correctly np.savetxt(output_file, alldat, fmt = '%+7.4f', header=file_header) # end of loop over metallicity values return
def __init__(self, **params): ''' ''' # initiate FSPS Composite Stellar Population object self.pop = fsps.StellarPopulation(zcontinuous=1) # update the params with given params self.updateParams(**params) # some useful constants self.lsun = 3.846e33 # erg/s self.pc = 3.085677581467e18 # cm self.lightspeed = 2.998e18 # AA/s self.to_cgs = self.lsun / (4. * np.pi * (self.pc * 10)**2) # default cosmology self.cosmo = FlatLambdaCDM(H0=70, Om0=0.3)
def FSPS_sspLum(theta): ''' FSPS wrapper that deals with NMF SFH and ZH basis and other parameters. :param theta: numpy array that specifies parameters. Indices 0 to Ncomp_sfh-1 specifies the SFH basis parameters. Indices Ncomp_sfh to Ncomp_sfh + Ncomp_zh specifies the ZH basis parameters. Index -1 specifes tau_ISM (dust) :return wave_rest rest-frame wavelength grid provided by FSPS :return lum_ssp: luminosity in uints of Lsun/AA of ssp. This can be converted to observed flux of units erg/s/cm^2/Angstrom by multiplying x Lsun/(4pi dlum^2)/(1+z) ''' # initalize fsps object ssp = fsps.StellarPopulation( zcontinuous= 1, # SSPs are interpolated to the value of logzsol before the spectra and magnitudes are computed sfh=0, # single SSP imf_type=1, # chabrier dust_type=2 # Calzetti (2000) ) ispec = Fitters.iSpeculator() t_lookback = ispec._nmf_t_lookback nmf_sfh_basis = ispec._nmf_sfh_basis nmf_zh_basis = ispec._nmf_zh_basis theta_sfh = theta[:4] theta_zh = theta[4:6] theta_dust = theta[-1] # dust parameter sfh = np.dot(theta_sfh, nmf_sfh_basis) zh = np.dot(theta_zh, nmf_zh_basis) for i, t, m, z in zip(range(len(t_lookback)), t_lookback, sfh, zh): if m <= 0: # no star formation in this bin continue ssp.params['logzsol'] = np.log10(z / 0.0190) # log(Z/Zsun) ssp.params['dust2'] = theta_dust wave_rest, lum_i = ssp.get_spectrum(tage=t, peraa=True) # in units of Lsun/AA if i == 0: lum_ssp = np.zeros(len(wave_rest)) lum_ssp += m * lum_i return wave_rest, lum_ssp
def plot_a_spectrum(): t_start = time.time() sps = fsps.StellarPopulation(zcontinuous=1) spec = sps.get_spectrum() print time.time() - t_start, ' seconds' # takes 3 mins... wtf prettyplot() pretty_colors = prettycolors() fig = plt.figure() sub = fig.add_subplot(111) for i in range(spec[1].shape[0]): sub.plot(spec[0], 1.e17 * (spec[1][i, :]), c=pretty_colors[i % 10]) sub.set_xlabel(r'$\lambda$', fontsize=25) sub.set_xlim([1000, 10000]) fig.savefig('aspectrum.png') plt.close() return None
def __init__(self, field, galaxy, rshift, trials = 1000): from sim_engine import F_lam_per_M self.rshift = rshift sp = fsps.StellarPopulation(zcontinuous = 1, logzsol = 0, sfh = 3, dust_type = 2) sp.params['dust1'] = 0 ppf_dict = {} params = ['m', 'a', 'm1', 'm2', 'm3', 'm4', 'm5', 'm6', 'lm','d'] for i in params: x,px = np.load('../data/posteriors/{0}_{1}_SFfit_p1_P{2}.npy'.format(field, galaxy, i),allow_pickle=True) ppf_dict[i] = Gen_PPF(x,px) idx = 0 flam_grid=[] while idx < trials: try: draw = np.zeros(len(params)) for i in range(len(draw)): draw[i] = ppf_dict[params[i]](np.random.rand(1))[0] sp.params['dust2'] = draw[9] sp.params['logzsol'] = np.log10(draw[0]) time, sfr, tmax = convert_sfh(get_agebins(draw[1], binnum = 6), draw[2:8], maxage = draw[1]*1E9) sp.set_tabular_sfh(time,sfr) self.wave, flux = sp.get_spectrum(tage = draw[1], peraa = True) flam_grid.append(F_lam_per_M(flux, self.wave * (1 + self.rshift), self.rshift, 0, sp.stellar_mass)*10**draw[8]) idx +=1 except: pass self.SPEC = np.percentile(flam_grid,50, axis = 0) self.SPEC_16 = np.percentile(flam_grid,16, axis = 0) self.SPEC_84 = np.percentile(flam_grid,84, axis = 0)
def make_ssp_templates_fsps(velscale, lamrange, ages, metallicities): #initialise FSPS models sp = fsps.StellarPopulation(compute_vega_mags=False, zcontinuous=1, sfh=0) #total number of templates N = len(ages) * len(metallicities) #put in log10(Z/Z_solar) metallicities = np.log10(np.array(metallicities) / 0.019) #get the wavelength vector and initialise the array to hold all the templates wave = set_common_grid() templates = np.zeros((len(wave), N)) #now loop through the given metallicities and ages to create each template in turn c = 0 for Z in metallicities: sp.params['logzsol'] = Z for age in ages: wave_fsps, flux_fsps = sp.get_spectrum(tage=age, peraa=True) #in L_solar/AA #now to common grid wave, flux = to_common_grid(wave_fsps, flux_fsps, lamrange[0], lamrange[1]) templates[:, c] = flux / np.median(flux) c = c + 1 #now mask and re-grid mask = ((wave >= lamrange[0]) & (wave <= lamrange[1])) wave = wave[mask] template_rb, logLam, velscale_out = util.log_rebin([wave[0], wave[-1]], templates[mask, 0], velscale=velscale) templates_out = np.zeros((len(logLam), N)) templates_out[:, 0] = template_rb plt.plot(np.exp(1)**logLam, templates_out[:, 0]) for i in range(1, N): templates_out[:, i], logLam, velscale_out = util.log_rebin( [wave[0], wave[-1]], templates[mask, i], velscale=velscale) templates_out[:, i] = templates_out[:, i] plt.plot(np.exp(1)**logLam, templates_out[:, i]) return logLam, templates_out
def SF_spec_adjust(Gs): sp = fsps.StellarPopulation(zcontinuous=1, logzsol=0, sfh=3, dust_type=2) sp.params['dust1'] = 0 sp.params['dust2'] = fit_db['bfd'] sp.params['logzsol'] = np.log10(fit_db['bfm']) time, sfr, tmax = convert_sfh(get_agebins(fit_db['bfa'], binnum=6), [ fit_db['bfm1'], fit_db['bfm2'], fit_db['bfm3'], fit_db['bfm4'], fit_db['bfm5'], fit_db['bfm6'] ], maxage=fit_db['bfa'] * 1E9) sp.set_tabular_sfh(time, sfr) wave, flux = sp.get_spectrum(tage=fit_db['bfa'], peraa=True) flam = F_lam_per_M(flux, wave * (1 + specz), specz, 0, sp.stellar_mass) * 10**fit_db['bflm'] return wave, flam, sp