コード例 #1
0
def build_model(**kwargs):

    from prospect.models.templates import TemplateLibrary
    from prospect.models import priors, sedmodel

    model_params = TemplateLibrary["parametric_sfh"]
    model_params.update(TemplateLibrary["dust_emission"])

    #fixed delayed-tau SFH
    model_params['tau']['isfree'] = False
    model_params['tau']['init'] = 1.0
    model_params['sf_start'] = {
        "N": 1,
        "isfree": False,
        "init": 1.0,
        "units": "start of SF, Gyr"
    }
    model_params["lumdist"] = {
        "N": 1,
        "isfree": False,
        "init": 1.0e-5,
        "units": "Mpc"
    }
    model_params['tage']['prior'] = priors.TopHat(mini=1.0, maxi=10.0)
    model_params['tage']['init'] = 5.0
    model_params['mass']['prior'] = priors.TopHat(mini=1e7, maxi=1e13)
    model_params['logzsol']['init'] = 0.2
    model_params['logzsol']['isfree'] = True
    model_params['logzsol']['prior'] = priors.ClippedNormal(mini=-1.5,
                                                            maxi=0.5,
                                                            mean=0.0,
                                                            sigma=0.3)

    #dust emission
    model_params['duste_gamma']['init'] = 0.01
    model_params['duste_qpah']['init'] = 3.5
    model_params['duste_umin']['init'] = 1.0
    model_params = model_library(model_params, int(sys.argv[1]), False)

    model = sedmodel.SedModel(model_params)

    return model
コード例 #2
0
ファイル: fit_host.py プロジェクト: muryelgp/TDEpy
def build_model(gal_ebv, object_redshift=None, init_theta=None):
    """Build a prospect.models.SedModel object

    :param object_redshift: (optional, default: None)
        If given, produce spectra and observed frame photometry appropriate
        for this redshift. Otherwise, the redshift will be zero.

    :param  init_theta: (optional, default: [1e10, -1, 10, 1])
        The initial guess on the parameters for mcmc.

    :returns model:
        An instance of prospect.models.SedModel
    """
    from prospect.models.sedmodel import SedModel
    from prospect.models.templates import TemplateLibrary
    from prospect.models import priors

    # Get (a copy of) one of the prepackaged model set dictionaries.
    model_params = TemplateLibrary["parametric_sfh"]

    model_params["sfh"]["init"] = 4
    Av_init = gal_ebv * 3.1
    # print(init_theta)
    # Changing the initial values appropriate for our objects and data
    model_params["mass"]["init"] = init_theta[0]
    model_params["logzsol"]["init"] = init_theta[1]
    model_params["dust2"]["init"] = Av_init
    model_params["tage"]["init"] = init_theta[2]
    model_params["tau"]["init"] = init_theta[3]

    # Setting the priors forms and limits
    model_params["mass"]["prior"] = priors.LogUniform(mini=1e6, maxi=1e12)
    model_params["logzsol"]["prior"] = priors.Uniform(mini=-1.8, maxi=0.3)
    model_params["dust2"]["prior"] = priors.ClippedNormal(mean=Av_init, sigma=0.05, mini=Av_init,
                                                          maxi=Av_init + 0.1)
    # model_params["dust2"]["prior"] = priors.Uniform(mini=0.0, maxi=0.5)
    model_params["tage"]["prior"] = priors.Uniform(mini=0.1, maxi=13.8)
    model_params["tau"]["prior"] = priors.Uniform(mini=0.001, maxi=30)

    # Setting the spread of the walkers for the mcmc sampling
    model_params["mass"]["disp_floor"] = 1e8
    model_params["logzsol"]['disp_floor'] = 0.5
    model_params["dust2"]["disp_floor"] = 0.01
    model_params["tage"]["disp_floor"] = 5.0
    model_params["tau"]["disp_floor"] = 3.0

    model_params["mass"]["init_disp"] = 1e8
    model_params["logzsol"]['init_disp'] = 0.5
    model_params["dust2"]["init_disp"] = 0.01
    model_params["tage"]["init_disp"] = 5.0
    model_params["tau"]["init_disp"] = 3.0

    # Fixing and defining the object redshift
    model_params["zred"]['isfree'] = False
    model_params["zred"]['init'] = object_redshift

    # ldist = cosmo.luminosity_distance(object_redshift).value
    # model_params["lumdist"] = {"N": 1, "isfree": False, "init": ldist, "units": "Mpc"}

    # Now instantiate the model object using this dictionary of parameter specifications
    model = SedModel(model_params)

    return model
