예제 #1
0
def build_obs(fit_data, snr=10, **extras):
    import numpy as np
    import scipy
    import fsps
    import astropy
    import math

    from prospect.utils.obsutils import fix_obs
    import sedpy

    # The obs dictionary, empty for now
    obs = {}

    # These are the names of the relevant filters,
    # in the same order as the photometric data (see below)
    # And here we instantiate the `Filter()` objects using methods in `sedpy`,
    # and put the resultinf list of Filter objects in the "filters" key of the `obs` dictionary
    obs["filters"] = sedpy.observate.load_filters(fit_data['filtername'])
    # Now we store the measured fluxes for a single object, **in the same order as "filters"**
    # In this example we use a row of absolute AB magnitudes from Johnson et al. 2013 (NGC4163)
    # We then turn them into apparent magnitudes based on the supplied `ldist` meta-parameter.
    # You could also, e.g. read from a catalog.
    # The units of the fluxes need to be maggies (Jy/3631) so we will do the conversion here too.

    obs["maggies"] = [x / 3631 for x in fit_data['flux']]
    obs['maggies'] = np.array(obs['maggies'])

    # And now we store the uncertainties (again in units of maggies)
    # In this example we are going to fudge the uncertainties based on the supplied `snr` meta-parameter.
    obs["maggies_unc"] = [x / 3631 for x in fit_data["unc"]]
    obs['maggies_unc'] = np.array(obs['maggies_unc'])

    # Now we need a mask, which says which flux values to consider in the likelihood.
    # IMPORTANT: the mask is *True* for values that you *want* to fit,
    # and *False* for values you want to ignore.  Here we ignore the spitzer bands.
    obs["phot_mask"] = np.array([True for f in obs["filters"]])

    # This is an array of effective wavelengths for each of the filters.
    # It is not necessary, but it can be useful for plotting so we store it here as a convenience
    obs["phot_wave"] = np.array([f.wave_effective for f in obs["filters"]])

    # We do not have a spectrum, so we set some required elements of the obs dictionary to None.
    # (this would be a vector of vacuum wavelengths in angstroms)
    obs["wavelength"] = None
    # (this would be the spectrum in units of maggies)
    obs["spectrum"] = None
    # (spectral uncertainties are given here)
    obs['unc'] = None
    # (again, to ignore a particular wavelength set the value of the
    #  corresponding elemnt of the mask to *False*)
    obs['mask'] = None

    # This function ensures all required keys are present in the obs dictionary,
    # adding default values if necessary
    obs = fix_obs(obs)

    # Due to some unknown reason, fix_obs will change true to false in phot_mask.We do it again after the function.
    obs["phot_mask"] = np.array([True for f in obs["filters"]])

    return obs
예제 #2
0
def build_obs(objid=objid, phottable=None, luminosity_distance=None, **kwargs):

    from prospect.utils.obsutils import fix_obs

    wl, flux, flux_err = prospector_wl_flux(path_spec, path_err)
    maggies, emaggies = phot_maggies(work_df_uvista)

    obs = {}
    filternames = [
        "UVISTA_Ks",
        "UVISTA_H",
        "UVISTA_J",
        "UVISTA_Y",
        "IB427.SuprimeCam",
        "IB464.SuprimeCam",
        "IB484.SuprimeCam",
        "IB505.SuprimeCam",
        "IB527.SuprimeCam",
        "IB574.SuprimeCam",
        "IB624.SuprimeCam",
        "IB679.SuprimeCam",
        "IB709.SuprimeCam",
        "IB738.SuprimeCam",
        "IB767.SuprimeCam",
        "IB827.SuprimeCam",
        "spitzer_irac_ch1",
        "spitzer_irac_ch2",
        "spitzer_irac_ch3",
        "spitzer_irac_ch4",  #"spitzer_mips_24",
        "galex_FUV",
        "galex_NUV",
        "u_megaprime_sagem",
        "B_subaru",
        "V_subaru",
        "g_subaru",
        "r_subaru",
        "i_subaru",
        "z_subaru",
    ]
    obs['filters'] = load_filters(filternames)
    obs['maggies'] = maggies
    floor_phot = 0.05 * obs['maggies']
    obs['maggies_unc'] = np.clip(emaggies, floor_phot, np.inf)
    obs['wavelength'] = wl
    obs['spectrum'] = flux
    floor_spec = 0.01 * obs['spectrum']
    obs['unc'] = np.clip(flux_err, floor_spec, np.inf)
    obs['objid'] = objid

    obs = fix_obs(obs)
    return obs
def build_obs(snr=50,mags=np.array({}),**extras):
    obs = {}
    BB = ['hsc_{0}'.format(b) for b in ['g','r','i','z','y']]
    NB = ['{0}'.format(b) for b in ['N708','N540']]
    filternames = BB + NB
    obs["filters"] = sedpy.observate.load_filters(filternames)
    obs["maggies"] = 10**(-0.4*mags)
    obs["maggies_unc"] = (1./snr) * obs["maggies"]
    obs["phot_wave"] = np.array([f.wave_effective for f in obs["filters"]])
    obs["wavelength"] = None
    obs["spectrum"] = None
    obs['unc'] = None
    obs['mask'] = None
    obs = fix_obs(obs)
                                      
    return obs
