Esempio n. 1
0
def _mini_mocha_galid(lib='bc03'):
    ''' pick 100 unique Lgal galids that roughly fall under the BGS target selection 
    for the mini mock challenge: r < 20. 
    '''
    # gather all galids
    galids = []
    dir_inputs = os.path.join(UT.lgal_dir(), 'gal_inputs')
    for finput in glob.glob(dir_inputs + '/*'):
        galids.append(int(os.path.basename(finput).split('_')[2]))
    galids = np.array(galids)
    n_id = len(galids)

    # get noiseless source spectra
    _, spectra_s = _lgal_noiseless_spectra(galids, lib=lib)
    # get DECAM photometry
    photo, _ = FM.Photo_DESI(spectra_s['wave'], spectra_s['flux_dust'])

    target_selection = (photo[:, 1] <= 20.)
    print('%i Lgal galaxies within target_selection' %
          np.sum(target_selection))

    # now randomly choose 100 galids
    mini_galids = np.random.choice(galids[target_selection],
                                   size=100,
                                   replace=False)
    fids = os.path.join(UT.dat_dir(), 'mini_mocha', 'lgal.galids.%s.txt' % lib)
    np.savetxt(fids,
               mini_galids,
               fmt='%i',
               header='%i Lgal galids for mini mock challenge' %
               len(mini_galids))
    return None
Esempio n. 2
0
def QA_fm_Lgal_mini_mocha(lib='bc03'):
    ''' quality assurance/sanity plots 
    '''
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    mpl.rcParams['text.usetex'] = True
    mpl.rcParams['font.family'] = 'serif'
    mpl.rcParams['axes.linewidth'] = 1.5
    mpl.rcParams['axes.xmargin'] = 1
    mpl.rcParams['xtick.labelsize'] = 'x-large'
    mpl.rcParams['xtick.major.size'] = 5
    mpl.rcParams['xtick.major.width'] = 1.5
    mpl.rcParams['ytick.labelsize'] = 'x-large'
    mpl.rcParams['ytick.major.size'] = 5
    mpl.rcParams['ytick.major.width'] = 1.5
    mpl.rcParams['legend.frameon'] = False

    # read mini mocha data
    fmm = h5py.File(
        os.path.join(UT.dat_dir(), 'mini_mocha',
                     'lgal.mini_mocha.%s.v%s.hdf5' % (lib, version)), 'r')

    ngal = fmm['spec_flux_source'][...].shape[0]

    # plot BGS spectra and source spectra for sanity checks
    fig = plt.figure(figsize=(15, 15))
    for ii, i in enumerate(
            np.random.choice(np.arange(ngal), size=3, replace=False)):
        sub = fig.add_subplot(3, 1, ii + 1)
        for band in ['b', 'r', 'z']:
            sub.plot(fmm['spec_wave_%s_bgs' % band][...],
                     fmm['spec_flux_%s_bgs' % band][...][0, i, :],
                     c='C0')
        sub.plot(fmm['spec_wave_source'][...],
                 fmm['spec_fiber_flux_source'][...][i, :],
                 c='k',
                 ls='--')
        sub.set_xlim(3.6e3, 9.8e3)
        sub.set_ylim(-2, 10)
    sub.set_xlabel('wavelength', fontsize=25)
    fig.savefig(os.path.join(UT.dat_dir(), 'mini_mocha',
                             'lgal.mini_mocha.%s.v%s.png' % (lib, version)),
                bbox_inches='tight')
    return None
Esempio n. 3
0
def Fbestfit_specphoto(igal,
                       noise='bgs0_legacy',
                       sample='mini_mocha',
                       method='ifsps'):
    ''' file name of best-fit of photometry of spectral_challenge galaxy #igal
    :param igal: 
        index of spectral_challenge galaxy 
    :param noise:
        noise of the spectra. If noise == 'none', no noise. If noise =='legacy', 
        then legacy like noise. (default: 'none') 
    :param sample: 
        mini_mocha
    :param method: 
        fitting method. (default: ifsps)
    '''
    model = 'vanilla'
    f_bf = os.path.join(
        UT.dat_dir(), sample, 'ifsps',
        'lgal.specphoto.noise_%s.%s.%i.hdf5' % (noise, model, igal))
    return f_bf
