Beispiel #1
0
 def get_sfr(self):
     """
     Return Star Formation Rate (SFR) chain.
     If there are age bins in the fitted model, return the most recent SFR.
     
     
     Returns
     -------
     np.array
     """
     if self.has_agebins():
         _mass = self.get_mass()
         _agebins = self.model_dict[
             io._DEFAULT_NON_PARAMETRIC_SFH["agebins"]]["init"]
         if self._has_param_(io._DEFAULT_NON_PARAMETRIC_SFH["z_fraction"]):
             _z_fraction = self._get_param_chain_(
                 io._DEFAULT_NON_PARAMETRIC_SFH["z_fraction"])
             _sfr = [
                 transforms.zfrac_to_sfr(total_mass=_mass[ii],
                                         z_fraction=_z_fraction.T[ii],
                                         agebins=_agebins)[0]
                 for ii in np.arange(self.len_chains)
             ]
         elif self._has_param_(
                 io._DEFAULT_NON_PARAMETRIC_SFH["logsfr_ratios"]):
             _logsfr_ratios = self._get_param_chain_(
                 io._DEFAULT_NON_PARAMETRIC_SFH["logsfr_ratios"])
             _logmass = np.log10(_mass)
             _sfr = [
                 transforms.logsfr_ratios_to_sfrs(
                     logmass=_logmass,
                     logsfr_ratios=_logsfr_ratios.T[ii],
                     agebins=_agebins)[0]
                 for ii in np.arange(self.len_chains)
             ]
         else:
             _sfr = None
         return np.array(_sfr)
     elif not self.has_agebins() and self._has_param_([
             self.PHYS_PARAMS[_p]["prosp_name"]
             for _p in ["tage", "tau", "mass"]
     ]):
         _tage, _tau, _mass = [
             self._get_param_chain_(self.PHYS_PARAMS[_p]["prosp_name"])
             for _p in ["tage", "tau", "mass"]
         ]
         return tools.sfh_delay_tau_to_sfr(tage=_tage, tau=_tau, mass=_mass)
     else:
         _sfr = np.atleast_2d(
             self._get_param_chain_(self.PHYS_PARAMS["sfr"]["prosp_name"]))
         return _sfr[0]
# Get the zfractions from corner quantiles
zf1 = corner.quantile(samples[:, 2], q=[0.16, 0.5, 0.84])
zf2 = corner.quantile(samples[:, 3], q=[0.16, 0.5, 0.84])
zf3 = corner.quantile(samples[:, 4], q=[0.16, 0.5, 0.84])
zf4 = corner.quantile(samples[:, 5], q=[0.16, 0.5, 0.84])
zf5 = corner.quantile(samples[:, 6], q=[0.16, 0.5, 0.84])

zf_arr = np.array([zf1[1], zf2[1], zf3[1], zf4[1], zf5[1]])

cq_mass = corner.quantile(samples[:, 7], q=[0.16, 0.5, 0.84])

new_agebins = pt.zred_to_agebins(zred=obj_z, agebins=agebins)

# now convert to sfh and its errors
sfr = pt.zfrac_to_sfr(total_mass=cq_mass[1], z_fraction=zf_arr, agebins=new_agebins)

# ----------- plot
fig = plt.figure(figsize=(8,4))
ax = fig.add_subplot(111)

ax.set_xlabel(r'$\mathrm{Time\, [yr];\, since\ galaxy\ formation}$', fontsize=20)
#ax.xaxis.set_label_coords(x=1.2,y=-0.06)
ax.set_ylabel(r'$\mathrm{SFR\, [M_\odot/yr]}$', fontsize=20)

for a in range(nagebins):
    ax.plot(10**new_agebins[a], np.ones(len(new_agebins[a])) * sfr[a], color='mediumblue', lw=3.5)

#ax.set_xlim(0.0, 10.1335)