コード例 #3
0
def loss_function(args):


    tau_mean, const_mean, tage_mean, fburst_mean, tburst_mean, logzsol_mean, gas_logz_mean, gas_logu_mean,\
        tau_sig, const_sig, tage_sig, fburst_sig, tburst_sig, logzsol_sig, gas_logz_sig, gas_logu_sig = args

    set_size = 3000

    tau_arr = [
        float(
            priors.ClippedNormal(mean=abs(tau_mean),
                                 sigma=abs(tau_sig),
                                 mini=1.0,
                                 maxi=8.0).sample()) for _ in range(set_size)
    ]

    const_arr = [
        float(
            priors.ClippedNormal(mean=abs(const_mean),
                                 sigma=abs(const_sig),
                                 mini=0.0,
                                 maxi=0.5).sample()) for _ in range(set_size)
    ]

    tage_arr = [
        float(
            priors.ClippedNormal(mean=abs(tage_mean),
                                 sigma=abs(tage_sig),
                                 mini=1.0,
                                 maxi=11.0).sample()) for _ in range(set_size)
    ]

    fburst_arr = [
        float(
            priors.ClippedNormal(mean=abs(fburst_mean),
                                 sigma=abs(fburst_sig),
                                 mini=0.0,
                                 maxi=0.8).sample()) for _ in range(set_size)
    ]

    tburst_arr = [
        float(
            priors.ClippedNormal(mean=abs(tburst_mean),
                                 sigma=abs(tburst_sig),
                                 mini=0.0,
                                 maxi=abs(tage_mean)).sample())
        for _ in range(set_size)
    ]

    logzsol_arr = [
        float(
            priors.ClippedNormal(mean=-1 * abs(logzsol_mean),
                                 sigma=abs(logzsol_sig),
                                 mini=-1.5,
                                 maxi=0.0).sample()) for _ in range(set_size)
    ]

    gas_logz_arr = [
        float(
            priors.ClippedNormal(mean=-1 * abs(gas_logz_mean),
                                 sigma=abs(gas_logz_sig),
                                 mini=-1.5,
                                 maxi=0.0).sample()) for _ in range(set_size)
    ]

    gas_logu_arr = [
        float(
            priors.ClippedNormal(mean=-1 * abs(gas_logu_mean),
                                 sigma=abs(gas_logu_sig),
                                 mini=-4.0,
                                 maxi=-1.0).sample()) for _ in range(set_size)
    ]

    # Fix the fburst + const > 1 issue
    for ii in np.arange(len(const_arr)):
        if const_arr[ii] + fburst_arr[ii] >= 0.95:
            f_over = (const_arr[ii] + fburst_arr[ii]) - 0.95
            if fburst_arr[ii] >= (f_over + 0.01):
                fburst_arr[ii] = fburst_arr[ii] - (f_over + 0.01)
            else:
                const_arr[ii] = const_arr[ii] - (f_over + 0.01)

    # Fixed the rest
    dust1_arr = np.full(set_size, 0.1)
    dust2_arr = np.full(set_size, 0.0)
    sf_trunc_arr = np.full(set_size, 0.0)

    # List of model parameters
    dwarf_sample_parameters = [{
        'dust1': dust1_arr[ii],
        'dust2': dust2_arr[ii],
        'logzsol': logzsol_arr[ii],
        'gas_logz': gas_logz_arr[ii],
        'gas_logu': gas_logu_arr[ii],
        'const': const_arr[ii],
        'tau': tau_arr[ii],
        'tage': tage_arr[ii],
        'sf_trunc': sf_trunc_arr[ii],
        'fburst': fburst_arr[ii],
        'tburst': tburst_arr[ii]
    } for ii in np.arange(set_size)]

    # Double check
    for ii, model in enumerate(dwarf_sample_parameters):
        if model['fburst'] + model['const'] >= 0.99:
            print(ii, model['fburst'], model['const'])

    # Initialize the spop model
    spop_tau = setup_fsps_spop(zcontinuous=1,
                               imf_type=2,
                               sfh=1,
                               dust_type=0,
                               dust_index=-1.3,
                               dust1_index=-1.0)

    # Get the SDSS filters
    sdss_bands = fsps.find_filter('SDSS')

    dwarf_sample_gaussian = generate_dwarf_population(spop_tau,
                                                      dwarf_sample_parameters,
                                                      filters=sdss_bands,
                                                      n_jobs=6)

    # Measure colors and emission line EWs
    # - SDSS_EMLINES is a pre-defined dict of emission lines center wavelength and the
    # wavelength window for measuring EW.
    # - You can save the results in a numpy array
    dwarf_sample_table = measure_color_ew(dwarf_sample_gaussian,
                                          em_list=SDSS_EMLINES,
                                          output=None)

    bin_size = 200

    ur_size = np.linspace(0.0, 2.5, bin_size)
    ug_size = np.linspace(0.0, 2.0, bin_size)
    gr_size = np.linspace(-0.1, 0.8, bin_size)
    gi_size = np.linspace(-0.2, 1.3, bin_size)
    ha_size = np.linspace(0.0, 3.0, bin_size)
    hb_size = np.linspace(-0.5, 2.5, bin_size)
    oiii_size = np.linspace(-1.0, 3.0, bin_size)

    obs_ur = data_to_distribution(
        np.asarray(sdss_use['M_u'] - sdss_use['M_r']), ur_size)
    obs_ug = data_to_distribution(
        np.asarray(sdss_use['M_u'] - sdss_use['M_g']), ug_size)
    obs_gr = data_to_distribution(
        np.asarray(sdss_use['M_g'] - sdss_use['M_r']), gr_size)
    obs_gi = data_to_distribution(
        np.asarray(sdss_use['M_g'] - sdss_use['M_i']), gi_size)
    obs_ha = data_to_distribution(np.log10(abs(sdss_use['H_ALPHA_EQW'])),
                                  ha_size)
    obs_hb = data_to_distribution(np.log10(abs(sdss_use['H_BETA_EQW'])),
                                  hb_size)
    obs_oiii = data_to_distribution(np.log10(abs(sdss_use['OIII_5007_EQW'])),
                                    oiii_size)

    model_ur = data_to_distribution(dwarf_sample_table['ur_color'], ur_size)
    model_ug = data_to_distribution(dwarf_sample_table['ug_color'], ug_size)
    model_gr = data_to_distribution(dwarf_sample_table['gr_color'], gr_size)
    model_gi = data_to_distribution(dwarf_sample_table['gi_color'], gi_size)
    model_ha = data_to_distribution(
        np.log10(abs(dwarf_sample_table['ew_halpha'])), ha_size)
    model_hb = data_to_distribution(
        np.log10(abs(dwarf_sample_table['ew_hbeta'])), hb_size)
    model_oiii = data_to_distribution(
        np.log10(abs(dwarf_sample_table['ew_oiii_5007'])), oiii_size)

    obs_stack = np.transpose(
        np.vstack([obs_ur, obs_ug, obs_gr, obs_gi, obs_ha, obs_hb, obs_oiii]))

    model_stack = np.transpose(
        np.vstack([
            model_ur, model_ug, model_gr, model_gi, model_ha, model_hb,
            model_oiii
        ]))

    total_loss = entropy(obs=obs_stack, model=model_stack)

    return total_loss