Esempio n. 4
0
def compare_FSPS_Speculator():
    '''
    '''
    tt_i = np.array([0.25, 0.25, 0.25, 0.25, 1e-4, 1e-4, 0., 1.5])

    w0, lum0 = FSPS_sspLum(tt_i)
    w1, lum1 = Speculator_sspLum(tt_i)
    wlim0 = (w0 > 3e3)
    wlim1 = (w1 > 3e3)
    print(np.sum(lum0))
    print(np.sum(lum1))
    print(lum0[wlim0])
    print(lum1[wlim1])

    fig = plt.figure(figsize=(10, 5))
    sub = fig.add_subplot(111)
    sub.plot(w0, lum0, c='k', label='FSPS')
    sub.plot(w1, lum1, c='C0', label='Speculator')
    sub.set_xlim(3e3, 1e4)
    ffig = os.path.join(UT.dat_dir(), '_fsps_speculator_comparison.png')
    fig.savefig(ffig, bbox_inches='tight')
    return None
Esempio n. 5
0
def fm_TNG_minimocha():
    ''' generate spectroscopy and photometry for the mini Mock Challenge (MoCha)
    
    * input: galaxy properties (SFH, ZH, etc), noiseless spectra 
    * "true" photometry directly from noiseless spectra
    * assign photometric uncertainty and fiber flux using legacy imaging 
    * "measured" photometry and fiber flux + fiber source spectra (scaled down noiseless spectra), 
    * "BGS" spectra

    notes
    -----
    *   only 5000 galaxies for the mini_mocha 
    '''
    from scipy.spatial import cKDTree as KDTree
    # read TNG source spectra
    ftng = h5py.File(os.path.join(UT.dat_dir(), 'tng', 'tng.hdf5'), 'r')
    wave = ftng['wave'][...]
    sed = ftng['sed_neb'][...][:5000, :]  # SED with nebular emission lines
    ngal = sed.shape[0]
    print('%i illustris tng galaxies' % ngal)

    _wave_s = wave * u.Angstrom
    _spec_s = sed * u.Lsun / u.Hz

    H0 = 70 * u.km / u.s / u.Mpc

    # 0a. assign redshifts z ~ U(0.001, 0.4)
    zred = np.random.uniform(0.001, 0.4, size=ngal)

    # 0b. generate 'true' photometry from noiseless spectra
    wave_s = np.tile(_wave_s.value, (ngal, 1))  # redshift wavelength
    wave_s *= (1. + zred[:, None])

    # convert fluxes
    _spec = _spec_s / (
        4. * np.pi *
        (zred[:, None] * const.c / H0).to(u.cm)**2) / _wave_s**2 * const.c
    spec_s = (_spec.to(u.erg / u.s / u.cm**2 / u.Angstrom)).value * 1e17

    photo_true, mag_true = FM.Photo_DESI(wave_s, spec_s)

    # r < 20 cut
    target_selection = (mag_true[:, 1] <= 20.)

    # compile meta data
    meta = {}
    meta['logM_total'] = ftng['logmstar'][...][:ngal][target_selection]
    meta['sfr_100myr'] = 10.**ftng['logsfr.100'][...][:ngal][target_selection]
    meta['redshift'] = zred[target_selection]  # save to metadata

    # 1. generate 'true' photometry from noiseless spectra
    wave_s = wave_s[target_selection, :]
    spec_s = spec_s[target_selection, :]
    photo_true = photo_true[target_selection, :]

    # 2. assign uncertainties to the photometry using BGS targets from the Legacy survey
    bgs_targets = h5py.File(
        os.path.join(UT.dat_dir(), 'bgs.1400deg2.rlim21.0.hdf5'), 'r')
    n_targets = len(bgs_targets['ra'][...])

    bands = ['g', 'r', 'z', 'w1', 'w2', 'w3', 'w4']

    bgs_photo = np.zeros((n_targets, len(bands)))
    bgs_photo_ivar = np.zeros((n_targets, len(bands)))
    bgs_fiberflux = np.zeros(n_targets)  # r-band fiber flux
    for ib, band in enumerate(bands):
        bgs_photo[:, ib] = bgs_targets['flux_%s' % band][...]
        bgs_photo_ivar[:, ib] = bgs_targets['flux_ivar_%s' % band][...]
    bgs_fiberflux = bgs_targets['fiberflux_r'][...]

    # construct KD tree from BGS targets (currently downsampled)
    bgs_features = np.array([
        bgs_photo[:, 0], bgs_photo[:, 1], bgs_photo[:, 2],
        bgs_photo[:, 0] - bgs_photo[:, 1], bgs_photo[:, 1] - bgs_photo[:, 2]
    ]).T
    tree = KDTree(bgs_features)
    # match ivars and fiberflux
    match_features = np.array([
        photo_true[:, 0], photo_true[:, 1], photo_true[:, 2],
        photo_true[:, 0] - photo_true[:, 1],
        photo_true[:, 1] - photo_true[:, 2]
    ]).T
    dist, indx = tree.query(match_features)
    photo_ivars = bgs_photo_ivar[indx, :]
    photo_fiber_true = bgs_fiberflux[indx]

    # 3.a. apply the uncertainty to the photometry to get "measured" photometry.
    photo_meas = photo_true + photo_ivars**-0.5 * np.random.randn(
        photo_true.shape[0], photo_true.shape[1])
    # ***this needs to be checked; sometimes it gives greater than 1***
    # ***this needs to be checked; sometimes it gives greater than 1***
    # ***this needs to be checked; sometimes it gives greater than 1***
    # ***this needs to be checked; sometimes it gives greater than 1***
    f_fiber = np.clip(photo_fiber_true / photo_true[:, 1], None,
                      1.)  # (r fiber flux) / (r total flux)
    meta['logM_fiber'] = np.log10(f_fiber) + meta['logM_total']

    # apply uncertainty to fiber flux as well
    photo_fiber_meas = photo_fiber_true + f_fiber * photo_ivars[:,
                                                                1]**-0.5 * np.random.randn(
                                                                    photo_true.
                                                                    shape[0])
    photo_ivar_fiber = f_fiber**-2 * photo_ivars[:, 1]

    # 3.b. get fiber spectra by scaling down noiseless Lgal source spectra
    spectra_fiber = spec_s * f_fiber[:, None]  # 10e-17 erg/s/cm2/A

    # 4. generate BGS like spectra
    # read in sampled observing conditions, sky brightness, and exposure time
    _fsky = os.path.join(UT.dat_dir(), 'mini_mocha',
                         'bgs.exposure.surveysim.150s.v0p4.sample.hdf5')
    fsky = h5py.File(_fsky, 'r')

    nexp = len(fsky['airmass'][...])  # number of exposures
    wave_sky = fsky['wave'][...]  # sky wavelength
    sbright_sky = fsky['sky'][...]

    # store to meta-data
    for k in [
            'airmass', 'moon_alt', 'moon_ill', 'moon_sep', 'seeing', 'sun_alt',
            'sun_sep', 'texp_total', 'transp'
    ]:
        meta[k] = fsky[k][...]
    meta['wave_sky'] = wave_sky
    meta['sbright_sky'] = sbright_sky

    # generate BGS spectra for the exposures
    spectra_bgs = {}
    for iexp in range(nexp):
        # sky brightness of exposure
        Isky = [wave_sky, sbright_sky[iexp]]

        fbgs = os.path.join(
            UT.dat_dir(), 'mini_mocha',
            'tng.mini_mocha.bgs_spec.%iof%i.fits' % (iexp + 1, nexp))

        # interpolate source spectra onto linearly spaced wavelengths
        wlin = np.linspace(1e3, 2e4, 19000)
        spectra_fiber_lin = np.zeros((spectra_fiber.shape[0], len(wlin)))
        for i in range(spectra_fiber.shape[0]):
            spectra_fiber_lin[i] = np.interp(wlin, wave_s[i, :],
                                             spectra_fiber[i, :])

        bgs_spec = FM.Spec_BGS(
            wlin,  # wavelength  
            spectra_fiber_lin,  # fiber spectra flux 
            fsky['texp_total'][...][iexp],  # exp time
            fsky['airmass'][...][iexp],  # airmass 
            Isky,
            filename=fbgs)

        if iexp == 0:
            spectra_bgs['wave_b'] = bgs_spec.wave['b']
            spectra_bgs['wave_r'] = bgs_spec.wave['r']
            spectra_bgs['wave_z'] = bgs_spec.wave['z']
            spectra_bgs['flux_b'] = np.zeros(
                (nexp, bgs_spec.flux['b'].shape[0],
                 bgs_spec.flux['b'].shape[1]))
            spectra_bgs['flux_r'] = np.zeros(
                (nexp, bgs_spec.flux['r'].shape[0],
                 bgs_spec.flux['r'].shape[1]))
            spectra_bgs['flux_z'] = np.zeros(
                (nexp, bgs_spec.flux['z'].shape[0],
                 bgs_spec.flux['z'].shape[1]))
            spectra_bgs['ivar_b'] = np.zeros(
                (nexp, bgs_spec.flux['b'].shape[0],
                 bgs_spec.flux['b'].shape[1]))
            spectra_bgs['ivar_r'] = np.zeros(
                (nexp, bgs_spec.flux['r'].shape[0],
                 bgs_spec.flux['r'].shape[1]))
            spectra_bgs['ivar_z'] = np.zeros(
                (nexp, bgs_spec.flux['z'].shape[0],
                 bgs_spec.flux['z'].shape[1]))

        spectra_bgs['flux_b'][iexp] = bgs_spec.flux['b']
        spectra_bgs['flux_r'][iexp] = bgs_spec.flux['r']
        spectra_bgs['flux_z'][iexp] = bgs_spec.flux['z']

        spectra_bgs['ivar_b'][iexp] = bgs_spec.ivar['b']
        spectra_bgs['ivar_r'][iexp] = bgs_spec.ivar['r']
        spectra_bgs['ivar_z'][iexp] = bgs_spec.ivar['z']

    # write out everything
    fmeta = os.path.join(UT.dat_dir(), 'mini_mocha', 'tng.mini_mocha.meta.p')
    pickle.dump(meta, open(fmeta, 'wb'))  # meta-data

    fout = h5py.File(
        os.path.join(UT.dat_dir(), 'mini_mocha', 'tng.mini_mocha.hdf5'), 'w')

    fout.create_dataset('redshift', data=zred)
    # photometry
    for i, b in enumerate(bands):
        # 'true'
        fout.create_dataset('photo_flux_%s_true' % b, data=photo_true[:, i])
        fout.create_dataset('photo_ivar_%s_true' % b, data=photo_ivars[:, i])
        # 'measured'
        fout.create_dataset('photo_flux_%s_meas' % b, data=photo_meas[:, i])

    # fiber flux
    fout.create_dataset('photo_fiberflux_r_true', data=photo_fiber_true)
    fout.create_dataset('photo_fiberflux_r_meas', data=photo_fiber_meas)
    fout.create_dataset('photo_fiberflux_r_ivar', data=photo_ivar_fiber)
    fout.create_dataset('frac_fiber',
                        data=f_fiber)  # fraction of flux in fiber

    # spectroscopy
    # noiseless source spectra
    wlim = (_wave_s.value > 1e3) & (_wave_s.value < 2e4)
    fout.create_dataset('spec_wave_source', data=wave_s[:, wlim])
    fout.create_dataset('spec_flux_source', data=spec_s[:, wlim])
    # noiseless source spectra in fiber
    fout.create_dataset('spec_fiber_flux_source', data=spectra_fiber[:, wlim])

    # BGS source spectra
    for k in spectra_bgs.keys():
        fout.create_dataset('spec_%s_bgs' % k, data=spectra_bgs[k])
    fout.close()
    return None