# --------- param stuff
def main(field, galaxy_seq):

    #vers = (np.__version__, scipy.__version__, h5py.__version__, fsps.__version__, prospect.__version__)
    #print("Numpy: {}\nScipy: {}\nH5PY: {}\nFSPS: {}\nProspect: {}".format(*vers))

    # -------------- Decide field and filters
    # Read in catalog from Lou
    if 'North' in field:
        df = pandas.read_pickle(adap_dir + 'GOODS_North_SNeIa_host_phot.pkl')

        all_filters = [
            'LBC_U_FLUX', 'ACS_F435W_FLUX', 'ACS_F606W_FLUX', 'ACS_F775W_FLUX',
            'ACS_F814W_FLUX', 'ACS_F850LP_FLUX', 'WFC3_F105W_FLUX',
            'WFC3_F125W_FLUX', 'WFC3_F140W_FLUX', 'WFC3_F160W_FLUX',
            'MOIRCS_K_FLUX', 'CFHT_Ks_FLUX', 'IRAC_CH1_SCANDELS_FLUX',
            'IRAC_CH2_SCANDELS_FLUX', 'IRAC_CH3_FLUX', 'IRAC_CH4_FLUX'
        ]

        #all_filters = ['LBC_U_FLUX', 'ACS_F435W_FLUX', 'ACS_F606W_FLUX',
        #'ACS_F775W_FLUX', 'ACS_F850LP_FLUX']

        seq = np.array(df['ID'])
        i = int(np.where(seq == galaxy_seq)[0])

    elif 'South' in field:
        df = pandas.read_pickle(adap_dir + 'GOODS_South_SNeIa_host_phot.pkl')

        all_filters = [
            'CTIO_U_FLUX', 'ACS_F435W_FLUX', 'ACS_F606W_FLUX',
            'ACS_F775W_FLUX', 'ACS_F814W_FLUX', 'ACS_F850LP_FLUX',
            'WFC3_F098M_FLUX', 'WFC3_F105W_FLUX', 'WFC3_F125W_FLUX',
            'WFC3_F160W_FLUX', 'HAWKI_KS_FLUX', 'IRAC_CH1_FLUX',
            'IRAC_CH2_FLUX', 'IRAC_CH3_FLUX', 'IRAC_CH4_FLUX'
        ]

        #all_filters = ['CTIO_U_FLUX', 'ACS_F435W_FLUX', 'ACS_F606W_FLUX',
        #'ACS_F775W_FLUX', 'ACS_F850LP_FLUX']

        seq = np.array(df['Seq'])
        i = int(np.where(seq == galaxy_seq)[0])

    #print('Read in pickle with the following columns:')
    #print(df.columns)
    #print('Rows in DataFrame:', len(df)

    print("Match index:", i, "for Seq:", galaxy_seq)

    # -------------- Preliminary stuff
    # Set up for emcee
    nwalkers = 1000
    niter = 500

    ndim = 12

    # Other set up
    obj_ra = df['RA'][i]
    obj_dec = df['DEC'][i]

    obj_z = df['zbest'][i]

    print("Object redshift:", obj_z)
    age_at_z = astropy_cosmo.age(obj_z).value
    print("Age of Universe at object redshift [Gyr]:", age_at_z)

    # ------------- Get obs data
    fluxes = []
    fluxes_unc = []
    useable_filters = []

    for ft in range(len(all_filters)):
        filter_name = all_filters[ft]

        flux = df[filter_name][i]
        fluxerr = df[filter_name + 'ERR'][i]

        if np.isnan(flux):
            continue

        if flux <= 0.0:
            continue

        if (fluxerr < 0) or np.isnan(fluxerr):
            fluxerr = 0.1 * flux

        fluxes.append(flux)
        fluxes_unc.append(fluxerr)
        useable_filters.append(filter_name)

    #print("\n")
    #print(df.loc[i])
    #print(fluxes, len(fluxes))
    #print(useable_filters, len(useable_filters))

    fluxes = np.array(fluxes)
    fluxes_unc = np.array(fluxes_unc)

    # Now build the prospector observation
    obs = build_obs(fluxes, fluxes_unc, useable_filters)

    # Set params for run
    run_params = {}
    run_params["object_redshift"] = obj_z
    run_params["fixed_metallicity"] = None
    run_params["add_duste"] = True
    #run_params["dust_type"] = 4

    run_params["zcontinuous"] = 1

    # Generate the model SED at the initial value of theta
    #theta = model.theta.copy()
    #initial_spec, initial_phot, initial_mfrac = model.sed(theta, obs=obs, sps=sps)

    verbose = True
    run_params["verbose"] = verbose

    model = build_model(**run_params)
    print("\nInitial free parameter vector theta:\n  {}\n".format(model.theta))
    #print("Initial parameter dictionary:\n{}".format(model.params))
    print("\n----------------------- Model details: -----------------------")
    print(model)
    print(
        "----------------------- End model details. -----------------------\n")

    # Here we will run all our building functions
    obs = build_obs(fluxes, fluxes_unc, useable_filters)
    sps = build_sps(**run_params)

    #plot_data(obs)
    #sys.exit(0)

    # --- start fitting ----
    # Set this to False if you don't want to do another optimization
    # before emcee sampling (but note that the "optimization" entry
    # in the output dictionary will be (None, 0.) in this case)
    # If set to true then another round of optmization will be performed
    # before sampling begins and the "optmization" entry of the output
    # will be populated.
    """
    run_params["optimize"] = False
    run_params["min_method"] = 'lm'
    # We'll start minimization from "nmin" separate places, 
    # the first based on the current values of each parameter and the 
    # rest drawn from the prior.  Starting from these extra draws 
    # can guard against local minima, or problems caused by 
    # starting at the edge of a prior (e.g. dust2=0.0)
    run_params["nmin"] = 5

    run_params["emcee"] = True
    run_params["dynesty"] = False
    # Number of emcee walkers
    run_params["nwalkers"] = nwalkers
    # Number of iterations of the MCMC sampling
    run_params["niter"] = niter
    # Number of iterations in each round of burn-in
    # After each round, the walkers are reinitialized based on the 
    # locations of the highest probablity half of the walkers.
    run_params["nburn"] = [8, 16, 32, 64]
    run_params["progress"] = True

    hfile = adap_dir + "emcee_" + field + "_" + str(galaxy_seq) + ".h5"

    if not os.path.isfile(hfile):

        print("Now running with Emcee.")
        output = fit_model(obs, model, sps, lnprobfn=lnprobfn, **run_params)

        print('done emcee in {0}s'.format(output["sampling"][1]))
    
        writer.write_hdf5(hfile, run_params, model, obs,
                          output["sampling"][0], output["optimization"][0],
                          tsample=output["sampling"][1],
                          toptimize=output["optimization"][1])
    
        print('Finished with Seq: ' + str(galaxy_seq))

    """

    hfile = adap_dir + "dynesty_" + field + "_" + str(galaxy_seq) + ".h5"

    if not os.path.isfile(hfile):

        print("Now running with Dynesty.")

        run_params["emcee"] = False
        run_params["dynesty"] = True
        run_params["nested_method"] = "rwalk"
        run_params["nlive_init"] = 400
        run_params["nlive_batch"] = 200
        run_params["nested_dlogz_init"] = 0.05
        run_params["nested_posterior_thresh"] = 0.05
        run_params["nested_maxcall"] = int(1e6)

        #from multiprocessing import Pool
        #with Pool(6) as pool:
        #    run_params["pool"] = pool
        output = fit_model(obs, model, sps, lnprobfn=lnprobfn, **run_params)
        print('done dynesty in {0}s'.format(output["sampling"][1]))

        writer.write_hdf5(hfile,
                          run_params,
                          model,
                          obs,
                          output["sampling"][0],
                          output["optimization"][0],
                          tsample=output["sampling"][1],
                          toptimize=output["optimization"][1])

        print('Finished with Seq: ' + str(galaxy_seq))

    # -------------------------
    # Visualizing results

    results_type = "dynesty"  # "emcee" | "dynesty"
    # grab results (dictionary), the obs dictionary, and our corresponding models
    # When using parameter files set `dangerous=True`
    #result, obs, _ = reader.results_from("{}_" + str(galaxy_seq) + \
    #                 ".h5".format(results_type), dangerous=False)

    result, obs, _ = reader.results_from(adap_dir + results_type + "_" + \
                     field + "_" + str(galaxy_seq) + ".h5", dangerous=False)

    #The following commented lines reconstruct the model and sps object,
    # if a parameter file continaing the `build_*` methods was saved along with the results
    #model = reader.get_model(result)
    #sps = reader.get_sps(result)

    # let's look at what's stored in the `result` dictionary
    print(result.keys())

    parnames = np.array(result['theta_labels'])
    print('Parameters in this model:', parnames)
    """
    if results_type == "emcee":

        chosen = np.random.choice(result["run_params"]["nwalkers"], size=150, replace=False)
        tracefig = reader.traceplot(result, figsize=(10,6), chains=chosen)

        tracefig.savefig(adap_dir + 'trace_' + field + '_' + str(galaxy_seq) + '.pdf', 
            dpi=200, bbox_inches='tight')

    else:
        tracefig = reader.traceplot(result, figsize=(10,6))
        tracefig.savefig(adap_dir + 'trace_' + field + '_' + str(galaxy_seq) + '.pdf', 
            dpi=200, bbox_inches='tight')
    """

    # Get chain for corner plot
    if results_type == 'emcee':
        trace = result['chain']
        thin = 5
        trace = trace[:, ::thin, :]
        samples = trace.reshape(trace.shape[0] * trace.shape[1],
                                trace.shape[2])
    else:
        samples = result['chain']

    # Plot SFH
    #print(model) # to copy paste agebins from print out

    nagebins = 6
    agebins = np.array([[0., 8.], [8., 8.47712125], [8.47712125, 9.],
                        [9., 9.47712125], [9.47712125, 9.77815125],
                        [9.77815125, 10.13353891]])

    # Get the zfractions from corner quantiles
    zf1 = corner.quantile(samples[:, 2], q=[0.16, 0.5, 0.84])
    zf2 = corner.quantile(samples[:, 3], q=[0.16, 0.5, 0.84])
    zf3 = corner.quantile(samples[:, 4], q=[0.16, 0.5, 0.84])
    zf4 = corner.quantile(samples[:, 5], q=[0.16, 0.5, 0.84])
    zf5 = corner.quantile(samples[:, 6], q=[0.16, 0.5, 0.84])

    zf_arr = np.array([zf1[1], zf2[1], zf3[1], zf4[1], zf5[1]])
    zf_arr_l = np.array([zf1[0], zf2[0], zf3[0], zf4[0], zf5[0]])
    zf_arr_u = np.array([zf1[2], zf2[2], zf3[2], zf4[2], zf5[2]])

    cq_mass = corner.quantile(samples[:, 7], q=[0.16, 0.5, 0.84])

    print("Total mass:", "{:.3e}".format(cq_mass[1]), "+",
          "{:.3e}".format(cq_mass[2] - cq_mass[1]), "-",
          "{:.3e}".format(cq_mass[1] - cq_mass[0]))
    # -----------

    new_agebins = pt.zred_to_agebins(zred=obj_z, agebins=agebins)
    print("New agebins:", new_agebins)

    # -----------------------
    # now convert to sfh and its errors
    sfr = pt.zfrac_to_sfr(total_mass=cq_mass[1],
                          z_fraction=zf_arr,
                          agebins=new_agebins)
    sfr_l = pt.zfrac_to_sfr(total_mass=cq_mass[1],
                            z_fraction=zf_arr_l,
                            agebins=new_agebins)
    sfr_u = pt.zfrac_to_sfr(total_mass=cq_mass[1],
                            z_fraction=zf_arr_u,
                            agebins=new_agebins)

    print("----------")
    print("z fractions:      ", zf_arr)
    print("Lower z fractions:", zf_arr_l)
    print("Upper z fractions:", zf_arr_u)

    print("----------")
    print("Inferred SFR:  ", sfr)
    print("Lower sfr vals:", sfr_l)
    print("Upper sfr vals:", sfr_u)

    #############
    x_agebins = 10**new_agebins / 1e9

    fig = plt.figure(figsize=(8, 4))
    ax = fig.add_subplot(111)

    ax.set_xlabel(r'$\mathrm{Time\, [Gyr];\, since\ galaxy\ formation}$',
                  fontsize=20)
    ax.set_ylabel(r'$\mathrm{SFR\, [M_\odot/yr]}$', fontsize=20)

    for a in range(len(agebins)):
        ax.plot(x_agebins[a],
                np.ones(len(x_agebins[a])) * sfr[a],
                color='mediumblue',
                lw=3.0)
        # put in some poisson errors
        sfr_err = np.ones(len(x_agebins[a])) * np.sqrt(sfr[a])
        sfr_plt = np.ones(len(x_agebins[a])) * sfr[a]
        sfr_low_fill = sfr_plt - sfr_err
        sfr_up_fill = sfr_plt + sfr_err
        ax.fill_between(x_agebins[a],
                        sfr_low_fill,
                        sfr_up_fill,
                        color='gray',
                        alpha=0.6)

    #ax.set_ylim(np.min(sfr_low_fill) * 0.3, np.max(sfr_up_fill) * 1.1)

    fig.savefig(adap_dir + 'sfh_' + field + '_' + str(galaxy_seq) + '.pdf',
                dpi=200,
                bbox_inches='tight')

    sys.exit(0)

    # Keep code block for future use if needed
    """
    # combination of linear and log axis from
    # https://stackoverflow.com/questions/21746491/combining-a-log-and-linear-scale-in-matplotlib

    # linear part i.e., first age bin
    ax.plot(x_agebins[0], np.ones(len(x_agebins[0])) * sfr[0], color='mediumblue', lw=3.5)
    #ax.fill_between(x_agebins[0], np.ones(len(x_agebins[0])) * sfr_l[0], 
    #               np.ones(len(x_agebins[0])) * sfr_u[0], color='gray', alpha=0.5)

    ax.set_xlim(0.0, 8.0)
    ax.spines['right'].set_visible(False)
    ax.yaxis.set_ticks_position('left')
    ax.xaxis.set_label_coords(x=1.2,y=-0.06)

    # now log axis 
    divider = make_axes_locatable(ax)
    axlog = divider.append_axes("right", size=3.0, pad=0, sharey=ax)
    axlog.set_xscale('log')

    for a in range(1, nagebins):
        axlog.plot(x_agebins[a], np.ones(len(x_agebins[a])) * sfr[a], color='mediumblue', lw=3.5)
        #axlog.fill_between(x_agebins[a], np.ones(len(x_agebins[a])) * sfr_l[a], 
        #                np.ones(len(x_agebins[a])) * sfr_u[a], color='gray', alpha=0.5)

    axlog.set_xlim(8.0, x_agebins[-1, -1] + 0.1)
    axlog.spines['left'].set_visible(False)
    axlog.yaxis.set_ticks_position('right')
    axlog.tick_params(labelright=False)

    axlog.xaxis.set_ticks(ticks=[8.0, 9.0])
    axlog.xaxis.set_ticks(ticks=[8.2, 8.4, 8.6, 8.8, 9.2, 9.4, 9.6], minor=True)

    axlog.set_xticklabels(['8', '9'])
    axlog.set_xticklabels(labels=[], minor=True)

    fig.savefig(adap_dir + 'sfh_' + field + '_' + str(galaxy_seq) + '.pdf',
        dpi=200, bbox_inches='tight')
    """

    # ---------- corner plot
    # set up corner ranges and labels
    math_parnames = [
        r'$\mathrm{log(Z_\odot)}$', r'$\mathrm{dust2}$', r'$zf_1$', r'$zf_2$',
        r'$zf_3$', r'$zf_4$', r'$zf_5$', r'$\mathrm{M_s}$',
        r'$\mathrm{f_{agn}}$', r'$\mathrm{agn_\tau}$',
        r'$\mathrm{dust_{ratio}}$', r'$\mathrm{dust_{index}}$'
    ]

    #math_parnames = [r'$\mathrm{M_s}$', r'$\mathrm{log(Z_\odot)}$',
    #r'$\mathrm{dust2}$', r'$\mathrm{t_{age}}$', r'$\mathrm{log(\tau)}$']

    # Fix labels for corner plot and
    # Figure out ranges for corner plot
    corner_range = []
    for d in range(ndim):

        # Get corner estimate and errors
        cq = corner.quantile(x=samples[:, d], q=[0.16, 0.5, 0.84])

        low_err = cq[1] - cq[0]
        up_err = cq[2] - cq[1]

        # Decide the padding for the plot range
        # depending on how large the error is relative
        # to the central estimate.
        if low_err * 2.5 >= cq[1]:
            sigma_padding_low = 1.2
        else:
            sigma_padding_low = 3.0

        if up_err * 2.5 >= cq[1]:
            sigma_padding_up = 1.2
        else:
            sigma_padding_up = 3.0

        low_lim = cq[1] - sigma_padding_low * low_err
        up_lim = cq[1] + sigma_padding_up * up_err

        corner_range.append((low_lim, up_lim))

        # Print estimate to screen
        if 'mass' in parnames[d]:
            pn = '{:.3e}'.format(cq[1])
            pnu = '{:.3e}'.format(up_err)
            pnl = '{:.3e}'.format(low_err)
        else:
            pn = '{:.3f}'.format(cq[1])
            pnu = '{:.3f}'.format(up_err)
            pnl = '{:.3f}'.format(low_err)

        print(parnames[d], ":  ", pn, "+", pnu, "-", pnl)

    # Corner plot
    cornerfig = corner.corner(samples,
                              quantiles=[0.16, 0.5, 0.84],
                              labels=math_parnames,
                              label_kwargs={"fontsize": 14},
                              range=corner_range,
                              smooth=0.5,
                              smooth1d=0.5)

    # loop over all axes *again* and set title
    # because it won't let me set the
    # format for soem titles separately
    # Looping has to be done twice because corner
    # plotting has to be done to get the figure.
    corner_axes = np.array(cornerfig.axes).reshape((ndim, ndim))

    for d in range(ndim):
        # Get corner estimate and errors
        cq = corner.quantile(x=samples[:, d], q=[0.16, 0.5, 0.84])

        low_err = cq[1] - cq[0]
        up_err = cq[2] - cq[1]

        ax_c = corner_axes[d, d]

        if 'mass' in parnames[d]:
            ax_c.set_title(math_parnames[d] + r"$ \, =\,$" + csn(cq[1], sigfigs=3) + \
            r"$\substack{+$" + csn(up_err, sigfigs=3) + r"$\\ -$" + \
            csn(low_err, sigfigs=3) + r"$}$", fontsize=11, pad=15)
        else:
            ax_c.set_title(math_parnames[d] + r"$ \, =\,$" + r"${:.3f}$".format(cq[1]) + \
            r"$\substack{+$" + r"${:.3f}$".format(up_err) + r"$\\ -$" + \
            r"${:.3f}$".format(low_err) + r"$}$", fontsize=11, pad=10)

    cornerfig.savefig(adap_dir + 'corner_' + field + '_' + \
        str(galaxy_seq) + '.pdf', dpi=200, bbox_inches='tight')

    sys.exit(0)

    # maximum a posteriori (of the locations visited by the MCMC sampler)
    pmax = np.argmax(result['lnprobability'])
    if results_type == "emcee":
        p, q = np.unravel_index(pmax, result['lnprobability'].shape)
        theta_max = result['chain'][p, q, :].copy()
    else:
        theta_max = result["chain"][pmax, :]

    #print('Optimization value: {}'.format(theta_best))
    #print('MAP value: {}'.format(theta_max))

    # make SED plot for MAP model and some random model
    # randomly chosen parameters from chain
    randint = np.random.randint
    if results_type == "emcee":
        theta = result['chain'][randint(nwalkers), randint(niter)]
    else:
        theta = result["chain"][randint(len(result["chain"]))]

    # generate models
    a = 1.0 + model.params.get('zred', 0.0)  # cosmological redshifting
    # photometric effective wavelengths
    wphot = obs["phot_wave"]
    # spectroscopic wavelengths
    if obs["wavelength"] is None:
        # *restframe* spectral wavelengths, since obs["wavelength"] is None
        wspec = sps.wavelengths
        wspec *= a  #redshift them
    else:
        wspec = obs["wavelength"]

    # sps = reader.get_sps(result)  # this works if using parameter files
    mspec, mphot, mextra = model.mean_model(theta, obs, sps=sps)
    mspec_map, mphot_map, _ = model.mean_model(theta_max, obs, sps=sps)

    # establish bounds
    xmin, xmax = np.min(wphot) * 0.8, np.max(wphot) / 0.8
    ymin, ymax = obs["maggies"].min() * 0.8, obs["maggies"].max() / 0.4

    # Make plot of data and model
    fig3 = plt.figure(figsize=(9, 4))
    ax3 = fig3.add_subplot(111)

    ax3.set_xlabel(r'$\mathrm{\lambda\ [\AA]}$', fontsize=15)
    #ax3.set_ylabel(r'$\mathrm{f_\lambda\ [erg\, s^{-1}\, cm^{-2}\, \AA^{-1}]}$', fontsize=15)
    ax3.set_ylabel(r'$\mathrm{Flux\ Density\ [maggies]}$', fontsize=15)

    ax3.loglog(wspec,
               mspec,
               label='Model spectrum (random draw)',
               lw=0.7,
               color='navy',
               alpha=0.7)
    ax3.loglog(wspec,
               mspec_map,
               label='Model spectrum (MAP)',
               lw=0.7,
               color='green',
               alpha=0.7)
    ax3.errorbar(wphot,
                 mphot,
                 label='Model photometry (random draw)',
                 marker='s',
                 markersize=10,
                 alpha=0.8,
                 ls='',
                 lw=3,
                 markerfacecolor='none',
                 markeredgecolor='blue',
                 markeredgewidth=3)
    ax3.errorbar(wphot,
                 mphot_map,
                 label='Model photometry (MAP)',
                 marker='s',
                 markersize=10,
                 alpha=0.8,
                 ls='',
                 lw=3,
                 markerfacecolor='none',
                 markeredgecolor='green',
                 markeredgewidth=3)
    ax3.errorbar(wphot,
                 obs['maggies'],
                 yerr=obs['maggies_unc'],
                 label='Observed photometry',
                 ecolor='red',
                 marker='o',
                 markersize=10,
                 ls='',
                 lw=3,
                 alpha=0.8,
                 markerfacecolor='none',
                 markeredgecolor='red',
                 markeredgewidth=3)

    # plot transmission curves
    for f in obs['filters']:
        w, t = f.wavelength.copy(), f.transmission.copy()
        t = t / t.max()
        t = 10**(0.2 * (np.log10(ymax / ymin))) * t * ymin
        ax3.loglog(w, t, lw=3, color='gray', alpha=0.7)

    ax3.set_xlim([xmin, xmax])
    ax3.set_ylim([ymin, ymax])
    ax3.legend(loc='best', fontsize=11)

    fig3.savefig(adap_dir + 'sedplot_' + field + '_' + str(galaxy_seq) +
                 '.pdf',
                 dpi=200,
                 bbox_inches='tight')

    plt.clf()
    plt.cla()
    plt.close()

    return None
