def test_photometry(noise, sim='lgal', lib='bc03', sample='mini_mocha'): photo, meta = Data.Photometry(sim=sim, noise=noise, lib=lib, sample=sample) n_meta = len(meta['galid']) assert n_meta == len(meta['redshift']) n_photo = photo['flux'].shape[0] assert n_meta == n_photo
def test_iSpeculator(data_type): # initiate fitter iSpec = Fitters.iSpeculator(model_name='emulator') # default prior prior = iSpec._default_prior() specs, meta = Data.Spectra(sim='lgal', noise='bgs0', lib='bc03', sample='mini_mocha') photo, _ = Data.Photometry(sim='lgal', noise='legacy', lib='bc03', sample='mini_mocha') zred = meta['redshift'][0] w_obs = specs['wave'] flux_obs = specs['flux'][0] photo_obs = photo['flux'][0, :3] if data_type == 'spec': output = iSpec.MCMC_spec(w_obs, flux_obs, np.ones(len(w_obs)), zred, prior=prior, nwalkers=20, burnin=10, niter=10, silent=False) assert 'theta_med' in output.keys() elif data_type == 'photo': output = iSpec.MCMC_photo(photo_obs, np.ones(len(photo_obs)), zred, bands='desi', prior=prior, nwalkers=20, burnin=10, niter=10, opt_maxiter=100, silent=False) assert 'theta_med' in output.keys()
def cigaledata(sim='lgal', noise='none', lib='bc03', sample='mini_mocha', f_out='lgal.mini_mocha.noise.none.dat'): ''' generate data file for CIGALE (mini mocha)''' #reading data photo, meta = Data.Photometry(sim='lgal', noise=noise, lib='bc03', sample='mini_mocha') #dir_sample = os.path.join(UT.dat_dir(), sample) #reading ids and redshift redshift = np.array(meta['redshift'][:]) galid = np.array(meta['galid'][:]) bands = ['g', 'r', 'z', 'w1', 'w2'] #, 'w3', 'w4'] for icol, band in enumerate(bands): photo['flux'][:, icol] = photo[ 'flux'][:, icol] * 3631 * 1e-6 # convert to mJansky [mJy] if noise == 'none': # assume 0.1% flux error sample = np.concatenate( ( galid.reshape(-1, 1), redshift.reshape(-1, 1) #id, redshift , photo['flux'][:, 0].reshape(-1, 1), 0.001 * photo['flux'][:, 0].reshape(-1, 1) #flux_g,err_flux_g , photo['flux'][:, 1].reshape(-1, 1), 0.001 * photo['flux'][:, 1].reshape(-1, 1) #flux_r,err_flux_r , photo['flux'][:, 2].reshape(-1, 1), 0.001 * photo['flux'][:, 2].reshape(-1, 1) #flux_z,err_flux_z , photo['flux'][:, 3].reshape(-1, 1), 0.001 * photo['flux'][:, 3].reshape(-1, 1) #flux_w1,err_flux_w1 , photo['flux'][:, 4].reshape(-1, 1), 0.001 * photo['flux'][:, 4].reshape(-1, 1) #flux_w2,err_flux_w2 #,photo['flux'][:,5].reshape(-1,1),0.01*photo['flux'][:,5].reshape(-1,1) #flux_w3,err_flux_w3 #,photo['flux'][:,6].reshape(-1,1),0.01*photo['flux'][:,6].reshape(-1,1) #flux_w4,err_flux_w4 ), axis=1) if noise != 'none': photo['ivar'][:, icol] = photo[ 'ivar'][:, icol]**-0.5 * 3631 * 1e-6 # inverse variance to error [mJy] sample = np.concatenate( ( galid.reshape(-1, 1), redshift.reshape(-1, 1) #id, redshift , photo['flux'][:, 0].reshape(-1, 1), photo['ivar'][:, 0].reshape(-1, 1) #flux_g,err_flux_g , photo['flux'][:, 1].reshape(-1, 1), photo['ivar'][:, 1].reshape(-1, 1) #flux_r,err_flux_r , photo['flux'][:, 2].reshape(-1, 1), photo['ivar'][:, 2].reshape(-1, 1) #flux_z,err_flux_z , photo['flux'][:, 3].reshape(-1, 1), photo['ivar'][:, 3].reshape(-1, 1) #flux_w1,err_flux_w1 , photo['flux'][:, 4].reshape(-1, 1), photo['ivar'][:, 4].reshape(-1, 1) #flux_w2,err_flux_w2 #,photo['flux'][:,5].reshape(-1,1),photo['ivar'][:,5].reshape(-1,1) #flux_w3,err_flux_w3 #,photo['flux'][:,6].reshape(-1,1),photo['ivar'][:,6].reshape(-1,1) #flux_w4,err_flux_w4 ), axis=1) np.savetxt( os.path.join(cigale_dir(), f_out), sample, delimiter=' ', header= 'id redshift DECam_g DECam_g_err DECam_r DECam_r_err DECam_z DECam_z_err WISE1 WISE1_err WISE2 WISE2_err' ) # WISE3 WISE3_err WISE4 WISE4_err')
def validate_sample(sim): ''' generate some plots to validate the mini Mock Challenge photometry and spectroscopy ''' # read photometry photo, _ = Data.Photometry(sim=sim, noise='legacy', sample='mini_mocha') photo_g = 22.5 - 2.5 * np.log10(photo['flux'][:, 0]) photo_r = 22.5 - 2.5 * np.log10(photo['flux'][:, 1]) photo_z = 22.5 - 2.5 * np.log10(photo['flux'][:, 2]) flux_g = photo['flux'][:, 0] * 1e-9 * 1e17 * UT.c_light() / 4750.**2 * ( 3631. * UT.jansky_cgs()) flux_r = photo['flux'][:, 1] * 1e-9 * 1e17 * UT.c_light() / 6350.**2 * ( 3631. * UT.jansky_cgs()) flux_z = photo['flux'][:, 2] * 1e-9 * 1e17 * UT.c_light() / 9250.**2 * ( 3631. * UT.jansky_cgs()) # convert to 10^-17 ergs/s/cm^2/Ang ivar_g = photo['ivar'][:, 0] * (1e-9 * 1e17 * UT.c_light() / 4750.**2 * (3631. * UT.jansky_cgs()))**-2. ivar_r = photo['ivar'][:, 1] * (1e-9 * 1e17 * UT.c_light() / 6350.**2 * (3631. * UT.jansky_cgs()))**-2. ivar_z = photo['ivar'][:, 2] * ( 1e-9 * 1e17 * UT.c_light() / 9250.**2 * (3631. * UT.jansky_cgs()))**-2. # convert to 10^-17 ergs/s/cm^2/Ang # read BGS targets from imaging bgs_targets = h5py.File( os.path.join(UT.dat_dir(), 'bgs.1400deg2.rlim21.0.hdf5'), 'r') n_targets = len(bgs_targets['ra'][...]) bgs_g = 22.5 - 2.5 * np.log10(bgs_targets['flux_g'][...])[::10] bgs_r = 22.5 - 2.5 * np.log10(bgs_targets['flux_r'][...])[::10] bgs_z = 22.5 - 2.5 * np.log10(bgs_targets['flux_z'][...])[::10] # photometry validation fig = plt.figure(figsize=(6, 6)) sub = fig.add_subplot(111) DFM.hist2d(bgs_g - bgs_r, bgs_r - bgs_z, color='k', levels=[0.68, 0.95], range=[[-1., 3.], [-1., 3.]], bins=40, smooth=0.5, plot_datapoints=True, fill_contours=False, plot_density=False, linewidth=0.5, ax=sub) sub.scatter([-100.], [-100], c='k', s=1, label='BGS targets') sub.scatter(photo_g - photo_r, photo_r - photo_z, c='C0', s=1, label='LGal photometry') sub.legend(loc='upper left', handletextpad=0, markerscale=10, fontsize=20) sub.set_xlabel('$g-r$', fontsize=25) sub.set_xlim(-1., 3.) sub.set_ylabel('$r-z$', fontsize=25) sub.set_ylim(-1., 3.) ffig = os.path.join(UT.dat_dir(), 'mini_mocha', 'mini_mocha.%s.photo.png' % sim) fig.savefig(ffig, bbox_inches='tight') fig.savefig(UT.fig_tex(ffig, pdf=True), bbox_inches='tight') # read spectra spec_s, _ = Data.Spectra(sim=sim, noise='none', sample='mini_mocha') spec_bgs0, _ = Data.Spectra(sim=sim, noise='bgs0', sample='mini_mocha') spec_bgs1, _ = Data.Spectra(sim=sim, noise='bgs1', sample='mini_mocha') spec_bgs2, _ = Data.Spectra(sim=sim, noise='bgs2', sample='mini_mocha') # read sky brightness _fsky = os.path.join(UT.dat_dir(), 'mini_mocha', 'bgs.exposure.surveysim.150s.v0p4.sample.hdf5') fsky = h5py.File(_fsky, 'r') wave_sky = fsky['wave'][...] # sky wavelength sbright_sky = fsky['sky'][...] # spectra validationg fig = plt.figure(figsize=(10, 5)) sub = fig.add_subplot(111) for i, spec_bgs in enumerate([spec_bgs2, spec_bgs0]): wsort = np.argsort(spec_bgs['wave']) if i == 0: _plt, = sub.plot(spec_bgs['wave'][wsort], spec_bgs['flux'][0, wsort], c='C%i' % i, lw=0.25) else: sub.plot(spec_bgs['wave'][wsort], spec_bgs['flux'][0, wsort], c='C%i' % i, lw=0.25) _plt_photo = sub.errorbar( [4750, 6350, 9250], [flux_g[0], flux_r[0], flux_z[0]], [ivar_g[0]**-0.5, ivar_r[0]**-0.5, ivar_z[0]**-0.5], fmt='.r') _plt_sim, = sub.plot(spec_s['wave'][0, :], spec_s['flux'][0, :], c='k', ls='-', lw=1) _plt_sim0, = sub.plot(spec_s['wave'][0, :], spec_s['flux_unscaled'][0, :], c='k', ls=':', lw=0.25) leg = sub.legend([_plt_sim0, _plt_photo, _plt_sim, _plt], [ '%s spectrum' % sim.upper(), '%s photometry' % sim.upper(), '%s fiber spectrum' % sim.upper(), '%s BGS spectra' % sim.upper() ], loc='upper right', fontsize=17) for legobj in leg.legendHandles: legobj.set_linewidth(2.0) sub.set_xlabel('Wavelength [$A$]', fontsize=20) sub.set_xlim(3e3, 1e4) sub.set_ylabel('flux [$10^{-17} erg/s/cm^2/A$', fontsize=20) if sim == 'lgal': sub.set_ylim(-2., 8.) elif sim == 'tng': sub.set_ylim(0., None) ffig = os.path.join(UT.dat_dir(), 'mini_mocha', 'mini_mocha.%s.spectra.png' % sim) fig.savefig(ffig, bbox_inches='tight') fig.savefig(UT.fig_tex(ffig, pdf=True), bbox_inches='tight') return None
def fit_spectrophotometry(igal, sim='lgal', noise='bgs0_legacy', method='ifsps', model='emulator', nwalkers=100, burnin=100, niter='adaptive', maxiter=200000, opt_maxiter=100, overwrite=False, postprocess=False, justplot=False): ''' Fit Lgal spectra. `noise` specifies whether to fit spectra without noise or with BGS-like noise. Produces an MCMC chain and, if not on nersc, a corner plot of the posterior. :param igal: index of Lgal galaxy within the spectral_challenge :param noise: If 'bgs1'...'bgs8', fit BGS-like spectra. (default: 'none') :param justplot: If True, skip the fitting and plot the best-fit. This is mainly implemented because I'm having issues plotting in NERSC. (default: False) ''' noise_spec = noise.split('_')[0] noise_photo = noise.split('_')[1] # read noiseless Lgal spectra of the spectral_challenge mocks specs, meta = Data.Spectra(sim=sim, noise=noise_spec, lib='bc03', sample='mini_mocha') # read Lgal photometry of the mini_mocha mocks photo, _ = Data.Photometry(sim=sim, noise=noise_photo, lib='bc03', sample='mini_mocha') if meta['redshift'][igal] < 0.101: # current Speculator wavelength doesn't extend far enough # current Speculator wavelength doesn't extend far enough # current Speculator wavelength doesn't extend far enough # current Speculator wavelength doesn't extend far enough # current Speculator wavelength doesn't extend far enough return None w_obs = specs['wave'] flux_obs = specs['flux'][igal] ivar_obs = specs['ivar'][igal] if method == 'ispeculator': photo_obs = photo['flux'][igal, :3] photo_ivar_obs = photo['ivar'][igal, :3] else: photo_obs = photo['flux'][igal, :5] photo_ivar_obs = photo['ivar'][igal, :5] # get fiber flux factor prior range based on measured fiber flux f_fiber_true = (photo['fiberflux_r_true'][igal] / photo['flux_r_true'][igal]) prior_width = np.max([ 0.05, 5. * photo['fiberflux_r_ivar'][igal]**-0.5 / photo['flux'][igal, 1] ]) f_fiber_min = ( photo['fiberflux_r_meas'][igal]) / photo['flux'][igal, 1] - prior_width f_fiber_max = ( photo['fiberflux_r_meas'][igal]) / photo['flux'][igal, 1] + prior_width f_fiber_prior = [f_fiber_min, f_fiber_max] print('--- input ---') print('z = %f' % meta['redshift'][igal]) print('log M* total = %f' % meta['logM_total'][igal]) print('log M* fiber = %f' % meta['logM_fiber'][igal]) print('f_fiber = %f' % f_fiber_true) print('log SFR 100myr = %f' % np.log10(meta['sfr_100myr'][igal])) print('log Z_MW = %f' % np.log10(meta['Z_MW'][igal])) f_mcmc = os.path.join( UT.dat_dir(), 'mini_mocha', method, '%s.specphoto.noise_%s.%s.%i.mcmc.hdf5' % (sim, noise, model, igal)) if method == 'ifsps': ifitter = Fitters.iFSPS(model_name=model) elif method == 'ispeculator': ifitter = Fitters.iSpeculator(model_name=model) print('--- mcmc ---') if (justplot or not overwrite) and os.path.isfile(f_mcmc): print(' reading... %s' % os.path.basename(f_mcmc)) # read in mcmc chain fmcmc = h5py.File(f_mcmc, 'r') mcmc = {} for k in fmcmc.keys(): mcmc[k] = fmcmc[k][...] fmcmc.close() else: if os.path.isfile(f_mcmc) and not overwrite: print("** CAUTION: %s already exists **" % os.path.basename(f_mcmc)) print(' writing... %s' % os.path.basename(f_mcmc)) # initiating fit prior = ifitter._default_prior(f_fiber_prior=f_fiber_prior) mcmc = ifitter.MCMC_spectrophoto(w_obs, flux_obs, ivar_obs, photo_obs, photo_ivar_obs, meta['redshift'][igal], mask='emline', prior=prior, nwalkers=nwalkers, burnin=burnin, niter=niter, maxiter=maxiter, opt_maxiter=opt_maxiter, writeout=f_mcmc, silent=False) if postprocess: print('--- postprocessing ---') f_post = f_mcmc.replace('.mcmc.hdf5', '.postproc.hdf5') mcmc = ifitter.postprocess(mcmc_output=mcmc, writeout=f_post) i_fib = list(mcmc['theta_names'].astype(str)).index('f_fiber') print('log M* total = %f' % mcmc['theta_med'][0]) print('log M* fiber = %f' % (mcmc['theta_med'][0] + np.log10(mcmc['theta_med'][i_fib]))) print('---------------') try: # plotting on nersc never works. if os.environ['NERSC_HOST'] == 'cori': return None except KeyError: labels = [lbl_dict[_t] for _t in mcmc['theta_names'].astype(str)] truths = [None for _ in labels] truths[0] = meta['logM_total'][igal] truths[i_fib] = f_fiber_true if postprocess: i_sfr = list( mcmc['theta_names'].astype(str)).index('logsfr.100myr') truths[i_sfr] = np.log10(meta['sfr_100myr'][igal]) i_zw = list(mcmc['theta_names'].astype(str)).index('logz.mw') truths[i_zw] = np.log10(meta['Z_MW'][igal]) print('log SFR 100myr = %f' % np.median(mcmc['mcmc_chain'][:, i_sfr])) print('log Z_MW = %f' % np.median(mcmc['mcmc_chain'][:, i_zw])) # corner plot of the posteriors fig = DFM.corner(mcmc['mcmc_chain'], range=mcmc['prior_range'], quantiles=[0.16, 0.5, 0.84], levels=[0.68, 0.95], nbin=40, smooth=True, truths=truths, labels=labels, label_kwargs={'fontsize': 20}) if postprocess: fig.savefig(f_post.replace('.hdf5', '.png'), bbox_inches='tight') else: fig.savefig(f_mcmc.replace('.hdf5', '.png'), bbox_inches='tight') plt.close() fig = plt.figure(figsize=(18, 5)) gs = mpl.gridspec.GridSpec(1, 2, figure=fig, width_ratios=[1, 3], wspace=0.2) sub = plt.subplot(gs[0]) sub.errorbar(np.arange(len(photo_obs)), photo_obs, yerr=photo_ivar_obs**-0.5, fmt='.k', label='data') sub.scatter(np.arange(len(photo_obs)), mcmc['flux_photo_model'], c='C1', label='model') sub.legend(loc='upper left', markerscale=3, handletextpad=0.2, fontsize=15) sub.set_xticks([0, 1, 2, 3, 4]) sub.set_xticklabels(['$g$', '$r$', '$z$', 'W1', 'W2']) sub.set_xlim(-0.5, len(photo_obs) - 0.5) sub = plt.subplot(gs[1]) sub.plot(w_obs, flux_obs, c='k', lw=1, label='data') sub.plot(mcmc['wavelength_model'], mcmc['flux_spec_model'], c='C1', ls='--', lw=1, label=method) sub.legend(loc='upper right', fontsize=15) sub.set_xlabel('wavelength [$A$]', fontsize=20) sub.set_xlim(3600., 9800.) sub.set_ylim(-1., 5.) if postprocess: fig.savefig(f_post.replace('.hdf5', '.bestfit.png'), bbox_inches='tight') else: fig.savefig(f_mcmc.replace('.hdf5', '.bestfit.png'), bbox_inches='tight') plt.close() return None
def fit_photometry(igal, sim='lgal', noise='legacy', method='ifsps', model='emulator', nwalkers=100, burnin=100, niter='adaptive', maxiter=200000, opt_maxiter=100, overwrite=False, postprocess=False, justplot=False): ''' Fit simulated photometry. `noise` specifies whether to fit spectra without noise or with legacy-like noise. `dust` specifies whether to if spectra w/ dust or not. Produces an MCMC chain and, if not on nersc, a corner plot of the posterior. :param igal: index of Lgal galaxy within the spectral_challenge :param noise: If 'none', fit noiseless photometry. If 'legacy', fit Legacy-like photometry. (default: 'none') :param justplot: If True, skip the fitting and plot the best-fit. This is mainly implemented because I'm having issues plotting in NERSC. (default: False) ''' # read Lgal photometry of the mini_mocha mocks photo, meta = Data.Photometry(sim=sim, noise=noise, lib='bc03', sample='mini_mocha') if meta['redshift'][igal] < 0.101: # current Speculator wavelength doesn't extend far enough # current Speculator wavelength doesn't extend far enough # current Speculator wavelength doesn't extend far enough # current Speculator wavelength doesn't extend far enough # current Speculator wavelength doesn't extend far enough return None print('--- input ---') print('z = %f' % meta['redshift'][igal]) print('log M* total = %f' % meta['logM_total'][igal]) print('log SFR 100myr = %f' % np.log10(meta['sfr_100myr'][igal])) print('log Z MW = %f' % np.log10(meta['Z_MW'][igal])) if method == 'ispeculator': photo_obs = photo['flux'][igal, :3] ivar_obs = photo['ivar'][igal, :3] else: photo_obs = photo['flux'][igal, :5] ivar_obs = photo['ivar'][igal, :5] f_mcmc = os.path.join( UT.dat_dir(), 'mini_mocha', method, '%s.photo.noise_%s.%s.%i.mcmc.hdf5' % (sim, noise, model, igal)) # initiating fit if method == 'ifsps': ifitter = Fitters.iFSPS(model_name=model) elif method == 'ispeculator': ifitter = Fitters.iSpeculator(model_name=model) print('--- bestfit ---') if (justplot or not overwrite) and os.path.isfile(f_mcmc): # read in best-fit file with mcmc chain print(' reading in %s' % f_mcmc) fmcmc = h5py.File(f_mcmc, 'r') mcmc = {} for k in fmcmc.keys(): mcmc[k] = fmcmc[k][...] fmcmc.close() else: if os.path.isfile(f_mcmc) and not overwrite: print("** CAUTION: %s already exists **" % os.path.basename(f_bf)) print(' writing %s' % f_mcmc) prior = ifitter._default_prior(f_fiber_prior=None) mcmc = ifitter.MCMC_photo(photo_obs, ivar_obs, meta['redshift'][igal], bands='desi', prior=prior, nwalkers=nwalkers, burnin=burnin, niter=niter, maxiter=maxiter, opt_maxiter=opt_maxiter, writeout=f_mcmc, silent=False) if postprocess: print('--- postprocessing ---') f_post = f_mcmc.replace('.mcmc.hdf5', '.postproc.hdf5') mcmc = ifitter.postprocess(mcmc_output=mcmc, writeout=f_post) print('log M* total = %f' % mcmc['theta_med'][0]) print('---------------') try: # plotting on nersc never works. if os.environ['NERSC_HOST'] == 'cori': return None except KeyError: labels = [lbl_dict[_t] for _t in mcmc['theta_names'].astype(str)] truths = [None for _ in labels] truths[0] = meta['logM_total'][igal] if postprocess: i_sfr = list( mcmc['theta_names'].astype(str)).index('logsfr.100myr') truths[i_sfr] = np.log10(meta['sfr_100myr'][igal]) i_zmw = list(mcmc['theta_names'].astype(str)).index('logz.mw') truths[i_zmw] = np.log10(meta['Z_MW'][igal]) print('log SFR 100myr = %f' % np.median(mcmc['mcmc_chain'][:, i_sfr])) print('log Z MW = %f' % np.median(mcmc['mcmc_chain'][:, i_zmw])) fig = DFM.corner(mcmc['mcmc_chain'], range=mcmc['prior_range'], quantiles=[0.16, 0.5, 0.84], levels=[0.68, 0.95], nbin=40, smooth=True, truths=truths, labels=labels, label_kwargs={'fontsize': 20}) if postprocess: fig.savefig(f_post.replace('.hdf5', '.png'), bbox_inches='tight') else: fig.savefig(f_mcmc.replace('.hdf5', '.png'), bbox_inches='tight') plt.close() fig = plt.figure(figsize=(5, 3)) sub = fig.add_subplot(111) sub.errorbar(np.arange(len(photo_obs)), photo_obs, yerr=ivar_obs**-0.5, fmt='.k', label='data') sub.scatter(np.arange(len(photo_obs)), mcmc['flux_photo_model'], c='C1', label='model') sub.legend(loc='upper left', markerscale=3, handletextpad=0.2, fontsize=15) sub.set_xticks([0, 1, 2]) sub.set_xticklabels(['$g$', '$r$', '$z$']) sub.set_xlim(-0.5, len(photo_obs) - 0.5) if postprocess: fig.savefig(f_post.replace('.hdf5', '.bestfit.png'), bbox_inches='tight') else: fig.savefig(f_mcmc.replace('.hdf5', '.bestfit.png'), bbox_inches='tight') plt.close() return None
def mini_mocha_specphoto(noise='bgs0_legacy', sample='mini_mocha', method='ifsps'): ''' Compare properties inferred from forward modeled photometry to input properties ''' if noise != 'none': noise_spec = noise.split('_')[0] noise_photo = noise.split('_')[1] else: noise_spec = 'none' noise_photo = 'none' # read noiseless Lgal spectra of the spectral_challenge mocks specs, meta = Data.Spectra(sim='lgal', noise=noise_spec, lib='bc03', sample=sample) # read Lgal photometry of the mini_mocha mocks photo, _ = Data.Photometry(sim='lgal', noise=noise_photo, lib='bc03', sample=sample) Mstar_input = meta['logM_total'] # total mass Z_MW_input = meta['Z_MW'] # mass-weighted metallicity tage_input = meta['t_age_MW'] # mass-weighted age theta_inf = [] for igal in range(100): # read best-fit file and get inferred parameters _fbf = Fbestfit_specphoto(igal, noise=noise, method=method) fbf = h5py.File(_fbf, 'r') theta_inf_i = np.array([ fbf['theta_2sig_minus'][...], fbf['theta_1sig_minus'][...], fbf['theta_med'][...], fbf['theta_1sig_plus'][...], fbf['theta_2sig_plus'][...] ]) theta_inf.append(theta_inf_i) theta_inf = np.array(theta_inf) # inferred properties Mstar_inf = theta_inf[:, :, 0] Z_MW_inf = 10**theta_inf[:, :, 1] tage_inf = theta_inf[:, :, 2] fig = plt.figure(figsize=(15, 4)) # compare total stellar mass sub = fig.add_subplot(131) sub.errorbar(Mstar_input, Mstar_inf[:, 2], yerr=[ Mstar_inf[:, 2] - Mstar_inf[:, 1], Mstar_inf[:, 3] - Mstar_inf[:, 2] ], fmt='.C0') sub.plot([9., 12.], [9., 12.], c='k', ls='--') sub.set_xlabel(r'input $\log~M_{\rm tot}$', fontsize=25) sub.set_xlim(9., 12.) sub.set_ylabel(r'inferred $\log~M_{\rm tot}$', fontsize=25) sub.set_ylim(9., 12.) # compare metallicity sub = fig.add_subplot(132) sub.errorbar(Z_MW_input, Z_MW_inf[:, 2], yerr=[ Z_MW_inf[:, 2] - Z_MW_inf[:, 1], Z_MW_inf[:, 3] - Z_MW_inf[:, 2] ], fmt='.C0') sub.plot([1e-3, 1], [1e-3, 1.], c='k', ls='--') sub.set_xlabel(r'input MW $Z$', fontsize=20) sub.set_xscale('log') sub.set_xlim(1e-3, 5e-2) sub.set_ylabel(r'inferred MW $Z$', fontsize=20) sub.set_yscale('log') sub.set_ylim(1e-3, 5e-2) # compare age sub = fig.add_subplot(133) sub.errorbar(tage_input, tage_inf[:, 2], yerr=[ tage_inf[:, 2] - tage_inf[:, 1], tage_inf[:, 3] - tage_inf[:, 2] ], fmt='.C0') sub.plot([0, 13], [0, 13.], c='k', ls='--') sub.set_xlabel(r'input MW $t_{\rm age}$', fontsize=20) sub.set_xlim(0, 13) sub.set_ylabel(r'inferred MW $t_{\rm age}$', fontsize=20) sub.set_ylim(0, 13) fig.subplots_adjust(wspace=0.4) _ffig = os.path.join( dir_fig, 'mini_mocha.%s.specphotofit.vanilla.noise_%s.png' % (method, noise)) fig.savefig(_ffig, bbox_inches='tight') fig.savefig(UT.fig_tex(_ffig, pdf=True), bbox_inches='tight') return None
def mock_challenge_photo(noise='none', dust=False, method='ifsps'): ''' Compare properties inferred from forward modeled photometry to input properties ''' # read Lgal input input properties _, meta = Data.Photometry(sim='lgal', noise=noise, lib='bc03', sample='spectral_challenge') Mstar_input = meta['logM_total'] # total mass Z_MW_input = meta['Z_MW'] # mass-weighted metallicity tage_input = meta['t_age_MW'] # mass-weighted age theta_inf = [] for igal in range(97): # read best-fit file and get inferred parameters _fbf = Fbestfit_photo(igal, noise=noise, dust=dust, method=method) fbf = h5py.File(_fbf, 'r') theta_inf_i = np.array([ fbf['theta_2sig_minus'][...], fbf['theta_1sig_minus'][...], fbf['theta_med'][...], fbf['theta_1sig_plus'][...], fbf['theta_2sig_plus'][...] ]) theta_inf.append(theta_inf_i) theta_inf = np.array(theta_inf) # inferred properties Mstar_inf = theta_inf[:, :, 0] Z_MW_inf = 10**theta_inf[:, :, 1] tage_inf = theta_inf[:, :, 2] fig = plt.figure(figsize=(15, 4)) # compare total stellar mass sub = fig.add_subplot(131) sub.errorbar(Mstar_input, Mstar_inf[:, 2], yerr=[ Mstar_inf[:, 2] - Mstar_inf[:, 1], Mstar_inf[:, 3] - Mstar_inf[:, 2] ], fmt='.C0') sub.plot([9., 12.], [9., 12.], c='k', ls='--') sub.set_xlabel(r'input $\log~M_{\rm tot}$', fontsize=25) sub.set_xlim(9., 12.) sub.set_ylabel(r'inferred $\log~M_{\rm tot}$', fontsize=25) sub.set_ylim(9., 12.) # compare metallicity sub = fig.add_subplot(132) sub.errorbar(Z_MW_input, Z_MW_inf[:, 2], yerr=[ Z_MW_inf[:, 2] - Z_MW_inf[:, 1], Z_MW_inf[:, 3] - Z_MW_inf[:, 2] ], fmt='.C0') sub.plot([1e-3, 1], [1e-3, 1.], c='k', ls='--') sub.set_xlabel(r'input MW $Z$', fontsize=20) sub.set_xscale('log') sub.set_xlim(1e-3, 5e-2) sub.set_ylabel(r'inferred MW $Z$', fontsize=20) sub.set_yscale('log') sub.set_ylim(1e-3, 5e-2) # compare age sub = fig.add_subplot(133) sub.errorbar(tage_input, tage_inf[:, 2], yerr=[ tage_inf[:, 2] - tage_inf[:, 1], tage_inf[:, 3] - tage_inf[:, 2] ], fmt='.C0') sub.plot([0, 13], [0, 13.], c='k', ls='--') sub.set_xlabel(r'input MW $t_{\rm age}$', fontsize=20) sub.set_xlim(0, 13) sub.set_ylabel(r'inferred MW $t_{\rm age}$', fontsize=20) sub.set_ylim(0, 13) fig.subplots_adjust(wspace=0.4) _ffig = os.path.join( dir_fig, 'mock_challenge.photofit.%s.noise_%s.dust_%s.png' % (method, noise, ['no', 'yes'][dust])) fig.savefig(_ffig, bbox_inches='tight') return None
spec_obs = specs['flux'][0] spec_ivar_obs = specs['ivar'][0] # read nonoise Lgal spectra specs_non, _ = Data.Spectra(sim='lgal', noise='none', lib='bc03', sample='mini_mocha') w_obs_non = specs_non['wave'] spec_obs_non = specs_non['flux'][0] spec_ivar_obs_non = np.ones(w_obs_non.shape[0]) t0 = time.time() # read Lgal photometry of the mini_mocha mocks photo, _ = Data.Photometry(sim='lgal', noise='legacy', lib='bc03', sample='mini_mocha') print('Data.Photometry takes %.3f sec' % (time.time() - t0)) # 0.019sec photo_obs = photo['flux'][0, :5] photo_ivar_obs = photo['ivar'][0, :5] # initial fitter ifsps = Fitters.iFSPS(model_name='vanilla', prior=None) # middle of prior theta value theta_test = np.average(np.array(ifsps.priors), axis=1) # get mask t0 = time.time() _mask = ifsps._check_mask('emline', w_obs, spec_ivar_obs, meta['redshift'][0])
def fit_spectrophotometry(igal, noise='none', nwalkers=100, burnin=100, niter=1000, overwrite=False, justplot=False): ''' Fit Lgal spectra. `noise` specifies whether to fit spectra without noise or with BGS-like noise. Produces an MCMC chain and, if not on nersc, a corner plot of the posterior. :param igal: index of Lgal galaxy within the spectral_challenge :param noise: If 'none', fit noiseless spectra. If 'bgs1'...'bgs8', fit BGS-like spectra. (default: 'none') :param justplot: If True, skip the fitting and plot the best-fit. This is mainly implemented because I'm having issues plotting in NERSC. (default: False) ''' if noise != 'none': noise_spec = noise.split('_')[0] noise_photo = noise.split('_')[1] else: noise_spec = 'none' noise_photo = 'none' # read noiseless Lgal spectra of the spectral_challenge mocks specs, meta = Data.Spectra(sim='lgal', noise=noise_spec, lib='bc03', sample='mini_mocha') # read Lgal photometry of the mini_mocha mocks photo, _ = Data.Photometry(sim='lgal', noise=noise_photo, lib='bc03', sample='mini_mocha') model = 'vanilla' w_obs = specs['wave'] flux_obs = specs['flux'][igal] if noise_spec != 'none': ivar_obs = specs['ivar'][igal] else: ivar_obs = np.ones(len(w_obs)) photo_obs = photo['flux'][igal,:5] if noise_photo != 'none': photo_ivar_obs = photo['ivar'][igal,:5] else: photo_ivar_obs = np.ones(photo_obs.shape[0]) # get fiber flux factor prior range based on measured fiber flux f_fiber_true = (photo['fiberflux_r_meas'][igal]/photo['flux_r_true'][igal]) f_fiber_min = (photo['fiberflux_r_meas'][igal] - 3.*photo['fiberflux_r_ivar'][igal]**-0.5)/photo['flux'][igal,1] f_fiber_max = (photo['fiberflux_r_meas'][igal] + 3.*photo['fiberflux_r_ivar'][igal]**-0.5)/photo['flux'][igal,1] f_fiber_prior = [f_fiber_min, f_fiber_max] print(f_fiber_prior) print(f_fiber_true) print((photo['fiberflux_r_true'][igal]/photo['flux_r_true'][igal])) truths = [meta['logM_total'][igal], np.log10(meta['Z_MW'][igal]), meta['t_age_MW'][igal], None, None, f_fiber_true] labels = ['$\log M_*$', '$\log Z$', r'$t_{\rm age}$', 'dust2', r'$\tau$', r'$f_{\rm fiber}$'] print('--- input ---') print('z = %f' % meta['redshift'][igal]) print('log M* total = %f' % meta['logM_total'][igal]) print('log M* fiber = %f' % meta['logM_fiber'][igal]) print('MW Z = %f' % meta['Z_MW'][igal]) print('MW tage = %f' % meta['t_age_MW'][igal]) f_bf = os.path.join(UT.dat_dir(), 'mini_mocha', 'ifsps', 'lgal.specphoto.noise_%s.%s.%i.hdf5' % (noise, model, igal)) if not justplot: if os.path.isfile(f_bf): if not overwrite: print("** CAUTION: %s already exists **" % os.path.basename(f_bf)) # initiating fit ifsps = Fitters.iFSPS(model_name=model, prior=None) bestfit = ifsps.MCMC_spectrophoto( w_obs, flux_obs, ivar_obs, photo_obs, photo_ivar_obs, meta['redshift'][igal], f_fiber_prior=f_fiber_prior, mask='emline', nwalkers=nwalkers, burnin=burnin, niter=niter, writeout=f_bf, silent=False) else: # read in best-fit file with mcmc chain fbestfit = h5py.File(f_bf, 'r') bestfit = {} for k in fbestfit.keys(): bestfit[k] = fbestfit[k][...] print('--- bestfit ---') print('written to %s' % f_bf) print('log M* total = %f' % bestfit['theta_med'][0]) print('log M* fiber = %f' % (bestfit['theta_med'][0] + np.log10(bestfit['theta_med'][-1]))) print('log Z = %f' % bestfit['theta_med'][1]) print('---------------') try: # plotting on nersc never works. if os.environ['NERSC_HOST'] == 'cori': return None except KeyError: # corner plot of the posteriors fig = DFM.corner(bestfit['mcmc_chain'], range=bestfit['priors'], quantiles=[0.16, 0.5, 0.84], levels=[0.68, 0.95], nbin=40, smooth=True, truths=truths, labels=labels, label_kwargs={'fontsize': 20}) fig.savefig(f_bf.replace('.hdf5', '.png'), bbox_inches='tight') return None
def fit_photometry(igal, noise='none', nwalkers=100, burnin=100, niter=1000, overwrite=False, justplot=False): ''' Fit Lgal photometry. `noise` specifies whether to fit spectra without noise or with legacy-like noise. `dust` specifies whether to if spectra w/ dust or not. Produces an MCMC chain and, if not on nersc, a corner plot of the posterior. :param igal: index of Lgal galaxy within the spectral_challenge :param noise: If 'none', fit noiseless photometry. If 'legacy', fit Legacy-like photometry. (default: 'none') :param justplot: If True, skip the fitting and plot the best-fit. This is mainly implemented because I'm having issues plotting in NERSC. (default: False) ''' # read Lgal photometry of the mini_mocha mocks photo, meta = Data.Photometry(sim='lgal', noise=noise, lib='bc03', sample='mini_mocha') model = 'vanilla' photo_obs = photo['flux'][igal,:5] if noise != 'none': ivar_obs = photo['ivar'][igal,:5] truths = [meta['logM_total'][igal], np.log10(meta['Z_MW'][igal]), meta['t_age_MW'][igal], None, None] labels = ['$\log M_*$', '$\log Z$', r'$t_{\rm age}$', 'dust2', r'$\tau$'] if noise == 'none': # no noise ivar_obs = np.ones(photo_obs.shape[0]) print('--- input ---') print('z = %f' % meta['redshift'][igal]) print('log M* total = %f' % meta['logM_total'][igal]) print('MW Z = %f' % meta['Z_MW'][igal]) print('MW tage = %f' % meta['t_age_MW'][igal]) f_bf = os.path.join(UT.dat_dir(), 'mini_mocha', 'ifsps', 'lgal.photo.noise_%s.%s.%i.hdf5' % (noise, model, igal)) if not justplot: if os.path.isfile(f_bf): if not overwrite: print("** CAUTION: %s already exists **" % os.path.basename(f_bf)) return None # initiate fitting ifsps = Fitters.iFSPS(model_name=model, prior=None) bestfit = ifsps.MCMC_photo( photo_obs, ivar_obs, meta['redshift'][igal], bands='desi', nwalkers=nwalkers, burnin=burnin, niter=niter, writeout=f_bf, silent=False) else: # read in best-fit file with mcmc chain fbestfit = h5py.File(f_bf, 'r') bestfit = {} for k in fbestfit.keys(): bestfit[k] = fbestfit[k][...] print('--- bestfit ---') print('written to %s ---' % f_bf) print('log M* = %f' % bestfit['theta_med'][0]) print('log Z = %f' % bestfit['theta_med'][1]) print('---------------') try: # plotting on nersc never works. if os.environ['NERSC_HOST'] == 'cori': return None except KeyError: fig = DFM.corner(bestfit['mcmc_chain'], range=bestfit['priors'], quantiles=[0.16, 0.5, 0.84], levels=[0.68, 0.95], nbin=40, smooth=True, truths=truths, labels=labels, label_kwargs={'fontsize': 20}) fig.savefig(f_bf.replace('.hdf5', '.png'), bbox_inches='tight') return None