def build_obs(binNum=0, infile=None, **extras):

    import numpy as np
    from astropy.table import Table
    from sedpy.observate import load_filters
    from prospect.utils.obsutils import fix_obs

    table = Table.read(infile)

    flux_columns = [col for col in table.colnames if col.endswith('_flux')]
    e_flux_columns = [col.replace('flux', 'err') for col in flux_columns]
    nPix_columns = [col.replace('flux', 'nPix') for col in flux_columns]
    use_columns = [col.replace('flux', 'use') for col in flux_columns]
    filternames = ['hff_' + col.replace('_flux', '') for col in flux_columns]

    fluxes = np.array(list(table[flux_columns][binNum])) / 3631  # in maggies
    e_fluxes = np.array(list(
        table[e_flux_columns][binNum])) / 3631  # in maggies
    nPixels = np.array(list(table[nPix_columns][binNum]))
    use_col = np.array(list(table[use_columns][binNum]))

    fluxes_per_pixel = fluxes / nPixels
    e_fluxes_per_pixel = e_fluxes / nPixels

    max_SNR = 20
    SNR_acceptable = (fluxes_per_pixel / e_fluxes_per_pixel < max_SNR)
    e_fluxes_per_pixel[
        ~SNR_acceptable] = fluxes_per_pixel[~SNR_acceptable] / max_SNR

    obs = {}

    obs['filters'] = load_filters(filternames)
    obs['maggies'], obs['maggies_unc'] = fluxes_per_pixel, e_fluxes_per_pixel

    obs['phot_mask'] = use_col
    obs['phot_wave'] = np.array([f.wave_effective for f in obs['filters']])

    obs['wavelength'], obs['spectrum'] = None, None
    obs['unc'], obs['mask'] = None, None

    obs['binNum'], obs['nPixels'] = binNum, nPixels

    obs = fix_obs(obs)

    return obs
예제 #5
0
def build_cpz_obs(filter_selection, galaxy=None):
    """Build a dictionary of photometry (and eventually spectra?)
    Arguments are hyperparameters that are likely to change over runs

    :returns obs:
        A dictionary of observational data to use in the fit.
    """
    obs = {}
    if galaxy is not None:
        obs["filters"], obs["maggies"], obs[
            'maggies_unc'] = load_photometry.load_galaxy_for_prospector(
                galaxy, filter_selection)
    else:  # dummy galaxy
        obs["filters"], obs["maggies"], obs[
            'maggies_unc'] = load_photometry.load_dummy_galaxy_for_prospector(
                galaxy, filter_selection)

    # Now we need a mask, which says which flux values to consider in the likelihood.
    # IMPORTANT: the mask is *True* for values that you *want* to fit
    obs["phot_mask"] = np.array([True for _ in obs['filters']])

    # This is an array of effective wavelengths for each of the filters.
    # It is not necessary, but it can be useful for plotting so we store it here as a convenience
    obs["phot_wave"] = np.array([f.wave_effective for f in obs["filters"]])

    # We do not have a spectrum, so we set some required elements of the obs dictionary to None.
    # (this would be a vector of vacuum wavelengths in angstroms)
    # Note: could use the SDSS spectra here for truth label fitting
    obs["wavelength"] = None
    obs["spectrum"] = None
    obs['unc'] = None
    obs['mask'] = None

    # This function ensures all required keys are present in the obs dictionary,
    # adding default values if necessary
    obs = fix_obs(obs)

    return obs
예제 #6
0
def build_obs(objid=0, luminosity_distance=None, **kwargs):
    """Load photometry from an ascii file.  Assumes the following columns:
    `objid`, `filterset`, [`mag0`,....,`magN`] where N >= 11.  The User should
    modify this function (including adding keyword arguments) to read in their
    particular data format and put it in the required dictionary.

    :param objid:
        The object id for the row of the photomotery file to use.  Integer.
        Requires that there be an `objid` column in the ascii file.

    :param phottable:
        Name (and path) of the ascii file containing the photometry.

    :param luminosity_distance: (optional)
        The Johnson 2013 data are given as AB absolute magnitudes.  They can be
        turned into apparent magnitudes by supplying a luminosity distance.

    :returns obs:
        Dictionary of observational data.
    """

    from prospect.utils.obsutils import fix_obs

    #filterlist = load_filters(['sdss_u0', 'sdss_g0', 'sdss_r0', 'sdss_i0', 'sdss_z0',
    #               'galex_FUV', 'galex_NUV', 'wise_w1', 'wise_w2',
    #               'wise_w3', 'wise_w4'])

    filterlist = load_filters(args.filters)

    microns = np.load('{0}/Prospector_files/wave.npy'.format(args.path))
    angstroms = microns * 1e4

    spec = np.load('{0}/Prospector_files/spec.npy'.format(
        args.path))  # units of Jy
    f_lambda_cgs = (1 / 33333) * (1 / (angstroms**2)) * spec

    mags = getSED(angstroms, f_lambda_cgs,
                  filterlist=filterlist)  # AB magnitudes

    #print('AB mags', mags)
    #np.save('ab_mags.npy', mags)

    maggies = 10**(-0.4 * mags)  # convert to maggies

    wave_eff = np.zeros(len(filterlist))

    for i in range(len(filterlist)):
        filterlist[i].get_properties()
        wave_eff[i] = filterlist[i].wave_effective

    print('maggies', maggies)
    print('effective wavelengths', wave_eff)

    # Build output dictionary.
    obs = {}
    obs['filters'] = filterlist
    obs['maggies'] = maggies
    obs['maggies_unc'] = obs['maggies'] * 0.07
    obs['phot_mask'] = np.isfinite(np.squeeze(maggies))
    obs['wavelength'] = None
    obs['spectrum'] = None
    obs['unc'] = None

    obs['objid'] = None

    # This ensures all required keys are present and adds some extra useful info
    obs = fix_obs(obs)

    return obs
