def base_delayed_tau(): model_params = TemplateLibrary['parametric_sfh'] # Initialize with sensible numbers. model_params['tau']['init'] = 10.0 model_params['tage']['init'] = 1.0 model_params['logzsol']['init'] = 0.2 # optimize log-stellar mass, not linear stellar mass model_params['logmass'] = { 'N': 1, 'isfree': True, 'init': 11.0, 'prior': priors.TopHat(mini=10.0, maxi=12.0), 'units': '$M_{\odot}$' } model_params['mass']['isfree'] = False model_params['mass']['init'] = 10**model_params['logmass']['init'] model_params['mass']['prior'] = None model_params['mass']['depends_on'] = logmass2mass # Adjust the prior ranges. model_params['tau']['prior'] = priors.LogUniform(mini=0.01, maxi=30.0) model_params['tage']['prior'] = priors.LogUniform(mini=0.1, maxi=13.0) model_params['logzsol']['prior'] = priors.TopHat(mini=-0.5, maxi=0.3) #print('HACK!!!!!!!!!!!!!') #model_params['tau']['isfree'] = False #model_params['tage']['isfree'] = False #model_params['logzsol']['isfree'] = False #model_params['dust2']['isfree'] = False return model_params
def load_model(object_redshift=None, fixed_metallicity=None, **extras): """Construct a model. This method defines a number of parameter specification dictionaries and uses them to initialize a `models.sedmodel.SedModel` object, which generates a spectrum using the previous function's sps object """ model_params = TemplateLibrary["parametric_sfh"] model_params.update(TemplateLibrary["dust_emission"]) model_params.update(TemplateLibrary["burst_sfh"]) model_params["lumdist"] = { "N": 1, "isfree": False, "init": 1.0e-5, "units": "Mpc" } model_params['fburst']['isfree'] = True model_params['fage_burst']['isfree'] = True model_params['fage_burst']['prior'] = priors.TopHat(mini=0.0, maxi=1.0) model_params['logzsol']['init'] = 0.0 model_params['logzsol']['prior'] = priors.TopHat(mini=-2.0, maxi=0.5) model_params['mass']['prior'] = priors.TopHat(mini=1e7, maxi=1e13) # Set the dust and agn emission free model_params["duste_qpah"]["isfree"] = True model_params["duste_umin"]["isfree"] = True model_params["duste_gamma"]["isfree"] = True model_params['duste_gamma']['init'] = 0.1 model_params['duste_umin']['prior'] = priors.TopHat(mini=0.01, maxi=35) model_params['duste_qpah']['prior'] = priors.TopHat(mini=0.01, maxi=5.0) model_params["duste_gamma"]["prior"] = priors.TopHat(mini=1e-3, maxi=0.5) # Complexify the dust attenuation model_params["dust_type"] = { "N": 1, "isfree": False, "init": 4, "units": "FSPS index" } #Conroy & Kriek dust atten. model_params["dust2"]["prior"] = priors.TopHat(mini=0.0, maxi=4.0) model_params["dust1"] = { "N": 1, "isfree": True, "init": 0.0, "units": "optical depth towards young stars", "prior": priors.TopHat(mini=0.0, maxi=4.0) } model_params["dust_index"] = { "N": 1, "isfree": True, "init": 0.0, "units": "power-law multiplication of Calzetti", "prior": priors.TopHat(mini=-2.5, maxi=0.7) } # Now instantiate the model using this new dictionary of parameter specifications model = SedModel(model_params) return model
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
def load_model(agelims=[], **kwargs): """Load the model object. """ # These are parameters that can be set at initialization, e.g. to define the mock. fix_params = [ 'add_neb_emission', 'logzsol', 'dust2', 'total_mass', 'zred', 'sigma_smooth', 'polyorder' ] # Get a handy ordered list of parameter names pnames = [p['name'] for p in model_params] # set up the age bins and initial zfractions agebins = np.array([agelims[:-1], agelims[1:]]).T ncomp = len(agelims) - 1 sfr_fraction = np.ones(ncomp) / ncomp # constant sfr zinit = np.zeros(ncomp - 1) zinit[0] = 1 - sfr_fraction[0] for i in range(1, len(zinit)): zinit[i] = 1.0 - sfr_fraction[i] / np.prod(zinit[:i]) # THIS IS IMPORTANT # Set up the prior in `z` variables that corresponds to a dirichlet in sfr fraction alpha = np.arange(ncomp - 1, 0, -1) zprior = priors.Beta(alpha=alpha, beta=np.ones_like(alpha), mini=0.0, maxi=1.0) # Adjust SFH model parameters and initial values model_params[pnames.index('mass')]['N'] = ncomp model_params[pnames.index('agebins')]['N'] = ncomp model_params[pnames.index('agebins')]['init'] = agebins model_params[pnames.index('z_fraction')]['N'] = len(zinit) model_params[pnames.index('z_fraction')]['init'] = zinit model_params[pnames.index('z_fraction')]['prior'] = zprior # Adjust fixed parameters based on what's in run_params for k in fix_params: try: model_params[pnames.index(k)]['init'] = kwargs[k] except (KeyError): pass if 'zred' in kwargs: z = kwargs['zred'] v = np.array( [-100., 100.]) # lower and upper limits of residual velocity offset, km/s zlo, zhi = (1 + v / 3e5) * (1 + z) - 1.0 model_params[pnames.index('zred')]['prior'] = priors.TopHat(mini=zlo, maxi=zhi) # Instantiate and return model return sedmodel.PolySedModel(model_params)
def build_model(object_redshift=None,ldist=None,fixed_metallicity=None,add_duste=None, add_nebular=True,add_burst=True,**extras): model_params = TemplateLibrary["parametric_sfh"] model_params["tau"]["init"] = 3.0 model_params["dust2"]["init"] = 0.1 model_params["logzsol"]["init"] = -0.8 model_params["tage"]["init"] = 6.5 model_params["mass"]["init"] = 1e8 model_params["tage"]["prior"] = priors.TopHat(mini=0.1, maxi=11.) model_params["dust2"]["prior"] = priors.TopHat(mini=0.0, maxi=2.0) model_params["tau"]["prior"] = priors.LogUniform(mini=1., maxi=7.) model_params["mass"]["prior"] = priors.LogUniform(mini=1e7, maxi=1e12) model_params["zred"]["prior"] = priors.TopHat(mini=0.005, maxi=4.0) model_params["mass"]["disp_floor"] = 1e5 model_params["tau"]["disp_floor"] = 1.0 model_params["tage"]["disp_floor"] = 1.0 if fixed_metallicity is not None: model_params["logzsol"]["isfree"] = False model_params["logzsol"]['init'] = fixed_metallicity if object_redshift is not None: model_params["zred"]['isfree'] = False model_params["zred"]['init'] = object_redshift if object_redshift is None: model_params["zred"]['isfree'] = True model_params["zred"]['init'] = 0.1 if add_duste: model_params.update(TemplateLibrary["dust_emission"]) if add_nebular: model_params.update(TemplateLibrary["nebular"]) if add_burst: model_params.update(TemplateLibrary["burst_sfh"]) model_params["mass"]["isfree"] = True model_params["logzsol"]["isfree"] = True model_params["dust2"]["isfree"] = True model_params["tage"]["isfree"] = True model_params["tau"]["isfree"] = True model = SedModel(model_params) return model
def model_library(model_params, attenuation_model, dust1=False): from prospect.models import priors if attenuation_model == 0: name = 'MW' model_params["dust_type"] = { "N": 1, "isfree": False, "init": 1, "units": name } model_params["mrw"] = { "N": 1, "isfree": True, "init": 1.0, "units": "The ratio of total to selective absorption which characterizes the MW extinction curve", 'prior': priors.TopHat(mini=2.0, maxi=5.0) } model_params['uvb'] = { 'N': 1, 'isfree': True, 'init': 1.0, 'units': "characterizing the strength of the 2175A extinction feature with respect to the standard Cardelli et al. determination for the MW", 'prior': priors.TopHat(mini=0.1, maxi=3.0) } model_params["dust1"] = { "N": 1, "isfree": dust1, "init": 0.0, "prior": priors.TopHat(mini=0.0, maxi=1.5), "units": "optical depth towards young stars" } elif attenuation_model == 1: name = 'PL' model_params["dust_type"] = { "N": 1, "isfree": False, "init": 0, "units": name } #power-law model_params["dust2"]["prior"] = priors.TopHat(mini=0.0, maxi=2.0) model_params["dust1"] = { "N": 1, "isfree": dust1, "init": 0.0, "prior": priors.TopHat(mini=0.0, maxi=1.5), "units": "optical depth towards young stars" } model_params["dust_index"] = { "N": 1, "isfree": True, "init": -0.7, "units": "power-law multiplication of Calzetti", "prior": priors.TopHat(mini=-2.0, maxi=0.5) } model_params["dust_index1"] = { "N": 1, "isfree": True, "init": -1.0, "units": "power-law multiplication of Calzetti", "prior": priors.TopHat(mini=-2.0, maxi=0.5) } elif attenuation_model == 2: name = 'Calzetti' model_params["dust_type"] = { "N": 1, "isfree": False, "init": 2, "units": name } #Calzetti model_params["dust2"]["prior"] = priors.TopHat(mini=0.0, maxi=2.0) model_params["dust1"] = { "N": 1, "isfree": False, "init": 0.0, "units": "optical depth towards young stars" } elif attenuation_model == 3: name = 'KC' model_params["dust_type"] = { "N": 1, "isfree": False, "init": 4, "units": name } #Conroy & Kriek dust atten. model_params["dust2"]["prior"] = priors.TopHat(mini=0.0, maxi=2.0) model_params["dust1"] = { "N": 1, "isfree": dust1, "init": 0.0, "units": "optical depth towards young stars", "prior": priors.TopHat(mini=0.0, maxi=2.0) } model_params["dust_index"] = { "N": 1, "isfree": True, "init": -0.7, "units": "power-law multiplication of Calzetti", "prior": priors.TopHat(mini=-2.5, maxi=0.7) } return model_params
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
# The "mass" and "tau" parameters have logUniform priors (i.e. TopHat priors in # log(mass) and log(tau)), the rest have TopHat priors. # You should adjust the prior ranges (particularly in mass) to suit your objects. # # The other parameters are all fixed, but we may want to explicitly set their # values, which can be done here, to override any defaults in python-FSPS model_params = [] # --- Distance --- model_params.append({'name': 'zred', 'N': 1, 'isfree': False, 'init': 0.1, 'units': '', 'prior': priors.TopHat(mini=0.0, maxi=4.0)}) # --- SFH -------- # FSPS parameter model_params.append({'name': 'sfh', 'N': 1, 'isfree': False, 'init': 4, # This is delay-tau 'units': 'type', 'prior': None}) model_params.append({'name': 'mass', 'N': 1, 'isfree': True, 'init': 1e10, 'init_disp': 1e9, 'units': r'M_\odot', 'prior': priors.LogUniform(mini=1e7, maxi=1e12)})
def load_model(zred=None, add_neb=False, complex_atten=False, atten_bump=False, **extras): """Instantiate and return a ProspectorParams model subclass. :param zred: (optional, default: 0.1) The redshift of the model :param add_neb: (optional, default: False) If True, turn on nebular emission and add relevant parameters to the model. """ from prospect.models.sedmodel import SedModel from prospect.models.templates import TemplateLibrary model_params = TemplateLibrary["parametric_sfh"] if complex_atten == True: # --- Complexify dust attenuation --- # Switch to Kriek and Conroy 2013 model_params["dust_type"] = {'N': 1, 'isfree': False, 'init': 4, 'prior': None} if atten_bump == True: # Slope of the attenuation curve, expressed as the index of the power-law # that modifies the base Kriek & Conroy/Calzetti shape. # I.e. a value of zero is basically calzetti with a 2175AA bump model_params["dust_index"] = {'N': 1, 'isfree': False, 'init': 0.0, 'prior': None} # --- Distance --- model_params.update({'zred': {'N': 1, 'isfree': False, 'init': zred, 'units': '', 'prior': priors.TopHat(mini=0.0, maxi=5.8)}}) # --- SFH -------- # FSPS parameter model_params.update({'sfh': {'N': 1, 'isfree': False, 'init': 4, # This is delay-tau 'units': 'type', 'prior': None}}) model_params.update({'mass':{'N': 1, 'isfree': True, 'init': 1e10, 'init_disp': 1e9, 'units': r'M_\odot', 'prior': priors.LogUniform(mini=1e6, maxi=1e12)}}) model_params.update({'logzsol': {'N': 1, 'isfree': True, 'init': -0.3, 'init_disp': 0.3, 'units': r'$\log (Z/Z_\odot)$', 'prior': priors.TopHat(mini=-2.0, maxi=0.19)}}) # If zcontinuous > 1, use 3-pt smoothing model_params.update({'pmetals': {'N': 1, 'isfree': False, 'init': -99, 'prior': None}}) # FSPS parameter model_params.update({'tau': {'N': 1, 'isfree': True, 'init': 1.0, 'init_disp': 0.5, 'units': 'Gyr', 'prior':priors.LogUniform(mini=0.101, maxi=100)}}) # FSPS parameter model_params.update({'tage':{'N': 1, 'isfree': True, 'init': 5.0, 'init_disp': 3.0, 'units': 'Gyr', 'prior': priors.TopHat(mini=0.101, maxi=13.6)}}) model_params.update({'fage_burst': {'N': 1, 'isfree': False, 'init': 0.0, 'units': 'time at wich burst happens, as a fraction of `tage`', 'prior': priors.TopHat(mini=0.9, maxi=1.0)}}) # 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["mass"]["disp_floor"] = 1e7 model_params["mass"]["init_disp"] = 1e8 model_params["tau"]["disp_floor"] = 1.0 model_params["tage"]["disp_floor"] = 1.0 # FSPS parameter model_params.update({'tburst': {'N': 1, 'isfree': False, 'init': 0.0, 'units': '', 'prior': None,}}) #'depends_on': tburst_fage}}) # uncomment if using bursts. # FSPS parameter model_params.update({'fburst': {'N': 1, 'isfree': False, 'init': 0.0, 'units': '', 'prior': priors.TopHat(mini=0.0, maxi=0.5)}}) # ------ IMF --------- model_params.update({'imf_type': {'N': 1, 'isfree': False, 'init': 1, #1 = chabrier 'units': None, 'prior': None}}) # --- Dust --------- # FSPS parameter model_params.update({'dust_type': {'N': 1, 'isfree': False, 'init': 0, # power-laws 'units': 'index', 'prior': None}}) # FSPS parameter model_params.update({'dust2': {'N': 1, 'isfree': True, 'init': 0.35, 'reinit': True, 'init_disp': 0.3, 'units': 'Diffuse dust optical depth towards all stars at 5500AA', 'prior': priors.TopHat(mini=0.0, maxi=2.0)}}) # FSPS parameter model_params.update({'dust1': {'N': 1, 'isfree': False, 'init': 0.0, 'units': 'Extra optical depth towards young stars at 5500AA', 'prior': None}}) # FSPS parameter model_params.update({'dust_tesc': {'N': 1, 'isfree': False, 'init': 7.0, 'units': 'definition of young stars for the purposes of the CF00 dust model, log(Gyr)', 'prior': None}}) # FSPS parameter model_params.update({'dust_index': {'N': 1, 'isfree': False, 'init': -0.7, 'units': 'power law slope of the attenuation curve for diffuse dust', 'prior': priors.TopHat(mini=-1.0, maxi=0.4)}}) # FSPS parameter model_params.update({'dust1_index': {'N': 1, 'isfree': False, 'init': -1.0, 'units': 'power law slope of the attenuation curve for young-star dust', 'prior': None}}) # ---- Dust Emission --- # FSPS parameter model_params.update({'add_dust_emission': {'N': 1, 'isfree': False, 'init': False, 'units': 'index', 'prior': None}}) # An example of the parameters controlling the dust emission SED. There are others! model_params.update({'duste_gamma': {'N': 1, 'isfree': False, 'init': 0.01, 'init_disp': 0.2, 'disp_floor': 0.15, 'units': None, 'prior': priors.TopHat(mini=0.0, maxi=1.0)}}) model_params.update({'duste_umin': {'N': 1, 'isfree': False, 'init': 1.0, 'init_disp': 5.0, 'disp_floor': 4.5, 'units': None, 'prior': priors.TopHat(mini=0.1, maxi=25.0)}}) model_params.update({'duste_qpah': {'N': 1, 'isfree': False, 'init': 2.0, 'init_disp': 3.0, 'disp_floor': 3.0, 'units': 'percent', 'prior': priors.TopHat(mini=0.0, maxi=7.0)}}) # --- Stellar Pops ------------ # One could imagine changing these, though doing so *during* the fitting will # be dramatically slower. # FSPS parameter model_params.update({'tpagb_norm_type': {'N': 1, 'isfree': False, 'init': 2, 'units': 'index', 'prior': None}}) # FSPS parameter model_params.update({'add_agb_dust_model': {'N': 1, 'isfree': False, 'init': True, 'units': 'index', 'prior': None}}) # FSPS parameter model_params.update({'agb_dust': {'N': 1, 'isfree': False, 'init': 1, 'units': 'index', 'prior': None}}) # --- Nebular Emission ------ # For speed we turn off nebular emission in the demo model_params.update({'add_neb_emission': {'N': 1, 'isfree': False, 'init': False, 'prior': None}}) # FSPS parameter model_params.update({'gas_logz': {'N': 1, 'isfree': False, 'init': 0.0, 'units': r'log Z/Z_\odot', # 'depends_on': stellar_logzsol, 'prior': priors.TopHat(mini=-2.0, maxi=0.5)}}) # FSPS parameter model_params.update({'gas_logu': {'N': 1, 'isfree': False, 'init': -2.0, 'units': '', 'prior': priors.TopHat(mini=-4, maxi=-1)}}) # --- Calibration --------- # Only important if using a NoiseModel model_params.update({'phot_jitter': {'N': 1, 'isfree': False, 'init': 0.0, 'units': 'mags', 'prior': priors.TopHat(mini=0.0, maxi=0.2)}}) return SedModel(model_params)
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
def build_model(redshift, fixed_metallicity=None, dust=False, agn_mass=None, agn_eb_v=None, agn_torus_mass=None, igm_absorbtion=True, inclination=True, **extras): """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 ldist: (optional, default: 10) The luminosity distance (in Mpc) for the model. Spectra and observed frame (apparent) photometry will be appropriate for this luminosity distance. :param fixed_metallicity: (optional, default: None) If given, fix the model metallicity (:math:`log(Z/Z_sun)`) to the given value. :param dust: (optional, default: False) If `True`, add dust emission and associated (fixed) parameters to the model. :returns model: An instance of prospect.models.SedModel """ logging.debug(redshift) logging.debug(fixed_metallicity) logging.debug(dust) logging.debug(agn_mass) logging.debug(agn_eb_v) logging.debug(agn_torus_mass) logging.debug(igm_absorbtion) logging.debug(extras) # TODO increase galaxy extinction to 0.6 # Get (a copy of) one of the prepackaged model set dictionaries. # This is, somewhat confusingly, a dictionary of dictionaries, keyed by parameter name model_params = TemplateLibrary["parametric_sfh"] # add sfh and tau # dust2 init -.6, uniform [0, 2] uniform prior # delay-tau model with tau [0.1, 30] log-uniform prior # tage (burst start?) init 1, uniform (tophat) [0.001, 13.8] model_params['dust_type'] = { "N": 1, "isfree": False, "init": 2 } # Calzetti, as opposed to 0 for power law # fixed: Kroupa IMF # mass: lower 10^9, upper 10^12 # TODO set to logzsol=0 fixed, make this assumption # dust (optical depth at 5500A): init=0.6, prior [0, 2], hopefully this is okay? # sfh: 'delay-tau' is 4 # _parametric_["tau"] = {"N": 1, "isfree": True, # "init": 1, "units": "Gyr^{-1}", # "prior": priors.LogUniform(mini=0.1, maxi=30)} # my convention: if None, don't model. if value, model as fixed to value. If True, model as free. # Change the model parameter specifications based on some keyword arguments if fixed_metallicity is None: logging.info('Using free metallicity') model_params['logzsol']['isfree'] = True else: # make it a fixed parameter logging.info(f'Using fixed metallicity of {fixed_metallicity}') model_params["logzsol"]["isfree"] = False #And use value supplied by fixed_metallicity keyword model_params["logzsol"]['init'] = fixed_metallicity if dust: # Add dust emission (with fixed dust SED parameters) logging.info('Including dust emission fixed parameters') model_params.update(TemplateLibrary["dust_emission"]) else: logging.warning('Not using dust emission') if igm_absorbtion: logging.info('Using fixed IGM absorption (0.1 by default)') # Add (fixed) IGM absorption parameters: madau attenuation (fixed to 1.) model_params.update(TemplateLibrary["igm"]) else: logging.warning('Not using IGM absorbtion') if redshift is None: raise ValueError('Redshift set to None - must be included in model!') if isinstance(redshift, float): logging.info('Using fixed redshift of {}'.format(redshift)) # Set redshift as fixed to value model_params["zred"]['isfree'] = False model_params["zred"]['init'] = redshift else: logging.info('Using free redshift') # Set redshift as free assert redshift == True # not just truthy, but exactly True/bool model_params["zred"]['isfree'] = True if agn_mass is None: logging.warning('No AGN mass supplied - AGN not modelled') # finish early model = SedModel(model_params) return model elif isinstance(agn_mass, float): logging.info('AGN mass will be fixed at {}'.format(agn_mass)) model_params['agn_mass'] = { 'N': 1, 'isfree': False, 'init': agn_mass } # units? else: assert agn_mass == True logging.info('AGN mass will be free parameter') model_params['agn_mass'] = { 'N': 1, 'isfree': True, 'init': 1., 'prior': priors.LogUniform(mini=1e-7, maxi=15) } if agn_eb_v is None: logging.warning('AGN extinction not modelled') else: assert agn_mass if isinstance(agn_eb_v, float): logging.info('Using fixed agn_eb_v of {}'.format(agn_eb_v)) assert agn_mass model_params['agn_eb_v'] = { "N": 1, "isfree": False, "init": agn_eb_v, "units": "", 'prior': priors.TopHat(mini=0., maxi=0.5) } elif agn_mass == True: logging.info('Using free agn_eb_v') model_params['agn_eb_v'] = { "N": 1, "isfree": True, "init": 0.1, "units": "", 'prior': priors.TopHat(mini=0., maxi=0.5) } else: logging.warning('Not modelling AGN disk') if agn_torus_mass is None: logging.warning('Not modelling AGN torus') elif isinstance(agn_torus_mass, float): logging.info('Using fixed obscured torus of {}'.format(agn_torus_mass)) model_params['agn_torus_mass'] = { "N": 1, "isfree": False, "init": agn_torus_mass, "units": "", 'prior': priors.LogUniform(mini=1e-7, maxi=15) } else: logging.info('Using free obscured torus') model_params['agn_torus_mass'] = { "N": 1, "isfree": True, "init": .1, "units": "", 'prior': priors.LogUniform(mini=1e-7, maxi=15) } if inclination is None: raise ValueError( 'No model inclination preference supplied - set float to fix, or set True to leave free, but set something!' ) elif isinstance(inclination, float): logging.info('Using fixed inclination of {}'.format(inclination)) model_params['inclination'] = { "N": 1, "isfree": False, "init": inclination, "units": "", 'prior': priors.TopHat(mini=0., maxi=90.) } else: logging.info('Using free inclination') model_params['inclination'] = { "N": 1, "isfree": True, "init": 60., "units": "", 'prior': priors.TopHat(mini=0., maxi=90.) } # explicitly no FSPS dusty torus # model_params['fagn'] = None # model_params['agn_tau'] = None # Now instantiate the model object using this dictionary of parameter specifications model = SedModel(model_params) return model
# log(tau)), the rest have TopHat priors. # You should adjust the prior ranges (particularly in mass) to suit your objects. # # The other parameters are all fixed, but we may want to explicitly set their # values, which can be done here, to override any defaults in python-FSPS model_params = [] # --- Distance --- model_params.append({ 'name': 'zred', 'N': 1, 'isfree': False, 'init': 0.1, 'units': '', 'prior': priors.TopHat(mini=0.0, maxi=4.0) }) # --- SFH -------- # FSPS parameter model_params.append({ 'name': 'sfh', 'N': 1, 'isfree': False, 'init': 4, # This is delay-tau 'units': 'type', 'prior': None }) model_params.append({ 'name': 'mass',
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
# -------------- model_params = [] # --- Distance --- # This is the redshift. Because we are not separately supplying a ``lumdist`` # parameter, the distance will be determined from the redshift using a WMAP9 # cosmology, unless the redshift is 0, in which case the distance is assumed to # be 10pc (i.e. for absolute magnitudes) model_params.append({ 'name': 'zred', 'N': 1, 'isfree': False, 'init': 2.241, 'units': '', 'prior': priors.TopHat(mini=-0.001, maxi=0.001) }) # --- SFH -------- # This gives the start and stop of each age bin. We will adjust this in # load_model() below based on the `agelims` run_param model_params.append({ 'name': 'agebins', 'N': 1, 'isfree': False, 'init': [[0.0, 8.0], [8.0, 8.7]], 'units': 'log(yr)' }) # This will be the mass in each bin. It depends on other free and fixed
return 10**logtau ############# # MODEL_PARAMS ############# model_params = [] ###### BASIC PARAMETERS ########## model_params.append({ 'name': 'zred', 'N': 1, 'isfree': False, 'init': 0.1, 'units': '', 'prior': priors.TopHat(mini=0.0, maxi=4.0) }) model_params.append({ 'name': 'logmass', 'N': 1, 'isfree': True, 'init': 10.0, 'units': 'Msun', 'prior': priors.TopHat(mini=6.0, maxi=12.0) }) model_params.append({ 'name': 'mass', 'N': 1, 'isfree': False,
}) model_params.append({ 'name': 'tau', 'N': 1, 'isfree': True, 'init': 1, 'prior': priors.LogUniform(mini=0.1, maxi=30) }) model_params.append({ 'name': 'tage', 'N': 1, 'isfree': True, 'init': 5, 'prior': priors.TopHat(mini=0.1, maxi=14.1) }) model_params.append({ 'name': 'imf_type', 'N': 1, 'isfree': False, 'init': 2, #Kroupa 'prior': ' ' }) model_params.append({ 'name': 'dust_type', 'N': 1, 'isfree': False, 'init': 0,
def build_model(object_redshift=None, luminosity_distance=0.0, fixed_metallicity=None, remove_spec_continuum=True, add_neb=False, **extras): """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 luminosity_distance: (optional, default: 10) The luminosity distance (in Mpc) for the model. Spectra and observed frame (apparent) photometry will be appropriate for this luminosity distance. :param fixed_metallicity: (optional, default: None) If given, fix the model metallicity (:math:`log(Z/Z_sun)`) to the given value. :param add_duste: (optional, default: False) If `True`, add dust emission and associated (fixed) parameters to the model. :returns model: An instance of prospect.models.SedModel """ from prospect.models.sedmodel import PolySpecModel, PolySedModel from prospect.models.templates import TemplateLibrary from prospect.models import priors # Get (a copy of) one of the prepackaged model set dictionaries. # This is, somewhat confusingly, a dictionary of dictionaries, keyed by parameter name model_params = TemplateLibrary["ssp"] # --- Adjust Model Components --- # Here we add to and tweak the model components to get something that can describe our data # Fit for velocity dispersion. This adds parameters necessary for fitting for spectral broadening model_params.update(TemplateLibrary['spectral_smoothing']) model_params["sigma_smooth"]["prior"] = priors.TopHat(mini=5.0, maxi=100.0) # This removes the continuum from the spectroscopy. Highly recommended # when modeling both photometry & spectroscopy # If the normalization between the spectrum & photometry is off by ~> 10 # orders of magnitude, this can get numerically unstable. if remove_spec_continuum: model_params.update(TemplateLibrary['optimize_speccal']) # Here we set the order of the polynomial used to normalize the observed spectrum to the model. # Avoid using very high order polynomials as they will remove absorption lines, # and beware that spectral breaks (e.g. dn4000) may be optimized out by this procedure. # Rule of thumb: this removes continuum shape on wavelength scales # of (total_wavelength_range/polyorder). model_params['polyorder']["init"] = 12 # Now add the lumdist parameter by hand as another entry in the dictionary. # This will control the distance since the redshift is possibly decoupled from the hubble flow. # If luminosity_distance is less than or equal to 0, # then the distance is controlled by the "zred" parameter and a WMAP9 cosmology. if luminosity_distance > 0: model_params["lumdist"] = { "N": 1, "isfree": False, "init": luminosity_distance, "units": "Mpc" } # if we specify a redshift, let the model know, otherwise fit for it if object_redshift is not None: # make sure zred is fixed # And set the value to the object_redshift keyword model_params["zred"]['init'] = object_redshift else: model_params["zred"]['init'] = 0.0 model_params["zred"]['isfree'] = True # Change the model parameter specifications based on some keyword arguments # Here, if a value is passed in the 'fixed_metallicity' keyword, # we fix the metallicity in units of log(Z/Zsun) to that value if fixed_metallicity is not None: # make it a fixed parameter model_params["logzsol"]["isfree"] = False #And use value supplied by fixed_metallicity keyword model_params["logzsol"]['init'] = fixed_metallicity # This adds nebular emission using a fixed CLOUDY grid. # The gas-phase metallicity is set to the stellar metallicity by default # and the ionization parameter is fixed by default. # If there are nebular lines in the spectrum which is either (a) off of the CLOUDY grid, # or (b) not caused by star formation, recommend using analytical marginalization instead. if add_neb: model_params.update(TemplateLibrary["nebular"]) # --- Priors --- # Here we adjust our priors model_params["mass"]["prior"] = priors.LogUniform(mini=1e4, maxi=1e10) model_params["dust2"]["prior"] = priors.TopHat(mini=0.0, maxi=2.0) model_params["tage"]["prior"] = priors.TopHat(mini=0.1, maxi=13.7) model_params["logzsol"]["prior"] = priors.TopHat(mini=-1.98, maxi=0.19) model_params["zred"]["prior"] = priors.TopHat(mini=-0.05, maxi=0.05) # --- Initial Values --- # These are not really necessary, but they make the plots look better model_params["mass"]["init"] = 1e8 model_params["sigma_smooth"]["init"] = 20.0 # Now instantiate the model object using this dictionary of parameter specifications # Could also use SedModel, but SedModel is old and tired, SpecModel is the new hotness model = PolySpecModel(model_params) return model
def build_model(object_redshift=None, ldist=10.0, fixed_metallicity=None, add_duste=False, **extras): """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 ldist: (optional, default: 10) The luminosity distance (in Mpc) for the model. Spectra and observed frame (apparent) photometry will be appropriate for this luminosity distance. :param fixed_metallicity: (optional, default: None) If given, fix the model metallicity (:math:`log(Z/Z_sun)`) to the given value. :param add_duste: (optional, default: False) If `True`, add dust emission and associated (fixed) parameters to the model. :returns model: An instance of prospect.models.SedModel """ # Get (a copy of) one of the prepackaged model set dictionaries. # This is, somewhat confusingly, a dictionary of dictionaries, keyed by parameter name model_params = TemplateLibrary["parametric_sfh"] # 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 10Mpc to convert from absolute to apparent magnitudes, # so we use that here too, since the `maggies` are appropriate for that distance. model_params["lumdist"] = { "N": 1, "isfree": False, "init": ldist, "units": "Mpc" } # Let's make some changes to initial values appropriate for our objects and data model_params["zred"]["init"] = 0.0 model_params["dust2"]["init"] = 0.05 model_params["logzsol"]["init"] = -0.5 model_params["tage"]["init"] = 13. model_params["mass"]["init"] = 1e8 # These are dwarf galaxies, so lets also adjust the metallicity prior, # the tau parameter upward, and the mass prior downward model_params["dust2"]["prior"] = priors.TopHat(mini=0.0, maxi=2.0) model_params["tau"]["prior"] = priors.LogUniform(mini=1e-1, maxi=1e2) model_params["mass"]["prior"] = priors.LogUniform(mini=1e6, maxi=1e10) # 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["mass"]["disp_floor"] = 1e6 model_params["tau"]["disp_floor"] = 1.0 model_params["tage"]["disp_floor"] = 1.0 # Change the model parameter specifications based on some keyword arguments if fixed_metallicity is not None: # make it a fixed parameter model_params["logzsol"]["isfree"] = False #And use value supplied by fixed_metallicity keyword model_params["logzsol"]['init'] = fixed_metallicity 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 if add_duste: # Add dust emission (with fixed dust SED parameters) # Since `model_params` is a dictionary of parameter specifications, # and `TemplateLibrary` returns dictionaries of parameter specifications, # we can just update `model_params` with the parameters described in the # pre-packaged `dust_emission` parameter set. model_params.update(TemplateLibrary["dust_emission"]) # Now instantiate the model object using this dictionary of parameter specifications model = SedModel(model_params) return model
# values, possibly from something differnt than the FSPS defaults model_params = [] # --- Distance --- # This is the redshift. Because we are not separately supplying a ``lumdist`` # parameter, the distance will be determined from the redshift using a WMAP9 # cosmology, unless the redshift is 0, in which case the distance is assumed to # be 10pc (i.e. for absolute magnitudes) model_params.append({ 'name': 'zred', 'N': 1, 'isfree': False, 'init': 0.0, 'units': '', 'prior': priors.TopHat(mini=0.0, maxi=4.0) }) # --- SFH -------- # FSPS parameter. sfh=4 is a delayed-tau SFH model_params.append({ 'name': 'sfh', 'N': 1, 'isfree': False, 'init': 4, 'units': 'type' }) # Normalization of the SFH. If the ``mass_units`` parameter is not supplied, # this will be in surviving stellar mass. Otherwise it is in the total stellar # mass formed.
def load_model(zred=0.1, seed=None): """Initialize the priors on each free and fixed parameter. TBD: Do we need to define priors on dust, fburst, etc., etc.??? Args: zred (float): input (fixed) galaxy redshift. mass (float): initial stellar mass (Msun) logzsol (float): initial metallicity tage (float): initial age (Gyr) tau (float): initial SFH timescale (Gyr) dust2 (float): initial diffuse dust attenuation (dimensionless optical depth) Returns: sed (prospect.models.sedmodel.SedModel): SED priors and other stuff. Notes: #FSPS is Flexible Stellar Population systhesis or Something. FSPS parameters are documented here: http://dan.iel.fm/python-fsps/current/stellarpop_api/#api-reference Initialization parameters: * compute_vega_mags (must be set at initialization) * vactoair_flag (must be set at initialization) * zcontinuous (must be set at initialization) # MESS WITH THESE: Metallicity parameters: * zmet (default 1, ignored if zcontinuous>0) * logzsol (default 0.0, used if zcontinuous>0) * pmetals (default 2.0, only used if zcontinuous=2) Dust parameters: * add_agb_dust_model (default True) * add_dust_emission (default True) * cloudy_dust (default False) * agb_dust (default 1.0) * dust_type (default 0=power law) * dust_index, dust1_index * dust_tesc * dust1 (default 0.0) - extra optical depth towards young stars at 5500A * dust2 (default 0.0) - diffuse dust optical depth towards all stars at 5500A * dust_clumps, frac_nodust, frac_obrun * mwr, uvb, wgp1, wgp2, wgp3, * duste_gamma, duste_umin, duste_qpah Star formation history parameters: * sfh (default 0=SSP, 1=tau, 4=delayed, 5=truncated delayed tau) * tau (default 1) * const, sf_start, sf_trunc * tage (default 0.0) * fburst, tburst, sf_slope Miscellaneous parameters: * add_igm_absorption (default False) * igm_factor (default 1.0) * smooth_velocity (default True) * sigma_smooth, min_wave_smooth, max_wave_smooth * redshift_colors (default False, do not use) * compute_light_ages (default False, do not use) Stellar population parameters: * add_stellar_remnants (default True) * tpagb_norm_type (default 2) * dell (default 0.0, do not use) * delt (default 0.0, do not use) * redgb (default 1.0) * fcstar (default 1.0) * sbss (default 0.0) * fbhb (default 0.0) * pagb (default 1.0) * imf_type (default 2=Kroupa01) * imf1, imf2, imf3, vdmc, mdave, masscut * evtype (default 1) * tpagb_norm_type Emission lines: * add_neb_emission (default False) * add_neb_continuum (default False) * gas_logz (default 0.0) * gas_logu (default -2) Galaxy properties: * zred (default 0.0) AGN properties: * fagn (default 0.0) * agn_tau (default 10) Calibration parameters: * phot_jitter """ from prospect.models import priors, sedmodel model_params = [] ################################################## # Fixed priors # Galaxy redshift model_params.append({ 'name': 'zred', 'N': 1, 'isfree': False, 'init': zred, 'units': '', 'prior': None, }) model_params.append({ # current mass in stars, not integral of SFH 'name': 'mass_units', 'N': 1, 'isfree': False, 'init': 'mstar', # 'mformed' 'prior': None, }) # IMF (Chabrier) model_params.append({ 'name': 'imf_type', 'N': 1, 'isfree': False, 'init': 1, # 1 - Chabrier 'units': '', 'prior': None, }) # SFH parameterization (delayed-tau) model_params.append({ 'name': 'sfh', 'N': 1, 'isfree': False, 'init': 4, # 4 = delayed tau model 'units': 'type', 'prior': None, }) # Do not include dust emission model_params.append({ 'name': 'add_dust_emission', 'N': 1, 'isfree': False, 'init': False, # do not include dust emission 'units': 'index', 'prior': None, }) ################################################## # Free priors / parameters # Priors on stellar mass and stellar metallicity logmass_prior = priors.TopHat(mini=9.0, maxi=13.0) #, seed=seed) logmass_init = np.diff(logmass_prior.range) / 2.0 + logmass_prior.range[ 0] # logmass_prior.sample() model_params.append({ 'name': 'logmass', 'N': 1, 'isfree': True, 'init': logmass_init, # mass, 'init_disp': 0.5, # dex 'units': r'$M_{\odot}$', 'prior': logmass_prior, }) model_params.append({ 'name': 'mass', 'N': 1, 'isfree': False, 'init': 10**logmass_init, 'units': '', 'prior': None, 'depends_on': logmass2mass, }) logzsol_prior = priors.TopHat(mini=np.log10(0.004 / 0.019), maxi=np.log10(0.04 / 0.019)) #, seed=seed) logzsol_init = np.diff(logzsol_prior.range) / 2.0 + logzsol_prior.range[ 0] # logzsol_prior.sample(), # logzsol, model_params.append({ 'name': 'logzsol', 'N': 1, 'isfree': True, 'init': logzsol_init, 'init_disp': 0.3, # logzsol_prior.range[1] * 0.1, 'units': r'$\log_{10}\, (Z/Z_\odot)$', 'prior': logzsol_prior, # roughly (0.2-2)*Z_sun }) # Prior(s) on dust content dust2_prior = priors.TopHat(mini=0.0, maxi=3.0) #, seed=seed) dust2_init = np.diff(dust2_prior.range) / 2.0 + dust2_prior.range[ 0] # dust2_prior.sample(), # dust2, model_params.append({ 'name': 'dust2', 'N': 1, 'isfree': True, 'init': dust2_init, 'init_disp': 0.5, # dust2_prior.range[1] * 0.1, 'units': '', # optical depth 'prior': dust2_prior, }) # Priors on tau and age #tau_prior = priors.TopHat(mini=0.1, maxi=10.0)#, seed=seed) tau_prior = priors.LogUniform(mini=0.1, maxi=10.0) #, seed=seed) tau_init = np.diff(tau_prior.range) / 2.0 + tau_prior.range[ 0] # tau_prior.sample(), # tau, model_params.append({ 'name': 'tau', 'N': 1, 'isfree': True, 'init': tau_init, 'init_disp': 1.0, # tau_prior.range[1] * 0.1, 'units': 'Gyr', 'prior': tau_prior, }) tage_prior = priors.TopHat(mini=0.5, maxi=15) #, seed=seed) tage_init = np.diff(tage_prior.range) / 2.0 + tage_prior.range[ 0] # tage_prior.sample(), # tage, model_params.append({ 'name': 'tage', 'N': 1, 'isfree': True, 'init': tage_init, 'init_disp': 2.0, # tage_prior.range[1] * 0.1, 'units': 'Gyr', 'prior': tage_prior, }) model = sedmodel.SedModel(model_params) return model
def build_model(object_redshift=0.0, fixed_metallicity=None, add_duste=False, add_neb=False, luminosity_distance=0.0, **extras): no_dust = False # if True, get rid of all dust related parameters # set dust model type by hand dust_type = 0 """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)) """ # ----------------------------------------------------------- # # get dust model from config file # HAVING THIS MAKES THE MODEL NONETYPE # store config.txt inputs as dictionary #new_dict = {} #with open(args.path+"/config.txt") as config_file: # for line in config_file: # (key, val) = line.split() # new_dict[key] = val #config_file.close() # #for name, value in new_dict.items(): # split_name = name.split('/') # # if split_name[0] == 'dust_model': # config_dust_model = int(value) # print('dust_model from config file:', config_dust_model) # ----------------------------------------------------------- # from prospect.models.templates import TemplateLibrary from prospect.models import priors, sedmodel # --- Get a basic delay-tau SFH parameter set. --- # This has 5 free parameters: # "mass", "logzsol", "dust2", "tage", "tau" # And two fixed parameters # "zred"=0.1, "sfh"=4 # See the python-FSPS documentation for details about most of these # parameters. Also, look at `TemplateLibrary.describe("parametric_sfh")` to # view the parameters, their initial values, and the priors in detail. model_params = TemplateLibrary["parametric_sfh"] print('redshift is ', object_redshift) model_params["zred"]['init'] = object_redshift #print('template dust type:', model_params["dust_type"]['init']) # set dust type based on value set above model_params["dust_type"]['init'] = dust_type # set dust type to Chabrier (to match SKIRT) model_params["imf_type"]['init'] = 1 #model_params["dust_type"] = {"N": 1, "isfree": False, "init": config_dust_model} #model_params["zred"] = {"N": 1, "isfree": False, "init": object_redshift} #print('dust type set by config file:', model_params["dust_type"]['init']) #print('redshift is ', model_params["zred"]['init']) # Add lumdist parameter. If this is not added then the distance is # controlled by the "zred" parameter and a WMAP9 cosmology. if luminosity_distance > 0: print('applying luminosity distance', luminosity_distance) model_params["lumdist"] = { "N": 1, "isfree": False, "init": luminosity_distance, "units": "Mpc" } # mass logzsol dust2 tage tau duste_umin duste_qpah duste_gamma # Adjust model initial values (only important for optimization or emcee) model_params["mass"]["init"] = 1e11 model_params["logzsol"]["init"] = -1 model_params["dust2"]["init"] = 5 model_params["tage"]["init"] = 11 model_params["tau"]["init"] = 25 # If we are going to be using emcee, it is useful to provide an # initial scale for the cloud of walkers (the default is 0.1 times initial value) # For dynesty these can be skipped model_params["mass"]["init_disp"] = 1e10 model_params["logzsol"]["init_disp"] = 0.5 model_params["dust2"]["init_disp"] = 2.5 model_params["tage"]["init_disp"] = 2 model_params["tau"]["init_disp"] = 12.5 # adjust priors model_params["mass"]["prior"] = priors.LogUniform(mini=1e8, maxi=1e13) model_params["dust2"]["prior"] = priors.TopHat(mini=0.0, maxi=10.0) model_params["logzsol"]["prior"] = priors.TopHat(mini=-2.0, maxi=0.5) model_params["tage"]["prior"] = priors.LogUniform(mini=9, maxi=14) model_params["tau"]["prior"] = priors.LogUniform(mini=1e-1, maxi=50) # can go to 100 if no_dust: print('getting rid of all dust parameters') model_params["dust2"]["init"] = 0 model_params["dust2"]["isfree"] = False else: print('applying dust parameters') if add_duste: # Add dust emission (with fixed dust SED parameters) print('adding dust emission') model_params.update(TemplateLibrary["dust_emission"]) model_params["duste_umin"]["isfree"] = True model_params["duste_qpah"]["isfree"] = True model_params["duste_gamma"]["isfree"] = True model_params["duste_umin"]["prior"] = priors.TopHat(mini=0.1, maxi=25.0) model_params["duste_qpah"]["prior"] = priors.TopHat(mini=0.0, maxi=10.0) model_params["duste_gamma"]["prior"] = priors.TopHat(mini=0.0, maxi=1.0) model_params["duste_umin"]['init'] = 12.5 model_params["duste_qpah"]['init'] = 5 model_params["duste_gamma"]['init'] = 0.5 model_params["duste_umin"]['init_disp'] = 6.25 model_params["duste_qpah"]['init_disp'] = 2.5 model_params["duste_gamma"]['init_disp'] = 0.25 #model_params["duste_qpah"]["init"] = 9.0282 # calculated from https://skirt.ugent.be/skirt9/class_draine_li_dust_mix.html#a397683515561f08b8aae8f6107900337 under detailed description Mdust/MH values # ------------- DUST MODELS -------------- # # Set dust type from config file #model_params["dust_type"]['init'] = config_dust_model print('dust type set by config file:', model_params["dust_type"]['init']) # power law with index dust index set by dust_index if model_params["dust_type"]['init'] == 0: print('in the dust_type=0 if statement') model_params["dust1"] = { "N": 1, "isfree": True, "init": 0.0, "units": "optical depth for young population" } model_params["dust1"]["prior"] = priors.TopHat(mini=0.0, maxi=10.0) model_params["dust_index"] = { "N": 1, "isfree": True, "init": -0.7, "units": "Power law index of the attenuation curve" } model_params["dust_index"]["prior"] = priors.TopHat( mini=-5, maxi=5) # just guessing the range model_params["dust1_index"] = { "N": 1, "isfree": True, "init": -1, "units": "Power law index of the attenuation curve for young stars" } model_params["dust1_index"]["prior"] = priors.TopHat( mini=-5, maxi=5) # just guessing the range # Milky Way extinction law (with the R=AV/E(B−V) value given by mwr) parameterized by Cardelli et al. (1989), with variable UV bump strength if model_params["dust_type"]['init'] == 1: print('in the dust_type=1 if statement') model_params["dust1"] = { "N": 1, "isfree": True, "init": 0.0, "units": "optical depth for young population" } model_params["dust1"]["prior"] = priors.TopHat(mini=0.0, maxi=10.0) # mwr: The ratio of total to selective absorption which characterizes the MW extinction curve: R=AV/E(B−V) model_params["mwr"] = {"N": 1, "isfree": True, "init": 3.1} model_params["mwr"]["prior"] = priors.TopHat(mini=0.1, maxi=10.0) # uvb: Parameter characterizing the strength of the 2175A extinction feature with respect to the standard Cardelli et al. determination for the MW. model_params["uvb"] = {"N": 1, "isfree": True, "init": 1} model_params["uvb"]["prior"] = priors.TopHat(mini=0.1, maxi=10.0) # Calzetti et al. (2000) attenuation curve. Note that if this value is set then the dust attenuation is applied to all starlight equally (not split by age), and therefore the only relevant parameter is dust2, which sets the overall normalization if model_params["dust_type"]['init'] == 2: print('in the dust_type=2 if statement') # allows the user to access a variety of attenuation curve models from Witt & Gordon (2000) using the parameters wgp1 and wgp2. In this case the parameters dust1 and dust2 have no effect because the WG00 models specify the full attenuation curve. if model_params["dust_type"]['init'] == 3: print('in the dust_type=3 if statement') model_params["dust2"]["isfree"] = False # wgp1: Integer specifying the optical depth in the Witt & Gordon (2000) models model_params["wgp1"] = {"N": 1, "isfree": True, "init": 1} model_params["wgp1"]["prior"] = priors.TopHat(mini=1, maxi=18) # wgp2: Integer specifying the type of large-scale geometry and extinction curve model_params["wgp2"] = {"N": 1, "isfree": True, "init": 1} model_params["wgp2"]["prior"] = priors.TopHat(mini=1, maxi=6) # Kriek & Conroy (2013) attenuation curve. In this model the slope of the curve, set by the parameter dust_index, is linked to the strength of the UV bump if model_params["dust_type"]['init'] == 4: print('in the dust_type=4 if statement') # dust_index: Power law index of the attenuation curve. model_params["dust_index"] = {"N": 1, "isfree": True, "init": -0.7} model_params["dust_index"]["prior"] = priors.TopHat(mini=-5, maxi=5) # ---------------------------------------- # # Change the model parameter specifications based on some keyword arguments if fixed_metallicity is not None: # make it a fixed parameter print('fixing metallicity') model_params["logzsol"]["isfree"] = False #And use value supplied by fixed_metallicity keyword model_params["logzsol"]['init'] = fixed_metallicity if object_redshift != 0.0: print('applying redshift') # 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 if add_neb: # Add nebular emission (with fixed parameters) print('adding nebular emission') model_params.update(TemplateLibrary["nebular"]) # Now instantiate the model using this new dictionary of parameter specifications model = sedmodel.SedModel(model_params) return model
def load_model(obs, template_library='delayed-tau', verbose=False): """ http://dfm.io/python-fsps/current/stellarpop_api/#api-reference https://github.com/moustakas/siena-astrophysics/blob/master/research/redmapper/redmapper-stellar-mass.py#L125-L197 """ from prospect.models import priors from prospect.models.sedmodel import SedModel from prospect.models.templates import TemplateLibrary from prospect.models.transforms import dustratio_to_dust1 def base_delayed_tau(): model_params = TemplateLibrary['parametric_sfh'] # Initialize with sensible numbers. model_params['tau']['init'] = 10.0 model_params['tage']['init'] = 1.0 model_params['logzsol']['init'] = 0.2 # optimize log-stellar mass, not linear stellar mass model_params['logmass'] = { 'N': 1, 'isfree': True, 'init': 11.0, 'prior': priors.TopHat(mini=10.0, maxi=12.0), 'units': '$M_{\odot}$' } model_params['mass']['isfree'] = False model_params['mass']['init'] = 10**model_params['logmass']['init'] model_params['mass']['prior'] = None model_params['mass']['depends_on'] = logmass2mass # Adjust the prior ranges. model_params['tau']['prior'] = priors.LogUniform(mini=0.01, maxi=30.0) model_params['tage']['prior'] = priors.LogUniform(mini=0.1, maxi=13.0) model_params['logzsol']['prior'] = priors.TopHat(mini=-0.5, maxi=0.3) #print('HACK!!!!!!!!!!!!!') #model_params['tau']['isfree'] = False #model_params['tage']['isfree'] = False #model_params['logzsol']['isfree'] = False #model_params['dust2']['isfree'] = False return model_params if template_library == 'delayed-tau': # Underlying delayed tau model. model_params = base_delayed_tau() if template_library == 'bursty': # Underlying delayed tau model. model_params = base_delayed_tau() # Add bursts model_params.update(TemplateLibrary['burst_sfh']) model_params['fburst']['isfree'] = True model_params['fburst']['init'] = 0.1 model_params['fburst']['prior'] = priors.TopHat(mini=0.0, maxi=1.0) model_params['fage_burst']['isfree'] = True model_params['fage_burst']['init'] = 0.9 model_params['fage_burst']['prior'] = priors.TopHat(mini=0.5, maxi=1.0) # Add dust emission (with fixed dust SED parameters). model_params.update(TemplateLibrary['dust_emission']) model_params['duste_gamma']['isfree'] = True model_params['dust2']['init'] = 1.0 # diffuse dust model_params['dust2']['prior'] = priors.TopHat(mini=0.0, maxi=4.0) # Add more dust flexibility. if True: model_params['dust_type'] = { 'N': 1, 'isfree': False, 'init': 0, 'units': 'dust model' } model_params['dust_index'] = { 'N': 1, 'isfree': False, 'init': -0.7, 'units': 'power-law index', 'prior': None } #model_params['dust1'] = {'N': 1, 'isfree': False, 'init': 0.0, 'prior': None, # 'units': 'optical depth towards young stars', # 'depends_on': dustratio_to_dust1} #model_params['dust_ratio'] = {'N': 1, 'isfree': True, 'init': 1.0, # 'prior': priors.TopHat(mini=1.0, maxi=10.0), # 'units': 'dust1/dust2 ratio (optical depth to young stars vs diffuse)'} ## Add nebular emission. #model_params.update(TemplateLibrary['nebular']) ##model_params['add_neb_continuum']['init'] = False #model_params['gas_logu']['init'] = -1.0 # harder radiation field [default is -2.0] # Fixed redshift. model_params['zred']['init'] = obs['redshift'] model_params['zred']['isfree'] = False # Change the IMF from Kroupa to Salpeter. model_params['imf_type']['init'] = 0 # Now instantiate the model using this new dictionary of parameter specifications model = SedModel(model_params) if verbose: print(model) return model
def build_model(object_redshift=0.0, fixed_metallicity=None, add_duste=False, add_neb=False, luminosity_distance=0.0, **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 from prospect.models import priors, sedmodel # --- Get a basic delay-tau SFH parameter set. --- # This has 5 free parameters: # "mass", "logzsol", "dust2", "tage", "tau" # And two fixed parameters # "zred"=0.1, "sfh"=4 # See the python-FSPS documentation for details about most of these # parameters. Also, look at `TemplateLibrary.describe("parametric_sfh")` to # view the parameters, their initial values, and the priors in detail. model_params = TemplateLibrary["parametric_sfh"] # Add lumdist parameter. If this is not added then the distance is # controlled by the "zred" parameter and a WMAP9 cosmology. if luminosity_distance > 0: model_params["lumdist"] = { "N": 1, "isfree": False, "init": luminosity_distance, "units": "Mpc" } # Adjust model initial values (only important for optimization or emcee) model_params["dust2"]["init"] = 0.1 model_params["logzsol"]["init"] = -0.3 model_params["tage"]["init"] = 13. model_params["mass"]["init"] = 1e8 # If we are going to be using emcee, it is useful to provide an # initial scale for the cloud of walkers (the default is 0.1) # For dynesty these can be skipped model_params["mass"]["init_disp"] = 1e7 model_params["tau"]["init_disp"] = 3.0 model_params["tage"]["init_disp"] = 5.0 model_params["tage"]["disp_floor"] = 2.0 model_params["dust2"]["disp_floor"] = 0.1 # adjust priors model_params["dust2"]["prior"] = priors.TopHat(mini=0.0, maxi=2.0) model_params["tau"]["prior"] = priors.LogUniform(mini=1e-1, maxi=10) model_params["mass"]["prior"] = priors.LogUniform(mini=1e6, maxi=1e10) # Change the model parameter specifications based on some keyword arguments if fixed_metallicity is not None: # make it a fixed parameter model_params["logzsol"]["isfree"] = False #And use value supplied by fixed_metallicity keyword model_params["logzsol"]['init'] = fixed_metallicity if object_redshift != 0.0: # 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 if add_duste: # Add dust emission (with fixed dust SED parameters) model_params.update(TemplateLibrary["dust_emission"]) if add_neb: # Add nebular emission (with fixed parameters) model_params.update(TemplateLibrary["nebular"]) # Now instantiate the model using this new dictionary of parameter specifications model = sedmodel.SedModel(model_params) return model
# # The other parameters are all fixed, but we want to explicitly set their # values, possibly from something differnt than the FSPS defaults model_params = [] # --- Distance --- # This is the redshift. Because we are not separately supplying a ``lumdist`` # parameter, the distance will be determined from the redshift using a WMAP9 # cosmology, unless the redshift is 0, in which case the distance is assumed to # be 10pc (i.e. for absolute magnitudes) model_params.append({'name': 'zred', 'N': 1, 'isfree': False, 'init': 0.6, 'units': '', 'prior':priors.TopHat(mini=0.0, maxi=4.0)}) # --- SFH -------- # FSPS parameter. sfh=4 is a delayed-tau SFH model_params.append({'name': 'sfh', 'N': 1, 'isfree': False, 'init': 4, 'units': 'type' }) # Normalization of the SFH. If the ``mass_units`` parameter is not supplied, # this will be in surviving stellar mass. Otherwise it is in the total stellar # mass formed. model_params.append({'name': 'mass', 'N': 1, 'isfree': True, 'init': 5e11,