Exemple #1
0
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 
Exemple #2
0
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 
Exemple #3
0
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
Exemple #4
0
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
Exemple #5
0
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 
Exemple #7
0
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']) 
Exemple #8
0
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'])
Exemple #9
0
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 
Exemple #10
0
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
Exemple #11
0
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 
Exemple #12
0
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 
Exemple #13
0
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')
Exemple #14
0
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 
Exemple #15
0
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 
Exemple #17
0
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 
Exemple #18
0
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
Exemple #19
0
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
Exemple #20
0
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
Exemple #21
0
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 
Exemple #23
0
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 
Exemple #25
0
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
Exemple #27
0
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 
Exemple #28
0
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
Exemple #29
0
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 
Exemple #30
0
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