예제 #7
0
파일: fit_host.py 프로젝트: muryelgp/TDEpy
def build_obs(path, tde):
    """Build a dictionary of observational data.

    :returns obs:
        A dictionary of observational data to use in the fit.
    """
    from prospect.utils.obsutils import fix_obs
    import sedpy

    # The obs dictionary, empty for now
    obs = {}

    tde_dir = os.path.join(path, tde)
    try:
        band, wl_c, ab_mag, ab_mag_err, catalogs, apertures = np.loadtxt(
            os.path.join(tde_dir, 'host', 'host_phot_obs.txt'),
            dtype={'names': (
                'band', 'wl_0', 'ab_mag', 'ab_mag_err', 'catalog', 'apertures'),
                'formats': (
                    'U5', np.float, np.float, np.float, 'U10', 'U10')},
            unpack=True, skiprows=2)
    except:
        raise Exception('We should run download_host_data() before trying to fit it.')

    filter_dic = {'WISE_W4': 'wise_w4', 'WISE_W3': 'wise_w3', 'WISE_W2': 'wise_w2', 'WISE_W1': 'wise_w1',
                  'UKIDSS_Y': 'UKIRT_Y', 'UKIDSS_J': 'UKIRT_J', 'UKIDSS_H': 'UKIRT_H', 'UKIDSS_K': 'UKIRT_K',
                  '2MASS_J': 'twomass_J', '2MASS_H': 'twomass_H', '2MASS_Ks': 'twomass_Ks',
                  'PAN-STARRS_y': 'PAN-STARRS_y', 'PAN-STARRS_z': 'PAN-STARRS_z', 'PAN-STARRS_i': 'PAN-STARRS_i',
                  'PAN-STARRS_r': 'PAN-STARRS_r', 'PAN-STARRS_g': 'PAN-STARRS_g',
                  'DES_Y': 'decam_Y', 'DES_z': 'decam_z', 'DES_i': 'decam_i', 'DES_r': 'decam_r', 'DES_g': 'decam_g',
                  'SkyMapper_u': 'SkyMapper_u', 'SkyMapper_z': 'SkyMapper_z', 'SkyMapper_i': 'SkyMapper_i',
                  'SkyMapper_r': 'SkyMapper_r',
                  'SkyMapper_g': 'SkyMapper_g', 'SkyMapper_v': 'SkyMapper_v',
                  'SDSS_u': 'sdss_u0', 'SDSS_z': 'sdss_z0', 'SDSS_g': 'sdss_g0', 'SDSS_r': 'sdss_r0',
                  'SDSS_i': 'sdss_i0',
                  'GALEX_NUV': 'galex_NUV', 'GALEX_FUV': 'galex_FUV',
                  'Swift/UVOT_UVW1': 'uvot_w1', 'Swift/UVOT_UVW2': 'uvot_w2', 'Swift/UVOT_UVM2': 'uvot_m2',
                  'Swift/UVOT_V': 'uvot_V', 'Swift/UVOT_B': 'uvot_B', 'Swift/UVOT_U': 'uvot_U'}

    flag = np.isfinite(ab_mag * ab_mag_err)

    catalog_bands = [catalogs[i] + '_' + band[i] for i in range(len(catalogs))]
    filternames = [filter_dic[i] for i in catalog_bands]
    # And here we instantiate the `Filter()` objects using methods in `sedpy`,
    # and put the resultinf list of Filter objects in the "filters" key of the `obs` dictionary
    obs["filters"] = np.ndarray((0))
    for i in range(len(filternames)):
        # print(filternames[i])
        obs["filters"] = np.append(obs["filters"], sedpy.observate.Filter(filternames[i],
                                                                          directory=pkg_resources.resource_filename(
                                                                              "TDEpy", 'filters')))

    obs["phot_wave"] = np.zeros(flag.shape)
    obs["phot_mask"] = np.zeros(flag.shape)
    obs["maggies"] = np.zeros(flag.shape)
    obs["maggies_unc"] = np.zeros(flag.shape)
    obs["phot_mask"] = np.ones(np.shape(flag), dtype=bool)

    # Measurments
    for i in range(len(flag)):
        if flag[i]:
            mags = np.array(ab_mag[i])
            mags_err = np.array(ab_mag_err[i])
            signal = tools.mag_to_flux(mags, wl_c[i])
            noise = tools.dmag_to_df(mags_err, signal)
            snr = signal / noise
            obs["maggies"][i] = 10 ** (-0.4 * mags)
            obs["maggies_unc"][i] = obs["maggies"][i] * (1 / snr)
            obs["phot_wave"][i] = np.array(wl_c[i])
        else:
            obs["maggies"][i] = 0
            obs["maggies_unc"][i] = 10 ** (-0.4 * ab_mag[i])
            obs["phot_wave"][i] = np.array(wl_c[i])

    obs["wavelength"] = None
    obs["spectrum"] = None
    obs['unc'] = None
    obs['mask'] = None

    # This function ensures all required keys are present in the obs dictionary,
    # adding default values if necessary
    obs = fix_obs(obs)

    return obs
예제 #8
0
def build_obs(object_name="gc1", **extras):
    """Build a dictionary of observational data.  In this example
    we will read from text files named <object_name>.spec.dat and <object_name>.phot.dat

    Parameters
    ----------
    object_name : string
        The name of the object, used to find data files

    Returns
    -------
    obs : dictionary
        A dictionary of observational data to use in the fit.
    """
    from prospect.utils.obsutils import fix_obs
    from sedpy.observate import load_filters

    # The obs dictionary, empty for now
    obs = {}

    # These are the names of the relevant filters,
    # in the same order as the photometric data (see below)
    phot_file = "{}.phot.dat".format(object_name)
    spec_file = "{}.spec.dat".format(object_name)

    # --- Photometric Data ---

    # this is the description of the column formats
    if VERS == 2:
        stype = "S20"
    elif VERS == 3:
        stype = "U20"
    cols = [("filtername", stype), ("flux", np.float), ("unc", np.float)]
    # read the file
    phot = np.genfromtxt(phot_file, dtype=np.dtype(cols), skip_header=1)
    # And here we instantiate the `Filter()` objects using methods in `sedpy`,
    # and put the resulting list of Filter objects in the "filters" key of the `obs` dictionary
    # These Filter objects will perform projections of the model SED onto the filters.
    obs["filters"] = load_filters(phot["filtername"])
    # Now we store the measured fluxes for a single object, **in the same order as "filters"**
    # The units of the fluxes need to be maggies (Jy/3631) so we will do the conversion here too.
    obs["maggies"] = phot["flux"] * 1e-3 / 3631
    # And now we store the uncertainties (again in units of maggies)
    obs["maggies_unc"] = phot["unc"] * 1e-3 / 3631
    # Now we need a mask, which says which flux values to consider in the likelihood.
    # IMPORTANT: the mask is *True* for values that you *want* to fit,
    # and *False* for values you want to ignore.  Here we ignore the spitzer bands.
    obs["phot_mask"] = np.array(
        ['spitzer' not in f.name for f in obs["filters"]])
    # This is an array of effective wavelengths for each of the filters.
    # It is not necessary, but it can be useful for plotting so we store it here as a convenience
    obs["phot_wave"] = np.array([f.wave_effective for f in obs["filters"]])

    # --- Spectroscopic Data ---

    # this is the description of the column formats
    cols = [("wavelength", np.float), ("flux", np.float), ("unc", np.float)]
    # read the file
    spec = np.genfromtxt(spec_file, dtype=np.dtype(cols), skip_header=1)
    # add the wavelengths (restframe, vacuum)
    obs["wavelength"] = spec["wavelength"]
    # (this would be the spectrum in units of maggies)
    obs["spectrum"] = spec["flux"] * 1e-3 / 3631
    # (spectral uncertainties are given here)
    obs['unc'] = spec["unc"] * 1e-3 / 3631
    # (again, to ignore a particular wavelength set the value of the
    #  corresponding elemnt of the mask to *False*)
    obs['mask'] = spec["unc"] > 0

    # This function ensures all required keys are present in the obs dictionary,
    # adding default values if necessary
    obs = fix_obs(obs)

    # That's it!
    return obs
