def gather_models(cmddir, bf, age_range, logz, vvc_range, av, dmod): # form the array of models spanning age and v/vc grid space: # structure is an NxM dimensional matrix of Hess diagrams, indexed # by i for the ith vector along the rotation rate axis, and by j along # the jth age axis. Each Hess diagram is normalized to sum to one. vvc_pts = [] for i, a_vvc in enumerate(vvc_range): # step through in age, adding an age vector at each point in v/vc space age_vector = [] for j, an_age in enumerate(age_range): a_cmd = cmd.CMD(get_cmdf(cmddir, bf, an_age, logz, a_vvc, av, dmod)) model_hess = a_cmd.cmd['Nsim'] model_hess /= np.sum(model_hess) age_vector.append(model_hess) vvc_pts.append(np.array(age_vector)) gates = a_cmd.cmd['gate'] ugates = np.unique(gates) if len(ugates) > 1: dinds = np.digitize(gates, bins=ugates, right=True) else: dinds = None model = np.array(vvc_pts) return model, dinds
def genmod_bivvcspread(cmddir, age, mass, vvcmu1, vvcsig1, vvcmu2, vvcsig2, vvclim): vvcs = np.arange(0.0, vvclim, 0.1) vvcweights = gen_bigaussweights(vvcs, vvcmu1, vvcsig1, vvcmu2, vvcsig2) photbase = cmddir.split('/')[1] bf, av, agebin, logz, dmod = fio.parse_fname(photbase, mode="str") hess_arr = [] for vvc in vvcs: a_cmd = cmd.CMD(fio.get_cmdf(cmddir, bf, age, logz, vvc, av, dmod)) mock_hess = a_cmd.cmd['Nsim'] mock_hess /= np.sum(mock_hess) #if age == ages[0]: # composite_hess = mock_hess #else: # composite_hess += mock_hess hess_arr.append(mock_hess) hess_arr = np.array(hess_arr) #print(len(hess_arr)) #print(len(vvcweights)) composite_hess = np.sum(vvcweights*hess_arr.T, axis=1) #print(len(composite_hess)) truths = {} for i, vvc in enumerate(vvcs): truths[vvc] = mass*vvcweights[i] return mass*composite_hess, truths
def genmod_agespread(cmddir, mass, agemu, agesig): ages = np.arange(8.50, 9.50, 0.02) ageweights = gen_gaussweights(ages, agemu, agesig) photbase = cmddir.split('/')[1] bf, av, agebin, logz, dmod = fio.parse_fname(photbase, mode="str") hess_arr = [] for age in ages: a_cmd = cmd.CMD(fio.get_cmdf(cmddir, bf, age, logz, 0.0, av, dmod)) mock_hess = a_cmd.cmd['Nsim'] mock_hess /= np.sum(mock_hess) #if age == ages[0]: # composite_hess = mock_hess #else: # composite_hess += mock_hess hess_arr.append(mock_hess) hess_arr = np.array(hess_arr) #print(len(hess_arr)) #print(len(ageweights)) composite_hess = np.sum(ageweights*hess_arr.T, axis=1) #print(len(composite_hess)) truth = np.sum(composite_hess) return mass*composite_hess
def genmod_agebivvcspread(cmddir, mass, agemu, agesig, vvcmu1, vvcsig1, vvcmu2, vvcsig2, vvclim): ages = np.arange(8.50, 9.50, 0.02) #mu, sig = 9.00, 0.3 ageweights = gen_gaussweights(ages, agemu, agesig) vvcs = np.arange(0.0, vvclim, 0.1) #mu, sig = 0.3, 0.2 vvcweights = gen_bigaussweights(vvcs, vvcmu1, vvcsig1, vvcmu2, vvcsig2) photbase = cmddir.split('/')[1] bf, av, agebin, logz, dmod = fio.parse_fname(photbase, mode="str") composite_hess = cmd.CMD(fio.get_cmdf(cmddir, bf, 9.00, logz, 0.0, av, dmod)) composite_hess = np.zeros(len(composite_hess.cmd['Nsim'])) vvc_pts = [] for i, a_vvc in enumerate(vvcs): # step through in age, adding an age vector at each point in v/vc space age_vector = [] for j, an_age in enumerate(ages): a_cmd = cmd.CMD(fio.get_cmdf(cmddir, bf, an_age, logz, a_vvc, av, dmod)) model_hess = a_cmd.cmd['Nsim'] model_hess /= np.sum(model_hess) age_vector.append(model_hess) vvc_pts.append(np.array(age_vector)) model = np.array(vvc_pts) composite_hess += np.sum((vvcweights[:, np.newaxis])*np.sum(ageweights[:,np.newaxis]*model, axis=1), axis=0) #print(len(hess_arr)) #print(len(vvcweights)) #composite_hess = np.sum(vvcweights*hess_arr.T, axis=1) #print(len(composite_hess)) truths = {} for i, vvc in enumerate(vvcs): truths[vvc] = mass*vvcweights[i] return mass*composite_hess, truths
def pgplot(obs, model, cmddir, bf, age, logz, av, dmod, vvclim, weights, filters, age_range, svname=None, log=False, svdir=None): """ Creates a MATCH pg style plot of data, model, data-model, and -2lnP map. """ composite_cmd = cmd.CMD(fio.get_cmdf(cmddir, bf, age, logz, 0.0, av, dmod))#, ymag='I') composite_cmd.cmd['Nsim'] = np.zeros(len(composite_cmd.cmd['Nsim'])) vvc_range = np.arange(0.0, vvclim, 0.1) Nrot = len(vvc_range) #age_range = np.arange(8.5, 9.5, 0.02) mu = weights[Nrot] try: sigma = weights[Nrot+1] except IndexError: sigma = 0.0 ageweights = gen_gaussweights(age_range, mu, sigma) #for i, avvc in enumerate(vvc_range): # for j, anage in enumerate(age_range): # a_cmd = cmd.CMD(fio.get_cmdf(cmddir, bf, anage, logz, avvc, av, dmod))#, ymag='I') # 1 * (jth age weight, added i times) * ith rotation rate. # a_cmd.cmd['Nsim'] = (a_cmd.cmd['Nsim'] / np.sum(a_cmd.cmd['Nsim'])) * (best_gweights[j]) * (10**weights[i]) # add each cmd (re-weighted by solutions) to the composite CMD model. # composite_cmd.cmd['Nsim'] += a_cmd.cmd['Nsim'] vvcweights = weights[:Nrot] composite_cmd.cmd['Nsim'] += np.sum((10**vvcweights[:, np.newaxis])*np.sum(ageweights[:,np.newaxis]*model, axis=1), axis=0) composite_cmd.cmd['Nobs'] = obs # arbitrary vvc used -- just need a file name to break up. #fn_base = (fio.get_cmdf(cmddir, bf, age, logz, 0.0, av, dmod).split('/')[-1]).split('.out.cmd')[0] #fehval = float((fn_base.split('logz')[-1]).split('_')[0]) #lageval = float((fn_base.split('_t')[-1]).split('_')[0]) #avval = float((fn_base.split('_av')[-1]).split('_')[0]) #dmodval = float((fn_base.split('_dmod')[-1]).split('_')[0]) print(max(composite_cmd.cmd['Nsim'])) filters, photstrs = match_to_mist(filters) photstr = photstrs[0] print(filters) redmag_name = filters[1] bluemag_name = filters[0] color_name = "{:s}-{:s}".format(bluemag_name, redmag_name) # iso00 = rmm.ISOCMD(round(float(logz), 2), min(vvc_range), ebv= round(float(av), 2)/3.1, photstr=photstr, exttag='TP') # iso00.set_isodata(round(float(mu), 2), color_name, bluemag_name, dmod=round(float(dmod), 2)) # this try except is fudgy -- onl needed cause v/vc = 0.6 models aren't available on my local machine. # try: # iso06 = rmm.ISOCMD(round(float(logz), 2), max(vvc_range), ebv= round(float(av), 2)/3.1, photstr=photstr, exttag='TP') # except Exception as e: # iso06 = rmm.ISOCMD(round(float(logz), 2), 0.6, ebv= round(float(av), 2)/3.1, photstr=photstr, exttag='TP') #iso06.set_isodata(round(float(mu), 2), color_name, bluemag_name, dmod=round(float(dmod), 2)) # (x, y), i.e., (color, red mag) points of each isochrone in a list: #mist_pts = [ # isoget_colmags(iso00, [color_name, bluemag_name], lage=round(float(mu), 2), dmod=round(float(dmod), 2)), # isoget_colmags(iso06, [color_name, bluemag_name], lage=round(float(mu), 2), dmod=round(float(dmod), 2)) # ] # recalculate the d-m and signifigance hesses using the new hesses. composite_cmd.recalc() # create a MATCH pg style plot using the .cmd file: pgcmd_kwargs = {} #pgcmd_kwargs['mist_pts'] = mist_pts if svname == None: if svdir == None: pgcmd_kwargs['figname'] = os.path.join(cmddir, 'match_pgplot.png') else: pgcmd_kwargs['figname'] = os.path.join(cmddir, svdir, 'match_pgplot.png') else: if svdir == None: pgcmd_kwargs['figname'] = os.path.join(cmddir, svname) else: pgcmd_kwargs['figname'] = os.path.join(cmddir, svdir, svname) # four panel plot: if log: pgcmd_kwargs['logcounts'] = True composite_cmd.pgcmd(**pgcmd_kwargs) else: composite_cmd.pgcmd(**pgcmd_kwargs) return
vvclim = round(Nrot / 10.0, 1) vvc_range = np.arange(0.0, vvclim, 0.1) age_range = np.arange(7.9, 9.5, 0.02) # lower lim was 8.5 # default, dummy truths; will be reassigned: truths = {rot: 1e-11 for rot in vvc_range} mass = 5E4 # mock cluster "mass" or total counts; 1e6 was default # Generates mock data from the model library to use instead of observed data if told to: if "mock" in mode: # case of no rotation distribution: if mockd_vvcsig1 == 0.0: # and no age distribution (would be an SSP): if mockd_agesig == 0.0: obscmd = cmd.CMD( fio.get_cmdf(cmddir, bf, mockd_agemu, logz, mockd_vvcmu1, av, dmod)) obs = obscmd.cmd['Nobs'] # age distribution, no rotation distribution, P(sigtau); in practice will trigger so long as mode is mock-sigtau and agesig !=0.0: else: print("GENERATING MOCK DATA WITH AGE SPREAD...") obs = pr.genmod_agespread(cmddir, mass=mass, agemu=mockd_agemu, agesig=mockd_agesig) obsweight = np.sum(obs) # using lower limit of weight search prior for truths of "zero" components. truths = { rot: max([0.0, np.log10(obsweight * 1e-4)]) for rot in vvc_range
#ax6 = plt.subplot(gs[1, 0]) #ax7 = plt.subplot(gs[1, -1]) #ax8 = plt.subplot(gs[2, 0]) #ax9 = plt.subplot(gs[2, -1]) #ax10 = plt.subplot(gs[-1, 0]) #ax11 = plt.subplot(gs[-1, 1]) #ax12 = plt.subplot(gs[-1, 2]) #ax13 = plt.subplot(gs[-1, 3]) #ax14 = plt.subplot(gs[-1, 4]) #axa = [ax1,ax2,ax3,ax4,ax5,ax6,ax7,ax8,ax9,ax10,ax11,ax12,ax13,ax14] bf, age, logz, av, dmod = "0.00", 9.00, '-0.30', '0.0', '0.00' cmddir = 'output/bf0.00_av0.0_SFR0.01_t9.00_9.02_logZ-0.30_vvc0.4_Tycho_BTycho_V_ex/' # empty out a hess to use as a composite model later: composite_cmd = cmd.CMD(fio.get_cmdf(cmddir, bf, age, logz, 0.0, av, dmod)) #, ymag='I') composite_cmd.cmd['Nsim'] = np.zeros(len(composite_cmd.cmd['Nsim'])) obsweight = np.sum(composite_cmd.cmd['Nobs']) # need random weights and mu, sigma filters = ['Tycho_B', 'Tycho_V'] vvc_range = np.arange(0.0, 1.0, 0.2) Nrot = len(vvc_range) age_range = np.arange(8.5, 9.5, 0.2) mu = np.random.uniform(8.5, 9.3) sigma = 10**np.random.uniform(-2, 0) # try: # sigma = weights[Nrot+1] # except IndexError: # sigma = 0.0
def main(cluster_name, photbase, jobid, filters, dmod, ebv, local, star_num, truth, incvvc, savebest=True, bestax=None, justbest=False): global match_dir global scrn_dir global outpath global plotpath match_dir = get_workdir(data=cluster_name) # path to MATCH .scrn files: scrn_dir = os.path.join(get_scrndir(data=cluster_name), photbase, 'SLURM{:s}'.format(jobid)) # path to MATCH .cmd and .out files: outpath = os.path.join(get_outdir(data=cluster_name), photbase, 'SLURM{:s}'.format(jobid)) # path to place output plots in: plotpath = os.path.join(outpath, 'plots') #print(outpath) #vbests, vvcrits, qdict, bfdict = marginalize(cluster_name, photbase, sys.argv[3], sys.argv[4], local=local) #vvcrits, best_dict, qdict, bfdict = marginalize(cluster_name, photbase, sys.argv[3], sys.argv[4], local=local, incvvc=incvvc) # by default, readssp() will return an AVERAGE (over all runs) of the bestfit parameter value and uncertainty. # the original, unaveraged values are derived from the sspcombine solutions. if incvvc == 'all': vvcrits = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6] else: vvcrits = [incvvc] best_dict = {} for vvc in vvcrits: # read sspcombine output for age results (subsampled solution being used): starnums, sspbest_age, ssp_ageerr = readssp(data=cluster_name, solution='subsampled', fromfit=False, param='age', photname_base=photbase, incvvc=vvc) # read sspcombines for metallicity results: starnums, sspbest_logz, ssp_logzerr = readssp(data=cluster_name, solution='subsampled', fromfit=False, param='logZ', photname_base=photbase, incvvc=vvc) # dictionary whose keys are the corresponding vvc values for the best fit values found above (dmod, Av fixed): best_dict[vvc] = { 'lage': { 'val': float(sspbest_age[0]), 'err': float(ssp_ageerr[0]) }, 'feh': { 'val': float(sspbest_logz[0]), 'err': float(ssp_logzerr[0]) }, 'dmod': dmod, 'ebv': ebv } # if told to plot "truth" values: if truth: if 'Fakedata' in cluster_name: # true age bin (list), logZ +/- spread (list), v/vcrit (float) of artificial data fit to: true_age = plt_truth(None, cluster_name, photbase, 'lage', justval=True) true_feh = plt_truth(None, cluster_name, photbase, 'logZ', justval=True) true_vvc = plt_truth(None, cluster_name, photbase, 'vvcrit', justval=True) elif 'Hyades' in cluster_name: # Perryman et al.1998. true_age = [np.log10(575e6), np.log10(675e6)] # [Fe/H] -- e.g. deB01 says 0.14 +/- 0.05 true_feh = [0.15, 0.15] # assume canonically non-rotating: true_vvc = 0.0 elif 'Praesepe' in cluster_name: # source???. true_age = [np.log10(575e6), np.log10(675e6)] # [Fe/H] source??? true_feh = [0.15, 0.15] # assume canonically non-rotating: true_vvc = 0.0 elif 'Pleiades' in cluster_name: # source??? true_age = [np.log10(100e6), np.log10(125e6)] # [Fe/H] e.g. Soderblom+ 2009 says 0.03 +/- 0.02 true_feh = [0.00, 0.00] # assume canonically non-rotating: true_vvc = 0.0 truths = {'age': true_age, 'feh': true_feh, 'vvc': true_vvc} else: truths = None #plt.clf() # clearing out pre-existing output files that this script may have produced in prev. runs: if not justbest: for f in glob.glob(os.path.join(outpath, 'cmd*.png')): os.remove(f) for f in glob.glob(os.path.join(plotpath, 'cmd*.png')): os.remove(f) for f in glob.glob(os.path.join(plotpath, '*.txt')): os.remove(f) # if req., correct 2MASS filter names to those recognizable by MIST. for i, afilter in enumerate(filters): if afilter == 'J': filters[i] = '2MASS_J' elif afilter == 'Ks': filters[i] = '2MASS_Ks' elif afilter == 'B': filters[i] = 'Bessell_B' elif afilter == 'V': filters[i] = 'Bessell_V' # Retrieve the magnitude limits used in the fit (from the calcsfh .param file used): param_fname = glob.glob( os.path.join(match_dir, 'csfh_param', 'calcsfh_{:s}.param'.format(photbase)))[0] with open(param_fname, 'r') as f: lines = f.readlines() # Color limits: color_lims = lines[4].split(' ') minvmi = float(color_lims[3]) maxvmi = float(color_lims[4]) ibin = float(color_lims[0]) vibin = float(color_lims[1]) ilims = lines[6].split(' ') imin = float(ilims[1]) imax = float(ilims[0]) exclusions = lines[7].split('\n')[0] ntbins = int(lines[8]) tbins = lines[9:8 + ntbins] for i, aline in enumerate(tbins): tbins[i] = map(float, aline.split('\n')[0].split(' ')[-2:]) # Manage exclude gates (right now only works for one region): # If there are exclude gates... if int(exclusions[0]) > 0: # Get the exclude gate points: expts = map(float, exclusions.split(' ')[1:-1]) ex_x = expts[::2] ex_y = expts[1::2] ex_xy = zip(ex_x, ex_y) else: expts = None # Also get the residuals (???): # For overplotting data points, get the data points CMD x, y values from the photometry file: photf_v = np.genfromtxt(os.path.join(match_dir, 'photometry', '{:s}.phot'.format(photbase)), usecols=(0, )) photf_i = np.genfromtxt(os.path.join(match_dir, 'photometry', '{:s}.phot'.format(photbase)), usecols=(1, )) photf_vmi = photf_v - photf_i # Tuple storing the x, y values for plotting the data on a CMD (using color on x, red filter on y): photf_pts = (photf_vmi, photf_i) # match uses blue filter on y axis. photf_pts_alt = (photf_vmi, photf_v) # store number of data pts if told to: if star_num: nstars = len(photf_vmi) #plt.clf() bestfit = 99999.9 # Plot best isochrone for each v/vcrit individually: #================================================================= allfig = plt.figure() allax = allfig.add_subplot(111) # iterate through all v/vcrits used for fitting: for j, vvcrit in enumerate(vvcrits): #print(outpath) # get the .cmd file for making a MATCH pg style plot: fname = glob.glob( os.path.join(outpath, '*vvcrit{:.1f}*.cmd'.format(vvcrit)))[0] # use Phil's code to make a CMD object from the .cmd file: a_cmd = cmd.CMD(fname) # store the axis extents of the CMD data extent = a_cmd.extent if not justbest: fig = plt.figure() ax = fig.add_subplot(111) # scatter plot of stars from data file (observations): # w/ num of data points in the plot legend... if star_num: ax.scatter(*photf_pts, lw=0, s=8, c='r', label=r"$N_*$ = " + "{:d}".format(nstars)) ax.legend(loc='best') # just the scatter plot... else: ax.scatter(*photf_pts, lw=0, s=8, c='r') # X out masked data points. if expts != None: for k in range(len(photf_pts[0])): if (min(ex_x) < photf_vmi[k] < max(ex_x)) & (min(ex_y) < photf_v[k] < max(ex_y)): ax.scatter(photf_vmi[k], photf_i[k], s=12, c='k', marker='x') # Plot MIST isochrones corresponding to MATCH best-fit parameters. ax, iso, mist_pts = plotisocmd(ax=ax, vvcrit=vvcrit, best_dict=best_dict, filters=filters, truths=truths, extent=extent) # saving the plot of data points w/ isochrones overlaid: savename = os.path.join( plotpath, 'cmd_vvcrit{:.1f}_m2lnP{:.2f}.png'.format(vvcrit, a_cmd.fit)) fig.savefig(savename, dpi=300) # create a MATCH pg style plot using the .cmd file: # using photf_pts_alt because MATCH does its CMDs with V-I vs. V & not sure if this is changeable. a_cmd.pgcmd(photf_pts=photf_pts_alt, mist_pts=mist_pts, best_list=[ best_dict[vvcrit]['lage']['val'], best_dict[vvcrit]['feh']['val'] ]) # closing figure before moving on to next plots. fig.clf() #================================================================== # For plotting all best fits together (on another matplotlib axis): #================================================================== # Only scatter plot data points once (on axis 2/ all isochrones). if j == 0: allax.scatter(*photf_pts, lw=0, s=8, c='r') # Mark excluded region(s) if expts != None: for k in range(len(photf_pts[0])): if (min(ex_x) < photf_vmi[k] < max(ex_x)) & ( min(ex_y) < photf_v[k] < max(ex_y)): allax.scatter(photf_vmi[k], photf_i[k], s=12, c='k', marker='x') # all best isochrones are plotted together (no +/- 1 sigma isochrones are plotted): iso.isoplot(allax, xlims=extent[0:2], ylims=extent[2:], shade=vvcrit, legloc='upper right') # track which cmd has the overall highest lnP & corresponding v/vcrit. if a_cmd.fit < bestfit: bestfit = a_cmd.fit bestvvc = vvcrit # write best fit solutions +/- uncertainties to a summary file: # ------------------------------------------------------------- outlines = [ 'Hyades\n', '_______\n', 'Tycho B, V\n', '--------\n', '\n', '\n', '\n', '2MASS J, Ks\n', '-------\n', '\n', '\n', '\n', 'Praesepe\n', '________\n', 'Tycho B, V\n', '--------\n', '\n', '\n', '\n', '2MASS J, Ks\n', '-------\n', '\n', '\n', '\n', 'Pleiades\n_', '_______\n', 'Tycho B, V\n', '--------\n', '\n', '\n', '\n', '2MASS J, Ks\n', '-------\n', '\n', '\n', '\n' ] with open('/n/home12/sgossage/match_results.txt', 'rw+') as sumfile: # get current lines of the summary file: inlines = sumfile.readlines() #print(inlines) #print(len(inlines)) #print(len(outlines)) for i, line in enumerate(inlines): # maintain lines that already contain best fits if 'Best' in line: print(line) outlines[i] = line # update best fit line for the current run: if 'Hyades' in cluster_name: n = 4 elif 'Praesepe' in cluster_name: n = 16 elif 'Pleiades' in cluster_name: n = 28 if '2MASSJK' in photbase: n += 5 # print these lines when updating... # ...if using a distribution of roation rates... if '_rot' in cluster_name: n += 1 outlines[n] = 'Best (rotation distribution) v/vcrit = {:.1f}, ' \ 'age = {:.1f} +/- {:.1f} Myrs,' \ '[Fe/H] = {:.2f} +/- {:.2f}\n'.format(bestvvc, 10**best_dict[bestvvc]['lage']['val']/1e6, (10**(best_dict[bestvvc]['lage']['val'] + \ best_dict[bestvvc]['lage']['err']) - \ 10**best_dict[bestvvc]['lage']['val'])/1e6, best_dict[bestvvc]['feh']['val'], best_dict[bestvvc]['feh']['err']) # ...or else if not using a distribution of rotation rates. else: outlines[n] = 'Best v/vcrit = {:.1f}, ' \ 'age = {:.1f} +/- {:.1f} Myrs,' \ '[Fe/H] = {:.2f} +/- {:.2f}\n'.format(bestvvc, (10**best_dict[bestvvc]['lage']['val'])/1e6, (10**(best_dict[bestvvc]['lage']['val'] + \ best_dict[bestvvc]['lage']['err']) - \ 10**best_dict[bestvvc]['lage']['val'])/1e6, best_dict[bestvvc]['feh']['val'], best_dict[bestvvc]['feh']['err']) # return to top of file & then write lines out. sumfile.seek(0) sumfile.writelines(outlines) # After all, save image of the plot containing all isochrones plotted side by side. savename = os.path.join(plotpath, 'cmdall_bestvvcrit{:.1f}.png'.format(bestvvc)) allfig.savefig(savename, dpi=300) allfig.clf() #========================================================= if bestax == None: bestfig = plt.figure() bestax = bestfig.add_subplot(111) bestax.scatter(*photf_pts, lw=0, s=8, c='r') if expts != None: for k in range(len(photf_pts[0])): if (min(ex_x) < photf_vmi[k] < max(ex_x)) & (min(ex_y) < photf_v[k] < max(ex_y)): bestax.scatter(photf_vmi[k], photf_i[k], s=12, c='k', marker='x') bestax, bestiso, mist_pts = plotisocmd(ax=bestax, vvcrit=bestvvc, best_dict=best_dict, filters=filters, truths=truths, extent=extent) if savebest: # save the figure. bestfig.savefig(os.path.join( plotpath, 'bestcmd_vvcrit{:.1f}_m2lnP{:.2f}.png'.format(vvcrit, a_cmd.fit)), dpi=300) bestfig.clf() return bestax, allax
def main(cluster_name, photbase, jobid, filters, dmod, ebv, local, vvc, outname=None, savebest=True, bestax=None, justbest=False, txtlbl_kwargs={ "frameon": False, "fontsize": 14, "loc": 4 }, texts=['vvc', 'age', 'feh'], hess_datapts=True, hess_modeliso=True): global match_dir global scrn_dir global outpath global plotpath # path/to/Cluster match_dir = get_workdir(data=cluster_name) # path to MATCH .scrn files: scrn_dir = os.path.join(get_scrndir(data=cluster_name), photbase, 'SLURM{:s}'.format(jobid)) # path to MATCH .cmd and .out files: outpath = os.path.join(get_outdir(data=cluster_name), photbase, 'SLURM{:s}'.format(jobid)) # path to place output plots in: plotpath = os.path.join(outpath, 'plots') #print(outpath) rot = False if 'rot' in cluster_name: rot = True if outname != None: # Create corner PDF plot: if vvc != 'all': flist = glob.glob( os.path.join(scrn_dir, '*vvcrit{:.1f}*.scrn'.format(vvc))) params = ['lage', 'logZ'] else: flist = glob.glob(os.path.join(scrn_dir, '*.scrn')) ssp.combine_files(flist, outfile=outname) # Create a match SSP object from the combined scrns of the given runs: combineddata = ssp.SSP(outname) # Corner plots: # 'lage', 'vvcrit', 'logZ', 'dmod', 'Av' #pdffig, pdfax = combineddata.pdf_plots(['lage','logZ','vvcrit'], twod=False, quantile=True, cmap=plt.cm.Reds, interpolateq=True) #plt.close() #pdffig, pdfax = combineddata.pdf_plots(['lage','logZ','vvcrit'], twod=True, quantile=True, cmap=plt.cm.Reds, interpolateq=True) #plt.savefig(os.path.join(plotpath, 'pdfcornerplot.png')) #plt.close() #vbests, vvcrits, qdict, bfdict = marginalize(cluster_name, photbase, sys.argv[3], sys.argv[4], local=local) #vvcrits, best_dict, qdict, bfdict = marginalize(cluster_name, photbase, sys.argv[3], sys.argv[4], local=local, incvvc=incvvc) # by default, readssp() will return an AVERAGE (over all runs) of the bestfit parameter value and uncertainty. # the original, unaveraged values are derived from the sspcombine solutions. if vvc == 'all': vvcrits = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6] else: vvcrits = [vvc] #print(vvcrits) best_dict = {} # for vvc in vvcrits: # read sspcombine output for age results (subsampled solution being used): # sspbest_age, ssp_upageerr, ssp_loageerr = readssp(photname_base=photbase, data=cluster_name, # param='age', vvc=vvc, jobidstr=jobid) # read sspcombines for metallicity results: # sspbest_logz, ssp_uplogzerr, ssp_lologzerr = readssp(photname_base=photbase, data=cluster_name, # param='logZ', vvc=vvc, jobidstr=jobid) # dictionary whose keys are the corresponding vvc values for the best fit values found above (dmod, Av fixed): # best_dict[vvc] = {'lage': {'val': sspbest_age, 'uperr': ssp_upageerr, 'loerr': ssp_loageerr}, # 'feh': {'val': sspbest_logz, 'uperr': ssp_uplogzerr, 'loerr': ssp_lologzerr}, # 'dmod': dmod, # 'ebv': ebv} #plt.clf() # clearing out pre-existing output files that this script may have produced in prev. runs: if not justbest: for f in glob.glob(os.path.join(outpath, 'cmd*.png')): os.remove(f) for f in glob.glob(os.path.join(plotpath, 'cmd*.png')): os.remove(f) for f in glob.glob(os.path.join(plotpath, '*.txt')): os.remove(f) # if req., correct 2MASS filter names to those recognizable by MIST. for i, afilter in enumerate(filters): if afilter == 'J': filters[i] = '2MASS_J' elif afilter == 'Ks': filters[i] = '2MASS_Ks' elif afilter == 'B': filters[i] = 'Bessell_B' elif afilter == 'V': filters[i] = 'Bessell_V' # Retrieve the magnitude limits used in the fit (from the calcsfh .param file used): param_fname = glob.glob( os.path.join(match_dir, 'csfh_param', 'calcsfh_{:s}.param'.format(photbase)))[0] with open(param_fname, 'r') as f: lines = f.readlines() # Color limits: color_lims = lines[4].split(' ') minvmi = float(color_lims[3]) maxvmi = float(color_lims[4]) ibin = float(color_lims[0]) vibin = float(color_lims[1]) ilims = lines[6].split(' ') imin = float(ilims[1]) imax = float(ilims[0]) exclusions = lines[7].split('\n')[0] ntbins = int(lines[8]) tbins = lines[9:8 + ntbins] for i, aline in enumerate(tbins): tbins[i] = np.array( list(map(float, aline.split('\n')[0].split(' ')[-2:]))) # Manage exclude gates (right now only works for one region): # If there are exclude gates... if int(exclusions[0]) > 0: # Get the exclude gate points: expts = np.array(list(map(float, exclusions.split(' ')[1:-1]))) ex_x = expts[::2] ex_y = expts[1::2] ex_xy = zip(ex_x, ex_y) else: expts = None ex_xy = None # Also get the residuals (???): # For overplotting data points, get the data points CMD x, y values from the photometry file: photf_path = os.path.join(match_dir, 'photometry', '{:s}.phot'.format(photbase)) photf_v_raw = np.genfromtxt(photf_path, usecols=(0, )) photf_i_raw = np.genfromtxt(photf_path, usecols=(1, )) if any(photf_v_raw >= 99.999) or any(photf_i_raw >= 99.999): print("Bad photometric values detected in {:s}. Cutting them out...". format(photf_path)) photf_v = photf_v_raw[(photf_v_raw < 99.999) & (photf_i_raw < 99.999)] photf_i = photf_i_raw[(photf_v_raw < 99.999) & (photf_i_raw < 99.999)] else: photf_v = photf_v_raw photf_i = photf_i_raw photf_vmi = photf_v - photf_i # Tuple storing the x, y values for plotting the data on a CMD (using color on x, red filter on y): photf_pts = (photf_vmi, photf_i) # match uses blue filter on y axis. photf_pts_alt = (photf_vmi, photf_v) bestfit = 99999.9 # Plot best isochrone for each v/vcrit individually: #================================================================= allfig = plt.figure() allax = allfig.add_subplot(111) probfig, probax = plt.subplots(1, 1) # iterate through all v/vcrits used for fitting: for j, vvcrit in enumerate(vvcrits): print(outpath) # get the .cmd file for making a MATCH pg style plot: if 'flat' in cluster_name: fname = glob.glob(os.path.join(outpath, '*vvcflat*.cmd'))[0] else: try: fname = glob.glob( os.path.join(outpath, '*vvc{:.1f}*.cmd'.format(vvcrit)))[0] except IndexError: fname = glob.glob( os.path.join(outpath, '*vvcrit{:.1f}*.cmd'.format(vvcrit)))[0] # use Phil's code to make a CMD object from the .cmd file: a_cmd = cmd.CMD(fname, ymag='I') # store the axis extents of the CMD data extent = a_cmd.extent # read sspcombine output for age results (subsampled solution being used): sspbest_age, ssp_upageerr, ssp_loageerr = readssp( photname_base=photbase, data=cluster_name, param='age', vvc=vvcrit, jobidstr=jobid) # read sspcombines for metallicity results: sspbest_logz, ssp_uplogzerr, ssp_lologzerr = readssp( photname_base=photbase, data=cluster_name, param='logZ', vvc=vvcrit, jobidstr=jobid) # dictionary whose keys are the corresponding vvc values for the best fit values found above (dmod, Av fixed): best_dict[vvcrit] = { 'lage': { 'val': sspbest_age, 'uperr': ssp_upageerr, 'loerr': ssp_loageerr }, 'feh': { 'val': sspbest_logz, 'uperr': ssp_uplogzerr, 'loerr': ssp_lologzerr }, 'dmod': dmod, 'ebv': ebv, 'fit': a_cmd.fit } # to plot the fit statistic vs. v/vcrit: probax.scatter(vvcrit, a_cmd.fit) if True: #not justbest: fig = plt.figure() ax = fig.add_subplot(111) # scatter plot of stars from data file (observations): ax = pp.plotphot(*photf_pts, ax=ax) # X out masked data points. if expts is not None: for k in range(len(photf_pts[0])): if (min(ex_x) < photf_vmi[k] < max(ex_x)) & (min(ex_y) < photf_v[k] < max(ex_y)): ax.scatter(photf_vmi[k], photf_i[k], s=40, c='k', marker='x') # Plot MIST isochrones corresponding to MATCH best-fit parameters. ax, iso, isou, isol, mist_pts, axlims = plotisocmd( ax=ax, vvcrit=vvcrit, best_dict=best_dict, filters=filters, extent=extent, txtlbl_kwargs=txtlbl_kwargs, rot=rot, texts=texts) ax.set_title('{:s}'.format(cluster_name.split('rot')[0])) # saving the plot of data points w/ isochrones overlaid: savename = os.path.join( plotpath, 'cmd_vvc{:.1f}_m2lnP{:.2f}.png'.format(vvcrit, a_cmd.fit)) fig.savefig(savename, dpi=300) # create a MATCH pg style plot using the .cmd file: # using photf_pts_alt because MATCH does its CMDs with V-I vs. V & not sure if this is changeable. pgcmd_kwargs = {} if hess_datapts: pgcmd_kwargs['photf_pts'] = photf_pts_alt if hess_modeliso: pgcmd_kwargs['mist_pts'] = mist_pts pgcmd_kwargs['best_list'] = [ best_dict[vvcrit]['lage']['val'], best_dict[vvcrit]['feh']['val'] ] pgcmd_kwargs['ymag'] = 'V' # four panel plot of all hess diagrams: # a_cmd.pgcmd(**pgcmd_kwargs) for m in range(4): # each of the 4 plotted separately: pgcmd_kwargs['hess_i'] = m a_cmd.plthess(**pgcmd_kwargs) # closing figure before moving on to next plots. fig.clf() # track which cmd has the overall highest lnP & corresponding v/vcrit. if a_cmd.fit < bestfit: bestfit = a_cmd.fit bestvvc = vvcrit bestcmd = a_cmd # save plot of fit statistic vs. v/vc: probax.set_xlabel(r'$\Omega/\Omega_c$') probax.set_ylabel(r'$-2\ln$P') probfig.savefig(os.path.join(plotpath, 'lnpvsrot.png')) # write best fit solutions +/- uncertainties to a summary file: # ------------------------------------------------------------- print('WRITING RESULTS...') outlines = [ 'Hyades\n', '_______\n', 'Tycho B, V\n', '--------\n', '\n', '\n', '\n', '2MASS J, Ks\n', '-------\n', '\n', '\n', '\n', 'Praesepe\n', '________\n', 'Tycho B, V\n', '--------\n', '\n', '\n', '\n', '2MASS J, Ks\n', '-------\n', '\n', '\n', '\n', 'Pleiades\n_', '_______\n', 'Tycho B, V\n', '--------\n', '\n', '\n', '\n', '2MASS J, Ks\n', '-------\n', '\n', '\n', '\n' ] # writing results to a .txt file for reference (don't add fake data results though): if 'Fakedata' not in cluster_name: with open('/n/home12/sgossage/match_results.txt', 'r+') as sumfile: # get current lines of the summary file: inlines = sumfile.readlines() # print(inlines) #print(len(inlines)) #print(len(outlines)) for i, line in enumerate(inlines): # maintain lines that already contain best fits if ('Best' in line) | ('v/vcrit = 0.0' in line): print(line) outlines[i] = line # update best fit line for the current run: if 'Hyades' in cluster_name: n = 4 elif 'Praesepe' in cluster_name: n = 16 elif 'Pleiades' in cluster_name: n = 28 if '2MASSJK' in photbase: n += 5 # print these lines when updating... # ...if using a distribution of roation rates... if ('_rot' in cluster_name) | ('_flat' in cluster_name): n += 2 outlines[n] = 'Best (rotation distribution) v/vcrit = {:.1f}, ' \ 'age = {:.1f} + {:.1f} - {:.1f} Myrs,' \ '[Fe/H] = {:.2f} + {:.2f} - {:.2f}, -2lnP ={:.2f} \n'.format(bestvvc, (10**best_dict[bestvvc]['lage']['val'])/1e6, (10**(best_dict[bestvvc]['lage']['val'] + \ best_dict[bestvvc]['lage']['uperr']) - \ 10**best_dict[bestvvc]['lage']['val'])/1e6, (10**best_dict[bestvvc]['lage']['val'] - \ 10**(best_dict[bestvvc]['lage']['val'] - \ best_dict[bestvvc]['lage']['loerr']))/1e6, best_dict[bestvvc]['feh']['val'], best_dict[bestvvc]['feh']['uperr'], best_dict[bestvvc]['feh']['loerr'], best_dict[bestvvc]['fit']) # ...or else if not using a distribution of rotation rates. else: outlines[n] = 'Best v/vcrit = {:.1f}, ' \ 'age = {:.1f} + {:.1f} - {:.1f} Myrs,' \ '[Fe/H] = {:.2f} + {:.2f} - {:.2f}, -2lnP = {:.2f}\n'.format(bestvvc, (10**best_dict[bestvvc]['lage']['val'])/1e6, (10**(best_dict[bestvvc]['lage']['val'] + \ best_dict[bestvvc]['lage']['uperr']) - \ 10**best_dict[bestvvc]['lage']['val'])/1e6, (10**best_dict[bestvvc]['lage']['val'] - \ 10**(best_dict[bestvvc]['lage']['val'] - \ best_dict[bestvvc]['lage']['loerr']))/1e6, best_dict[bestvvc]['feh']['val'], best_dict[bestvvc]['feh']['uperr'], best_dict[bestvvc]['feh']['loerr'], best_dict[bestvvc]['fit']) n += 1 outlines[n] = 'v/vcrit = {:.1f}, ' \ 'age = {:.1f} + {:.1f} - {:.1f} Myrs,' \ '[Fe/H] = {:.2f} + {:.2f} - {:.2f}, -2lnP = {:.2f}\n'.format(0.0, (10**best_dict[0.0]['lage']['val'])/1e6, (10**(best_dict[0.0]['lage']['val'] + \ best_dict[0.0]['lage']['uperr']) - \ 10**best_dict[0.0]['lage']['val'])/1e6, (10**best_dict[0.0]['lage']['val'] - \ 10**(best_dict[0.0]['lage']['val'] - \ best_dict[0.0]['lage']['loerr']))/1e6, best_dict[0.0]['feh']['val'], best_dict[0.0]['feh']['uperr'], best_dict[0.0]['feh']['loerr'], best_dict[0.0]['fit']) # return to top of file & then write lines out. sumfile.seek(0) sumfile.writelines(outlines) #========================================================= if bestax == None: bestfig = plt.figure() bestax = bestfig.add_subplot(111) bestax.set_title('{:s}'.format(cluster_name.split('rot')[0])) #bestax.scatter(*photf_pts, lw=0, s=8, c='r') bestax = pp.plotphot(*photf_pts, ax=bestax) # if expts != None: ## for k in range(len(photf_pts[0])): # if (min(ex_x) < photf_vmi[k] < max(ex_x)) & (min(ex_y) < photf_v[k] < max(ex_y)): # bestax.scatter(photf_vmi[k], photf_i[k], s=40, c='k', marker='x') bestax, bestiso, bestisou, bestisol, mist_pts, axlims = plotisocmd( ax=bestax, vvcrit=bestvvc, best_dict=best_dict, filters=filters, extent=extent, txtlbl_kwargs=txtlbl_kwargs, rot=rot, texts=texts) if savebest: # save the figure. bestfig.savefig(os.path.join( plotpath, 'bestcmd_vvcrit{:.1f}_m2lnP{:.2f}.png'.format(vvcrit, a_cmd.fit)), dpi=300) bestfig.clf() return bestax, allax, ( bestiso, bestisou, bestisol), bestcmd, photf_pts, mist_pts, ex_xy, axlims