Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
    #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
Ejemplo n.º 8
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
Ejemplo n.º 9
0
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