예제 #9
0
def load_obs(seed=1, nproc=1, nmin=10, verbose=False, sps=None):
    """Load the photometry for NGC5322.
    
    """
    import sedpy
    from prospect.utils.obsutils import fix_obs

    # photometry in maggies and ivarmaggies
    phot = dict(FUV=[
        3.63e-4 * 1e3 / maggies2mJy, 1 / (9.76e-6 * 1e3 / maggies2mJy)**2
    ],
                NUV=[
                    1.87e-3 * 1e3 / maggies2mJy,
                    1 / (1.02e-5 * 1e3 / maggies2mJy)**2
                ],
                g=[51032.92 * 1e-9, 0.060252897 * 1e18],
                r=[108675.04 * 1e-9, 0.019527867 * 1e18],
                z=[173005.16 * 1e-9, 0.011034269 * 1e18],
                W1=[126294.73 * 1e-9, 0.1742277 * 1e18],
                W2=[67562.625 * 1e-9, 0.03782868 * 1e18],
                W3=[34738.555 * 1e-9, 0.000105459614 * 1e18],
                W4=[32283.23 * 1e-9, 2.8181848e-06 * 1e18])

    # Minimum uncertainties
    factor = 2.5 / np.log(10)
    minerr = dict(FUV=0.05,
                  NUV=0.3,
                  g=0.01,
                  r=0.01,
                  z=0.02,
                  W1=0.02,
                  W2=0.02,
                  W3=0.05,
                  W4=0.05)
    for key in phot.keys():
        maggies = phot[key][0]
        ivarmaggies = phot[key][1]
        err = factor / np.sqrt(ivarmaggies) / maggies
        err2 = err**2 + minerr[key]**2
        phot[key][1] = factor**2 / (maggies**2 * err2)

    galex = ['galex_FUV', 'galex_NUV']
    ls = ['sdss_{}0'.format(b) for b in ['g', 'r', 'z']]
    wise = ['wise_w{}'.format(n) for n in ['1', '2', '3', '4']]
    filternames = galex + ls + wise

    obs = {}
    obs['redshift'] = 0.0060
    obs["filters"] = sedpy.observate.load_filters(filternames)

    obs["maggies"] = np.array([phot[filt][0] for filt in phot.keys()])
    obs["maggies_unc"] = np.array(
        [1 / np.sqrt(phot[filt][1]) for filt in phot.keys()])

    # mask out W4
    #obs["phot_mask"] = np.array(['w4' in f.name for f in obs["filters"]])

    # Create a handy vector of effective wavelengths (optional)
    obs["phot_wave"] = [f.wave_effective for f in obs["filters"]]
    obs["wavelength"] = None  # spectral wavelength
    obs["spectrum"] = None
    obs['unc'] = None  # spectral uncertainties are given here
    obs['mask'] = [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0]
    obs = fix_obs(obs)

    run_params = {}
    run_params['redshift'] = obs['redshift']
    run_params['verbose'] = verbose
    run_params['debug'] = False
    run_params['seed'] = seed
    run_params['nproc'] = nproc
    run_params['param_file'] = ''  # no parameter file

    run_params['min_method'] = 'lm'
    run_params['nmin'] = 1

    if sps:
        run_params['sps_libraries'] = sps.ssp.libraries

    # dynesty Fitter parameters
    dyn_params = {
        'nested_bound': 'multi',  # bounding method
        'nested_sample': 'unif',  # 'unif', 'slice' # sampling method
        'nested_nlive_init': 100,
        'nested_nlive_batch': 100,
        'nested_bootstrap': 0,
        'nested_dlogz_init': 0.05,
        'nested_weight_kwargs': {
            "pfrac": 1.0
        },
        #'nested_stop_kwargs': {"post_thresh": 0.05}
    }
    run_params.update(dyn_params)

    return obs, run_params
예제 #10
0
def build_obs(snr=10.0, filterset=["sdss_g0", "sdss_r0"],
             add_noise=True, **kwargs):
    """Make a mock dataset.  Feel free to add more complicated kwargs, and put
    other things in the run_params dictionary to control how the mock is
    generated.

    :param snr:
        The S/N of the phock photometry.  This can also be a vector of same
        lngth as the number of filters.

    :param filterset:
        A list of `sedpy` filter names.  Mock photometry will be generated
        for these filters.

    :param add_noise: (optional, boolean, default: True)
        If True, add a realization of the noise to the mock spectrum
    """
    from prospect.utils.obsutils import fix_obs

    # We'll put the mock data in this dictionary, just as we would for real
    # data.  But we need to know which bands (and wavelengths if doing
    # spectroscopy) in which to generate mock data.
    mock = {}
    mock['wavelength'] = None # No spectrum
    mock['spectrum'] = None # No spectrum
    mock['filters'] = load_filters(filterset)

    # We need the models to make a mock
    sps = build_sps(**kwargs)
    mod = build_model(**kwargs)

    # Now we get the mock params from the kwargs dict
    params = {}
    for p in mod.params.keys():
        if p in kwargs:
            params[p] = np.atleast_1d(kwargs[p])

    # And build the mock
    mod.params.update(params)
    spec, phot, _ = mod.mean_model(mod.theta, mock, sps=sps)

    # Now store some ancillary, helpful info;
    # this information is not required to run a fit.
    mock['true_spectrum'] = spec.copy()
    mock['true_maggies'] = phot.copy()
    mock['mock_params'] = deepcopy(mod.params)
    mock['mock_snr'] = snr
    mock["phot_wave"] = np.array([f.wave_effective for f in mock["filters"]])

    # And store the photometry, adding noise if desired
    pnoise_sigma = phot / snr
    if add_noise:
        pnoise = np.random.normal(0, 1, len(phot)) * pnoise_sigma
        mock['maggies'] = phot + pnoise
    else:
        mock['maggies'] = phot.copy()
    mock['maggies_unc'] = pnoise_sigma
    mock['phot_mask'] = np.ones(len(phot), dtype=bool)

    # This ensures all required keys are present
    mock = fix_obs(mock)

    return mock