コード例 #4
0
    'name':
    'dust2',
    'N':
    1,
    'isfree':
    False,
    'init':
    0.7,
    'init_disp':
    0.25,
    'disp_floor':
    0.15,
    'units':
    '',
    'prior':
    priors.ClippedNormal(mini=0.0, maxi=2.0, mean=0.3, sigma=1)
})

model_params.append({
    'name': 'dust_index',
    'N': 1,
    'isfree': False,
    'init': -0.7,
    'init_disp': 0.25,
    'disp_floor': 0.15,
    'units': '',
    'prior': priors.TopHat(mini=-1.8, maxi=0.4)
})

model_params.append({
    'name': 'dust1_index',
コード例 #5
0
def build_model_un(object_redshift=None,
                   fixed_metallicity=None,
                   add_duste=False,
                   **extras):

    from prospect.models.sedmodel import SedModel
    from prospect.models.templates import TemplateLibrary
    from prospect.models import priors
    from prospect.models import transforms
    from prospect.models.templates import adjust_continuity_agebins
    from astropy.cosmology import WMAP9 as cosmos
    import prospect
    # Get (a copy of) one of the prepackaged model set dictionaries.
    # Get the 2018 prospector-alpha model manually
    model_params = (TemplateLibrary["continuity_sfh"])
    model_params.update(TemplateLibrary["dust_emission"])
    model_params.update(TemplateLibrary["nebular"])
    model_params.update(TemplateLibrary["agn"])

    # Set the dust and agn emission free
    model_params["fagn"]["isfree"] = True
    model_params["agn_tau"]["isfree"] = True

    # Complexify the dust attenuation
    model_params["dust_type"] = {
        "N": 1,
        "isfree": False,
        "init": 4,
        "units": "FSPS index"
    }
    model_params["dust2"]["prior"] = priors.TopHat(mini=0.0, maxi=4.0)
    model_params["dust1"] = {
        "N": 1,
        "isfree": False,
        'depends_on': transforms.dustratio_to_dust1,
        "init": 0.0,
        "units": "optical depth towards young stars"
    }

    model_params["dust_ratio"] = {
        "N": 1,
        "isfree": True,
        "init": 1.0,
        "units": "ratio of birth-cloud to diffuse dust",
        "prior": priors.ClippedNormal(mini=0.0, maxi=2.0, mean=1.0, sigma=0.3)
    }

    model_params["dust_index"] = {
        "N": 1,
        "isfree": True,
        "init": 0.0,
        "units": "power-law multiplication of Calzetti",
        "prior": priors.TopHat(mini=-2.0, maxi=0.5)
    }
    # in Gyr
    tuniv = cosmos.age(object_redshift).value
    model_params = adjust_continuity_agebins(model_params, tuniv)

    model_params["duste_qpah"]["isfree"] = False
    model_params["duste_umin"]["isfree"] = False
    model_params["duste_gamma"]["isfree"] = False
    model_params["duste_qpah"]["init"] = 2.0
    model_params["duste_umin"]["init"] = 1.0
    model_params["duste_gamma"]["init"] = 0.01
    model_params["duste_qpah"]["prior"] = priors.TopHat(mini=0.0, maxi=7.0)
    model_params["duste_umin"]["prior"] = priors.TopHat(mini=0.1, maxi=25.0)
    model_params["duste_gamma"]["prior"] = priors.TopHat(mini=0.0, maxi=1.0)
    model_params["duste_qpah"]["disp_floor"] = 3.0
    model_params["duste_umin"]["disp_floor"] = 4.5
    model_params["duste_gamma"]["disp_floor"] = 0.15
    model_params["duste_qpah"]["init_disp"] = 3.0
    model_params["duste_umin"]["init_disp"] = 5.0
    model_params["duste_gamma"]["init_disp"] = 0.2
    model_params['gas_logz']["isfree"] = True
    model_params['gas_logz']["init"] = 0.0
    model_params['gas_logz']["prior"] = priors.TopHat(mini=-2.0, maxi=0.5)
    model_params['gas_logu']["isfree"] = False
    model_params['gas_logu']["init"] = -1.0
    model_params['gas_logu']["prior"] = priors.TopHat(mini=-4.0, maxi=-1.0)
    # Now add the lumdist parameter by hand as another entry in the dictionary.
    # This will control the distance since we are setting the redshift to zero.
    # In `build_obs` above we used a distance of 10pc to convert from absolute to apparent magnitudes,
    # so we use that here too, since the `maggies` are appropriate for that distance.

    # Let's make some changes to values appropriate for our objects and data

    model_params["logzsol"]["prior"] = priors.TopHat(mini=-2.0, maxi=0.2)
    model_params["dust_index"]["prior"] = priors.TopHat(mini=-2.2, maxi=0.4)
    model_params["agn_tau"]["prior"] = priors.LogUniform(mini=5, maxi=1.5e2)
    model_params["dust2"]["prior"] = priors.TopHat(mini=1e-6, maxi=3.0)

    model_params['dust_type']['init'] = 0
    model_params['fagn']['init'] = 0.5
    model_params['dust2']['init'] = 0.1
    # If we are going to be using emcee, it is useful to provide a
    # minimum scale for the cloud of walkers (the default is 0.1)
    model_params["agn_tau"]["disp_floor"] = 1
    model_params["dust2"]["disp_floor"] = 1e-2
    model_params["logzsol"]["disp_floor"] = 1e-3
    model_params['fagn']['disp_floor'] = 1e-3
    model_params['dust_index']['disp_floor'] = 1e-3

    # Change the model parameter specifications based on some keyword arguments
    if object_redshift is not None:
        # make sure zred is fixed
        model_params["zred"]['isfree'] = False
        # And set the value to the object_redshift keyword
        model_params["zred"]['init'] = object_redshift

    # Change fit orders
    tparams = {}
    parnames = [m for m in model_params]
    fit_order = [
        'logmass', 'dust_index', 'dust2', 'logzsol', 'fagn', 'dust_ratio'
    ]
    for param in fit_order:
        tparams[param] = model_params[param]
    for param in model_params:
        if param not in fit_order:
            tparams[param] = model_params[param]
    model_params = tparams
    ########
    model_params['add_neb_emission']['init'] = False
    ########
    model_params['sfh']['init'] = 0
    # Now instantiate the model object using this dictionary of parameter specifications
    model = SedModel(model_params)
    #print(model_params['agebins'])
    return model
コード例 #6
0
def loss_function(args):

    tau_mean, const_mean, tage_mean, fburst_mean, tburst_mean, logzsol_mean, gas_logz_mean, gas_logu_mean = args

    set_size = 3000

    tau_arr = [
        float(
            priors.ClippedNormal(mean=tau_mean,
                                 sigma=tau_sig,
                                 mini=1.0,
                                 maxi=8.0).sample()) for _ in range(set_size)
    ]
    const_arr = [
        float(
            priors.ClippedNormal(mean=const_mean,
                                 sigma=const_sig,
                                 mini=0.0,
                                 maxi=0.5).sample()) for _ in range(set_size)
    ]
    tage_arr = [
        float(
            priors.ClippedNormal(mean=tage_mean,
                                 sigma=tage_sig,
                                 mini=1.0,
                                 maxi=11.0).sample()) for _ in range(set_size)
    ]
    fburst_arr = [
        float(
            priors.ClippedNormal(mean=fburst_mean,
                                 sigma=fbust_sig,
                                 mini=0.0,
                                 maxi=0.8).sample()) for _ in range(set_size)
    ]
    tburst_arr = [
        float(
            priors.ClippedNormal(mean=tburst_mean,
                                 sigma=tburst_sig,
                                 mini=0.0,
                                 maxi=8.0).sample()) for _ in range(set_size)
    ]
    logzsol_arr = [
        float(
            priors.ClippedNormal(mean=logzsol_mean,
                                 sigma=logzsol_sig,
                                 mini=-1.5,
                                 maxi=0.0).sample()) for _ in range(set_size)
    ]
    gas_logz_arr = [
        float(
            priors.ClippedNormal(mean=gas_logz_mean,
                                 sigma=gas_logz_sig,
                                 mini=-1.5,
                                 maxi=0.0).sample()) for _ in range(set_size)
    ]
    gas_logu_arr = [
        float(
            priors.ClippedNormal(mean=gas_logu_mean,
                                 sigma=gas_logu_sig,
                                 mini=-4.0,
                                 maxi=-1.0).sample()) for _ in range(set_size)
    ]

    # Fix the fburst + const > 1 issue
    for ii in np.arange(len(const_arr)):
        if const_arr[ii] + fburst_arr[ii] >= 0.95:
            f_over = (const_arr[ii] + fburst_arr[ii]) - 0.95
            if fburst_arr[ii] >= (f_over + 0.01):
                fburst_arr[ii] = fburst_arr[ii] - (f_over + 0.01)
            else:
                const_arr[ii] = const_arr[ii] - (f_over + 0.01)

    # Fixed the rest
    dust1_arr = np.full(set_size, 0.1)
    dust2_arr = np.full(set_size, 0.0)
    sf_trunc_arr = np.full(set_size, 0.0)

    # List of model parameters
    dwarf_sample_parameters = [{
        'dust1': dust1_arr[ii],
        'dust2': dust2_arr[ii],
        'logzsol': logzsol_arr[ii],
        'gas_logz': gas_logz_arr[ii],
        'gas_logu': gas_logu_arr[ii],
        'const': const_arr[ii],
        'tau': tau_arr[ii],
        'tage': tage_arr[ii],
        'sf_trunc': sf_trunc_arr[ii],
        'fburst': fburst_arr[ii],
        'tburst': tburst_arr[ii]
    } for ii in np.arange(set_size)]

    # Double check
    for ii, model in enumerate(dwarf_sample_parameters):
        if model['fburst'] + model['const'] >= 0.99:
            print(ii, model['fburst'], model['const'])

    # Initialize the spop model
    spop_tau = setup_fsps_spop(zcontinuous=1,
                               imf_type=2,
                               sfh=1,
                               dust_type=0,
                               dust_index=-1.3,
                               dust1_index=-1.0)

    # Get the SDSS filters
    sdss_bands = fsps.find_filter('SDSS')

    dwarf_sample_gaussian = generate_dwarf_population(spop_tau,
                                                      dwarf_sample_parameters,
                                                      filters=sdss_bands,
                                                      n_jobs=4)

    # Measure colors and emission line EWs
    # - SDSS_EMLINES is a pre-defined dict of emission lines center wavelength and the
    # wavelength window for measuring EW.
    # - You can save the results in a numpy array
    dwarf_sample_table = measure_color_ew(dwarf_sample_gaussian,
                                          em_list=SDSS_EMLINES,
                                          output=None)

    bin_size = 200

    ur_loss = loss(dwarf_sample_table['ur_color'],
                   np.asarray(sdss_use['M_u'] - sdss_use['M_r']),
                   np.linspace(0, 2.5, bin_size))
    ug_loss = loss(dwarf_sample_table['ug_color'],
                   np.asarray(sdss_use['M_u'] - sdss_use['M_g']),
                   np.linspace(0, 1.75, bin_size))
    gr_loss = loss(dwarf_sample_table['gr_color'],
                   np.asarray(sdss_use['M_g'] - sdss_use['M_r']),
                   np.linspace(-0.1, 0.8, bin_size))
    gi_loss = loss(dwarf_sample_table['gi_color'],
                   np.asarray(sdss_use['M_g'] - sdss_use['M_i']),
                   np.linspace(-0.2, 1.2, bin_size))
    OIII_loss = loss(np.log10(dwarf_sample_table['ew_oiii_5007']),
                     np.log10(-1.0 * (sdss_use['OIII_5007_EQW'])),
                     np.linspace(-1, 3, bin_size))
    Ha_loss = loss(np.log10(np.log10(dwarf_sample_table['ew_halpha'])),
                   np.log10(-1.0 * sdss_use['H_ALPHA_EQW']),
                   np.linspace(0, 3, bin_size))
    Hb_loss = loss(np.log10(dwarf_sample_table['ew_hbeta']),
                   np.log10(-1.0 * sdss_use['H_BETA_EQW']),
                   np.linspace(-0.5, 2.5, bin_size))

    total_loss = (ur_loss + ug_loss + gr_loss + gi_loss + OIII_loss + Ha_loss +
                  Hb_loss) / 7

    part_loss = [
        ur_loss, ug_loss, gr_loss, gi_loss, OIII_loss, Ha_loss, Hb_loss
    ]

    return total_loss
コード例 #7
0
ファイル: LEGAC_params.py プロジェクト: cwoodrum/LEGA-C
def build_model(fixed_metallicity=None, luminosity_distance=None, **extras):
    """Construct a model.  This method defines a number of parameter
    specification dictionaries and uses them to initialize a
    `models.sedmodel.SedModel` object.
    :param object_redshift:
        If given, given the model redshift to this value.
    :param add_dust: (optional, default: False)
        Switch to add (fixed) parameters relevant for dust emission.
    :param add_neb: (optional, default: False)
        Switch to add (fixed) parameters relevant for nebular emission, and
        turn nebular emission on.
    :param luminosity_distance: (optional)
        If present, add a `"lumdist"` parameter to the model, and set it's
        value (in Mpc) to this.  This allows one to decouple redshift from
        distance, and fit, e.g., absolute magnitudes (by setting
        luminosity_distance to 1e-5 (10pc))
    """
    from prospect.models.templates import TemplateLibrary, adjust_continuity_agebins
    from prospect.models import priors, sedmodel, transforms

    model_params = TemplateLibrary['continuity_sfh']

    ### BASIC PARAMETERS ###

    model_params["imf_type"] = {
        'N': 1,
        'isfree': False,
        'init': 1,  #1=Chabrier
        'prior': None
    }

    model_params['zred'] = {
        'N': 1,
        'isfree': True,
        'init': obj_red,
        "prior": priors.TopHat(mini=obj_red - 0.05, maxi=obj_red + 0.05)
    }

    model_params['add_igm_absorption'] = {
        'N': 1,
        'isfree': False,
        'init': 1,
        'units': None,
        'prior': None
    }

    model_params['add_agb_dust_model'] = {
        'N': 1,
        'isfree': False,
        'init': 1,
        'units': None,
        'prior': None
    }

    # model_params['pmetals'] = {'N': 1,
    #                             'isfree': False,
    #                             'init': -99,
    #                             'units': '',
    #                             'prior': priors.TopHat(mini=-3, maxi=-1)}

    ### SFH ###

    tuniv = WMAP9.age(obj_red).value
    model_params = adjust_continuity_agebins(model_params,
                                             tuniv=tuniv,
                                             nbins=7)

    ### DUST ABSORPTION ###

    model_params['dust_type'] = {
        'N': 1,
        'isfree': False,
        'init': 4,  #4=Kriek & Conroy
        'units': 'index',
        'prior': None
    }

    model_params['dust1'] = {
        'N': 1,
        'isfree': False,
        'depends_on': transforms.dustratio_to_dust1,
        'init': 0.,
        'units': 'optical depth towards young stars'
    }

    model_params['dust_ratio'] = {
        'N': 1,
        'isfree': True,
        'init': 1.0,
        'init_disp': 0.8,
        'disp_floor': 0.8,
        'units': 'ratio of birth-cloud to diffuse dust',
        'prior': priors.ClippedNormal(mini=0.0, maxi=2.0, mean=1.0, sigma=0.3)
    }

    model_params['dust2'] = {
        'N': 1,
        'isfree': True,
        'init': 1.0,
        'init_disp': 0.25,
        'disp_floor': 0.15,
        'units': 'optical depth at 5500AA',
        'prior': priors.ClippedNormal(mini=0.0, maxi=4.0, mean=0.3, sigma=1)
    }

    model_params['dust_index'] = {
        'N': 1,
        'isfree': True,
        'init': 0.0,
        'init_disp': 0.25,
        'disp_floor': 0.15,
        'units': 'power-law multiplication of Calzetti',
        'prior': priors.TopHat(mini=-2.0, maxi=0.5)
    }

    ### DUST EMISSION ###

    model_params.update(TemplateLibrary["dust_emission"])

    ### NEBULAR EMISSION ###

    model_params['add_neb_emission'] = {
        'N': 1,
        'isfree': False,
        'init': True,
        'prior': None
    }

    model_params['add_neb_continuum'] = {
        'N': 1,
        'isfree': False,
        'init': True,
        'prior': None
    }

    model_params['gas_logz'] = {
        'N': 1,
        'isfree': True,
        'init': 0.0,
        'units': r'log Z/Z_\odot',
        'prior': priors.TopHat(mini=-2.0, maxi=0.5)
    }

    model_params['gas_logu'] = {
        'N': 1,
        'isfree': True,
        'init': -1.0,
        'units': '',
        'prior': priors.TopHat(mini=-4.0, maxi=-1.0)
    }

    ### CALIBRATION ###
    model_params['polyorder'] = {'N': 1, 'init': 10, 'isfree': False}

    model_params['spec_norm'] = {
        'N': 1,
        'init': 1.0,
        'isfree': True,
        'prior': priors.Normal(sigma=0.2, mean=1.0),
        'units': 'f_true/f_obs'
    }

    model_params['spec_jitter'] = {
        "N": 1,
        "isfree": True,
        "init": 1.0,
        "prior": priors.TopHat(mini=0., maxi=4.0)
    }

    model_params['f_outlier_spec'] = {
        "N": 1,
        "isfree": True,
        "init": 0.01,
        "prior": priors.TopHat(mini=1e-5, maxi=0.5)
    }

    model_params['nsigma_outlier_spec'] = {
        "N": 1,
        "isfree": False,
        "init": 5.0
    }

    ### SMOOTHING ###

    model_params.update(TemplateLibrary["spectral_smoothing"])
    model_params["sigma_smooth"]["prior"] = priors.TopHat(mini=150, maxi=250)

    # Now instantiate the model using this new dictionary of parameter specifications
    model = sedmodel.SedModel(model_params)

    return model
コード例 #8
0
def build_model(objid=1,
                non_param_sfh=False,
                dirichlet_sfh=False,
                add_duste=False,
                add_neb=False,
                add_agn=False,
                switch_off_mix=False,
                marginalize_neb=True,
                n_bins_sfh=8,
                use_eline_prior=False,
                add_jitter=False,
                fit_continuum=False,
                switch_off_phot=False,
                switch_off_spec=False,
                fixed_dust=False,
                **extras):
    """Construct a model.  This method defines a number of parameter
    specification dictionaries and uses them to initialize a
    `models.sedmodel.SedModel` object.
    :param object_redshift:
        If given, given the model redshift to this value.
    :param add_dust: (optional, default: False)
        Switch to add (fixed) parameters relevant for dust emission.
    :param add_neb: (optional, default: False)
        Switch to add (fixed) parameters relevant for nebular emission, and
        turn nebular emission on.
    """
    # read in data table
    obs = build_obs(objid=objid)

    # get SFH template
    if non_param_sfh and not dirichlet_sfh:
        model_params = TemplateLibrary["continuity_sfh"]
    elif dirichlet_sfh:
        model_params = TemplateLibrary["dirichlet_sfh"]
    else:
        model_params = TemplateLibrary["parametric_sfh"]

    # fit for redshift
    # use catalog value as center of the prior
    model_params["zred"]['isfree'] = True
    model_params["zred"]["init"] = obs['redshift']
    model_params["zred"]["prior"] = priors.TopHat(mini=obs['redshift'] - 0.005,
                                                  maxi=obs['redshift'] + 0.005)

    # get SFH template
    if non_param_sfh:
        t_univ = cosmo.age(obs['redshift']).value
        tbinmax = 0.95 * t_univ * 1e9
        lim1, lim2, lim3, lim4 = 7.4772, 8.0, 8.5, 9.0
        agelims = [0, lim1, lim2, lim3] + np.log10(
            np.linspace(10**lim4, tbinmax,
                        n_bins_sfh - 4)).tolist() + [np.log10(t_univ * 1e9)]
        if dirichlet_sfh:
            model_params = adjust_dirichlet_agebins(model_params,
                                                    agelims=agelims)
            model_params["total_mass"]["prior"] = priors.LogUniform(mini=3e9,
                                                                    maxi=1e12)
        else:
            model_params = adjust_continuity_agebins(model_params,
                                                     tuniv=t_univ,
                                                     nbins=n_bins_sfh)
            agebins = np.array([agelims[:-1], agelims[1:]])
            model_params['agebins']['init'] = agebins.T
            model_params["logmass"]["prior"] = priors.TopHat(mini=9.5,
                                                             maxi=12.0)
    else:
        model_params["tau"]["prior"] = priors.LogUniform(mini=1e-1, maxi=10)
        model_params["tage"]["prior"] = priors.TopHat(
            mini=1e-3, maxi=cosmo.age(obs['redshift']).value)
        model_params["mass"]["prior"] = priors.LogUniform(mini=3e9, maxi=1e12)

    # metallicity (no mass-metallicity prior yet!)
    if fixed_dust:
        model_params["logzsol"]["prior"] = priors.ClippedNormal(mini=-1.0,
                                                                maxi=0.19,
                                                                mean=0.0,
                                                                sigma=0.15)
    else:
        model_params["logzsol"]["prior"] = priors.TopHat(mini=-1.0, maxi=0.19)

    # complexify the dust
    if fixed_dust:
        model_params['dust_type']['init'] = 2
        model_params["dust2"]["prior"] = priors.ClippedNormal(mini=0.0,
                                                              maxi=4.0,
                                                              mean=0.3,
                                                              sigma=1)
        model_params['dust1'] = {
            "N": 1,
            "isfree": False,
            "init": 0.0,
            "units": "optical depth towards young stars",
            "prior": None
        }
    else:
        model_params['dust_type']['init'] = 4
        model_params["dust2"]["prior"] = priors.ClippedNormal(mini=0.0,
                                                              maxi=4.0,
                                                              mean=0.3,
                                                              sigma=1)
        model_params["dust_index"] = {
            "N": 1,
            "isfree": True,
            "init": 0.0,
            "units": "power-law multiplication of Calzetti",
            "prior": priors.TopHat(mini=-1.0, maxi=0.4)
        }

        def to_dust1(dust1_fraction=None, dust1=None, dust2=None, **extras):
            return (dust1_fraction * dust2)

        model_params['dust1'] = {
            "N": 1,
            "isfree": False,
            'depends_on': to_dust1,
            "init": 0.0,
            "units": "optical depth towards young stars",
            "prior": None
        }
        model_params['dust1_fraction'] = {
            'N': 1,
            'isfree': True,
            'init': 1.0,
            'prior': priors.ClippedNormal(mini=0.0,
                                          maxi=2.0,
                                          mean=1.0,
                                          sigma=0.3)
        }

    # velocity dispersion
    model_params.update(TemplateLibrary['spectral_smoothing'])
    model_params["sigma_smooth"]["prior"] = priors.TopHat(mini=40.0,
                                                          maxi=400.0)

    # Change the model parameter specifications based on some keyword arguments
    if add_duste:
        # Add dust emission (with fixed dust SED parameters)
        model_params.update(TemplateLibrary["dust_emission"])
        model_params['duste_gamma']['isfree'] = True
        model_params['duste_gamma']['init'] = 0.01
        model_params['duste_gamma']['prior'] = priors.LogUniform(mini=1e-4,
                                                                 maxi=0.1)
        model_params['duste_qpah']['isfree'] = True
        model_params['duste_qpah']['prior'] = priors.TopHat(mini=0.5, maxi=7.0)
        model_params['duste_umin']['isfree'] = True
        model_params['duste_umin']['init'] = 1.0
        model_params['duste_umin']['prior'] = priors.ClippedNormal(mini=0.1,
                                                                   maxi=15.0,
                                                                   mean=2.0,
                                                                   sigma=1.0)

    if add_agn:
        # Allow for the presence of an AGN in the mid-infrared
        model_params.update(TemplateLibrary["agn"])
        model_params['fagn']['isfree'] = True
        model_params['fagn']['prior'] = priors.LogUniform(mini=1e-5, maxi=3.0)
        model_params['agn_tau']['isfree'] = True
        model_params['agn_tau']['prior'] = priors.LogUniform(mini=5.0,
                                                             maxi=150.)

    if add_neb:
        # Add nebular emission
        model_params.update(TemplateLibrary["nebular"])
        model_params['gas_logu']['isfree'] = True
        model_params['gas_logu']['init'] = -2.0
        model_params['gas_logz']['isfree'] = True
        _ = model_params["gas_logz"].pop("depends_on")
        model_params['nebemlineinspec'] = {
            'N': 1,
            'isfree': False,
            'init': False
        }

        if marginalize_neb:
            model_params.update(TemplateLibrary['nebular_marginalization'])
            #model_params.update(TemplateLibrary['fit_eline_redshift'])
            model_params['eline_prior_width']['init'] = 3.0
            model_params['use_eline_prior']['init'] = use_eline_prior

            # only marginalize over a few (strong) emission lines
            if True:
                #SPS_HOME = os.getenv('SPS_HOME')
                #emline_info = np.genfromtxt(SPS_HOME + '/data/emlines_info.dat', dtype=[('wave', 'f8'), ('name', 'S20')], delimiter=',')
                to_fit = [
                    '[OII]3726', '[OII]3729', 'H 3798', 'H 3835', 'H 3889',
                    'H 3970', '[NeIII]3870', 'H delta 4102', 'H gamma 4340',
                    '[OIII]4364', 'H beta 4861', '[OIII]4960', '[OIII]5007',
                    '[NII]6549', 'H alpha 6563', '[NII]6585'
                ]
                #idx = np.array([1 if name in to_fit else 0 for name in emline_info['name']], dtype=bool)
                model_params['lines_to_fit']['init'] = to_fit

            # model_params['use_eline_prior']['init'] = False
        else:
            model_params['nebemlineinspec']['init'] = True

    # This removes the continuum from the spectroscopy. Highly recommend
    # using when modeling both photometry & spectroscopy
    if fit_continuum:
        # order of polynomial that's fit to spectrum
        polyorder_estimate = int(
            np.clip(
                np.round((np.min([7500 * (obs['redshift'] + 1), 9150.0]) -
                          np.max([3525.0 * (obs['redshift'] + 1), 6000.0])) /
                         (obs['redshift'] + 1) * 100), 10, 30))
        model_params['polyorder'] = {
            'N': 1,
            'init': polyorder_estimate,
            'isfree': False
        }
        # fit for normalization of spectrum
        # model_params['spec_norm'] = {'N': 1,
        #                              'init': 0.8,
        #                              'isfree': True,
        #                              'prior': priors.Normal(sigma=0.2, mean=0.8),
        #                              'units': 'f_true/f_obs'}

    # This is a pixel outlier model. It helps to marginalize over
    # poorly modeled noise, such as residual sky lines or
    # even missing absorption lines
    if not switch_off_mix:
        model_params['f_outlier_spec'] = {
            "N": 1,
            "isfree": True,
            "init": 0.01,
            "prior": priors.TopHat(mini=1e-5, maxi=0.5)
        }
        model_params['nsigma_outlier_spec'] = {
            "N": 1,
            "isfree": False,
            "init": 50.0
        }

    # This is a multiplicative noise inflation term. It inflates the noise in
    # all spectroscopic pixels as necessary to get a good fit.
    if add_jitter:
        model_params['spec_jitter'] = {
            "N": 1,
            "isfree": True,
            "init": 1.0,
            "prior": priors.TopHat(mini=1.0, maxi=5.0)
        }

    # Now instantiate the model using this new dictionary of parameter specifications
    model = PolySpecModel(model_params)

    return model