Esempio n. 6
0
def cigale_dir(sample='mini_mocha'):
    return os.path.join(UT.dat_dir(), sample, 'cigale')
Esempio n. 7
0
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
Esempio n. 8
0
def fit_pFF_spectra(igal, noise='none', iter_max=10, overwrite=False):
    ''' Fit Lgal spectra. `noise` specifies whether to fit spectra without noise or 
    with BGS-like noise.  

    :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) 
    '''
    # read noiseless Lgal spectra of the spectral_challenge mocks
    specs, meta = Data.Spectra(sim='lgal',
                               noise=noise,
                               lib='bc03',
                               sample='mini_mocha')

    model = 'vanilla'
    w_obs = specs['wave']
    flux_obs = specs['flux'][igal]
    if noise != 'none': ivar_obs = specs['ivar'][igal]
    truths = [
        meta['logM_fiber'][igal],
        np.log10(meta['Z_MW'][igal]), meta['t_age_MW'][igal]
    ]
    labels = ['$\log M_*$', '$\log Z$', r'$t_{\rm age}$']

    if noise == 'none':  # no noise
        ivar_obs = np.ones(len(w_obs))

    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', 'pff',
                        'lgal.spec.noise_%s.%s.%i.hdf5' % (noise, model, igal))
    if os.path.isfile(f_bf):
        if not overwrite:
            print("** CAUTION: %s already exists **" % os.path.basename(f_bf))
    # initiating fit
    pff = Fitters.pseudoFirefly(model_name=model, prior=None)
    bestfit = pff.Fit_spec(w_obs,
                           flux_obs,
                           ivar_obs,
                           meta['redshift'][igal],
                           mask='emline',
                           fit_cap=1000,
                           iter_max=10,
                           writeout=f_bf,
                           silent=False)
    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('---------------')

    fig = plt.figure(figsize=(12, 4))
    sub = fig.add_subplot(111)
    sub.plot(bestfit['wavelength_data'],
             bestfit['flux_data'],
             c='k',
             zorder=1,
             lw=0.5)
    sub.plot(bestfit['wavelength_model'] * (1. + bestfit['redshift']),
             bestfit['flux_model'],
             c='C1')
    sub.set_xlabel('Wavelength', fontsize=20)
    sub.set_xlim(3500, 1e4)
    sub.set_ylabel('Flux', fontsize=20)
    sub.set_ylim(0., None)
    fig.savefig(f_bf.replace('.hdf5', '.png'), bbox_inches='tight')
    return None