Beispiel #4
0
Z_16 = thetas_16[thetas.index('massmet_2')]
Z_84 = thetas_84[thetas.index('massmet_2')]

print('sfr')
total_mass = 10**mass
time_bins_log = next(item for item in res['model_params']
                     if item["name"] == "agebins")['init']
print('time: ', len(time_bins_log))
print(time_bins_log)
zfrac_idx = [i for i, s in enumerate(thetas) if 'z_fraction' in s]
#print(zfrac_idx)
zfrac_chain = [item[zfrac_idx[0]:zfrac_idx[-1] + 1] for item in res['chain']]
#print(np.shape(zfrac_chain))
sfr_chain = []
for i in range(len(zfrac_chain)):
    sfr_chain.append(zfrac_to_sfr(total_mass, zfrac_chain[i], time_bins_log))
print(np.shape(sfr_chain))
sfr_quan = []
for i in range(np.shape(zfrac_chain)[1] + 1):
    sfr_quan.append(quantile([item[i] for item in sfr_chain], [.16, .5, .84]))

sfr_50.append([item[1] for item in sfr_quan])
sfr_16.append([item[0] for item in sfr_quan])
sfr_84.append([item[2] for item in sfr_quan])
time = []
#for val in time_bins_log:
#    time.append((10**val / 1.0e9)) #Gyr

print('sfr:', len(sfr_50[0]))
print(sfr_50[0][::-1])
zfrac_idx = [i for i, s in enumerate(thetas) if 'z_fraction' in s]
zfracs = best[zfrac_idx]
Z = best[Z_idx]
mass_idx = [i for i, s in enumerate(thetas) if 'massmet_1' in s]
mass = best[mass_idx]

print('Z', Z)
print('zfracs', zfracs)
print('mass', mass)

spec, phot, mass_frac = mod.mean_model(best, obs, sps)

#st_mass = (10**mass) * mass_frac

agelims = np.array([(10**x) / 1e9 for x in np.unique(np.ravel(agebins))])
sfrs = transforms.zfrac_to_sfr(mass, zfracs, agebins)

#sfrs.insert(0,sfrs[0])
sfrs = np.insert(sfrs, 0, sfrs[0])
#agelims1 = agelims[::-1]
#sfrs1 = sfrs[::-1]

sp_nodust = fsps.StellarPopulation(zcontinuous=1,
                                   add_dust_emission=False,
                                   logzsol=Z,
                                   sfh=3,
                                   dust_type=2,
                                   dust2=0)

sp_nodust.set_tabular_sfh(agelims, sfrs)