예제 #11
0
def build_obs(snr=10, ldist=10.0, **extras):
    """Build a dictionary of photometry (and eventually spectra?)
    Arguments are hyperparameters that are likely to change over runs
    
    :param snr:
        The S/N to assign to the photometry, since none are reported 
        in Johnson et al. 2013
        
    :param ldist:
        The luminosity distance to assume for translating absolute magnitudes 
        into apparent magnitudes.
        
    :returns obs:
        A dictionary of observational data to use in the fit.
    """
    obs = {}

    # These are the names of the relevant filters,
    # in the same order as the photometric data (see below)
    galex = ['galex_FUV', 'galex_NUV']
    spitzer = ['spitzer_irac_ch' + n for n in ['1', '2', '3', '4']]
    sdss = ['sdss_{0}0'.format(b) for b in ['u', 'g', 'r', 'i', 'z']]
    filternames = galex + sdss + spitzer
    # And here we instantiate the `Filter()` objects using methods in `sedpy`,
    # and put the resultinf list of Filter objects in the "filters" key of the `obs` dictionary
    obs["filters"] = sedpy.observate.load_filters(filternames)

    # Now we store the measured fluxes for a single object, **in the same order as "filters"**
    # In this example we use a row of absolute AB magnitudes from Johnson et al. 2013 (NGC4163)
    # We then turn them into apparent magnitudes based on the supplied `ldist` meta-parameter.
    # You could also, e.g. read from a catalog.
    # The units of the fluxes need to be maggies (Jy/3631) so we will do the conversion here too.
    M_AB = np.array([
        -11.93, -12.37, -13.37, -14.22, -14.61, -14.86, -14.94, -14.09, -13.62,
        -13.23, -12.78
    ])
    dm = 25 + 5.0 * np.log10(ldist)
    mags = M_AB + dm
    obs["maggies"] = 10**(-0.4 * mags)

    # And now we store the uncertainties (again in units of maggies)
    # In this example we are going to fudge the uncertainties based on the supplied `snr` meta-parameter.
    obs["maggies_unc"] = (1. / snr) * obs["maggies"]

    # Now we need a mask, which says which flux values to consider in the likelihood.
    # IMPORTANT: the mask is *True* for values that you *want* to fit,
    # and *False* for values you want to ignore.  Here we ignore the spitzer bands.
    obs["phot_mask"] = np.array(
        ['spitzer' not in f.name for f in obs["filters"]])

    # This is an array of effective wavelengths for each of the filters.
    # It is not necessary, but it can be useful for plotting so we store it here as a convenience
    obs["phot_wave"] = np.array([f.wave_effective for f in obs["filters"]])

    # We do not have a spectrum, so we set some required elements of the obs dictionary to None.
    # (this would be a vector of vacuum wavelengths in angstroms)
    # Note: could use the SDSS spectra here for truth label fitting
    obs["wavelength"] = None
    obs["spectrum"] = None
    obs['unc'] = None
    obs['mask'] = None

    # This function ensures all required keys are present in the obs dictionary,
    # adding default values if necessary
    obs = fix_obs(obs)

    return obs
예제 #12
0
 def build_obs(self, obs=None, phot_mask=None, spec_mask=None, verbose=False, warnings=True, set_data=False):
     """
     Build a dictionary containing observations in a prospector compatible format.
     
     Options
     -------
     obs : [dict or None]
         Can load an already existing prospector compatible 'obs' dictionary.
         Automatically change the attributes to the given 'obs' dictionary.
         Default is None.
     
     phot_mask : [list(string) or None]
         Give a list of filters you want the SED fitting to be run on.
         The other filter measurements will be masked.
         If None, no mask is applied.
         Default is None.
     
     spec_mask : [tuple(float or None, float or None) or np.array or None]
         Give a tuple of two wavelength in AA (lower_limit, upper_limit) to run 
         the SED fitting on the input spectrum between the given limits.
         The rest of the spectrum is masked.
         You can give None for a limit to keep the whole spectrum in that direction.
         You also can directly give your own mask array.
         If None, the whole spectrum is fitted.
         Default is None.
     
     verbose : [bool]
         If True, print the built observation dictionary.
         Default is False.
     
     warnings : [bool]
         If True, allow warnings to be printed.
         Default is True.
     
     set_data : [bool]
         If 'obs' is not None, set to True if you want to extract and set attributes from the given 'obs' dictionary.
         Default is False.
     
     
     Returns
     -------
     Void
     """
     from prospect.utils.obsutils import fix_obs
     if obs is not None:
         self._obs = fix_obs(obs)
         if set_data:
             self._set_data_from_obs(obs=self.obs, warnings=warnings)
         return
     
     from sedpy.observate import load_filters
     self._obs = {"filters":load_filters(io.filters_to_pysed(self.filters)) if self.has_phot_in() else None,
                  "zspec":self.z,
                  "name":self.name}
     ### Photometry ###
     if self.has_phot_in():
         self._obs.update({"maggies":np.array([self.phot_in[_filt] for _filt in self.filters]),
                           "maggies_unc":np.array([self.phot_in[_filt+".err"] for _filt in self.filters])})
         if phot_mask is not None:
             self._obs["phot_mask"] = np.array([_f in phot_mask for _f in self.filters])
     ### Spectrometry ###
     self._obs["wavelength"] = None
     if self.has_spec_in():
         self._obs.update({"wavelength":np.array(self.spec_in["lbda"]),
                           "spectrum":np.array(self.spec_in["spec"]),
                           "unc":np.array(self.spec_in["spec.err"]) if "spec.err" in self.spec_in.keys() else None})
         if spec_mask is not None:
             if type(spec_mask) in [list, tuple, np.ndarray] and len(spec_mask) == 2:
                 _lim_low, _lim_up = spec_mask
                 _spec_mask = np.ones(len(self.obs["wavelength"]), dtype = bool)
                 if _lim_low is not None:
                     _spec_mask &= self.obs["wavelength"] > _lim_low
                 if _lim_up is not None:
                     _spec_mask &= self.obs["wavelength"] < _lim_up
                 self._obs["mask"] = _spec_mask
             elif type(spec_mask) in [list, tuple, np.ndarray] and len(spec_mask)==len(self.spec_in["lbda"]):
                 self._obs["mask"] = np.array(spec_mask)
             else:
                 if warnings:
                     warn(f"Cannot apply a mask on spectrum because the 'spec_mask' you give is not compliant ({spec_mask})")
     self._obs = fix_obs(self._obs)
     if verbose:
         print(tools.get_box_title(title="Built obs", box="\n#=#\n#   {}   #\n#=#\n"))
         pprint(self.obs)