Esempio n. 9
0
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
Esempio n. 10
0
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
Esempio n. 11
0
# --- plotting ---
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rcParams['text.usetex'] = True
mpl.rcParams['font.family'] = 'serif'
mpl.rcParams['axes.linewidth'] = 1.5
mpl.rcParams['axes.xmargin'] = 1
mpl.rcParams['xtick.labelsize'] = 'x-large'
mpl.rcParams['xtick.major.size'] = 5
mpl.rcParams['xtick.major.width'] = 1.5
mpl.rcParams['ytick.labelsize'] = 'x-large'
mpl.rcParams['ytick.major.size'] = 5
mpl.rcParams['ytick.major.width'] = 1.5
mpl.rcParams['legend.frameon'] = False

dir_fig = os.path.join(UT.dat_dir(), 'mini_mocha')


def mini_mocha_spec(noise='bgs0_legacy', sample='mini_mocha', method='ifsps'):
    ''' Compare properties inferred from forward modeled spectra 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',
Esempio n. 12
0
def fm_Lgal_mini_mocha(lib='bc03'):
    ''' generate spectroscopy and photometry for the mini Mock Challenge (MoCha)
    
    * input: galaxy properties (SFH, ZH, etc), noiseless spectra 
    * "true" photometry directly from noiseless spectra
    * assign photometric uncertainty and fiber flux using legacy imaging 
    * "measured" photometry and fiber flux + fiber source spectra (scaled down noiseless spectra), 
    * "BGS" spectra
    '''
    from scipy.spatial import cKDTree as KDTree
    # read in mini mocha galids
    fids = os.path.join(UT.dat_dir(), 'mini_mocha', 'lgal.galids.%s.txt' % lib)
    galids = np.loadtxt(fids, skiprows=1)

    # get Lgal meta data
    _meta = _lgal_metadata(galids)

    # get noiseless source spectra
    _meta_spec, spectra_s = _lgal_noiseless_spectra(galids, lib=lib)

    # compile meta-data
    meta = {}
    for k in _meta.keys():
        meta[k] = _meta[k]
    for k in _meta_spec.keys():
        meta[k] = _meta_spec[k]
    print('%.2f < z < %.2f' % (meta['redshift'].min(), meta['redshift'].max()))

    # 1. generate 'true' photometry from noiseless spectra
    photo_true, _ = FM.Photo_DESI(spectra_s['wave'], spectra_s['flux_dust'])

    # 2. assign uncertainties to the photometry using BGS targets from the Legacy survey
    bgs_targets = h5py.File(
        os.path.join(UT.dat_dir(), 'bgs.1400deg2.rlim21.0.hdf5'), 'r')
    n_targets = len(bgs_targets['ra'][...])

    bands = ['g', 'r', 'z', 'w1', 'w2', 'w3', 'w4']

    bgs_photo = np.zeros((n_targets, len(bands)))
    bgs_photo_ivar = np.zeros((n_targets, len(bands)))
    bgs_fiberflux = np.zeros(n_targets)  # r-band fiber flux
    for ib, band in enumerate(bands):
        bgs_photo[:, ib] = bgs_targets['flux_%s' % band][...]
        bgs_photo_ivar[:, ib] = bgs_targets['flux_ivar_%s' % band][...]
    bgs_fiberflux = bgs_targets['fiberflux_r'][...]

    # construct KD tree from BGS targets (currently downsampled)
    bgs_features = np.array([
        bgs_photo[:, 0], bgs_photo[:, 1], bgs_photo[:, 2],
        bgs_photo[:, 0] - bgs_photo[:, 1], bgs_photo[:, 1] - bgs_photo[:, 2]
    ]).T
    tree = KDTree(bgs_features)
    # match ivars and fiberflux
    match_features = np.array([
        photo_true[:, 0], photo_true[:, 1], photo_true[:, 2],
        photo_true[:, 0] - photo_true[:, 1],
        photo_true[:, 1] - photo_true[:, 2]
    ]).T
    dist, indx = tree.query(match_features)
    photo_ivars = bgs_photo_ivar[indx, :]
    photo_fiber_true = bgs_fiberflux[indx]

    # 3.a. apply the uncertainty to the photometry to get "measured" photometry.
    photo_meas = photo_true + photo_ivars**-0.5 * np.random.randn(
        photo_true.shape[0], photo_true.shape[1])

    f_fiber = photo_fiber_true / photo_true[:,
                                            1]  # (r fiber flux) / (r total flux)
    assert f_fiber.max() <= 1.
    meta['logM_fiber'] = np.log10(f_fiber) + meta['logM_total']

    # apply uncertainty to fiber flux as well
    photo_fiber_meas = photo_fiber_true + f_fiber * photo_ivars[:,
                                                                1]**-0.5 * np.random.randn(
                                                                    photo_true.
                                                                    shape[0])
    photo_ivar_fiber = f_fiber**-2 * photo_ivars[:, 1]

    # 3.b. get fiber spectra by scaling down noiseless Lgal source spectra
    spectra_fiber = spectra_s[
        'flux_dust'] * f_fiber[:, None]  # 10e-17 erg/s/cm2/A

    # 4. generate BGS like spectra
    # read in sampled observing conditions, sky brightness, and exposure time
    _fsky = os.path.join(UT.dat_dir(), 'mini_mocha',
                         'bgs.exposure.surveysim.150s.v0p4.sample.hdf5')
    fsky = h5py.File(_fsky, 'r')

    nexp = len(fsky['airmass'][...])  # number of exposures
    wave_sky = fsky['wave'][...]  # sky wavelength
    sbright_sky = fsky['sky'][...]

    # store to meta-data
    for k in [
            'airmass', 'moon_alt', 'moon_ill', 'moon_sep', 'seeing', 'sun_alt',
            'sun_sep', 'texp_total', 'transp'
    ]:
        meta[k] = fsky[k][...]
    meta['wave_sky'] = wave_sky
    meta['sbright_sky'] = sbright_sky

    # generate BGS spectra for the exposures
    spectra_bgs = {}
    for iexp in range(nexp):

        # sky brightness of exposure
        Isky = [wave_sky * u.Angstrom, sbright_sky[iexp]]

        fbgs = os.path.join(
            UT.dat_dir(), 'mini_mocha', 'lgal.bgs_spec.%s.v%s.%iof%i.fits' %
            (lib, version, iexp + 1, nexp))

        bgs_spec = FM.Spec_BGS(
            spectra_s['wave'],  # wavelength  
            spectra_fiber,  # fiber spectra flux 
            fsky['texp_total'][...][iexp],  # exp time
            fsky['airmass'][...][iexp],  # airmass 
            Isky,
            filename=fbgs)

        if iexp == 0:
            spectra_bgs['wave_b'] = bgs_spec.wave['b']
            spectra_bgs['wave_r'] = bgs_spec.wave['r']
            spectra_bgs['wave_z'] = bgs_spec.wave['z']
            spectra_bgs['flux_b'] = np.zeros(
                (nexp, bgs_spec.flux['b'].shape[0],
                 bgs_spec.flux['b'].shape[1]))
            spectra_bgs['flux_r'] = np.zeros(
                (nexp, bgs_spec.flux['r'].shape[0],
                 bgs_spec.flux['r'].shape[1]))
            spectra_bgs['flux_z'] = np.zeros(
                (nexp, bgs_spec.flux['z'].shape[0],
                 bgs_spec.flux['z'].shape[1]))
            spectra_bgs['ivar_b'] = np.zeros(
                (nexp, bgs_spec.flux['b'].shape[0],
                 bgs_spec.flux['b'].shape[1]))
            spectra_bgs['ivar_r'] = np.zeros(
                (nexp, bgs_spec.flux['r'].shape[0],
                 bgs_spec.flux['r'].shape[1]))
            spectra_bgs['ivar_z'] = np.zeros(
                (nexp, bgs_spec.flux['z'].shape[0],
                 bgs_spec.flux['z'].shape[1]))

        spectra_bgs['flux_b'][iexp] = bgs_spec.flux['b']
        spectra_bgs['flux_r'][iexp] = bgs_spec.flux['r']
        spectra_bgs['flux_z'][iexp] = bgs_spec.flux['z']

        spectra_bgs['ivar_b'][iexp] = bgs_spec.ivar['b']
        spectra_bgs['ivar_r'][iexp] = bgs_spec.ivar['r']
        spectra_bgs['ivar_z'][iexp] = bgs_spec.ivar['z']

    # write out everything
    fmeta = os.path.join(UT.dat_dir(), 'mini_mocha',
                         'lgal.mini_mocha.%s.v%s.meta.p' % (lib, version))
    fout = h5py.File(
        os.path.join(UT.dat_dir(), 'mini_mocha',
                     'lgal.mini_mocha.%s.v%s.hdf5' % (lib, version)), 'w')

    pickle.dump(meta, open(fmeta, 'wb'))  # meta-data

    # photometry
    for i, b in enumerate(bands):
        # 'true'
        fout.create_dataset('photo_flux_%s_true' % b, data=photo_true[:, i])
        fout.create_dataset('photo_ivar_%s_true' % b, data=photo_ivars[:, i])
        # 'measured'
        fout.create_dataset('photo_flux_%s_meas' % b, data=photo_meas[:, i])

    # fiber flux
    fout.create_dataset('photo_fiberflux_r_true', data=photo_fiber_true)
    fout.create_dataset('photo_fiberflux_r_meas', data=photo_fiber_meas)
    fout.create_dataset('photo_fiberflux_r_ivar', data=photo_ivar_fiber)
    fout.create_dataset('frac_fiber',
                        data=f_fiber)  # fraction of flux in fiber

    # spectroscopy
    # noiseless source spectra
    wlim = (spectra_s['wave'] < 2e5) & (spectra_s['wave'] > 1e3
                                        )  # truncating the spectra
    fout.create_dataset('spec_wave_source', data=spectra_s['wave'][wlim])
    fout.create_dataset('spec_flux_source',
                        data=spectra_s['flux_dust'][:, wlim])
    # noiseless source spectra in fiber
    fout.create_dataset('spec_fiber_flux_source', data=spectra_fiber[:, wlim])

    # BGS source spectra
    for k in spectra_bgs.keys():
        fout.create_dataset('spec_%s_bgs' % k, data=spectra_bgs[k])
    fout.close()
    return None
Esempio n. 13
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 
Esempio n. 14
0
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