def show_corner(self, savefile=None, **kwargs): """ Plot a corner plot of the fitted parameters. Return the figure. Options ------- savefile : [string or None] Give a directory to save the figure. Default is None (not saved). showpars : [list(string) or None] List of the parameters to show. If None, plot every fitted parameters (listed in 'self.theta_labels'). Defaults is None. truths : [list(float) or None] List of truth values for the chosen parameters to add them on the plot. Default is None. start : [int] Integer giving the iteration number from which to start plotting. Default is 0. thin : [int] The thinning of each chain to perform when drawing samples to plot. Default is 1. chains : [np.array or slice] If results are from an ensemble sampler, setting 'chain' to an integer array of walker indices will cause only those walkers to be used in generating the plot. Useful for to keep the plot from getting too cluttered. Default is slice(None, None, None). logify : [list(string)] A list of parameter names to plot in log scale. Default is ["mass", "tau"]. **kwargs: Remaining keywords are passed to the 'corner' plotting package. Returns ------- matplotlib.Figure """ import prospect.io.read_results as reader _data = self._get_plot_data_() _fig = reader.subcorner(_data, **kwargs) if savefile is not None: _fig.savefig(savefile) return _fig
def corner_plot(result): imax = np.argmax(result['lnprobability']) i, j = np.unravel_index(imax, result['lnprobability'].shape) theta_max = result['chain'][i, j, :].copy() try: parnames = np.array(result['theta_labels'], dtype='U20') except KeyError: parnames = np.array(result['model'].theta_labels()) ind_show = slice(None) thin = 5 chains = slice(None) start = 0 # Get the arrays we need (trace, wghts) trace = result['chain'][..., ind_show] if trace.ndim == 2: trace = trace[None, :] trace = trace[chains, start::thin, :] wghts = result.get('weights', None) if wghts is not None: wghts = wghts[start::thin] samples = trace.reshape(trace.shape[0] * trace.shape[1], trace.shape[2]) logify = ["mass", "tau"] # logify some parameters xx = samples.copy() for p in logify: if p in parnames: idx = parnames.tolist().index(p) xx[:, idx] = np.log10(xx[:, idx]) parnames[idx] = "log({})".format(parnames[idx]) bounds = [] data = np.zeros(np.shape(xx)) for i, x in enumerate(xx): a, b, c, d, e = x data[i, :] = a, b, c, d, e for i in range(np.shape(xx)[1]): sig1 = theta_max[i] - np.percentile((data[:, i]), 16) sig2 = np.percentile((data[:, i]), 84) - theta_max[i] mean_dist = np.mean([sig1, sig2]) if i == 0 or i == 4: bounds.append((np.log10(theta_max[i]) - 4 * mean_dist, np.log10(theta_max[i]) + 4 * mean_dist)) else: bounds.append((theta_max[i] - 4 * mean_dist, theta_max[i] + 4 * mean_dist)) cornerfig = reader.subcorner(result, thin=5, fig=plt.subplots(5, 5, figsize=(27, 27))[0], logify=["mass", "tau"], range=bounds) return cornerfig
imax = np.argmax(result['lnprobability']) if results_type == 'emcee': i, j = np.unravel_index(imax, result['lnprobability'].shape) theta_max = result['chain'][i, j, :].copy() thin = 5 else: theta_max = result['chain'][imax, :] thin = 1 if verbose: print('MAP value: {}'.format(theta_max)) if plots: cornerfig = reader.subcorner(result, start=0, thin=thin, fig=plt.subplots(5, 5, figsize=(9, 9))[0]) # STEP 3: plot SED and residuals randint = np.random.randint if results_type == 'emcee': nwalkers, niter = result['run_params']['nwalkers'], result['run_params'][ 'niter'] theta = result['chain'][randint(nwalkers), randint(niter)] else: theta = result['chain'][randint(len(result['chain']))] # get helpful info for plotting a = 1.0 + model.params.get('zred', 0.0) wspec = sps.wavelengths obs['phot_wave'] = np.array([f.wave_effective for f in obs['filters']])
def viewer(file_name): import time, sys, os import h5py import numpy as np import scipy from matplotlib.pyplot import * import matplotlib.pyplot as plt import fsps import sedpy import prospect import emcee import astropy import math from func import * import prospect.io.read_results as reader results_type = "emcee" # | "dynesty" # grab results (dictionary), the obs dictionary, and our corresponding models # When using parameter files set `dangerous=True` tem_name = file_name[:-8] + '{}.h5' #result, obs, _ = reader.results_from(tem_name.format(results_type), dangerous=False) result, obs, _ = reader.results_from(file_name, 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()) if results_type == "emcee": chosen = np.random.choice(result["run_params"]["nwalkers"], size=10, replace=False) tracefig = reader.traceplot(result, figsize=(20, 10), chains=chosen) else: tracefig = reader.traceplot(result, figsize=(20, 10)) # maximum a posteriori (of the locations visited by the MCMC sampler) imax = np.argmax(result['lnprobability']) if results_type == "emcee": i, j = np.unravel_index(imax, result['lnprobability'].shape) theta_max = result['chain'][i, j, :].copy() thin = 5 else: theta_max = result["chain"][imax, :] thin = 1 print('MAP value: {}'.format(theta_max)) cornerfig = reader.subcorner(result, start=0, thin=thin, fig=subplots(15, 15, figsize=(27, 27))[0]) # --- Draw final fitting curve --- run_params = result['run_params'] print(run_params) model = build_model(**run_params) print(model) sps = build_sps(**run_params) 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"] # Get enssential data to calculate sfr z_fraction = theta_max[5:10] total_mass = theta_max[0] agebins = model.params['agebins'] x = np.zeros(6) for i in range(6): if i == 5: x[i] = (agebins[i][0] + agebins[i][1]) / 2 else: x[i] = (agebins[i][0] + agebins[i + 1][0]) / 2 sfr = prospect.models.transforms.zfrac_to_sfr(total_mass, z_fraction, agebins) # Calculate the 16% and 84% value from emcee results z_fraction1 = [] z_fraction2 = [] z_fraction3 = [] z_fraction4 = [] z_fraction5 = [] for i in range(30): for j in range(3000): z_fraction1.append(result['chain'][i][j][5]) z_fraction2.append(result['chain'][i][j][6]) z_fraction3.append(result['chain'][i][j][7]) z_fraction4.append(result['chain'][i][j][8]) z_fraction5.append(result['chain'][i][j][9]) zerr_1 = [np.percentile(z_fraction1, 16), np.percentile(z_fraction1, 84)] zerr_2 = [np.percentile(z_fraction2, 16), np.percentile(z_fraction2, 84)] zerr_3 = [np.percentile(z_fraction3, 16), np.percentile(z_fraction3, 84)] zerr_4 = [np.percentile(z_fraction4, 16), np.percentile(z_fraction4, 84)] zerr_5 = [np.percentile(z_fraction5, 16), np.percentile(z_fraction5, 84)] # Build upper and lower z_fraction array z_max = np.zeros(5) z_min = np.zeros(5) for i in range(5): z_min[i] = eval('zerr_{}[0]'.format(i + 1)) z_max[i] = eval('zerr_{}[1]'.format(i + 1)) #print(z_min) #print(z_max) # Build new sfr sfr_max = prospect.models.transforms.zfrac_to_sfr(total_mass, z_max, agebins) sfr_min = prospect.models.transforms.zfrac_to_sfr(total_mass, z_min, agebins) # randomly chosen parameters from chain randint = np.random.randint if results_type == "emcee": nwalkers, niter = run_params['nwalkers'], run_params['niter'] # Draw 100 random plots from mcmc figure(figsize=(16, 16)) ax = plt.subplot(211) for i in range(100): # Get data from any random chain theta = result['chain'][randint(nwalkers), randint(niter)] mspec_t, mphot_t, mextra = model.mean_model(theta, obs, sps=sps) # unit conversion to erg/cm^2/s mspec = (mspec_t * 1e-23) * 3e18 / wspec mphot = (mphot_t * 1e-23) * 3e18 / wphot # plot them out loglog(wspec, mspec, lw=0.7, color='grey', alpha=0.3) else: theta = result["chain"][randint(len(result["chain"]))] # now do it again for best fit model # sps = reader.get_sps(result) # this works if using parameter files mspec_map_t, mphot_map_t, _ = model.mean_model(theta_max, obs, sps=sps) # units conversion to erg/cm^2/s mspec_map = (mspec_map_t * 1e-23) * 3e18 / wspec mphot_map = (mphot_map_t * 1e-23) * 3e18 / wphot ob = (obs['maggies'] * 1e-23) * 3e18 / wphot ob_unc = (obs['maggies_unc'] * 1e-23) * 3e18 / wphot # calculate reduced chi^2 chi = np.float128(0) for i in range(len(wphot)): var = ob_unc[i] chi += np.float128((mphot_map[i] - ob[i])**2) / var**2 # Make plot of best fit model loglog(wspec, mspec_map, label='Model spectrum (MAP)', lw=0.7, color='green', alpha=0.7) errorbar(wphot, mphot_map, label='Model photometry (MAP)', marker='s', markersize=10, alpha=0.8, ls='', lw=3, markerfacecolor='none', markeredgecolor='green', markeredgewidth=3) errorbar(wphot, ob, yerr=ob_unc, label='Observed photometry', ecolor='red', marker='o', markersize=10, ls='', lw=3, alpha=0.8, markerfacecolor='none', markeredgecolor='red', markeredgewidth=3) text(0, 1, 'Chi-squared/N-phot =' + str(chi / len(wphot)), horizontalalignment='center', verticalalignment='center', transform=ax.transAxes) # Setup bound xmin, xmax = np.min(wphot) * 0.6, np.max(wphot) / 0.8 temp = np.interp(np.linspace(xmin, xmax, 10000), wphot, mphot_map) ymin, ymax = temp.min() * 0.8, temp.max() * 10 xlabel('Wavelength [A]', fontsize=20) ylabel('Flux Density [erg/cm^2/s]', fontsize=20) xlim([xmin, xmax]) ylim([ymin, ymax]) legend(loc='lower right', fontsize=15) tight_layout() # plt.show() # plot sfr on the same canvas from mpl_toolkits.axes_grid.inset_locator import inset_axes in_axes = inset_axes( ax, width="25%", # width = 30% of parent_bbox height=2, # height : 1 inch loc='upper center') in_axes.scatter(10**(x - 9), sfr) #plt.fill_between(10**(x-9), sfr_min, sfr_max) xlabel('Age [Gyr]', fontsize=10) ylabel('SFR [M_sun/yr]', fontsize=10) #plt.xscale('log') plt.yscale('log') # plot residue as subplot figure(figsize=(16, 8)) plt.subplot(212, sharex=ax) import pylab residue = abs(mphot_map - ob) scatter(wphot, abs(mphot_map - ob), label='Residue', lw=2, alpha=0.8) plt.xscale('log') plt.yscale('log') xmin, xmax = np.min(wphot) * 0.8, np.max(wphot) / 0.8 temp = np.interp(np.linspace(xmin, xmax, 10000), wphot, residue) ymin, ymax = temp.min() * 0.1, temp.max() / 0.8 xlabel('Wavelength [A]', fontsize=20) ylabel('Flux Change [erg/cm^2/s]', fontsize=20) xlim([xmin, xmax]) ylim([ymin, ymax]) legend(loc='best', fontsize=15) tight_layout() return
def main(): vers = (np.__version__, scipy.__version__, h5py.__version__, fsps.__version__, prospect.__version__) print( "Numpy: {}\nScipy: {}\nH5PY: {}\nFSPS: {}\nProspect: {}".format(*vers)) # And we will store some meta-parameters that control the input arguments to this method: run_params = {} run_params["snr"] = 10.0 run_params["ldist"] = 10.0 # Build the obs dictionary using the meta-parameters obs = build_obs(**run_params) # Look at the contents of the obs dictionary print("Obs Dictionary Keys:\n\n{}\n".format(obs.keys())) print("--------\nFilter objects:\n") print(obs["filters"]) # --- Plot the Data ---- """ # This is why we stored these... wphot = obs["phot_wave"] # 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 fig = plt.figure(figsize=(10,5)) ax = fig.add_subplot(111) # plot all the data ax.plot(wphot, obs['maggies'], label='All observed photometry', marker='o', markersize=12, alpha=0.8, ls='', lw=3, color='slateblue') # overplot only the data we intend to fit mask = obs["phot_mask"] ax.errorbar(wphot[mask], obs['maggies'][mask], yerr=obs['maggies_unc'][mask], label='Photometry to fit', marker='o', markersize=8, alpha=0.8, ls='', lw=3, ecolor='tomato', markerfacecolor='none', markeredgecolor='tomato', markeredgewidth=3) # plot Filters 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 ax.loglog(w, t, lw=3, color='gray', alpha=0.7) # prettify ax.set_xlabel('Wavelength [A]') ax.set_ylabel('Flux Density [maggies]') ax.set_xlim([xmin, xmax]) ax.set_ylim([ymin, ymax]) ax.set_xscale("log") ax.set_yscale("log") ax.legend(loc='best', fontsize=20) fig.tight_layout() plt.show() """ # ---------------------------- from prospect.models import priors mass_param = { "name": "mass", # The mass parameter here is a scalar, so it has N=1 "N": 1, # We will be fitting for the mass, so it is a free parameter "isfree": True, # This is the initial value. For fixed parameters this is the # value that will always be used. "init": 1e8, # This sets the prior probability for the parameter "prior": priors.LogUniform(mini=1e6, maxi=1e12), # this sets the initial dispersion to use when generating # clouds of emcee "walkers". It is not required, but can be very helpful. "init_disp": 1e6, # this sets the minimum dispersion to use when generating #clouds of emcee "walkers". It is not required, but can be useful if # burn-in rounds leave the walker distribution too narrow for some reason. "disp_floor": 1e6, # This is not required, but can be helpful "units": "solar masses formed", } from prospect.models.templates import TemplateLibrary # Look at all the prepackaged parameter sets TemplateLibrary.show_contents() # Check a specific model. # This shows the defaults and params for the model. # parametric_sfh in this case (delayed-tau) # This is the one we will use TemplateLibrary.describe("parametric_sfh") run_params["object_redshift"] = 0.0 run_params["fixed_metallicity"] = None run_params["add_duste"] = True model = build_model(**run_params) print(model) print("\nInitial free parameter vector theta:\n {}\n".format(model.theta)) print("Initial parameter dictionary:\n{}".format(model.params)) run_params["zcontinuous"] = 1 sps = build_sps(**run_params) # 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) #title_text = ','.join(["{}={}".format(p, model.params[p][0]) # for p in model.free_params]) 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"] # establish bounds xmin, xmax = np.min(wphot) * 0.8, np.max(wphot) / 0.8 temp = np.interp(np.linspace(xmin, xmax, 10000), wspec, initial_spec) ymin, ymax = temp.min() * 0.8, temp.max() / 0.4 """ fig = plt.figure(figsize=(10,5)) ax = fig.add_subplot(111) # plot model + data ax.loglog(wspec, initial_spec, label='Model spectrum', lw=0.7, color='navy', alpha=0.7) ax.errorbar(wphot, initial_phot, label='Model photometry', marker='s',markersize=10, alpha=0.8, ls='', lw=3, markerfacecolor='none', markeredgecolor='blue', markeredgewidth=3) ax.errorbar(wphot, obs['maggies'], yerr=obs['maggies_unc'], label='Observed photometry', marker='o', markersize=10, alpha=0.8, ls='', lw=3, ecolor='red', markerfacecolor='none', markeredgecolor='red', markeredgewidth=3) ax.set_title(title_text) # plot Filters 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 ax.loglog(w, t, lw=3, color='gray', alpha=0.7) # prettify ax.set_xlabel('Wavelength [A]') ax.set_ylabel('Flux Density [maggies]') ax.set_xlim([xmin, xmax]) ax.set_ylim([ymin, ymax]) ax.legend(loc='best', fontsize=20) fig.tight_layout() plt.show() """ verbose = True run_params["verbose"] = verbose # Here we will run all our building functions obs = build_obs(**run_params) sps = build_sps(**run_params) model = build_model(**run_params) # For fsps based sources it is useful to # know which stellar isochrone and spectral library # we are using print(sps.ssp.libraries) # --- start minimization ---- run_params["dynesty"] = False run_params["emcee"] = False run_params["optimize"] = True 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"] = 2 output = fit_model(obs, model, sps, lnprobfn=lnprobfn, **run_params) print("Done optmization in {}s".format(output["optimization"][1])) print(model.theta) (results, topt) = output["optimization"] # Find which of the minimizations gave the best result, # and use the parameter vector for that minimization ind_best = np.argmin([r.cost for r in results]) print(ind_best) theta_best = results[ind_best].x.copy() print(theta_best) # generate model prediction = model.mean_model(theta_best, obs=obs, sps=sps) pspec, pphot, pfrac = prediction """ fig = plt.figure(figsize=(10,5)) ax = fig.add_subplot(111) # plot Data, best fit model, and old models ax.loglog(wspec, initial_spec, label='Old model spectrum', lw=0.7, color='gray', alpha=0.5) ax.errorbar(wphot, initial_phot, label='Old model Photometry', marker='s', markersize=10, alpha=0.6, ls='', lw=3, markerfacecolor='none', markeredgecolor='gray', markeredgewidth=3) ax.loglog(wspec, pspec, label='Model spectrum', lw=0.7, color='slateblue', alpha=0.7) ax.errorbar(wphot, pphot, label='Model photometry', marker='s', markersize=10, alpha=0.8, ls='', lw=3, markerfacecolor='none', markeredgecolor='slateblue', markeredgewidth=3) ax.errorbar(wphot, obs['maggies'], yerr=obs['maggies_unc'], label='Observed photometry', marker='o', markersize=10, alpha=0.8, ls='', lw=3, ecolor='tomato', markerfacecolor='none', markeredgecolor='tomato', markeredgewidth=3) # plot filter 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 ax.loglog(w, t, lw=3, color='gray', alpha=0.7) # Prettify ax.set_xlabel('Wavelength [A]') ax.set_ylabel('Flux Density [maggies]') ax.set_xlim([xmin, xmax]) ax.set_ylim([ymin, ymax]) ax.legend(loc='best', fontsize=20) fig.tight_layout() plt.show() """ # 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["emcee"] = True run_params["dynesty"] = False # Number of emcee walkers run_params["nwalkers"] = 128 # Number of iterations of the MCMC sampling run_params["niter"] = 512 # 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"] = [16, 32, 64] 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])) hfile = "demo_emcee_mcmc.h5" writer.write_hdf5(hfile, run_params, model, obs, output["sampling"][0], output["optimization"][0], tsample=output["sampling"][1], toptimize=output["optimization"][1]) print('Finished') # ------------------- print("Now running with Dynesty.") run_params["dynesty"] = True run_params["optmization"] = False run_params["emcee"] = False 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(1e7) output = fit_model(obs, model, sps, lnprobfn=lnprobfn, **run_params) print('done dynesty in {0}s'.format(output["sampling"][1])) hfile = "demo_dynesty_mcmc.h5" writer.write_hdf5(hfile, run_params, model, obs, output["sampling"][0], output["optimization"][0], tsample=output["sampling"][1], toptimize=output["optimization"][1]) print('Finished') # ------------------------- # 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( "demo_{}_mcmc.h5".format(results_type), 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()) if results_type == "emcee": chosen = np.random.choice(result["run_params"]["nwalkers"], size=10, replace=False) tracefig = reader.traceplot(result, figsize=(20, 10), chains=chosen) else: tracefig = reader.traceplot(result, figsize=(20, 10)) # maximum a posteriori (of the locations visited by the MCMC sampler) imax = np.argmax(result['lnprobability']) if results_type == "emcee": i, j = np.unravel_index(imax, result['lnprobability'].shape) theta_max = result['chain'][i, j, :].copy() thin = 5 else: theta_max = result["chain"][imax, :] thin = 1 print('Optimization value: {}'.format(theta_best)) print('MAP value: {}'.format(theta_max)) cornerfig = reader.subcorner(result, start=0, thin=thin, truths=theta_best, fig=plt.subplots(5, 5, figsize=(8, 8))[0]) plt.show() return None
tracefig = traceplot(res, figsize=(20, 10), chains=chosen) savefig(outroot + '_parameter_traces.png') # Conerplot # Maximum Likelihood (of the locations visited by the MCMC sampler) imax = np.argmax(res['lnprobability']) i, j = np.unravel_index(imax, res['lnprobability'].shape) theta_max = res['chain'][i, j, :].copy() n_param = len(theta_max) size = int(n_param * n_param) + 2 print('Max Likelihood value: {}'.format(theta_max)) cornerfig = subcorner(res, start=0, thin=5, truths=theta_input, fig=subplots(n_param, n_param, figsize=(size, size))[0]) savefig(outroot + '_cornerplot.png') # randomly chosen parameters from chain randint = np.random.randint nwalkers, niter = run_params['nwalkers'], run_params['niter'] theta = res['chain'][randint(nwalkers), randint(niter)] res['run_params']['param_file'] = 'plot_emcee.py' # generate models model = load_model(**res['run_params']) sps = load_sps(**res['run_params']) # this works if using parameter files mspec_map, mphot_map, _ = model.mean_model(theta_max, obs, sps=sps) a = 1.0 + model.params.get('zred', 0.0)
def run_prospector(name_z): import time, sys, os import h5py import numpy as np import scipy from matplotlib.pyplot import * #%matplotlib inline import fsps import sedpy import prospect import emcee import astropy import math from prospect.fitting import fit_model from prospect.fitting import lnprobfn from func import * import matplotlib.pyplot as plt # --- Output files --- name = name_z[0] z = name_z[1] path_input = '/home/kk/work/data/red_magic/' + name path = '/home/kk/work/result/red_magic/' + name[:-4] '''try: os.mkdir(path) except: pass fe = open(path+'/para.txt','w')''' # --- Set up the essential parameter --- data_list = [ 'sdss_u', 'sdss_g', 'sdss_r', 'sdss_i', 'galex_fuv', 'galex_nuv', 'pan-starrs_ps1_i', 'pan-starrs_ps1_r', 'pan-starrs_ps1_g', 'pan-starrs_ps1_y', 'pan-starrs_ps1_z', 'sdss_z', 'ukidss_j', 'ukidss_h', 'ukidss_k', 'wise_w1', 'spitzer_irac_3.6', '_=3.6um', 'spitzer_irac_4.5', '_=4.5um', 'wise_w2', 'spitzer_irac_5.8', 'spitzer_irac_8.0', 'wise_w3', 'wise_w4', 'spitzer_mips_24', '2mass_h', '2mass_ks', '2mass_j', 'gaia_gaia2_gbp', 'gaia_gaia2_g', 'gaia_gaia2_grp', 'gaia_g', 'ukidss_y', 'vista_j', 'vista_h', 'vista_ks' ] run_params = {} run_params["snr"] = 10.0 run_params["object_redshift"] = z run_params["fixed_metallicity"] = None run_params["add_duste"] = True # --- Start build up the model --- fit_data = load_data(path_input, data_list) obs = build_obs(fit_data, **run_params) sps = build_sps(**run_params) model = build_model(**run_params) #fe.write(str(obs)) #print(fit_data) # --- Draw initial data plot --- wphot = obs["phot_wave"] # 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 figure(figsize=(16, 8)) # plot all the data plot(wphot, obs['maggies'], label='All observed photometry', marker='o', markersize=12, alpha=0.8, ls='', lw=3, color='slateblue') # overplot only the data we intend to fit mask = obs["phot_mask"] errorbar(wphot[mask], obs['maggies'][mask], yerr=obs['maggies_unc'][mask], label='Photometry to fit', marker='o', markersize=8, alpha=0.8, ls='', lw=3, ecolor='tomato', markerfacecolor='none', markeredgecolor='tomato', markeredgewidth=3) # prettify xlabel('Wavelength [A]') ylabel('Flux Density [maggies]') xlim([xmin, xmax]) ylim([ymin, ymax]) xscale("log") yscale("log") legend(loc='best', fontsize=20) #tight_layout() #plt.savefig(path+'/input.png') # run minimization and emcee with error handling condition = False while condition is False: try: # --- start minimization ---- run_params["dynesty"] = False run_params["emcee"] = False run_params["optimize"] = True run_params["min_method"] = 'lm' run_params["nmin"] = 5 output = fit_model(obs, model, sps, lnprobfn=lnprobfn, **run_params) print("Done optmization in {}s".format(output["optimization"][1])) # save theta_best for later use (results, topt) = output["optimization"] ind_best = np.argmin([r.cost for r in results]) theta_best = results[ind_best].x.copy() # --- start emcee --- run_params["optimize"] = False run_params["emcee"] = True run_params["dynesty"] = False run_params["nwalkers"] = 30 run_params["niter"] = 8000 run_params["nburn"] = [300, 800, 1600] output = fit_model(obs, model, sps, lnprobfn=lnprobfn, **run_params) print('done emcee in {0}s'.format(output["sampling"][1])) condition = True # sort out different errors and apply method to proceed except AssertionError as e: # error: sfr cannot be negative if str(e) == 'sfr cannot be negative.': obs = build_obs(fit_data, **run_params) sps = build_sps(**run_params) model = build_model(**run_params) # error: number of residules are less than variables except ValueError as e: if str( e ) == "Method 'lm' doesn't work when the number of residuals is less than the number of variables.": print(name) return # error: residule are not finite in the initial point elif str(e) == "Residuals are not finite in the initial point.": print(name) return # write final results to file from prospect.io import write_results as writer hfile = path + '_emcee.h5' print(hfile) writer.write_hdf5(hfile, run_params, model, obs, output["sampling"][0], output["optimization"][0], tsample=output["sampling"][1], toptimize=output["optimization"][1]) #fe.write(str(obs)) print('Finished') ############################################################################## import prospect.io.read_results as reader results_type = "emcee" # | "dynesty" # grab results (dictionary), the obs dictionary, and our corresponding models # When using parameter files set `dangerous=True` #tem_name = hfile[:-8]+'{}.h5' #result, obs, _ = reader.results_from(tem_name.format(results_type), dangerous=False) result, obs, _ = reader.results_from(hfile, 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()) # Make plot of data and model if results_type == "emcee": chosen = np.random.choice(result["run_params"]["nwalkers"], size=10, replace=False) tracefig = reader.traceplot(result, figsize=(20, 10), chains=chosen) else: tracefig = reader.traceplot(result, figsize=(20, 10)) #plt.savefig(path+'/trace.png') # maximum a posteriori (of the locations visited by the MCMC sampler) imax = np.argmax(result['lnprobability']) if results_type == "emcee": i, j = np.unravel_index(imax, result['lnprobability'].shape) theta_max = result['chain'][i, j, :].copy() thin = 5 else: theta_max = result["chain"][imax, :] thin = 1 #f.Write('Optimization value: {}'.format(theta_best)) #fe.write(str('MAP value: {}'.format(theta_max))) #fe.close() cornerfig = reader.subcorner(result, start=0, thin=thin, truths=theta_best, fig=subplots(15, 15, figsize=(27, 27))[0]) #plt.savefig(path+'/corner.png') # --- Draw final fitting curve --- 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"] # Get enssential data to calculate sfr z_fraction = theta_max[5:10] total_mass = theta_max[0] agebins = model.params['agebins'] x = np.zeros(6) for i in range(6): if i == 5: x[i] = (agebins[i][0] + agebins[i][1]) / 2 else: x[i] = (agebins[i][0] + agebins[i + 1][0]) / 2 sfr = prospect.models.transforms.zfrac_to_sfr(total_mass, z_fraction, agebins) # Calculate the 16% and 84% value from emcee results z_fraction1 = [] z_fraction2 = [] z_fraction3 = [] z_fraction4 = [] z_fraction5 = [] for i in range(30): for j in range(3000): z_fraction1.append(result['chain'][i][j][5]) z_fraction2.append(result['chain'][i][j][6]) z_fraction3.append(result['chain'][i][j][7]) z_fraction4.append(result['chain'][i][j][8]) z_fraction5.append(result['chain'][i][j][9]) zerr_1 = [np.percentile(z_fraction1, 16), np.percentile(z_fraction1, 84)] zerr_2 = [np.percentile(z_fraction2, 16), np.percentile(z_fraction2, 84)] zerr_3 = [np.percentile(z_fraction3, 16), np.percentile(z_fraction3, 84)] zerr_4 = [np.percentile(z_fraction4, 16), np.percentile(z_fraction4, 84)] zerr_5 = [np.percentile(z_fraction5, 16), np.percentile(z_fraction5, 84)] # Build upper and lower z_fraction array z_max = np.zeros(5) z_min = np.zeros(5) for i in range(5): z_min[i] = eval('zerr_{}[0]'.format(i + 1)) z_max[i] = eval('zerr_{}[1]'.format(i + 1)) #print(z_min) #print(z_max) # Build new sfr sfr_max = prospect.models.transforms.zfrac_to_sfr(total_mass, z_max, agebins) sfr_min = prospect.models.transforms.zfrac_to_sfr(total_mass, z_min, agebins) # randomly chosen parameters from chain randint = np.random.randint if results_type == "emcee": nwalkers, niter = run_params['nwalkers'], run_params['niter'] # Draw 100 random plots from mcmc figure(figsize=(16, 16)) ax = plt.subplot(211) for i in range(100): # Get data from any random chain theta = result['chain'][randint(nwalkers), randint(niter)] mspec_t, mphot_t, mextra = model.mean_model(theta, obs, sps=sps) # unit conversion to erg/cm^2/s mspec = (mspec_t * 1e-23) * 3e18 / wspec mphot = (mphot_t * 1e-23) * 3e18 / wphot # plot them out loglog(wspec, mspec, lw=0.7, color='grey', alpha=0.3) else: theta = result["chain"][randint(len(result["chain"]))] # now do it again for best fit model # sps = reader.get_sps(result) # this works if using parameter files mspec_map_t, mphot_map_t, _ = model.mean_model(theta_max, obs, sps=sps) # units conversion to erg/cm^2/s mspec_map = (mspec_map_t * 1e-23) * 3e18 / wspec mphot_map = (mphot_map_t * 1e-23) * 3e18 / wphot ob = (obs['maggies'] * 1e-23) * 3e18 / wphot ob_unc = (obs['maggies_unc'] * 1e-23) * 3e18 / wphot # calculate reduced chi^2 chi = 0 for i in range(len(wphot)): var = ob_unc[i] chi += (mphot_map[i] - ob[i])**2 / var**2 # Make plot of best fit model loglog(wspec, mspec_map, label='Model spectrum (MAP)', lw=0.7, color='green', alpha=0.7) errorbar(wphot, mphot_map, label='Model photometry (MAP)', marker='s', markersize=10, alpha=0.8, ls='', lw=3, markerfacecolor='none', markeredgecolor='green', markeredgewidth=3) errorbar(wphot, ob, yerr=ob_unc, label='Observed photometry', ecolor='red', marker='o', markersize=10, ls='', lw=3, alpha=0.8, markerfacecolor='none', markeredgecolor='red', markeredgewidth=3) text(0, 1, 'Chi-squared/Nphot =' + str(chi / len(wphot)), horizontalalignment='center', verticalalignment='center', transform=ax.transAxes) # Setup bound xmin, xmax = np.min(wphot) * 0.6, np.max(wphot) / 0.8 temp = np.interp(np.linspace(xmin, xmax, 10000), wphot, mphot_map) ymin, ymax = temp.min() * 0.8, temp.max() * 10 xlabel('Wavelength [A]', fontsize=20) ylabel('Flux Density [erg/cm^2/s]', fontsize=20) xlim([xmin, xmax]) ylim([ymin, ymax]) legend(loc='lower right', fontsize=15) tight_layout() # plt.show() # plot sfr on the same canvas from mpl_toolkits.axes_grid.inset_locator import inset_axes in_axes = inset_axes( ax, width="25%", # width = 30% of parent_bbox height=2, # height : 1 inch loc='upper center') in_axes.scatter(10**(x - 9), sfr) #plt.fill_between(10**(x-9), sfr_min, sfr_max) xlabel('Age [Gyr]', fontsize=10) ylabel('SFR [M_sun/yr]', fontsize=10) #plt.xscale('log') plt.yscale('log') plt.savefig(path + '_fitting.png') # plot residue as subplot figure(figsize=(16, 8)) plt.subplot(212, sharex=ax) import pylab residue = abs(mphot_map - ob) scatter(wphot, abs(mphot_map - ob), label='Residue', lw=2, alpha=0.8) plt.xscale('log') plt.yscale('log') xmin, xmax = np.min(wphot) * 0.8, np.max(wphot) / 0.8 temp = np.interp(np.linspace(xmin, xmax, 10000), wphot, residue) ymin, ymax = temp.min() * 0.1, temp.max() / 0.8 xlabel('Wavelength [A]', fontsize=20) ylabel('Flux Change [erg/cm^2/s]', fontsize=20) xlim([xmin, xmax]) ylim([ymin, ymax]) legend(loc='best', fontsize=15) tight_layout()