예제 #13
0
def build_obs(objid=0, phottable='demo_photometry.dat',
             luminosity_distance=None, **kwargs):
    """Load photometry from an ascii file.  Assumes the following columns:
    `objid`, `filterset`, [`mag0`,....,`magN`] where N >= 11.  The User should
    modify this function (including adding keyword arguments) to read in their
    particular data format and put it in the required dictionary.

    :param objid:
        The object id for the row of the photomotery file to use.  Integer.
        Requires that there be an `objid` column in the ascii file.

    :param phottable:
        Name (and path) of the ascii file containing the photometry.

    :param luminosity_distance: (optional)
        The Johnson 2013 data are given as AB absolute magnitudes.  They can be
        turned into apparent magnitudes by supplying a luminosity distance.

    :returns obs:
        Dictionary of observational data.
    """
    # Writes your code here to read data.  Can use FITS, h5py, astropy.table,
    # sqlite, whatever.
    # e.g.:
    # import astropy.io.fits as pyfits
    # catalog = pyfits.getdata(phottable)

    from prospect.utils.obsutils import fix_obs

    # Here we will read in an ascii catalog of magnitudes as a numpy structured
    # array
    with open(phottable, 'r') as f:
        # drop the comment hash
        header = f.readline().split()[1:]
    catalog = np.genfromtxt(phottable, comments='#',
                            dtype=np.dtype([(n, np.float) for n in header]))

    # Find the right row
    ind = catalog['objid'] == float(objid)
    # Here we are dynamically choosing which filters to use based on the object
    # and a flag in the catalog.  Feel free to make this logic more (or less)
    # complicated.
    filternames = filtersets[int(catalog[ind]['filterset'])]
    # And here we loop over the magnitude columns
    mags = [catalog[ind]['mag{}'.format(i)] for i in range(len(filternames))]
    mags = np.array(mags)
    # And since these are absolute mags, we can shift to any distance.
    if luminosity_distance is not None:
        dm = 25 + 5 * np.log10(luminosity_distance)
        mags += dm

    # Build output dictionary.
    obs = {}
    # This is a list of sedpy filter objects.    See the
    # sedpy.observate.load_filters command for more details on its syntax.
    obs['filters'] = load_filters(filternames)
    # This is a list of maggies, converted from mags.  It should have the same
    # order as `filters` above.
    obs['maggies'] = np.squeeze(10**(-mags/2.5))
    # HACK.  You should use real flux uncertainties
    obs['maggies_unc'] = obs['maggies'] * 0.07
    # Here we mask out any NaNs or infs
    obs['phot_mask'] = np.isfinite(np.squeeze(mags))
    # We have no spectrum.
    obs['wavelength'] = None
    obs['spectrum'] = None

    # Add unessential bonus info.  This will be stored in output
    #obs['dmod'] = catalog[ind]['dmod']
    obs['objid'] = objid

    # This ensures all required keys are present and adds some extra useful info
    obs = fix_obs(obs)

    return obs
예제 #14
0
def build_obs(infile=None, filterFile=None, binNum=0, **kwargs):
    '''
    Construct the observations to use for fitting.
    
    Parameters
    ----------
    fluxes : list, optional
        The fluxes to use. The default is None.
    errs : list, optional
        The uncertainties on the above fluxes. The default is None.
    filterset : list, optional
        The filters that the observations were taken in. The default is None.
    binNum : int, optional
        The bin number for the galaxy. The default is 0.
    **kwargs : kwargs
        Additional keyword arguments.
        
    Returns
    -------
    obs : dict
        Dictionary of observational data.
    
    '''

    import numpy as np

    from astropy.table import Table
    from sedpy.observate import load_filters
    from prospect.utils.obsutils import fix_obs

    with open(filterFile) as file:  # open the file containing strings of the
        filters = []  # filters and create a list containing
        for line in file:  # those strings
            filt = line.strip()
            filters.append(filt)

    table = Table.read(infile)
    flux_cols = [string for string in table.colnames if '_flux' in string]
    err_cols = [string for string in table.colnames if '_err' in string]
    nPix_cols = [string for string in table.colnames if '_nPix' in string]
    flux_table = table[flux_cols]  # create a table using only the flux columns
    err_table = table[err_cols]  # create a table using only the err columns
    nPix_table = table[nPix_cols]  # create a table using only the nPix columns

    fluxes = list(flux_table[binNum])  # get the fluxes for the bin
    errs = list(err_table[binNum])  # get the uncertainties for the bin
    nPixels = list(nPix_table[binNum])  # get the number of pixels for the bin

    # build output dictionary.
    obs = {}

    # this is a list of sedpy filter objects. See the
    # sedpy.observate.load_filters command for more details on its syntax.
    filters_directory = 'D:\Documents\GitHub\HFF\hff_filters'  # '/home/clawlorf/HFF/hff_filters/'
    obs['filters'] = load_filters(filters, directory=filters_directory)

    # this is a list of maggies, converted from fluxes. It should have the same
    # order as `filters` above.
    measures = np.array(fluxes) / 3631 / np.array(nPixels)
    obs['maggies'] = measures

    # this is a list of maggie uncertainties, converted from fluxes. It should
    # have the same order as `filters` above.
    uncerts = np.array(errs) / 3631 / np.array(nPixels)
    SN = measures / uncerts
    SN[SN > 100] = 100.0  # set the S/N maximum to 100
    obs['maggies_unc'] = obs['maggies'] / SN

    # here we mask out any NaNs or infs
    obs['phot_mask'] = np.array([
        False, True, True, False, True, False, True, False, False, True, False,
        True, False, True, True, True
    ])  #np.array([True]*len(filters))

    # here we place the effective wavelengths for each of the filters
    obs['phot_wave'] = np.array([f.wave_effective for f in obs['filters']])

    # we have no spectrum.
    obs['wavelength'] = None
    obs['spectrum'] = None
    obs['unc'] = None
    obs['mask'] = None

    # add unessential bonus info. This will be stored in output.
    obs['binNum'] = binNum

    # this ensures all required keys are present and adds extra useful info
    obs = fix_obs(obs)

    return obs
