def prospector_LGAL_sourceSpec_i(galid, mask=False, infer_method='dynesty'): ''' run prospector on L-Gal source spectra ''' # read in source spectra f_name = 'gal_spectrum_'+str(galid)+'_BGS_template_BC03_Stelib.fits' f_inspec = fits.open(''.join([UT.dat_dir(), 'Lgal/templates/', f_name])) specin = f_inspec[1].data zred = f_inspec[0].header['REDSHIFT'] wave = specin['wave'] flux = specin['flux_nodust_nonoise'] * 1e3 * 1e17 # in units of erg/s/A/cm2 prosp = Fitters.Prospector() str_mask = '' if mask: str_mask = '.masked' f_name = ''.join([UT.dat_dir(), 'Lgal/templates/', 'prospector.', infer_method, str_mask, '.gal_spectrum_', str(galid), '_BGS_template_BC03_Stelib.h5']) if infer_method == 'dynesty': # run dynamic nested sampling prosp.dynesty_spec(wave, flux, None, zred, nested=True, maxcall_init=50000, maxcall=100000, write=True, output_file=f_name) elif infer_method == 'emcee': # emcee prosp.emcee_spec(wave, flux, None, zred, mask=mask, write=True, output_file=f_name, silent=False) return None
def prospector_LGAL_desiSpec_i(galid, mask=False, infer_method='dynesty'): ''' run prospector on L-Gal DESI-like spectra ''' # read in source spectra (only to get the redshift) f_name = 'gal_spectrum_'+str(galid)+'_BGS_template_BC03_Stelib.fits' f_inspec = fits.open(''.join([UT.dat_dir(), 'Lgal/templates/', f_name])) zred = f_inspec[0].header['REDSHIFT'] # read desi-like spectra f_name = 'gal_spectrum_'+str(galid)+'_BGS_template_BC03_Stelib.fits' f_outspec = ''.join([UT.dat_dir(), 'Lgal/spectra/', 'desi_out_', f_name]) spec_desi = desiIO.read_spectra(f_outspec) wave = np.concatenate([spec_desi.wave[b] for b in ['b', 'r', 'z']]) flux = np.concatenate([spec_desi.flux[b][0] for b in ['b', 'r', 'z']]) # 10-17 ergs/s/cm2/AA flux_unc = np.concatenate([spec_desi.ivar[b][0]**-0.5 for b in ['b', 'r', 'z']]) prosp = Fitters.Prospector() str_mask = '' if mask: str_mask = '.masked' f_name = ''.join([UT.dat_dir(), 'Lgal/spectra/', 'prospector.', infer_method, str_mask, '.desi_out_gal_spectrum_', str(galid), '_BGS_template_BC03_Stelib.h5']) if infer_method == 'dynesty': # run dynamic nested sampling prosp.dynesty_spec(wave, flux, flux_unc, zred, mask=mask, nested=True, maxcall_init=25000, maxcall=50000, write=True, output_file=f_name) elif infer_method == 'emcee': # emcee prosp.emcee_spec(wave, flux, flux_unc, zred, mask=mask, write=True, output_file=f_name, silent=False) return None
def firefly_LGAL_sourceSpec_i(galid, model='m11', model_lib='MILES', imf='cha', hpf_mode='on'): ''' run firefly on L-Gal source spectra ''' # read in source spectra f_name = 'gal_spectrum_' + str(galid) + '_BGS_template_BC03_Stelib.fits' f_inspec = fits.open(''.join([UT.dat_dir(), 'Lgal/templates/', f_name])) specin = f_inspec[1].data spec_in = {} spec_in['redshift'] = f_inspec[0].header['REDSHIFT'] spec_in['wave'] = specin['wave'] spec_in['flux'] = specin[ 'flux_dust_nonoise'] * 1e-4 * 1e7 * 1e17 #from W/A/m2 to 10e-17 erg/s/A/cm2 spec_in[ 'flux_dust_nonoise'] = specin['flux_dust_nonoise'] * 1e-4 * 1e7 * 1e17 spec_in['flux_nodust_nonoise'] = specin[ 'flux_nodust_nonoise'] * 1e-4 * 1e7 * 1e17 # structure source spectra for firefly read in gspec = Spec.GSfirefly() gspec.generic(spec_in['wave'], spec_in['flux_dust_nonoise'], redshift=spec_in['redshift']) gspec.path_to_spectrum = UT.dat_dir() # output firefly file f_name = ''.join([ 'firefly.', model, '.', model_lib, '.imf_', imf, '.dust_', hpf_mode, '.', 'gal_spectrum_', str(galid), '_BGS_template_BC03_Stelib.hdf5' ]) f_firefly = ''.join([UT.dat_dir(), 'Lgal/templates/', f_name]) firefly = Fitters.Firefly( gspec, f_firefly, # output file co.Planck13, # comsology models=model, # model ('m11', 'bc03', 'm09') model_libs=[model_lib], # model library for M11 imfs=[imf], # IMF used ('ss', 'kr', 'cha') hpf_mode= hpf_mode, # uses HPF to dereden the spectrum age_limits=[0, 15], Z_limits=[-3., 5.], wave_limits=[3350., 9000.], suffix=None, downgrade_models=False, data_wave_medium='vacuum', use_downgraded_models=False, write_results=True) bestfit = firefly.fit_models_to_data() return None
def obs_condition(sampling='spacefill', overwrite=False): ''' Sample mock BGS observing conditions ''' if sampling == 'spacefill': f_obscond = ''.join([UT.dat_dir(), 'spectral_challenge/', 'bgs_mockexp_obscond_testset.', sampling, '.txt']) else: raise NotImplementedError("maybe implement random later") if os.path.isfile(f_obscond) and not overwrite: out_obscond = np.loadtxt(f_obscond, unpack=True, skiprows=1) else: # read in bgs mock exposure observing conditions generated from # https://github.com/changhoonhahn/feasiBGS/blob/master/notebook/local_bgs_mockexp.ipynb f_exp = ''.join([UT.dat_dir(), 'spectral_challenge/', 'bgs_survey_exposures.withsun.hdf5']) f = h5py.File(f_exp, 'r') mock_exps = {} for k in f.keys(): mock_exps[k] = f[k].value f.close() nexps = len(mock_exps['RA']) # we want to sample main meta-data from the mock exposures meta_keys = ['MOONFRAC', 'MOONALT', 'SUNALT'] #'AIRMASS', 'SUNSEP', 'MOONSEP' meta = np.zeros((nexps, len(meta_keys))) for i, k in enumerate(meta_keys): meta[:,i] = mock_exps[k] if sampling == 'spacefill': histmd, edges = np.histogramdd(meta, 2) _hasexp = histmd > 0. has_exp = np.where(_hasexp) print('%i exposures' % np.sum(_hasexp)) iexp_sample = [] for i in range(np.sum(_hasexp)): in_bin = np.ones(nexps).astype(bool) for i_dim in range(len(meta_keys)): in_bin = (in_bin & (meta[:,i_dim] > edges[i_dim][has_exp[i_dim]][i]) & (meta[:,i_dim] <= edges[i_dim][has_exp[i_dim]+1][i])) assert np.sum(in_bin) > 0 iexp_sample.append(np.random.choice(np.arange(nexps)[in_bin], 1)[0]) iexp_sample = np.array(iexp_sample) out_keys = ['AIRMASS', 'SEEING', 'EXPTIME', 'MOONFRAC', 'MOONALT', 'MOONSEP', 'SUNALT', 'SUNSEP'] hdr = ', '.join([k.lower() for k in out_keys]) out_obscond = np.zeros((len(iexp_sample), len(out_keys))) for i, k in enumerate(out_keys): out_obscond[:,i] = mock_exps[k][iexp_sample] np.savetxt(f_obscond, out_obscond, header=hdr) return out_obscond.T
def firefly_LGAL_desiSpec_i(galid, model='m11', model_lib='MILES', imf='cha', hpf_mode='on'): ''' run firelfy on L-Gal DESI-like spectra ''' t0 = time.time() # read in source spectra (only to get the redshift) f_name = 'gal_spectrum_' + str(galid) + '_BGS_template_BC03_Stelib.fits' f_inspec = fits.open(''.join([UT.dat_dir(), 'Lgal/templates/', f_name])) redshift = f_inspec[0].header['REDSHIFT'] # read desi-like spectra f_name = 'gal_spectrum_' + str(galid) + '_BGS_template_BC03_Stelib.fits' f_outspec = ''.join([UT.dat_dir(), 'Lgal/spectra/', 'desi_out_', f_name]) spec_desi = desiIO.read_spectra(f_outspec) gspec = Spec.GSfirefly() gspec.DESIlike(spec_desi, redshift=redshift) gspec.path_to_spectrum = UT.dat_dir() # output firefly file f_out = ''.join([ 'firefly.', model, '.', model_lib, '.imf_', imf, '.dust_', hpf_mode, '.', 'desi_out_', f_name.split('.fits')[0], '.hdf5' ]) f_firefly = ''.join([UT.dat_dir(), 'Lgal/spectra/', f_out]) firefly = Fitters.Firefly( gspec, f_firefly, # output file co.Planck13, # comsology models=model, # model ('m11', 'bc03', 'm09') model_libs=[model_lib], # model library for M11 imfs=[imf], # IMF used ('ss', 'kr', 'cha') hpf_mode= hpf_mode, # uses HPF to dereden the spectrum age_limits=[0, 15], Z_limits=[-3., 5.], wave_limits=[3350., 9000.], suffix=None, downgrade_models=False, data_wave_medium='vacuum', use_downgraded_models=False, write_results=True) bestfit = firefly.fit_models_to_data() print('galid %i took %f' % (galid, (time.time() - t0) / 60.)) return None
def singleSP(iz, age=1., mtot=1e8, zred=0.01): ''' construct spectra of single stellar population with single metallicity, no dust, no nonsense from firefly SSPs (for consistency). metallicity set by z_arr[iz] where z_arr is ''' z_arr = np.array([0.5, 1.0, 2.0, 10**-1.301, 10**-1.302, 10**-2.301, 10**-2.302, 10**-0.6, 10**-0.9, 10**-1.2, 10**-1.6, 10**-1.9]) z_strs = np.array(['z001', 'z002', 'z004', 'z0001.bhb', 'z0001.rhb', 'z10m4.bhb', 'z10m4.rhb', 'z-0.6', 'z-0.9', 'z-1.2', 'z-1.6', 'z-1.9']) z_metal = z_arr[iz] f_ssp = os.environ['STELLARPOPMODELS_DIR']+'/data/SSP_M11_MILES/ssp_M11_MILES.cha'+z_strs[iz] model_age, model_wave, model_flux = np.loadtxt(f_ssp, unpack=True, usecols=[0,2,3]) isage = (model_age == age) wave = model_wave[isage] # wavelength flux = model_flux[isage] # flux [ergs/s/A] cosmo = FlatLambdaCDM(70., 0.3) wave *= (1. + zred) flux *= mtot / (4.*np.pi * cosmo.luminosity_distance(zred).to(U.cm).value**2) fig = plt.figure(figsize=(10,4)) sub = fig.add_subplot(111) sub.plot(wave, flux, c='k', lw=1) sub.set_xlabel('observed-frame wavelength [$A$]', fontsize=15) sub.set_xlim([3500., 1e4]) sub.set_ylabel('flux [$ergs/s/cm^2/A$]', fontsize=15) sub.set_ylim([0., flux[(wave > 3000.) & (wave < 1e4)].max()]) fig.savefig(''.join([UT.fig_dir(), 'SSP.iz', str(iz), '.age', str(age), '.z', str(zred), '.png']), bbox_inches='tight') # save spectra f_spec = ''.join([UT.dat_dir(), 'SSP.iz', str(iz), '.age', str(age), '.z', str(zred), '.dat']) np.savetxt(f_spec, np.vstack([wave, flux]).T) return None
def f_BGSspec(galid, iobs, lib='bc03', obs_sampling='spacefill', nobs=8): ''' DESI BGS-like spectra ''' fsource = f_Source(galid, lib=lib) fsource = fsource.rsplit('/',1)[1].rsplit('.', 1)[0] return ''.join([UT.dat_dir(), 'spectral_challenge/bgs/', 'BGSsim.', fsource, '.obscond_', obs_sampling, '.', str(iobs+1), 'of', str(nobs), '.fits'])
def f_Source(galid, lib='bc03'): ''' source spectra ''' if lib == 'bc03': lib_str = 'BC03_Stelib' elif lib == 'fsps': lib_str = 'FSPS_uvmiles' return ''.join([UT.dat_dir(), 'Lgal/templates/', 'gal_spectrum_'+str(galid)+'_BGS_template_', lib_str, '.fits'])
def myFirefly_lgal_sourceSpec(galid, dust=False, lib='bc03', model='m11', model_lib='MILES', imf='kr'): ''' run firefly on simulated source spectra from testGalIDs LGal ''' # read in source spectra specin = lgal_sourceSpectra(galid, lib=lib) redshift = specin['meta']['REDSHIFT'] print('z = %f' % redshift) wave = specin['wave'] wave_rest = wave / (1.+redshift) if not dust: flux = specin['flux_nodust_nonoise'] # output firefly file f_specin = f_Source(galid, lib=lib) if not dust: f_firefly = ''.join([UT.dat_dir(), 'spectral_challenge/bgs/', 'myFirefly.', model, '.', model_lib, '.imf_', imf, '.nodust__', f_specin.rsplit('/', 1)[1].rsplit('.fits', 1)[0], '.nodust.hdf5']) ffly = Fitters.myFirefly( Planck13, # comsology model=model, model_lib=model_lib, imf=imf, dust_corr=False, # no dust correction age_lim=[0., Planck13.age(redshift).value], # can't have older populations logZ_lim=[-2.,1.]) mask = ffly.emissionlineMask(wave_rest) ff_fit, ff_prop = ffly.Fit(wave, flux, flux*0.001, redshift, mask=mask, flux_unit=1e-17, f_output=f_firefly, silent=False) print ff_prop['logM_total'] return None
def testGalIDs(): ''' get gal IDs for test set of LGal SAM objects ''' # read in spectral challenge test set filenames set by Rita f_test = ''.join([UT.dat_dir(), 'spectral_challenge/', 'lgal_filenames_testset_BC03_Stellib.txt']) fnames_test = np.loadtxt(f_test, unpack=True, dtype='S', skiprows=1) # get gal ID's from the filename galid_test = [int(fname.split('_')[2]) for fname in fnames_test] return galid_test
def firefly_lgal_bgsSpec(galid, iobs, lib='bc03', obs_sampling='spacefill', model='m11', model_lib='MILES', imf='cha', hpf_mode='on'): ''' run firefly on simulated DESI BGS spectra from testGalIDs LGal ''' obscond = obs_condition(sampling=obs_sampling) if iobs >= obscond.shape[0]: raise ValueError # read in source spectra f_inspec = fits.open(f_Source(galid, lib=lib)) redshift = f_inspec[0].header['REDSHIFT'] # read in simulated DESI bgs spectra f_bgsspec = f_BGSspec(galid, iobs, lib=lib, obs_sampling=obs_sampling, nobs=obscond.shape[0]) if not os.path.isfile(f_bgsspec): raise ValueError('spectra file does not exist') spec_desi = read_spectra(f_bgsspec) gspec = Spec.GSfirefly() gspec.DESIlike(spec_desi, redshift=redshift) gspec.path_to_spectrum = UT.dat_dir() # output firefly file f_bgs = f_BGSspec(galid, iobs, lib=lib, obs_sampling=obs_sampling, nobs=obscond.shape[0]) f_firefly = ''.join([UT.dat_dir(), 'spectral_challenge/bgs/', 'firefly.', model, '.', model_lib, '.imf_', imf, '.dust_', hpf_mode, '__', f_bgs.rsplit('/', 1)[1].rsplit('.fits', 1)[0], '.hdf5']) firefly = Fitters.Firefly(gspec, f_firefly, # output file co.Planck13, # comsology models = model, # model ('m11', 'bc03', 'm09') model_libs = [model_lib], # model library for M11 imfs = [imf], # IMF used ('ss', 'kr', 'cha') hpf_mode = hpf_mode, # uses HPF to dereden the spectrum age_limits = [0, np.log10(co.Planck13.age(redshift).value * 1e9)], Z_limits = [0.001, 4.], wave_limits = [3350., 9000.], suffix=None, downgrade_models = False, data_wave_medium = 'vacuum', use_downgraded_models = False, write_results = True) bestfit = firefly.fit_models_to_data() return None
def firefly_lgal_sourceSpec(galid, dust=True, lib='bc03', model='m11', model_lib='MILES', imf='cha', hpf_mode='on'): ''' run firefly on simulated source spectra from testGalIDs LGal ''' # read in source spectra specin = lgal_sourceSpectra(galid, lib=lib) redshift = specin['meta']['REDSHIFT'] gspec = Spec.GSfirefly() if dust: gspec.generic(specin['wave'], specin['flux_dust_nonoise'], redshift=redshift) else: gspec.generic(specin['wave'], specin['flux_nodust_nonoise'], redshift=redshift) gspec.path_to_spectrum = UT.dat_dir() # output firefly file f_specin = f_Source(galid, lib=lib) if dust: f_firefly = ''.join([UT.dat_dir(), 'spectral_challenge/bgs/', 'firefly.', model, '.', model_lib, '.imf_', imf, '.dust_', hpf_mode, '__', f_specin.rsplit('/', 1)[1].rsplit('.fits', 1)[0], '.hdf5']) else: f_firefly = ''.join([UT.dat_dir(), 'spectral_challenge/bgs/', 'firefly.', model, '.', model_lib, '.imf_', imf, '.dust_', hpf_mode, '__', f_specin.rsplit('/', 1)[1].rsplit('.fits', 1)[0], '.nodust.hdf5']) firefly = Fitters.Firefly(gspec, f_firefly, # output file co.Planck13, # comsology models = model, # model ('m11', 'bc03', 'm09') model_libs = [model_lib], # model library for M11 imfs = [imf], # IMF used ('ss', 'kr', 'cha') hpf_mode = hpf_mode, # uses HPF to dereden the spectrum age_limits = [0, np.log10(co.Planck13.age(redshift).value * 1e9)], wave_limits = [3350., 9000.], suffix=None, downgrade_models = False, data_wave_medium = 'vacuum', Z_limits = [0.001, 4.], use_downgraded_models = False, write_results = True) bestfit = firefly.fit_models_to_data() return None
def f_nonoise(galid, lib='bc03'): ''' retrun noiseless spectra template file name :param galid: galaxy id number :param lib: (default: 'bc03') specify stellar population synthesis library. Options are 'bc03' and 'fsps' ''' if lib == 'bc03': lib_str = 'BC03_Stelib' elif lib == 'fsps': lib_str = 'FSPS_uvmiles' return os.path.join(UT.dat_dir(), 'Lgal', 'templates', 'gal_spectrum_'+str(galid)+'_BGS_template_'+lib_str+'.fits')
def prospector_mockdata(infer_method='dynesty'): ''' ''' prosp = Fitters.Prospector() # mock data tt = np.array([-0.5, 0.3, 3., 12., 1e10]) zred = 0.1 mock_lam = np.linspace(3000, 1e4, 1e3) mock_flux_maggies, _, _ = prosp.model(mock_lam, tt, zred) # convert to 10^-17 ergs/s/cm^2/Ang mock_flux = mock_flux_maggies * 1e17 * UT.c_light() / mock_lam**2 * (3631. * UT.jansky_cgs()) if infer_method == 'dynesty': # run dynamic nested sampling prosp.dynesty_spec(mock_lam, mock_flux, None, zred, nested=True, maxcall_init=50000, maxcall=50000, write=True, output_file=''.join([UT.dat_dir(), 'prospector_dynesty_mock_test.h5'])) elif infer_method == 'emcee': # emcee prosp.emcee_spec(mock_lam, mock_flux, None, zred, write=True, output_file=''.join([UT.dat_dir(), 'prospector_emcee_mock_test.h5']), silent=False) return None
def firefly_LGAL_desiSpec(model='m11', model_lib='MILES', imf='cha', hpf_mode='on'): ''' run firefly on all LGal DESI-like spectra ''' # read in galids f_ids = ''.join([UT.dat_dir(), 'Lgal/galid_BGS_BC03_templates.txt']) galids = np.loadtxt(f_ids, unpack=True, dtype='int') for id in galids: firefly_LGAL_desiSpec_i(id, model=model, model_lib=model_lib, imf=imf, hpf_mode=hpf_mode) return None
def singleSP_myfirefly(iz, age=1., mtot=1e8, zred=0.01): ''' fit the single stellar population file from `singleSP` using firefly ''' z_arr = np.array([0.5, 1.0, 2.0, 10**-1.301, 10**-1.302, 10**-2.301, 10**-2.302, 10**-0.6, 10**-0.9, 10**-1.2, 10**-1.6, 10**-1.9]) f_spec = ''.join([UT.dat_dir(), 'SSP.iz', str(iz), '.age', str(age), '.z', str(zred), '.dat']) wave, flux = np.loadtxt(f_spec, unpack=True, usecols=[0,1]) wave_rest = wave/(1.+zred) err = flux * 0.001 cosmo = FlatLambdaCDM(70., 0.3) ffly = Fitters.myFirefly(cosmo, model='m11', model_lib='MILES', imf='cha', dust_corr=False, # no dust correction age_lim=[0., cosmo.age(zred).value], # can't have older populations logZ_lim=[np.log10(z_arr[iz])-0.1, np.log10(z_arr[iz])+0.1]) mask = ffly.emissionlineMask(wave_rest) ff_fit, ff_prop = ffly.Fit(wave, flux, err, zred, mask=mask, flux_unit=1.) print('total mass = %f' % ff_prop['logM_total']) for i in range(ff_prop['n_ssp']): print('--- SSP %i; weight=%f ---' % (i, ff_prop['weightLight_ssp_'+str(i)])) print('age = %f'% ff_prop['age_ssp_'+str(i)]) print('log Z = %f'% ff_prop['logZ_ssp_'+str(i)]) print('log M_tot = %f' % ff_prop['logM_total_ssp_'+str(i)]) fig = plt.figure() sub = fig.add_subplot(111) sub.plot(ff_fit['wavelength'], ff_fit['flux'], label='SSP') sub.plot(ff_fit['wavelength'], ff_fit['flux_model'], label='myFirefly best-fit') sub.plot(ff_fit['wavelength'], ff_fit['flux'] - ff_fit['flux_model'], label='residual') #sub.plot(wave_rest, flux, c='k', ls=':') sub.set_xlim([3e3, 1e4]) fig.savefig(''.join([UT.fig_dir(), 'myfirefly.SSP.iz', str(iz), '.age', str(age), '.z', str(zred), '.png']), bbox_inches='tight') return None
def prospector_lgal_bgsSpec(galid, iobs, lib='bc03', obs_sampling='spacefill', mask=False, infer_method='dynesty'): ''' run prospector on simulated DESI BGS spectra from testGalIDs LGal ''' obscond = obs_condition(sampling=obs_sampling) if iobs >= obscond.shape[0]: raise ValueError # read in source spectra f_inspec = fits.open(f_Source(galid, lib=lib)) redshift = f_inspec[0].header['REDSHIFT'] # read in simulated DESI bgs spectra f_bgsspec = f_BGSspec(galid, iobs, lib=lib, obs_sampling=obs_sampling, nobs=obscond.shape[0]) if not os.path.isfile(f_bgsspec): raise ValueError('spectra file does not exist') spec_desi = read_spectra(f_bgsspec) wave = np.concatenate([spec_desi.wave[b] for b in ['b', 'r', 'z']]) flux = np.concatenate([spec_desi.flux[b][0] for b in ['b', 'r', 'z']]) # 10-17 ergs/s/cm2/AA flux_unc = np.concatenate([spec_desi.ivar[b][0]**-0.5 for b in ['b', 'r', 'z']]) # output firefly file str_mask = '' if mask: str_mask = '.masked' f_bgs = f_BGSspec(galid, iobs, lib=lib, obs_sampling=obs_sampling, nobs=obscond.shape[0]) f_prosp = ''.join([UT.dat_dir(), 'spectral_challenge/bgs/', 'prospector.', infer_method, str_mask, '__', f_bgs.rsplit('/', 1)[1].rsplit('.fits', 1)[0], '.h5']) prosp = Fitters.Prospector() if infer_method == 'dynesty': # run dynamic nested sampling prosp.dynesty_spec(wave, flux, flux_unc, redshift, mask=mask, nested=True, maxcall_init=25000, maxcall=50000, write=True, output_file=f_prosp) elif infer_method == 'emcee': # emcee prosp.emcee_spec(wave, flux, flux_unc, redshift, mask=mask, write=True, output_file=f_prosp, silent=False) return None
def prospector_lgal_bgsSpec_validate(galid, iobs, lib='bc03', obs_sampling='spacefill', mask=False, infer_method='dynesty'): obscond = obs_condition(sampling=obs_sampling) if iobs >= obscond.shape[0]: raise ValueError # read in source spectra and meta data specin = lgal_sourceSpectra(galid, lib=lib) zred = specin['meta']['REDSHIFT'] # read in simulated DESI bgs spectra _spec_desi = lgal_bgsSpec(galid, iobs, lib=lib, obs_sampling=obs_sampling) spec_desi = {} spec_desi['wave'] = np.concatenate([_spec_desi.wave[b] for b in ['b', 'r', 'z']]) spec_desi['flux'] = np.concatenate([_spec_desi.flux[b][0] for b in ['b', 'r', 'z']]) # 10-17 ergs/s/cm2/AA spec_desi['flux_unc'] = np.concatenate([_spec_desi.ivar[b][0]**-0.5 for b in ['b', 'r', 'z']]) # output firefly file str_mask = '' if mask: str_mask = '.masked' f_bgs = f_BGSspec(galid, iobs, lib=lib, obs_sampling=obs_sampling, nobs=obscond.shape[0]) f_prosp = ''.join([UT.dat_dir(), 'spectral_challenge/bgs/', 'prospector.', infer_method, str_mask, '__', f_bgs.rsplit('/', 1)[1].rsplit('.fits', 1)[0], '.h5']) chain, lnp = UT.readProspector(f_prosp) imax = np.argmax(lnp) i, j = np.unravel_index(imax, lnp.shape) prosp = Fitters.Prospector() tt_map_d = chain[i,j,:] flux_map, _, _ = prosp.model(spec_desi['wave'], tt_map_d, zred) # spectra comparison fig = plt.figure(figsize=(15,5)) sub = fig.add_subplot(111) sub.plot(spec_desi['wave'], spec_desi['flux'], c='k', lw=0.5, label='DESI-like') sub.plot(specin['wave'], specin['flux'], c='C0', lw=1, label='Source') sub.plot(spec_desi['wave'], flux_map, c='C1', lw=1, label='Prospector best-fit') sub.legend(loc='upper right', fontsize=20) sub.set_xlabel('Wavelength [$\AA$]', fontsize=25) sub.set_xlim([spec_desi['wave'].min(), spec_desi['wave'].max()]) sub.set_ylabel('flux [$10^{-17} erg/s/cm^2/\AA$]', fontsize=25) sub.set_ylim([0., 2.*specin['flux'][(specin['wave'] > spec_desi['wave'].min()) & (specin['wave'] < spec_desi['wave'].max())].max()]) fig.savefig(''.join([f_prosp.rsplit('/', 1)[0], '/', '_spectra.', f_prosp.rsplit('/', 1)[1].rsplit('.', 1)[0], '.png']), bbox_inches='tight') # compare inferred properties to input properties gal_input = LGalInput(galid) fig = plt.figure(figsize=(7,4)) sub = fig.add_subplot(111) sub.plot(gal_input['sfh_t'], gal_input['sfh_disk'], color='C0', label='disk') sub.plot(gal_input['sfh_t'], gal_input['sfh_bulge'], color='red', label='bulge') sub.plot(gal_input['sfh_t'], gal_input['sfh_bulge'] + gal_input['sfh_disk'], color='black', label='total') chain_flat = chain.reshape(chain.shape[0] * chain.shape[1], chain.shape[2]) mmed = np.percentile(chain_flat[:,4], [50]) sub.plot([0., 15.], [mmed, mmed], c='k', ls='--', label='Firefly') sub.set_xlabel('Lookback time (Gyr)', fontsize=25) sub.set_xlim([1e-2, 13.]) sub.set_ylabel(r'Mass formed (M$_\odot$)', fontsize=25) sub.set_yscale('log') sub.set_ylim([1e8, 5e10]) fig.savefig(''.join([f_prosp.rsplit('/', 1)[0], '/', '_mstar.', f_prosp.rsplit('/', 1)[1].rsplit('.', 1)[0], '.png']), bbox_inches='tight') return None
def obs_SkyBrightness(sampling='spacefill', overwrite=False): ''' sky brightness of the sampled observing condition ''' # observing condition obscond = obs_condition(sampling=sampling) f_skybright = ''.join([ UT.dat_dir(), 'spectral_challenge/', 'sky_brightness.bgs_mockexp_obscond_testset.', sampling, '.p' ]) if os.path.isfile(f_skybright) and not overwrite: wave, skybrights = pickle.load(open(f_skybright, 'rb')) return wave, skybrights else: from feasibgs import skymodel as Sky specsim_sky = Sky.specsim_initialize('desi') specsim_wave = specsim_sky._wavelength # Ang for i in range(obscond.shape[0]): airmass, seeing, exptime, moonfrac, moonalt, moonsep, sunalt, sunsep = obscond[ i, :] # re-scaled KS contribution specsim_sky.airmass = airmass specsim_sky.moon.moon_phase = np.arccos(2. * moonfrac - 1) / np.pi specsim_sky.moon.moon_zenith = (90. - moonalt) * U.deg specsim_sky.moon.separation_angle = moonsep * U.deg # re-calibrated KS coefficients specsim_sky.moon.KS_CR = 458173.535128 specsim_sky.moon.KS_CM0 = 5.540103 specsim_sky.moon.KS_CM1 = 178.141045 I_ks_rescale = specsim_sky.surface_brightness if sunalt > -20.: import pandas as pd # there is twilight contributions # read in coefficients from Parker fmoon = ''.join( [UT.dat_dir(), 'spectral_challenge/', 'MoonResults.csv']) coeffs = pd.DataFrame.from_csv(fmoon) coeffs.columns = [ 'wl', 'model', 'data_var', 'unexplained_var', ' X2', 'rX2', 'c0', 'c_am', 'tau', 'tau2', 'c_zodi', 'c_isl', 'sol', 'I', 't0', 't1', 't2', 't3', 't4', 'm0', 'm1', 'm2', 'm3', 'm4', 'm5', 'm6', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec', 'c2', 'c3', 'c4', 'c5', 'c6' ] # keep moon models twi_coeffs = coeffs[coeffs['model'] == 'twilight'] coeffs = coeffs[coeffs['model'] == 'moon'] # order based on wavelengths for convenience wave_sort = np.argsort(np.array(coeffs['wl'])) for k in coeffs.keys(): coeffs[k] = np.array(coeffs[k])[wave_sort] for k in twi_coeffs.keys(): twi_coeffs[k] = np.array(twi_coeffs[k])[wave_sort] I_twi = ( twi_coeffs['t0'] * np.abs(sunalt) + # CT2 twi_coeffs['t1'] * np.abs(sunalt)**2 + # CT1 twi_coeffs['t2'] * np.abs(sunsep)**2 + # CT3 twi_coeffs['t3'] * np.abs(sunsep) # CT4 ) * np.exp(-twi_coeffs['t4'] * airmass) + twi_coeffs['c0'] I_twi = np.array(I_twi) / np.pi I_twi_interp = sp.interpolate.interp1d( 10. * np.array(coeffs['wl']), I_twi, fill_value='extrapolate') skybright = I_ks_rescale.value + I_twi_interp( specsim_wave.value) else: skybright = I_ks_rescale.value if i == 0: skybrights = np.zeros((obscond.shape[0], len(skybright))) skybrights[i, :] = skybright pickle.dump([specsim_wave.value, skybrights], open(f_skybright, 'wb')) return specsim_wave.value, skybrights
def mFF_BGSspectra_LGal_FSPS_nodust(galid, iobs, imf='chabrier', obs_sampling='spacefill'): ''' generate spectra from LGal_FSPS_nodust ''' # read source spectra for meta data f_lgal = ''.join([ UT.dat_dir(), 'spectral_challenge/bgs/', 'LGAL.', str(galid), '.FSPS.nodust.imf_', imf, '.hdf5' ]) f_source = h5py.File(f_lgal, 'r') zred = f_source.attrs['zred'] # read bgs spectra f_bgs = ''.join([ f_lgal.rsplit('.hdf5', 1)[0], '.BGS.', obs_sampling, '_obs', str(iobs), '.fits' ]) bgs_spec = UT.readDESIspec(f_bgs) wave_bgs = np.concatenate([bgs_spec['wave_' + b] for b in ['b', 'r', 'z']]) # observed frame flux_bgs = np.concatenate([ bgs_spec['flux_' + b][0] for b in ['b', 'r', 'z'] ]) # 10-17 ergs/s/cm2/AA flux_err_bgs = np.concatenate( [bgs_spec['ivar_' + b][0]**-0.5 for b in ['b', 'r', 'z']]) wavesort = np.argsort(wave_bgs) # sort by wavelenght wave_bgs = wave_bgs[wavesort] flux_bgs = flux_bgs[wavesort] flux_err_bgs = flux_err_bgs[wavesort] ffly = Fitters.myFirefly( Planck13, # comsology model='m11', model_lib='MILES', imf='cha', dust_corr=False, # no dust correction age_lim=[0., 13.], # can't have older populations logZ_lim=[-3., 1.]) mask = ffly.emissionlineMask(wave_bgs / (1. + zred)) f_mff = ''.join([ f_bgs.rsplit('/', 1)[0], '/mFF.', f_bgs.rsplit('/', 1)[1].rsplit('.fits', 1)[0], '.hdf5' ]) ff_fit, ff_prop = ffly.Fit(wave_bgs, flux_bgs, flux_err_bgs, zred, mask=mask, f_output=f_mff, flux_unit=1e-17) print('input: total_mass = %f' % f_source.attrs['logM_total']) print('firefly: total mass = %f' % ff_prop['logM_total']) _ssp_age, _ssp_z, _ssp_mtot = [], [], [] for i in range(ff_prop['n_ssp']): print('--- SSP %i; weight=%f ---' % (i, ff_prop['weightLight_ssp_' + str(i)])) print('age = %f' % ff_prop['age_ssp_' + str(i)]) print('log Z = %f' % ff_prop['logZ_ssp_' + str(i)]) print('log M_tot = %f' % ff_prop['logM_total_ssp_' + str(i)]) _ssp_age.append(ff_prop['age_ssp_' + str(i)]) _ssp_z.append(10**ff_prop['logZ_ssp_' + str(i)]) _ssp_mtot.append(10**ff_prop['logM_total_ssp_' + str(i)]) agesort = np.argsort(_ssp_age) ssp_age = np.array(_ssp_age)[agesort] ssp_z = np.array(_ssp_z)[agesort] ssp_mtot = np.array(_ssp_mtot)[agesort] # validation plot fig = plt.figure(figsize=(12, 10)) gs = mpl.gridspec.GridSpec(2, 2, figure=fig) sub = plt.subplot(gs[0, :]) # flux plot sub.plot(wave_bgs, flux_bgs, c='C0', lw=1, label='LGal BGS spectrum') sub.plot(ff_fit['wavelength'] * (1. + zred), ff_fit['flux_model'], c='C1', label='FIREFLY best-fit') sub.plot(ff_fit['wavelength'] * (1. + zred), ff_fit['flux'] - ff_fit['flux_model'], c='r', label='residual') sub.text(0.05, 0.95, ('$M_\mathrm{tot}=10^{%.2f}; M_\mathrm{firefly} = 10^{%.2f}$' % (f_source.attrs['logM_total'], ff_prop['logM_total'])), ha='left', va='top', transform=sub.transAxes, fontsize=20) sub.set_xlabel('observed-frame wavelength', fontsize=25) sub.set_xlim([3e3, 1e4]) sub.set_ylabel('flux [$erg/s/cm^2/A$]', fontsize=25) sub.legend(loc='upper right', fontsize=20) sub = plt.subplot(gs[1, 0]) # SFH sub.plot(f_source.attrs['tage'], f_source.attrs['sfh_bulge'], c='C0', ls=':', label='Bulge') sub.plot(f_source.attrs['tage'], f_source.attrs['sfh_disk'], c='C0', ls='--', label='Disk') sub.plot(f_source.attrs['tage'], f_source.attrs['sfh_bulge'] + f_source.attrs['sfh_disk'], c='C0', label='Total') sub.plot(ssp_age, ssp_mtot, c='C1') sub.set_xlabel('Lookback Time [$Gyr$]', fontsize=20) sub.set_xlim([0., 13.]) sub.set_ylabel("$M_\mathrm{formed}$", fontsize=25) sub.set_yscale("log") sub.set_ylim([5e6, 5e10]) sub = plt.subplot(gs[1, 1]) # ZH sub.plot(f_source.attrs['tage'], f_source.attrs['Z_bulge'], c='C0', ls=':', label='Bulge') sub.plot(f_source.attrs['tage'], f_source.attrs['Z_disk'], c='C0', ls='--', label='Disk') sub.plot(ssp_age, ssp_z, c='C1') sub.set_xlabel('Lookback Time [$Gyr$]', fontsize=20) sub.set_xlim([0., 13.]) sub.set_ylabel("metallicity, $Z$", fontsize=25) sub.set_yscale('log') sub.set_ylim([1e-3, 1e-1]) fig.subplots_adjust(wspace=0.25, hspace=0.25) fig.savefig(''.join([f_mff.rsplit('.hdf5', 1)[0], '.png']), bbox_inches='tight') plt.close() return None
def BGSspectra_LGal_FSPS_nodust(galid, iobs=0, imf='chabrier', obs_sampling='spacefill', validate=False): ''' ''' from feasibgs import forwardmodel as FM # read in galaxy source spectrum and metadata f_source = ''.join([ UT.dat_dir(), 'spectral_challenge/bgs/', 'LGAL.', str(galid), '.FSPS.nodust.imf_', imf, '.hdf5' ]) fh5 = h5py.File(f_source, 'r') wave = fh5['wavelength'].value flux_total = fh5['flux'].value flux_disk = fh5['flux_disk'].value flux_bulge = fh5['flux_bulge'].value zred = fh5.attrs['zred'] logM_disk = fh5.attrs['logM_disk'] logM_bulge = fh5.attrs['logM_bulge'] logM_total = fh5.attrs['logM_total'] zred = fh5.attrs['zred'] t_lb = fh5.attrs['tage'] # lookback time (age) sfh_disk = fh5.attrs['sfh_disk'] sfh_bulge = fh5.attrs['sfh_bulge'] Z_disk = fh5.attrs['Z_disk'] Z_bulge = fh5.attrs['Z_bulge'] fh5.close() # BGS -like spectrum wmin, wmax = 3523.0, 9923.0 wave_source = np.arange(wmin, wmax, 0.2) flux_source_interp = sp.interpolate.interp1d(wave, flux_total * 1e17, fill_value='extrapolate') flux_source = flux_source_interp(wave_source) # read in observing conditions obscond = obs_condition(sampling=obs_sampling) airmass, seeing, exptime, _, _, _, _, _ = obscond[iobs, :] # read in sky surface brightness w_sky, skybrights = obs_SkyBrightness(sampling=obs_sampling) skybright = np.clip( skybrights[iobs, :], 0, None) * 1e-17 * U.erg / U.angstrom / U.arcsec**2 / U.cm**2 / U.second f_bgs = ''.join([ f_source.rsplit('.hdf5', 1)[0], '.BGS.', obs_sampling, '_obs', str(iobs), '.fits' ]) # simulate BGS spectra fdesi = FM.fakeDESIspec() # BGS spectra output file bgs_spec = fdesi.simExposure(wave_source, np.atleast_2d(flux_source), exptime=exptime, airmass=airmass, seeing=seeing, skycondition={ 'name': 'input', 'sky': skybright, 'wave': w_sky }, filename=f_bgs) if not validate: return None # validation plot fig = plt.figure(figsize=(12, 10)) gs = mpl.gridspec.GridSpec(2, 2, figure=fig) sub = plt.subplot(gs[0, :]) # flux plot for band in ['b', 'r', 'z']: sub.plot(bgs_spec.wave[band], 1e-17 * bgs_spec.flux[band][0], color='gray', lw=0.25) for m, fi in zip(sfh_bulge, flux_bulge): if m > 0.: sub.plot(wave, fi, ls='--', lw=0.1) sub.plot(wave, np.sum(flux_bulge, axis=0), c='C0', ls='--', label='Bulge') for m, fi in zip(sfh_disk, flux_disk): if m > 0.: sub.plot(wave, fi, ls='--', lw=0.1) sub.plot(wave, fi, lw=0.1) sub.plot(wave, np.sum(flux_disk, axis=0), c='C1', label='Disk') sub.plot(wave, flux_total, c='k', ls=':', label='Total') sub.set_xlabel('observed-frame wavelength', fontsize=25) sub.set_xlim([3e3, 1e4]) sub.set_ylabel('flux [$erg/s/cm^2/A$]', fontsize=25) sub.set_ylim([-1e-18, 1e-15]) sub.legend(loc='upper right', fontsize=20) sub = plt.subplot(gs[1, 0]) # SFH sub.plot(t_lb, sfh_bulge, c='C0', label='Bulge') sub.plot(t_lb, sfh_disk, c='C1', label='Disk') sub.text( 0.05, 0.95, ('$M_\mathrm{tot}=10^{%.1f}, M_\mathrm{disk}=10^{%.1f}, M_\mathrm{bulge}=10^{%.1f}$' % (logM_total, logM_disk, logM_bulge)), ha='left', va='top', transform=sub.transAxes, fontsize=15) sub.set_xlabel('Lookback Time [$Gyr$]', fontsize=20) sub.set_xlim([0., 13.]) sub.set_ylabel("$M_\mathrm{formed}$", fontsize=25) sub.set_yscale("log") sub.set_ylim([5e6, 5e10]) sub = plt.subplot(gs[1, 1]) # ZH sub.plot(t_lb, Z_bulge, c='C0', label='Bulge') sub.plot(t_lb, Z_disk, c='C1', label='Disk') sub.set_xlabel('Lookback Time [$Gyr$]', fontsize=20) sub.set_xlim([0., 13.]) sub.set_ylabel("metallicity, $Z$", fontsize=25) sub.set_yscale('log') sub.set_ylim([1e-3, 1e-1]) fig.subplots_adjust(wspace=0.25, hspace=0.25) fig.savefig(f_bgs.rsplit('.hdf5', 1)[0] + '.png', bbox_inches='tight') plt.close() return None
def singleSP_SFH_myfirefly(iz, zred=0.01): ''' construct spectra with single metallicity, with eagle SFH, no dust, no nonsense ''' z_arr = np.array([0.5, 1.0, 2.0, 10**-1.301, 10**-1.302, 10**-2.301, 10**-2.302, 10**-0.6, 10**-0.9, 10**-1.2, 10**-1.6, 10**-1.9]) z_strs = np.array(['z001', 'z002', 'z004', 'z0001.bhb', 'z0001.rhb', 'z10m4.bhb', 'z10m4.rhb', 'z-0.6', 'z-0.9', 'z-1.2', 'z-1.6', 'z-1.9']) z_metal = z_arr[iz] # read in SFH and M_* f_eagle = h5py.File(''.join([UT.dat_dir(), '0EAGLE_SFRHs.hdf5']), 'r') i_zmid = np.abs(z_arr[iz] - 10**np.array(logZ_mid)).argmin() logZ = logZ_mid[i_zmid] t = age_bounds[:,1] dt = age_bounds[:,2] - age_bounds[:,0] sfh = f_eagle['SFRH'].value[0,:,i_zmid] f_ssp = os.environ['STELLARPOPMODELS_DIR']+'/data/SSP_M11_MILES/ssp_M11_MILES.cha'+z_strs[iz] model_age, model_wave, model_flux = np.loadtxt(f_ssp, unpack=True, usecols=[0,2,3]) age_uniq = np.sort(np.unique(model_age)) age_bin = np.concatenate([[0], 0.5*(age_uniq[1:] + age_uniq[:-1])]) mtot_bin, flux_bin = [], [] for i_a in range(len(age_bin)-1): in_agebin = ((14.-t >= age_bin[i_a]) & (14-t < age_bin[i_a+1])) mtot_i = np.sum(dt[in_agebin] * sfh[in_agebin] * 1e9) mtot_bin.append(mtot_i) assert np.sum(mtot_bin) == np.sum(sfh * dt * 1e9) print('log M_tot = %f' % np.log10(np.sum(mtot_bin))) # read in spectra f_spec = ''.join([UT.dat_dir(), 'SSP_SFH.iz', str(iz), '.z', str(zred), '.dat']) wave, flux = np.loadtxt(f_spec, unpack=True, usecols=[0,1]) wave_rest = wave/(1.+zred) err = flux * 0.001 cosmo = FlatLambdaCDM(70., 0.3) ffly = Fitters.myFirefly(cosmo, model='m11', model_lib='MILES', imf='cha', dust_corr=False, # no dust correction age_lim=[0., cosmo.age(zred).value], # can't have older populations logZ_lim=[np.log10(z_arr[iz])-0.1, np.log10(z_arr[iz])+0.1]) mask = ffly.emissionlineMask(wave_rest) ff_fit, ff_prop = ffly.Fit(wave, flux, err, zred, mask=mask, flux_unit=1.) print('total mass = %f' % ff_prop['logM_total']) ssp_age_bin0, ssp_age_bin1 = [], [] ssp_mtot = [] for i in range(ff_prop['n_ssp']): print('--- SSP %i; weight=%f ---' % (i, ff_prop['weightLight_ssp_'+str(i)])) print('age = %f'% ff_prop['age_ssp_'+str(i)]) print('log Z = %f'% ff_prop['logZ_ssp_'+str(i)]) print('log M_tot = %f' % ff_prop['logM_total_ssp_'+str(i)]) i_age_bin = np.abs(age_uniq - ff_prop['age_ssp_'+str(i)]).argmin() ssp_age_bin0.append(age_bin[i_age_bin]) ssp_age_bin1.append(age_bin[i_age_bin+1]) ssp_mtot.append(10**ff_prop['logM_total_ssp_'+str(i)]) fig = plt.figure(figsize=(12,4)) sub = fig.add_subplot(121) sub.bar(age_bin[:-1], mtot_bin, width=age_bin[:-1]-age_bin[1:], alpha=0.75) sub.bar(ssp_age_bin0, ssp_mtot, width=np.array(ssp_age_bin0)-np.array(ssp_age_bin1), alpha=0.75) sub.set_xlabel('Lookback Time [Gyr]', fontsize=25) sub.set_xlim([0., 14]) sub.set_ylabel("$M_\mathrm{form}$", fontsize=25) sub.set_yscale("log") sub.set_ylim([1e7, 5e9]) sub = fig.add_subplot(122) sub.plot(ff_fit['wavelength'], ff_fit['flux'], label='SSP') sub.plot(ff_fit['wavelength'], ff_fit['flux_model'], label='myFirefly best-fit') sub.plot(ff_fit['wavelength'], ff_fit['flux'] - ff_fit['flux_model'], label='residual') #sub.plot(wave_rest, flux, c='k', ls=':') sub.set_xlim([3e3, 1e4]) fig.savefig(''.join([UT.fig_dir(), 'myfirefly.SSP_SFH.iz', str(iz), '.z', str(zred), '.png']), bbox_inches='tight') return None
def LGalInput(galid): f_input = ''.join([UT.dat_dir(), 'Lgal/gal_inputs/', 'gal_input_' + str(galid) + '_BGS_template_FSPS_uvmiles.csv']) gal_input = Table.read(f_input, delimiter=' ') return gal_input
def singleSP_SFH(iz, zred=0.01): ''' construct spectra with single metallicity, with eagle SFH, no dust, no nonsense ''' z_arr = np.array([0.5, 1.0, 2.0, 10**-1.301, 10**-1.302, 10**-2.301, 10**-2.302, 10**-0.6, 10**-0.9, 10**-1.2, 10**-1.6, 10**-1.9]) z_strs = np.array(['z001', 'z002', 'z004', 'z0001.bhb', 'z0001.rhb', 'z10m4.bhb', 'z10m4.rhb', 'z-0.6', 'z-0.9', 'z-1.2', 'z-1.6', 'z-1.9']) z_metal = z_arr[iz] # read in SFH and M_* f_eagle = h5py.File(''.join([UT.dat_dir(), '0EAGLE_SFRHs.hdf5']), 'r') i_zmid = np.abs(z_arr[iz] - 10**np.array(logZ_mid)).argmin() logZ = logZ_mid[i_zmid] t = age_bounds[:,1] dt = age_bounds[:,2] - age_bounds[:,0] sfh = f_eagle['SFRH'].value[0,:,i_zmid] f_ssp = os.environ['STELLARPOPMODELS_DIR']+'/data/SSP_M11_MILES/ssp_M11_MILES.cha'+z_strs[iz] model_age, model_wave, model_flux = np.loadtxt(f_ssp, unpack=True, usecols=[0,2,3]) age_uniq = np.sort(np.unique(model_age)) age_bin = np.concatenate([[0], 0.5*(age_uniq[1:] + age_uniq[:-1])]) mtot_bin, flux_bin = [], [] for i_a in range(len(age_bin)-1): in_agebin = ((14.-t >= age_bin[i_a]) & (14-t < age_bin[i_a+1])) mtot_i = np.sum(dt[in_agebin] * sfh[in_agebin] * 1e9) mtot_bin.append(mtot_i) isage = (model_age == age_uniq[i_a]) flux_i = model_flux[isage] * mtot_i flux_bin.append(flux_i) if i_a == 0: wave = model_wave[isage] # wavelength flux = flux_i else: flux += flux_i flux_bin = np.array(flux_bin) cosmo = FlatLambdaCDM(70., 0.3) wave *= (1. + zred) flux /= (4.*np.pi * cosmo.luminosity_distance(zred).to(U.cm).value**2) flux_bin /= (4.*np.pi * cosmo.luminosity_distance(zred).to(U.cm).value**2) assert np.sum(mtot_bin) == np.sum(sfh * dt * 1e9) print('log M_tot = %f' % np.log10(np.sum(mtot_bin))) fig = plt.figure(figsize=(12,4)) sub = fig.add_subplot(121) sub.bar(age_bin[:-1], mtot_bin, width=age_bin[:-1]-age_bin[1:]) sub.bar(14.-age_bounds[:,0], sfh * dt * 1e9, width=dt) sub.set_xlabel('Lookback Time [Gyr]', fontsize=25) sub.set_xlim([0., 14]) sub.set_ylabel("$M_\mathrm{form}$", fontsize=25) sub.set_yscale("log") sub.set_ylim([1e7, 5e9]) sub = fig.add_subplot(122) for i in range(flux_bin.shape[0]): sub.plot(wave, flux_bin[i]) sub.plot(wave, flux, c='k', lw=3) sub.set_xlabel('observed-frame wavelength [$A$]', fontsize=20) sub.set_xlim([3500., 1e4]) sub.set_ylabel('flux [$ergs/s/cm^2/A$]', fontsize=20) fig.savefig(''.join([UT.fig_dir(), 'SSP_SFH.iz', str(iz), '.z', str(zred), '.png']), bbox_inches='tight') # save spectra f_spec = ''.join([UT.dat_dir(), 'SSP_SFH.iz', str(iz), '.z', str(zred), '.dat']) np.savetxt(f_spec, np.vstack([wave, flux]).T) return None
def myFirefly_lgal_sourceSpec_validate(galid, dust=False, lib='bc03', obs_sampling='spacefill', model='m11', model_lib='MILES', imf='kr'): obscond = obs_condition(sampling=obs_sampling) if iobs >= obscond.shape[0]: raise ValueError # read in source spectra and meta data specin = lgal_sourceSpectra(galid, lib=lib) zred = specin['meta']['REDSHIFT'] # read firefly file f_specin = f_Source(galid, lib=lib) if not dust: f_firefly = ''.join([UT.dat_dir(), 'spectral_challenge/bgs/', 'myFirefly.', model, '.', model_lib, '.imf_', imf, '.nodust__', f_specin.rsplit('/', 1)[1].rsplit('.fits', 1)[0], '.nodust.hdf5']) fh = h5py.File(f_firefly, 'r') ff_fit = {} for k in fh.keys(): ff_fit[k] = fh[k].value ff_prop = {} for k in fh.attrs.keys(): ff_prop[k] = fh.attrs[k] # spectra comparison fig = plt.figure(figsize=(15,5)) sub = fig.add_subplot(111) if not dust: sub.plot(specin['wave'], specin['flux_nodust_nonoise'], c='C0', lw=1, label='Source') sub.plot(ff_fit['wavelength'] * (1. + zred), ff_fit['flux_model'], c='C1', label='FIREFLY best-fit') sub.plot(ff_fit['wavelength'] * (1. + zred), ff_fit['flux'] - ff_fit['flux_model'], c='r', label='residual') sub.legend(loc='upper right', fontsize=20) sub.set_xlabel('Wavelength [$\AA$]', fontsize=25) sub.set_xlim([3.3e3, 9.8e3]) sub.set_ylabel('flux [$10^{-17} erg/s/cm^2/\AA$]', fontsize=25) sub.set_ylim([0., 1.5*specin['flux_nodust_nonoise'][(specin['wave'] > 3e3) & (specin['wave'] < 1e4)].max()]) fig.savefig(''.join([f_firefly.rsplit('/', 1)[0], '/', '_spectra.', f_firefly.rsplit('/', 1)[1].rsplit('.', 1)[0], '.png']), bbox_inches='tight') # compare inferred properties to input properties gal_input = LGalInput(galid) print('input: total_mass = %f' % np.sum(gal_input['sfh_disk'] + gal_input['sfh_bulge'])) print('firefly: total mass = %f' % ff_prop['logM_total']) ssp_age, ssp_z, ssp_mtot = [], [], [] for i in range(ff_prop['n_ssp']): print('--- SSP %i; weight=%f ---' % (i, ff_prop['weightLight_ssp_'+str(i)])) print('age = %f'% ff_prop['age_ssp_'+str(i)]) print('log Z = %f'% ff_prop['logZ_ssp_'+str(i)]) print('log M_tot = %f' % ff_prop['logM_total_ssp_'+str(i)]) ssp_age.append(ff_prop['age_ssp_'+str(i)]) ssp_z.append(10**ff_prop['logZ_ssp_'+str(i)]) ssp_mtot.append(10**ff_prop['logM_total_ssp_'+str(i)]) fig = plt.figure(figsize=(12,4)) sub = fig.add_subplot(121) sub.plot(gal_input['sfh_t'], gal_input['sfh_disk'], color='C0', label='disk') sub.plot(gal_input['sfh_t'], gal_input['sfh_bulge'], color='red', label='bulge') sub.plot(gal_input['sfh_t'], gal_input['sfh_bulge'] + gal_input['sfh_disk'], color='black', label='total') sub.plot(ssp_age, ssp_mtot) print ssp_age print np.log10(ssp_mtot) sub.set_xlabel('Lookback time (Gyr)', fontsize=25) sub.set_xlim([1e-2, 13.]) sub.set_ylabel(r'Mass formed (M$_\odot$)', fontsize=25) sub.set_yscale('log') sub.set_ylim([1e7, 5e10]) sub = fig.add_subplot(122) sub.plot(gal_input['sfh_t'], gal_input['Z_disk'], label='disk') sub.plot(gal_input['sfh_t'], gal_input['Z_bulge'], color='red', label='bulge') sub.plot([0., 0.], [0., 0.], c='k', ls='-', label='total') sub.plot(ssp_age, ssp_z) sub.legend(fontsize=15, ncol=2) sub.set_xlabel('Lookback time (Gyr)', fontsize=25) sub.set_xlim([1e-2, 13.]) sub.set_ylabel('Metallicity', fontsize=25) sub.set_yscale('log') sub.set_ylim([0., 0.1]) fig.savefig(''.join([f_firefly.rsplit('/', 1)[0], '/', '_mstar.', f_firefly.rsplit('/', 1)[1].rsplit('.', 1)[0], '.png']), bbox_inches='tight') return None
def fit_test(galid): cosmo = co.Planck13 #spec = gs.GalaxySpectrumFIREFLY(None, milky_way_reddening=True) # read in source spectra f_s = ''.join([ UT.dat_dir(), 'Lgal/templates/', 'gal_spectrum_', str(galid), '_BGS_template_BC03_Stelib.fits' ]) f_inspec = fits.open(f_s) hdr = f_inspec[0].header specin = f_inspec[1].data meta = {} for k in hdr.keys(): meta[k] = hdr[k] zred = meta['REDSHIFT'] f_input = ''.join([ UT.dat_dir(), 'Lgal/gal_inputs/', 'gal_input_', str(galid), '_BGS_template_FSPS_uvmiles.csv' ]) gal_input = Table.read(f_input, delimiter=' ') spec_in = {} spec_in['wave'] = specin['wave'] #flux = specin['flux_dust_nonoise'] * u.Watt / u.AA / u.m**2 #from W/A/m2 to 10e-17 erg/s/cm2/A #flux = flux.to(1e-17*u.erg/u.s/u.cm**2/u.AA) spec_in[ 'flux_dust_nonoise'] = specin['flux_dust_nonoise'] * 1e-4 * 1e7 * 1e17 spec_in['flux_nodust_nonoise'] = specin[ 'flux_nodust_nonoise'] * 1e-4 * 1e7 * 1e17 gspec = Spec.GSfirefly() gspec.generic(spec_in['wave'], spec_in['flux_nodust_nonoise'], redshift=zred) gspec.path_to_spectrum = UT.dat_dir() outputfile = 'test.fits' bestfit = spm.StellarPopulationModel(gspec, outputfile, cosmo, models='m11', model_libs=['MILES'], imfs=['cha'], hpf_mode='on', age_limits=[0., 15.], downgrade_models=False, data_wave_medium='vacuum', Z_limits=[0.001, 4.], wave_limits=[3350., 9000.], use_downgraded_models=False, write_results=True) bestfit.fit_models_to_data() keys = [ 'age_lightW', 'age_massW', 'metallicity_lightW', 'metallicity_massW', 'stellar_mass' ] #, 'HIERARCH stellar_mass'] units = [ 'Age_unit', 'Age_unit', 'Metallicity_unit', 'Metallicity_unit', 'Mass_unit' ] #, 'Mass_unit'] #for k, un in zip(keys, units): # print('%s, %s = %f' % (k, bestfit.thdulist[1].header[un], bestfit.thdulist[1].header[k])) print('redshift = %f' % zred) print('input log M*= %f' % np.log10( np.sum(gal_input['sfh_disk']) + np.sum(gal_input['sfh_bulge']))) print(np.log10(bestfit.averages['stellar_mass'])) print(bestfit.thdulist[1].header['stellar_mass']) print(bestfit.thdulist[1].header['total_mass']) plt.plot(bestfit.thdulist[1].data['wavelength'], bestfit.thdulist[1].data['original_data']) plt.plot(bestfit.thdulist[1].data['wavelength'], bestfit.thdulist[1].data['firefly_model'], ls='--') plt.ylim([0., 2.]) plt.savefig('test' + str(galid) + '.png') plt.close() return None
def firefly_Mstar(lib='bc03', obs_sampling='spacefill', model='m11', model_lib='MILES', imf='cha', hpf_mode='on'): ''' see how well Mstar inferred from firefly reproduces the input mstar ''' obscond = obs_condition(sampling=obs_sampling) galids = testGalIDs() obs = [0]#range(8) mtot_ffly_source, mtot_ffly_source_nodust, mtot_ffly_obs = [], [], [] mstar_ffly_source, mstar_ffly_source_nodust, mstar_ffly_obs = [], [], [] mtot_input, mdisk_input, mbulg_input = [], [], [] for iobs in obs: mstar_ffly, mtot_ffly = [], [] for galid in galids: # read firefly fitting output f_bgs = f_BGSspec(galid, iobs, lib=lib, obs_sampling=obs_sampling, nobs=obscond.shape[0]) f_firefly = ''.join([UT.dat_dir(), 'spectral_challenge/bgs/', 'firefly.', model, '.', model_lib, '.imf_', imf, '.dust_', hpf_mode, '__', f_bgs.rsplit('/', 1)[1].rsplit('.fits', 1)[0], '.hdf5']) ffly_out, ffly_prop = UT.readFirefly(f_firefly) mstar_ffly.append(10**ffly_prop['stellar_mass']) if iobs == 0: gal_input = LGalInput(galid) mdisk_input.append(np.sum(gal_input['sfh_disk'])) mbulg_input.append(np.sum(gal_input['sfh_bulge'])) mtot_input.append(np.sum(gal_input['sfh_disk'])+np.sum(gal_input['sfh_bulge'])) # source firefly file f_specin = f_Source(galid, lib=lib) f_firefly_s = ''.join([UT.dat_dir(), 'spectral_challenge/bgs/', 'firefly.', model, '.', model_lib, '.imf_', imf, '.dust_', hpf_mode, '__', f_specin.rsplit('/', 1)[1].rsplit('.fits', 1)[0], '.hdf5']) ffly_out, ffly_prop = UT.readFirefly(f_firefly_s) mtot_ffly_source.append(10**ffly_prop['total_mass']) mstar_ffly_source.append(10**ffly_prop['stellar_mass']) # source no dust firefly file f_firefly_s = ''.join([UT.dat_dir(), 'spectral_challenge/bgs/', 'firefly.', model, '.', model_lib, '.imf_', imf, '.dust_', hpf_mode, '__', f_specin.rsplit('/', 1)[1].rsplit('.fits', 1)[0], '.nodust.hdf5']) ffly_out, ffly_prop = UT.readFirefly(f_firefly_s) mtot_ffly_source_nodust.append(10**ffly_prop['total_mass']) mstar_ffly_source_nodust.append(10**ffly_prop['stellar_mass']) mtot_ffly_obs.append(mstar_ffly) mstar_ffly_obs.append(mstar_ffly) fig = plt.figure(figsize=(7,7)) sub = fig.add_subplot(111) sub.hist(np.log10(mtot_input), range=(9,12), bins=20, histtype='step', color='k', linewidth=2, label='input') sub.hist(np.log10(mstar_ffly_source), range=(9,12), bins=20, histtype='step', color='k', linewidth=1, linestyle=':', label='source') sub.hist(np.log10(mstar_ffly_source_nodust), range=(9,12), bins=20, histtype='step', color='r', linewidth=1, linestyle=':', label='source (no dust)') for iobs in obs: sub.hist(np.log10(mstar_ffly_obs[iobs]), range=(9,12), bins=20, histtype='step', color='C'+str(iobs), linewidth=1, label=r'bgs; $i_\mathrm{obs}='+str(iobs+1)+'$') sub.set_xlabel(r'$\log(\,M_*$ [$M_\odot$]\,)', fontsize=25) sub.set_xlim([9, 12]) sub.legend(loc='upper right', frameon=True, fontsize=20) fig.savefig(''.join([UT.fig_dir(), 'mstar_hist.', f_firefly.rsplit('/', 1)[1].rsplit('__', 1)[0], '.png']), bbox_inches='tight') fig = plt.figure(figsize=(7,7)) sub = fig.add_subplot(111) sub.scatter(mtot_input, mtot_ffly_source, s=10, color='k', label='source') sub.scatter(mtot_input, mtot_ffly_source_nodust, s=10, color='r', label='source (no dust)') for iobs in obs: sub.scatter(mtot_input, mtot_ffly_obs[iobs], s=5, color='C'+str(iobs), label=r'bgs; $i_\mathrm{obs}='+str(iobs+1)+'$') sub.plot([1e8, 1e12], [1e8,1e12], c='k', ls='--') sub.set_xlabel(r'$M_*^\mathrm{(input)}$ [$M_\odot$]', fontsize=25) sub.set_xscale('log') sub.set_xlim([1e8, 1e12]) sub.set_ylabel(r'$M_*^\mathrm{(firefly)}$ [$M_\odot$]', fontsize=25) sub.set_yscale('log') sub.set_ylim([1e8, 1e12]) sub.legend(loc='upper left', markerscale=5, handletextpad=0, fontsize=20) fig.savefig(''.join([UT.fig_dir(), 'mstar_comparison.', f_firefly.rsplit('/', 1)[1].rsplit('__', 1)[0], '.png']), bbox_inches='tight') fig = plt.figure(figsize=(7,7)) sub = fig.add_subplot(111) sub.hist(np.log10(mtot_input) - np.log10(mstar_ffly_source), range=(-1,5), bins=20, color='k', histtype='stepfilled', alpha=0.5, label='source') sub.hist(np.log10(mtot_input) - np.log10(mstar_ffly_source_nodust), range=(-1,5), bins=20, color='r', histtype='stepfilled', alpha=0.5, label='source (no dust)') for iobs in obs: sub.hist(np.log10(mtot_input) - np.log10(mstar_ffly_obs[iobs]), range=(-1,5), bins=20, histtype='stepfilled', alpha=0.5, color='C'+str(iobs), label=r'bgs; $i_\mathrm{obs}='+str(iobs+1)+'$') sub.set_xlabel(r'$\log(\,M_*^\mathrm{(input)}\,)-\,\log(\,M_*^\mathrm{(firefly)}\,)$ ', fontsize=25) sub.set_xlim([-1, 5]) sub.legend(loc='upper right', fontsize=20) fig.savefig(''.join([UT.fig_dir(), 'dmstar_hist.', f_firefly.rsplit('/', 1)[1].rsplit('__', 1)[0], '.png']), bbox_inches='tight') return None
def LGal_FSPS_nodust(galid, imf='chabrier', validate=False): ''' simplest spectra. No dust. No emission lines. No nothing. :params galid: id of galaxy in the GQP spectral challenge test set :params iobs: index of observing condition :params imf: (default: chabrier) imf of the SSP in FSPS forward model :params obs_sampling: (default: obs_sampling) sampling strategy of the observing parameters :params validate: (default: False) if true generate plots that validate the spectra ''' # get Lgal galaxy SF and Z histories f_input = ''.join([ UT.dat_dir(), 'Lgal/gal_inputs/', 'gal_input_', str(galid), '_BGS_template_FSPS_uvmiles.csv' ]) lgal = np.loadtxt(f_input, skiprows=1, unpack=True, delimiter=' ') t_lb = lgal[0] # lookback time [Gyr] sfh_disk = lgal[2] # M* formed in disk at t_lb Z_disk = lgal[4] # Z of disk at t_lb sfh_bulge = lgal[3] # M* formed in bulge at t_lb Z_bulge = lgal[5] # Z of bulge at t_lb logM_disk = np.log10(np.sum(sfh_disk)) logM_bulge = np.log10(np.sum(sfh_bulge)) logM_total = np.log10(np.sum(sfh_disk) + np.sum(sfh_bulge)) print('disk: log(Mformed) = %f' % logM_disk) print('bulge: log(Mformed) = %f' % logM_bulge) print('total: log(Mformed) = %f' % logM_total) # get redshift f_lgal = fits.open(''.join([ UT.dat_dir(), 'Lgal/templates/', 'gal_spectrum_' + str(galid) + '_BGS_template_FSPS_uvmiles.fits' ])) zred = f_lgal[0].header['REDSHIFT'] # disk contribution wave_rest, lum_disk = FOMO.FSPS_nodust(t_lb, sfh_disk, Z_disk, imf=imf) wave, flux_disk = FOMO.zSpectrum(wave_rest, lum_disk, zred, cosmo=Planck13) # bulge contribution _, lum_bulge = FOMO.FSPS_nodust(t_lb, sfh_bulge, Z_bulge, imf=imf) wave, flux_bulge = FOMO.zSpectrum(wave_rest, lum_bulge, zred, cosmo=Planck13) flux_total = np.sum(flux_disk, axis=0) + np.sum(flux_bulge, axis=0) # write out galaxy source spectrum f_output = ''.join([ UT.dat_dir(), 'spectral_challenge/bgs/', 'LGAL.', str(galid), '.FSPS.nodust.imf_', imf, '.hdf5' ]) fh5 = h5py.File(f_output, 'w') # store metadata fh5.attrs['logM_disk'] = logM_disk fh5.attrs['logM_bulge'] = logM_bulge fh5.attrs['logM_total'] = logM_total fh5.attrs['tage'] = t_lb # lookback time (age) fh5.attrs['sfh_disk'] = sfh_disk fh5.attrs['sfh_bulge'] = sfh_bulge fh5.attrs['Z_disk'] = Z_disk fh5.attrs['Z_bulge'] = Z_bulge fh5.attrs['zred'] = zred fh5.create_dataset('wavelength_rest', data=wave_rest) fh5.create_dataset('wavelength', data=wave) # observe-frame wavelength fh5.create_dataset('flux', data=flux_total) # flux of spectrum [erg/s/cm^2/A] fh5.create_dataset('flux_disk', data=flux_disk) # flux of disk SSPs fh5.create_dataset('flux_bulge', data=flux_bulge) # flux of bulge SSPs fh5.close() if not validate: return None # validation plot fig = plt.figure(figsize=(12, 10)) gs = mpl.gridspec.GridSpec(2, 2, figure=fig) sub = plt.subplot(gs[0, :]) # flux plot for m, fi in zip(sfh_bulge, flux_bulge): if m > 0.: sub.plot(wave, fi, ls='--', lw=0.1) sub.plot(wave, np.sum(flux_bulge, axis=0), c='C0', ls='--', label='Bulge') for m, fi in zip(sfh_disk, flux_disk): if m > 0.: sub.plot(wave, fi, ls='--', lw=0.1) sub.plot(wave, fi, lw=0.1) sub.plot(wave, np.sum(flux_disk, axis=0), c='C1', label='Disk') sub.plot(wave, flux_total, c='k', ls=':', label='Total') sub.set_xlabel('observed-frame wavelength', fontsize=25) sub.set_xlim([3e3, 1e4]) sub.set_ylabel('flux [$erg/s/cm^2/A$]', fontsize=25) sub.set_ylim([-1e-18, 1e-15]) sub.legend(loc='upper right', fontsize=20) sub = plt.subplot(gs[1, 0]) # SFH sub.plot(t_lb, sfh_bulge, c='C0', label='Bulge') sub.plot(t_lb, sfh_disk, c='C1', label='Disk') sub.text( 0.05, 0.95, ('$M_\mathrm{tot}=10^{%.1f}, M_\mathrm{disk}=10^{%.1f}, M_\mathrm{bulge}=10^{%.1f}$' % (logM_total, logM_disk, logM_bulge)), ha='left', va='top', transform=sub.transAxes, fontsize=15) sub.set_xlabel('Lookback Time [$Gyr$]', fontsize=20) sub.set_xlim([0., 13.]) sub.set_ylabel("$M_\mathrm{formed}$", fontsize=25) sub.set_yscale("log") sub.set_ylim([5e6, 5e10]) sub = plt.subplot(gs[1, 1]) # ZH sub.plot(t_lb, Z_bulge, c='C0', label='Bulge') sub.plot(t_lb, Z_disk, c='C1', label='Disk') sub.set_xlabel('Lookback Time [$Gyr$]', fontsize=20) sub.set_xlim([0., 13.]) sub.set_ylabel("metallicity, $Z$", fontsize=25) sub.set_yscale('log') sub.set_ylim([1e-3, 1e-1]) fig.subplots_adjust(wspace=0.25, hspace=0.25) fig.savefig(f_output.rsplit('.hdf5', 1)[0] + '.png', bbox_inches='tight') plt.close() return None
def Lgal_nonoisePhoto(lib='bc03', dust=False, overwrite=False, validate=False): ''' generate noiseless photometry from noiseless spectral_challenge Lgal spectra generated by Rita. Super simple code that convolves the spectra with the bandpass decam g, r, z, W1, W2, W3, W4 filtes. ''' fsource = f_nonoise(4, lib=lib) fsource = os.path.basename(fsource).rsplit('.', 1)[0].rsplit('_BGS_template_')[1] if dust: str_dust = 'dust' else: str_dust = 'nodust' fphot = os.path.join(UT.dat_dir(), 'spectral_challenge', 'bgs','photo.%s.%s.nonoise.dat' % (fsource, str_dust)) if os.path.isfile(fphot) and not overwrite: _mags = np.loadtxt(fphot, unpack=True, skiprows=1, usecols=range(1,8)) mags = _mags.T else: galids = np.unique(testGalIDs()) # IDs of spectral_challenge galaxies fluxes = np.zeros((len(galids), 8)) fluxes[:,0] = galids for i, gid in enumerate(galids): # read ins ource spectra spec_source = Lgal_nonoiseSpectra(gid, lib=lib) if dust: flux = spec_source['flux_dust_nonoise'] else: flux = spec_source['flux_nodust_nonoise'] # apply filters filter_response = specFilter.load_filters('decam2014-g', 'decam2014-r', 'decam2014-z','wise2010-W1', 'wise2010-W2', 'wise2010-W3', 'wise2010-W4') fluxes_i = filter_response.get_ab_maggies(np.atleast_2d(flux)*U.Watt/U.m**2/U.Angstrom, spec_source['wave']*U.Angstrom) fluxes[i,1:] = 1e9 * np.array([fluxes_i[0][0], fluxes_i[0][1], fluxes_i[0][2], fluxes_i[0][3], fluxes_i[0][4], fluxes_i[0][5], fluxes_i[0][6]]) # nanomaggies fmt = ['%.5e' for i in range(8)] fmt[0] = '%i' np.savetxt(fphot, fluxes, header='galid, g, r, z, W1, W2, W3, W4 fluxes in nanomaggies', fmt=fmt) mags = fUT.flux2mag(fluxes[:,1:], method='log') if validate: # compare the Lgal nonoise photometry to photometry from GAMA-Legacy cats = Cats.GamaLegacy() gleg = cats.Read('g15') fig = plt.figure(figsize=(20,4)) for i_b, band in enumerate(['g', 'r', 'z', 'w1', 'w2']): sub = fig.add_subplot(1,5,i_b+1) sub.hist(fUT.flux2mag(gleg['legacy-photo']['flux_%s' % band]), color='k', range=(14,25), density=True, label='Legacy') sub.hist(mags[:,i_b], color='C1', range=(14, 25), density=True, alpha=0.5, label='LGal\nSpectral\nChallenge') sub.set_xlabel('%s magnitude' % band, fontsize=20) sub.set_xlim(14, 25) sub.legend(loc='upper right', fontsize=15) fig.savefig(os.path.join(UT.fig_dir(), os.path.basename(fphot).replace('dat', 'hist.png')), bbox_inches='tight') plt.close() # g-r vs r-z fig = plt.figure(figsize=(6,6)) sub = fig.add_subplot(111) g_r = fUT.flux2mag(gleg['legacy-photo']['flux_g']) - fUT.flux2mag(gleg['legacy-photo']['flux_r']) r_z = fUT.flux2mag(gleg['legacy-photo']['flux_r']) - fUT.flux2mag(gleg['legacy-photo']['flux_z']) sub.scatter(g_r, r_z, c='k', s=1, label='Legacy') g_r = mags[:,0] - mags[:,1] r_z = mags[:,1] - mags[:,2] sub.scatter(g_r, r_z, c='C1', s=4, zorder=10, label='LGal\nSpectral Challenge') sub.set_xlabel('$g - r$', fontsize=20) sub.set_xlim(-1., 3.) sub.set_ylabel('$r - z$', fontsize=20) sub.set_ylim(-1., 3.) sub.legend(loc='upper right', handletextpad=0.2, markerscale=3, fontsize=15) fig.savefig(os.path.join(UT.fig_dir(), os.path.basename(fphot).replace('dat', 'color.png')), bbox_inches='tight') plt.close() return mags
def Lgal_noisePhoto(lib='bc03', dust=False, overwrite=False, validate=False): ''' generate photometry from noiseless spectral_challenge Lgal spectra generated by Rita then add realistic noise from Legacy survey. ''' fsource = f_nonoise(4, lib=lib) fsource = os.path.basename(fsource).rsplit('.', 1)[0].rsplit('_BGS_template_')[1] if dust: str_dust = 'dust' else: str_dust = 'nodust' fphot = os.path.join(UT.dat_dir(), 'spectral_challenge', 'bgs', 'mag.%s.%s.legacy_noise.dat' % (fsource, str_dust)) if os.path.isfile(fphot) and not overwrite: _mags = np.loadtxt(fphot, unpack=True, skiprows=1, usecols=[-7, -6, -5, -4, -3, -2, -1]) mags = _mags.T else: galids = np.unique(testGalIDs()) # IDs of unique spectral_challenge spectra mags = np.zeros((len(galids), 7)) for i, gid in enumerate(galids): # read ins ource spectra spec_source = Lgal_nonoiseSpectra(gid, lib=lib) if dust: flux = spec_source['flux_dust_nonoise'] else: flux = spec_source['flux_nodust_nonoise'] # apply filters filter_response = specFilter.load_filters('decam2014-g', 'decam2014-r', 'decam2014-z', 'wise2010-W1', 'wise2010-W2', 'wise2010-W3', 'wise2010-W4') mags_i = filter_response.get_ab_magnitudes(flux*U.Watt/U.m**2/U.Angstrom, spec_source['wave']*U.Angstrom) mags[i,:] = np.array([mags_i[0][0], mags_i[0][1], mags_i[0][2], mags_i[0][3], mags_i[0][4], mags_i[0][5], mags_i[0][6]]) # this is because mags_i is an astropy table. ugh fluxs = fUT.mag2flux(mags, method='log') # add in noise from legacy cats = Cats.GamaLegacy() gleg = cats.Read('g15') for ib, band in enumerate(['g', 'r', 'z', 'w1', 'w2', 'w3', 'w4']): _flux = gleg['legacy-photo']['flux_%s' % band] _ivar = gleg['legacy-photo']['flux_ivar_%s' % band] if ib == 0: gleg_fluxs = np.zeros((len(_flux), 7)) gleg_ivars = np.zeros((len(_flux), 7)) gleg_fluxs[:,ib] = _flux gleg_ivars[:,ib] = _ivar tree = KDTree(gleg_fluxs[:,:5]) dist, indx = tree.query(fluxs[:,:5]) ivars = np.zeros_like(mags) ivars = gleg_ivars[indx,:] # now lets apply noise to thse mags sig = ivars**-0.5 fluxs += sig * np.random.randn(sig.shape[0], sig.shape[1]) # noisy flux noisy_mags = fUT.flux2mag(fluxs) hdr = 'galid, flux_g, flux_r, flux_z, flux_w1, flux_w2, flux_w3, flux_w4, flux_ivar_g, flux_ivar_r, flux_ivar_z, flux_ivar_w1, flux_ivar_w2, flux_ivar_w3, flux_ivar_w4, mag_g, mag_r, mag_z, mag_w1, mag_w2, mag_w3, mag_w4' fmt = ['%.5e' for i in range(22)] fmt[0] = '%i' np.savetxt(fphot, np.vstack([galids, fluxs.T, ivars.T, noisy_mags.T]).T, header=hdr, fmt=fmt) if validate: # compare the Lgal nonoise photometry to photometry from GAMA-Legacy cats = Cats.GamaLegacy() gleg = cats.Read('g15') # histogram of magnitudes fig = plt.figure(figsize=(20,4)) for i_b, band in enumerate(['g', 'r', 'z', 'w1', 'w2']): sub = fig.add_subplot(1,5,i_b+1) sub.hist(fUT.flux2mag(gleg['legacy-photo']['flux_%s' % band]), color='k', range=(14,25), density=True, label='Legacy') sub.hist(mags[:,i_b], color='C1', range=(14, 25), density=True, alpha=0.5, label='LGal\nSpectral\nChallenge') sub.set_xlabel('%s magnitude' % band, fontsize=20) sub.set_xlim(14, 25) sub.legend(loc='upper right', fontsize=15) fig.savefig(os.path.join(UT.fig_dir(), os.path.basename(fphot).replace('dat', 'hist.png')), bbox_inches='tight') plt.close() # g-r vs r-z fig = plt.figure(figsize=(6,6)) sub = fig.add_subplot(111) g_r = fUT.flux2mag(gleg['legacy-photo']['flux_g']) - fUT.flux2mag(gleg['legacy-photo']['flux_r']) r_z = fUT.flux2mag(gleg['legacy-photo']['flux_r']) - fUT.flux2mag(gleg['legacy-photo']['flux_z']) sub.scatter(g_r, r_z, c='k', s=1, label='Legacy') g_r = mags[:,0] - mags[:,1] r_z = mags[:,1] - mags[:,2] sub.scatter(g_r, r_z, c='C1', s=4, zorder=10, label='LGal\nSpectral Challenge') sub.set_xlabel('$g - r$', fontsize=20) sub.set_xlim(-1., 3.) sub.set_ylabel('$r - z$', fontsize=20) sub.set_ylim(-1., 3.) sub.legend(loc='upper right', handletextpad=0.2, markerscale=3, fontsize=15) fig.savefig(os.path.join(UT.fig_dir(), os.path.basename(fphot).replace('dat', 'color.png')), bbox_inches='tight') plt.close() return mags