예제 #15
0
def build_obs(fluxes, fluxes_unc, bandpasses, **extras):
    """Build a dictionary of observational data. 

    :param fluxes:
        Observed fluxes

    :param bandpasses:
        Bandpasses for the quoted observed fluxes

    :returns obs:
        A dictionary of observational data to use in the fit.
    """

    # The obs dictionary, empty for now
    obs = {}

    # These are the names of the relevant filters,
    # in the same order as the photometric data (see below)

    # For our data
    """
       'CTIO_U', 'VIMOS_U',
       'ACS_F435W', 'ACS_F606W', 'ACS_F775W', 'ACS_F814W',
       'ACS_F850LP', 'WFC3_F098M', 'WFC3_F105W',
       'WFC3_F125W', 'WFC3_F160W', 'ISAAC_KS', 'HAWKI_KS',
       'IRAC_CH1', 'IRAC_CH2', 'IRAC_CH3', 'IRAC_CH4'
    """

    ground_u = ['decam_u', 'LBT_LBCB_besselU']
    hst = [
        'acs_wfc_f435w', 'acs_wfc_f606w', 'acs_wfc_f775w', 'acs_wfc_f814w',
        'acs_wfc_f850lp', 'wfc3_ir_f098m', 'wfc3_ir_f105w', 'wfc3_ir_f125w',
        'wfc3_ir_f140w', 'wfc3_ir_f160w'
    ]
    k_bands = ['HAWKI_Ks', 'Subaru_MOIRCS_K', 'CFHT_Wircam_Ks']
    spitzer = ['spitzer_irac_ch' + n for n in ['1', '2', '3', '4']]

    filternames = ground_u + hst + k_bands + spitzer

    # This code block is necessary to ensure that we
    # handle negative since we're ignoring them, i.e.,
    # need to make sure that we do not load the same
    # filters each time. The filters are only loaded
    # depending on the filters given in useable_filters.
    filternames_toload = []
    for ft in filternames:
        if ft == 'decam_u':
            bp = 'CTIO'
        elif ft == 'LBT_LBCB_besselU':
            bp = 'LBC'
        elif ft == 'HAWKI_Ks':
            bp = 'HAWKI'
        elif ft == 'Subaru_MOIRCS_K':
            bp = 'MOIRCS'
        elif ft == 'CFHT_Wircam_Ks':
            bp = 'CFHT'
        else:
            bp = (ft.split('_')[-1]).upper()
        #print('\nft:', ft)
        for j in range(len(bandpasses)):
            bandpass = bandpasses[j]
            #print('bp and bandpass:'******'unc'] = None
    # (again, to ignore a particular wavelength set the value of the
    #  corresponding elemnt of the mask to *False*)
    obs['mask'] = None

    # This function ensures all required keys are present in the obs dictionary,
    # adding default values if necessary
    obs = fix_obs(obs)

    return obs
예제 #16
0
def build_obs(snr=10.0, filterset=["sdss_g0", "sdss_r0"],
              add_noise=True, **kwargs):
    """Make a mock dataset.  Feel free to add more complicated kwargs, and put
    other things in the run_params dictionary to control how the mock is
    generated.

    :param snr:
        The S/N of the phock photometry.  This can also be a vector of same
        lngth as the number of filters.

    :param filterset:
        A list of `sedpy` filter names.  Mock photometry will be generated
        for these filters.

    :param add_noise: (optional, boolean, default: True)
        If True, add a realization of the noise to the mock spectrum
    """
    from prospect.utils.obsutils import fix_obs

    # We'll put the mock data in this dictionary, just as we would for real
    # data.  But we need to know which bands (and wavelengths if doing
    # spectroscopy) in which to generate mock data.
    mock = {}
    mock['wavelength'] = None  # No spectrum
    mock['spectrum'] = None    # No spectrum
    mock['filters'] = load_filters(filterset)

    # We need the models to make a mock
    sps = build_sps(**kwargs)
    mod = build_model(**kwargs)

    # Now we get the mock params from the kwargs dict
    params = {}
    for p in mod.params.keys():
        if p in kwargs:
            params[p] = np.atleast_1d(kwargs[p])

    # And build the mock
    mod.params.update(params)
    spec, phot, _ = mod.mean_model(mod.theta, mock, sps=sps)

    # Now store some ancillary, helpful info;
    # this information is not required to run a fit.
    mock['true_spectrum'] = spec.copy()
    mock['true_maggies'] = phot.copy()
    mock['mock_params'] = deepcopy(mod.params)
    mock['mock_snr'] = snr
    mock["phot_wave"] = np.array([f.wave_effective for f in mock["filters"]])

    # And store the photometry, adding noise if desired
    pnoise_sigma = phot / snr
    if add_noise:
        pnoise = np.random.normal(0, 1, len(phot)) * pnoise_sigma
        mock['maggies'] = phot + pnoise
    else:
        mock['maggies'] = phot.copy()
    mock['maggies_unc'] = pnoise_sigma
    mock['phot_mask'] = np.ones(len(phot), dtype=bool)

    # This ensures all required keys are present
    mock = fix_obs(mock)

    return mock
예제 #17
0
def build_obs(objid=0,
              phottable='demo_photometry.dat',
              luminosity_distance=None,
              **kwargs):
    """Load photometry from an ascii file.  Assumes the following columns:
    `objid`, `filterset`, [`mag0`,....,`magN`] where N >= 11.  The User should
    modify this function (including adding keyword arguments) to read in their
    particular data format and put it in the required dictionary.

    :param objid:
        The object id for the row of the photomotery file to use.  Integer.
        Requires that there be an `objid` column in the ascii file.

    :param phottable:
        Name (and path) of the ascii file containing the photometry.

    :param luminosity_distance: (optional)
        The Johnson 2013 data are given as AB absolute magnitudes.  They can be
        turned into apparent magnitudes by supplying a luminosity distance.

    :returns obs:
        Dictionary of observational data.
    """
    # Writes your code here to read data.  Can use FITS, h5py, astropy.table,
    # sqlite, whatever.
    # e.g.:
    # import astropy.io.fits as pyfits
    # catalog = pyfits.getdata(phottable)

    from prospect.utils.obsutils import fix_obs

    # Here we will read in an ascii catalog of magnitudes as a numpy structured
    # array
    with open(phottable, 'r') as f:
        # drop the comment hash
        header = f.readline().split()[1:]
    catalog = np.genfromtxt(phottable,
                            comments='#',
                            dtype=np.dtype([(n, np.float) for n in header]))

    # Find the right row
    ind = catalog['objid'] == float(objid)
    # Here we are dynamically choosing which filters to use based on the object
    # and a flag in the catalog.  Feel free to make this logic more (or less)
    # complicated.
    filternames = filtersets[int(catalog[ind]['filterset'])]
    # And here we loop over the magnitude columns
    mags = [catalog[ind]['mag{}'.format(i)] for i in range(len(filternames))]
    mags = np.array(mags)
    # And since these are absolute mags, we can shift to any distance.
    if luminosity_distance is not None:
        dm = 25 + 5 * np.log10(luminosity_distance)
        mags += dm

    # Build output dictionary.
    obs = {}
    # This is a list of sedpy filter objects.    See the
    # sedpy.observate.load_filters command for more details on its syntax.
    obs['filters'] = load_filters(filternames)
    # This is a list of maggies, converted from mags.  It should have the same
    # order as `filters` above.
    obs['maggies'] = np.squeeze(10**(-mags / 2.5))
    # HACK.  You should use real flux uncertainties
    obs['maggies_unc'] = obs['maggies'] * 0.07
    # Here we mask out any NaNs or infs
    obs['phot_mask'] = np.isfinite(np.squeeze(mags))
    # We have no spectrum.
    obs['wavelength'] = None
    obs['spectrum'] = None

    # Add unessential bonus info.  This will be stored in output
    #obs['dmod'] = catalog[ind]['dmod']
    obs['objid'] = objid

    # This ensures all required keys are present and adds some extra useful info
    obs = fix_obs(obs)

    return obs
def build_obs(mags, snr=10, ldist=10.0, **extras):
    """Build a dictionary of observational data.  In this example
    the data consist of photometry for a single nearby dwarf galaxy
    from Johnson et al. 2013.

    :param snr:
        The S/N to assign to the photometry, since none are reported
        in Johnson et al. 2013

    :param ldist:
        The luminosity distance to assume for translating absolute magnitudes
        into apparent magnitudes.

    :returns obs:
        A dictionary of observational data to use in the fit.
    """

    from prospect.utils.obsutils import fix_obs

    # The obs dictionary, empty for now
    obs = {}

    # These are the names of the relevant filters,
    # in the same order as the photometric data (see below)
    sdss_griz = ['sdss_{0}0'.format(b) for b in ['g', 'r', 'i', 'z']]
    y = ['decam_Y']
    filternames = sdss_griz + y
    # And here we instantiate the `Filter()` objects using methods in `sedpy`,
    # and put the resultinf list of Filter objects in the "filters" key of the `obs` dictionary
    obs["filters"] = sedpy.observate.load_filters(filternames)

    # Now we store the measured fluxes for a single object, **in the same order as "filters"**
    # In this example we use a row of absolute AB magnitudes from Johnson et al. 2013 (NGC4163)
    # We then turn them into apparent magnitudes based on the supplied `ldist` meta-parameter.
    # You could also, e.g. read from a catalog.
    # The units of the fluxes need to be maggies (Jy/3631) so we will do the conversion here too.
    #M_AB =
    #dm = 25 + 5.0 * np.log10(ldist)
    #mags = np.array([17.41900063, 16.98089981, 16.8614006, 16.48570061, 16.27280045])
    obs["maggies"] = 10**(-0.4 * mags)

    # And now we store the uncertainties (again in units of maggies)
    # In this example we are going to fudge the uncertainties based on the supplied `snr` meta-parameter.
    obs["maggies_unc"] = (1. / snr) * obs["maggies"]

    # This is an array of effective wavelengths for each of the filters.
    # It is not necessary, but it can be useful for plotting so we store it here as a convenience
    obs["phot_wave"] = np.array([f.wave_effective for f in obs["filters"]])

    # We do not have a spectrum, so we set some required elements of the obs dictionary to None.
    # (this would be a vector of vacuum wavelengths in angstroms)
    obs["wavelength"] = None
    # (this would be the spectrum in units of maggies)
    obs["spectrum"] = None
    # (spectral uncertainties are given here)
    obs['unc'] = None
    # (again, to ignore a particular wavelength set the value of the
    #  corresponding elemnt of the mask to *False*)
    obs['mask'] = None

    # This function ensures all required keys are present in the obs dictionary,
    # adding default values if necessary
    obs = fix_obs(obs)

    return obs