def plot_beast_ifit(filters, waves, stats, pdf1d_hdu, starnum):

    # setup the plot grid
    gridNrow, gridNcol = 5, 12
    gs = gridspec.GridSpec(
        gridNrow,
        gridNcol,
        height_ratios=[1.0] * gridNrow,
        width_ratios=[1.0] * gridNcol,
    )
    ax = []

    # axes for the big SED plot. Leave empty columns right of the plot to
    # put the legend and values.
    sed_height = 2
    free_cols = 3
    index_sedplot = len(ax)
    ax.append(plt.subplot(gs[0:sed_height, 0:-1 - free_cols]))

    # axes for the 1D PDFs
    nprim = 4
    nsec = 3
    nderiv = 3

    indices_1dpdf = []
    rows = [sed_height + i for i in range(3)]
    widths = [3, 4, 4]
    naxes = [nprim, nsec, nderiv]
    for r, w, n in zip(rows, widths, naxes):
        for i in range(n):
            indices_1dpdf.append(len(ax))
            ax.append(plt.subplot(gs[r, i * w:(i + 1) * w]))

    # plot the SED
    # print(np.sort(stats.colnames))

    n_filters = len(filters)

    # get the observations
    waves *= 1e-4
    obs_flux = np.empty((n_filters), dtype=np.float)
    mod_flux = np.empty((n_filters, 3), dtype=np.float)
    mod_flux_nd = np.empty((n_filters, 3), dtype=np.float)
    mod_flux_wbias = np.empty((n_filters, 3), dtype=np.float)
    k = starnum

    c = ap_SkyCoord(
        ra=stats["RA"][k] * ap_units.degree,
        dec=stats["DEC"][k] * ap_units.degree,
        frame="icrs",
    )
    corname = ("PHAT J" + c.ra.to_string(unit=ap_units.hourangle,
                                         sep="",
                                         precision=2,
                                         alwayssign=False,
                                         pad=True) +
               c.dec.to_string(sep="", precision=2, alwayssign=True, pad=True))

    for i, cfilter in enumerate(filters):
        obs_flux[i] = stats[cfilter][k]
        fluxname = "log" + cfilter
        mod_flux[i, 0] = np.power(10.0, stats[fluxname + "_wd_p50"][k])
        mod_flux[i, 1] = np.power(10.0, stats[fluxname + "_wd_p16"][k])
        mod_flux[i, 2] = np.power(10.0, stats[fluxname + "_wd_p84"][k])
        mod_flux_nd[i, 0] = np.power(10.0, stats[fluxname + "_nd_p50"][k])
        mod_flux_nd[i, 1] = np.power(10.0, stats[fluxname + "_nd_p16"][k])
        mod_flux_nd[i, 2] = np.power(10.0, stats[fluxname + "_nd_p84"][k])
        if "sym" + fluxname + "_wd_bias_p50" in stats.colnames:
            mod_flux_wbias[i, 0] = inverse_symlog(stats["sym" + fluxname +
                                                        "_wd_bias_p50"][k])
            mod_flux_wbias[i, 1] = inverse_symlog(stats["sym" + fluxname +
                                                        "_wd_bias_p16"][k])
            mod_flux_wbias[i, 2] = inverse_symlog(stats["sym" + fluxname +
                                                        "_wd_bias_p84"][k])

    sed_ax = ax[index_sedplot]
    sed_ax.plot(waves, obs_flux, "ko", label="observed")

    if "symlog" + filters[0] + "_wd_bias_p50" in stats.colnames:
        sed_ax.plot(waves,
                    mod_flux_wbias[:, 0],
                    "b-",
                    label="stellar+dust+bias")
        sed_ax.fill_between(waves,
                            mod_flux_wbias[:, 1],
                            mod_flux_wbias[:, 2],
                            color="b",
                            alpha=0.3)

    sed_ax.plot(waves, mod_flux[:, 0], "r-", label="stellar+dust")
    sed_ax.fill_between(waves,
                        mod_flux[:, 1],
                        mod_flux[:, 2],
                        color="r",
                        alpha=0.2)

    sed_ax.plot(waves, mod_flux_nd[:, 0], "y-", label="stellar only")
    sed_ax.fill_between(waves,
                        mod_flux_nd[:, 1],
                        mod_flux_nd[:, 2],
                        color="y",
                        alpha=0.1)

    # sed_ax.legend(loc='upper right', bbox_to_anchor=(1.25, 1.025), fontsize=8)
    sed_ax.legend(loc="lower right", fontsize=9)

    sed_ax.set_ylabel(r"Flux [ergs s$^{-1}$ cm$^{-2}$ $\AA^{-1}$]")
    sed_ax.set_yscale("log")

    sed_ax.text(0.5,
                -0.07,
                r"$\lambda$ [$\AA$]",
                transform=sed_ax.transAxes,
                va="top")
    sed_ax.set_xlim(0.2, 2.0)
    sed_ax.set_xscale("log")
    sed_ax.minorticks_off()
    sed_ax.set_xticks([0.2, 0.3, 0.4, 0.5, 0.8, 1.0, 2.0])
    sed_ax.get_xaxis().set_major_formatter(matplotlib.ticker.ScalarFormatter())
    sed_ax.get_xaxis().set_minor_formatter(matplotlib.ticker.ScalarFormatter())

    sed_ax.text(0.05,
                0.95,
                corname,
                transform=sed_ax.transAxes,
                va="top",
                ha="left")

    # add the text results
    keys = [
        "Av", "M_ini", "logA", "distance", "Rv", "f_A", "Z", "logT", "logg",
        "logL"
    ]
    dispnames = [
        "A(V)",
        "log(M)",
        "log(t)",
        "d(kpc)",
        "R(V)",
        r"f$_\mathcal{A}$",
        "Z",
        r"log(T$_\mathrm{eff})$",
        "log(g)",
        "log(L)",
    ]
    startprim, stopprim = 0, nprim - 1  # 0 1 2 3
    startsec, stopsec = stopprim + 1, stopprim + nsec  # 4 5 6
    startderiv, stopderiv = stopsec + 1, stopsec + nderiv  # 7 8 9
    laby = 0.96
    ty = np.linspace(laby - 0.1, 0.1, num=len(keys))
    ty[startsec:] -= 0.04
    ty[startderiv:] -= 0.04
    tx = [1.14, 1.3, 1.47]
    for i in range(len(keys)):
        sed_ax.text(tx[0],
                    ty[i],
                    dispnames[i],
                    ha="center",
                    transform=sed_ax.transAxes)
        sed_ax.text(
            tx[1],
            ty[i],
            disp_str(stats, starnum, keys[i]),
            ha="center",
            color="m",
            transform=sed_ax.transAxes,
        )
        best_val = stats[keys[i] + "_Best"][k]
        if keys[i] == "M_ini":
            best_val = np.log10(best_val)
        if keys[i] == "distance":
            best_val /= 1000.0
            dispnames[i] = dispnames[i].replace("pc", "kpc")
        sed_ax.text(
            tx[2],
            ty[i],
            "$" + "{0:.2f}".format(best_val) + "$",
            ha="center",
            color="c",
            transform=sed_ax.transAxes,
        )
    sed_ax.text(tx[0],
                laby,
                "Param",
                ha="center",
                transform=sed_ax.transAxes,
                fontsize=10)
    sed_ax.text(
        tx[1],
        laby,
        r"50$\pm$33%",
        ha="center",
        color="k",
        transform=sed_ax.transAxes,
        fontsize=10,
    )
    sed_ax.text(
        tx[2],
        laby,
        "Best",
        color="k",
        ha="center",
        transform=sed_ax.transAxes,
        fontsize=10,
    )

    # now draw boxes around the different kinds of parameters
    tax = sed_ax
    left, right = tx[0], tx[-1]

    def draw_box_around_values(start, stop, ls):
        deltaline = ty[start] - ty[start + 1]
        top = ty[start] + deltaline  # Draw the top border ABOVE the text
        bottom = ty[stop]
        rec = Rectangle(
            (left - 0.1, bottom - 0.02),
            right - left + 0.15,
            top - bottom + 0.01,
            fill=False,
            lw=2,
            transform=tax.transAxes,
            ls=ls,
        )
        rec = tax.add_patch(rec)
        rec.set_clip_on(False)

    # primary
    draw_box_around_values(startprim, stopprim, ls="dashed")

    # secondary
    draw_box_around_values(startsec, stopsec, ls="dotted")

    # derived
    draw_box_around_values(startderiv, stopderiv, ls="dashdot")

    # Make these plots:

    # A, M, t, dist,
    # R, fA, Z
    # logT, logg, logL

    # This is done by iterating over the axes created at the start of
    # this function, from left to right, line per line.

    # plot the primary parameter 1D PDFs
    ax_iter = (ax[i] for i in indices_1dpdf)
    first_primary_ax = next(ax_iter)
    plot_1dpdf(first_primary_ax, pdf1d_hdu, "Av", "A(V)", starnum, stats=stats)
    plot_1dpdf(next(ax_iter),
               pdf1d_hdu,
               "M_ini",
               "log(M)",
               starnum,
               logx=True,
               stats=stats)
    plot_1dpdf(next(ax_iter),
               pdf1d_hdu,
               "logA",
               "log(t)",
               starnum,
               stats=stats)
    last_primary_ax = next(ax_iter)
    plot_1dpdf(last_primary_ax,
               pdf1d_hdu,
               "distance",
               "d(kpc)",
               starnum,
               stats=stats)

    # plot the secondary parameter 1D PDFs
    first_secondary_ax = next(ax_iter)
    plot_1dpdf(first_secondary_ax,
               pdf1d_hdu,
               "Rv",
               "R(V)",
               starnum,
               stats=stats)
    plot_1dpdf(next(ax_iter),
               pdf1d_hdu,
               "f_A",
               r"f$_\mathcal{A}$",
               starnum,
               stats=stats)
    last_secondary_ax = next(ax_iter)
    plot_1dpdf(last_secondary_ax, pdf1d_hdu, "Z", "Z", starnum, stats=stats)

    # plot the derived parameter 1D PDFs
    first_derived_ax = next(ax_iter)
    plot_1dpdf(
        first_derived_ax,
        pdf1d_hdu,
        "logT",
        r"log(T$_\mathrm{eff})$",
        starnum,
        stats=stats,
    )
    plot_1dpdf(next(ax_iter),
               pdf1d_hdu,
               "logg",
               "log(g)",
               starnum,
               stats=stats)
    last_derived_ax = next(ax_iter)
    plot_1dpdf(last_derived_ax,
               pdf1d_hdu,
               "logL",
               "log(L)",
               starnum,
               stats=stats)

    # A more manual version of tight_layout
    plt.subplots_adjust(top=0.95,
                        bottom=0.05,
                        left=0.125,
                        right=0.925,
                        wspace=0.5,
                        hspace=0.5)

    # PLOT ALL THE BOXES AFTER CALLING TIGHT LAYOUT! Tight layout
    # changes the coordinates of the axes a little, but leaves the boxes
    # untouched. Therefore, we plot the boxes here by extracting the
    # coordinates of the axes after they have been modified by
    # tight_layout.

    def rectangle_around_axes(bottomleft_ax, topright_ax, pad, ls, label=None):
        """
        pad: tuple, (left, right, bottom, top)
        """
        left, bottom = bottomleft_ax.get_position().get_points()[0]
        right, top = topright_ax.get_position().get_points()[1]
        left -= pad[0]
        right += pad[1]
        bottom -= pad[2]
        top += pad[3]
        transf = plt.gcf().transFigure
        rec = Rectangle(
            (left, bottom),
            right - left,
            top - bottom,
            transform=transf,
            fill=False,
            lw=2,
            ls=ls,
        )
        rec = bottomleft_ax.add_patch(rec)
        rec.set_clip_on(False)

        if label:
            middle = (top + bottom) / 2.0
            moreleft = left  # pad[0]
            bottomleft_ax.text(
                moreleft,
                middle,
                label,
                transform=transf,
                rotation="vertical",
                fontstyle="oblique",
                va="center",
                ha="right",
            )

    rectanglePadding = (0.03, 0.01, 0.03, 0.01)

    # Box around primaries
    tax = first_primary_ax
    rectangle_around_axes(
        first_primary_ax,
        last_primary_ax,
        pad=rectanglePadding,
        ls="dashed",
        label="Primary",
    )
    tax.text(
        0.0,
        0.5,
        "Probability",
        transform=tax.transAxes,
        rotation="vertical",
        va="center",
        ha="right",
    )

    # Box around secondaries
    tax = first_secondary_ax
    rectangle_around_axes(
        first_secondary_ax,
        last_secondary_ax,
        pad=rectanglePadding,
        ls="dotted",
        label="Secondary",
    )
    tax.text(
        0.0,
        0.5,
        "Probability",
        transform=tax.transAxes,
        rotation="vertical",
        va="center",
        ha="right",
    )

    # Box around deriveds
    tax = first_derived_ax
    rectangle_around_axes(
        first_derived_ax,
        last_derived_ax,
        pad=rectanglePadding,
        ls="dashdot",
        label="Derived",
    )
    tax.text(
        0.0,
        0.5,
        "Probability",
        transform=tax.transAxes,
        rotation="vertical",
        va="center",
        ha="right",
    )
Beispiel #2
0
def plot_beast_ifit(filters, waves, stats, pdf1d_hdu):

    # setup the plot grid
    gridNrow, gridNcol = 5, 12
    gs = gridspec.GridSpec(gridNrow,
                           gridNcol,
                           height_ratios=[1.] * gridNrow,
                           width_ratios=[1.] * gridNcol)
    ax = []

    # axes for the big SED plot. Leave empty columns right of the plot to
    # put the legend and values.
    sed_height = 2
    free_cols = 2
    index_sedplot = len(ax)
    ax.append(plt.subplot(gs[0:sed_height, 0:-1 - free_cols]))

    # axes for the 1D PDFs
    nprim = 4
    nsec = 3
    nderiv = 3

    indices_1dpdf = []
    rows = [sed_height + i for i in range(3)]
    widths = [3, 4, 4]
    naxes = [nprim, nsec, nderiv]
    for r, w, n in zip(rows, widths, naxes):
        for i in range(n):
            indices_1dpdf.append(len(ax))
            ax.append(plt.subplot(gs[r, i * w:(i + 1) * w]))

    # plot the SED
    # print(np.sort(stats.colnames))

    n_filters = len(filters)

    # get the observations
    waves *= 1e-4
    obs_flux = np.empty((n_filters), dtype=np.float)
    mod_flux = np.empty((n_filters, 3), dtype=np.float)
    mod_flux_nd = np.empty((n_filters, 3), dtype=np.float)
    mod_flux_wbias = np.empty((n_filters, 3), dtype=np.float)
    k = starnum

    c = ap_SkyCoord(ra=stats['RA'][k] * ap_units.degree,
                    dec=stats['DEC'][k] * ap_units.degree,
                    frame='icrs')
    corname = ('PHAT J' + c.ra.to_string(unit=ap_units.hourangle,
                                         sep="",
                                         precision=2,
                                         alwayssign=False,
                                         pad=True) +
               c.dec.to_string(sep="", precision=2, alwayssign=True, pad=True))

    for i, cfilter in enumerate(filters):
        obs_flux[i] = stats[cfilter][k]
        mod_flux[i, 0] = np.power(10.0, stats['log' + cfilter + '_wd_p50'][k])
        mod_flux[i, 1] = np.power(10.0, stats['log' + cfilter + '_wd_p16'][k])
        mod_flux[i, 2] = np.power(10.0, stats['log' + cfilter + '_wd_p84'][k])
        mod_flux_nd[i, 0] = np.power(10.0,
                                     stats['log' + cfilter + '_nd_p50'][k])
        mod_flux_nd[i, 1] = np.power(10.0,
                                     stats['log' + cfilter + '_nd_p16'][k])
        mod_flux_nd[i, 2] = np.power(10.0,
                                     stats['log' + cfilter + '_nd_p84'][k])
        if 'log' + cfilter + '_wd_bias_p50' in stats.colnames:
            mod_flux_wbias[i, 0] = np.power(
                10.0, stats['log' + cfilter + '_wd_bias_p50'][k])
            mod_flux_wbias[i, 1] = np.power(
                10.0, stats['log' + cfilter + '_wd_bias_p16'][k])
            mod_flux_wbias[i, 2] = np.power(
                10.0, stats['log' + cfilter + '_wd_bias_p84'][k])
    sed_ax = ax[index_sedplot]
    sed_ax.plot(waves, obs_flux, 'ko', label='observed')

    if 'log' + filters[0] + '_wd_bias_p50' in stats.colnames:
        sed_ax.plot(waves,
                    mod_flux_wbias[:, 0],
                    'b-',
                    label='stellar+dust+bias')
        sed_ax.fill_between(waves,
                            mod_flux_wbias[:, 1],
                            mod_flux_wbias[:, 2],
                            color='b',
                            alpha=0.3)

    sed_ax.plot(waves, mod_flux[:, 0], 'r-', label='stellar+dust')
    sed_ax.fill_between(waves,
                        mod_flux[:, 1],
                        mod_flux[:, 2],
                        color='r',
                        alpha=0.2)

    sed_ax.plot(waves, mod_flux_nd[:, 0], 'y-', label='stellar only')
    sed_ax.fill_between(waves,
                        mod_flux_nd[:, 1],
                        mod_flux_nd[:, 2],
                        color='y',
                        alpha=0.1)

    sed_ax.legend(loc='upper right', bbox_to_anchor=(1.25, 1.025))

    sed_ax.set_ylabel(r'Flux [ergs s$^{-1}$ cm$^{-2}$ $\AA^{-1}$]')
    sed_ax.set_yscale('log')

    sed_ax.set_xscale('log')
    sed_ax.text(0.5,
                -0.01,
                r'$\lambda$ [$\AA$]',
                transform=sed_ax.transAxes,
                va='top')
    sed_ax.set_xlim(0.2, 2.0)
    sed_ax.set_xticks([0.2, 0.3, 0.4, 0.5, 0.8, 0.9, 1.0, 2.0])
    sed_ax.get_xaxis().set_major_formatter(matplotlib.ticker.ScalarFormatter())

    sed_ax.text(0.05,
                0.95,
                corname,
                transform=sed_ax.transAxes,
                va='top',
                ha='left')

    # add the text results
    keys = [
        'Av', 'M_ini', 'logA', 'distance', 'Rv', 'f_A', 'Z', 'logT', 'logg',
        'logL'
    ]
    dispnames = [
        'A(V)', 'log(M)', 'log(t)', 'distance(pc)', 'R(V)', r'f$_\mathcal{A}$',
        'Z', r'log(T$_\mathrm{eff})$', 'log(g)', 'log(L)'
    ]
    startprim, stopprim = 0, nprim - 1  # 0 1 2 3
    startsec, stopsec = stopprim + 1, stopprim + nsec  # 4 5 6
    startderiv, stopderiv = stopsec + 1, stopsec + nderiv  # 7 8 9
    laby = 0.72
    ty = np.linspace(laby - 0.07, 0.1, num=len(keys))
    ty[startsec:] -= 0.025
    ty[startderiv:] -= 0.025
    tx = [1.12, 1.2, 1.3]
    for i in range(len(keys)):
        sed_ax.text(tx[0],
                    ty[i],
                    dispnames[i],
                    ha='right',
                    transform=sed_ax.transAxes)
        sed_ax.text(tx[1],
                    ty[i],
                    disp_str(stats, starnum, keys[i]),
                    ha='center',
                    color='m',
                    transform=sed_ax.transAxes)
        best_val = stats[keys[i] + '_Best'][k]
        if keys[i] == 'M_ini':
            best_val = np.log10(best_val)
        if keys[i] == 'distance':
            best_val /= 1000.
            dispnames[i] = dispnames[i].replace('pc', 'kpc')
        sed_ax.text(tx[2],
                    ty[i],
                    '$' + "{0:.2f}".format(best_val) + '$',
                    ha='center',
                    color='c',
                    transform=sed_ax.transAxes)
    sed_ax.text(tx[0], laby, 'Param', ha='right', transform=sed_ax.transAxes)
    sed_ax.text(tx[1],
                laby,
                '50%$\pm$33%',
                ha='center',
                color='k',
                transform=sed_ax.transAxes)
    sed_ax.text(tx[2],
                laby,
                'Best',
                color='k',
                ha='center',
                transform=sed_ax.transAxes)

    # now draw boxes around the different kinds of parameters
    tax = sed_ax
    left, right = tx[0], tx[-1]

    def draw_box_around_values(start, stop, ls):
        deltaline = ty[start] - ty[start + 1]
        top = ty[start] + deltaline  # Draw the top border ABOVE the text
        bottom = ty[stop]
        rec = Rectangle((left - 0.1, bottom - 0.02),
                        right - left + 0.15,
                        top - bottom + 0.01,
                        fill=False,
                        lw=2,
                        transform=tax.transAxes,
                        ls=ls)
        rec = tax.add_patch(rec)
        rec.set_clip_on(False)

    # primary
    draw_box_around_values(startprim, stopprim, ls='dashed')

    # secondary
    draw_box_around_values(startsec, stopsec, ls='dotted')

    # derived
    draw_box_around_values(startderiv, stopderiv, ls='dashdot')

    # padding for rectangles of 1D PDFs
    pad = 0.1

    # Make these plots:

    # A, M, t, dist,
    # R, fA, Z
    # logT, logg, logL

    # This is done by iterating over the axes created at the start of
    # this function, from left to right, line per line.

    # plot the primary parameter 1D PDFs
    ax_iter = (ax[i] for i in indices_1dpdf)
    first_primary_ax = next(ax_iter)
    plot_1dpdf(first_primary_ax, pdf1d_hdu, 'Av', 'A(V)', starnum, stats=stats)
    plot_1dpdf(next(ax_iter),
               pdf1d_hdu,
               'M_ini',
               'log(M)',
               starnum,
               logx=True,
               stats=stats)
    plot_1dpdf(next(ax_iter),
               pdf1d_hdu,
               'logA',
               'log(t)',
               starnum,
               stats=stats)
    last_primary_ax = next(ax_iter)
    plot_1dpdf(last_primary_ax,
               pdf1d_hdu,
               'distance',
               'distance(pc)',
               starnum,
               stats=stats)

    # plot the secondary parameter 1D PDFs
    first_secondary_ax = next(ax_iter)
    plot_1dpdf(first_secondary_ax,
               pdf1d_hdu,
               'Rv',
               'R(V)',
               starnum,
               stats=stats)
    plot_1dpdf(next(ax_iter),
               pdf1d_hdu,
               'f_A',
               r'f$_\mathcal{A}$',
               starnum,
               stats=stats)
    last_secondary_ax = next(ax_iter)
    plot_1dpdf(last_secondary_ax, pdf1d_hdu, 'Z', 'Z', starnum, stats=stats)

    # plot the derived parameter 1D PDFs
    first_derived_ax = next(ax_iter)
    plot_1dpdf(first_derived_ax,
               pdf1d_hdu,
               'logT',
               r'log(T$_\mathrm{eff})$',
               starnum,
               stats=stats)
    plot_1dpdf(next(ax_iter),
               pdf1d_hdu,
               'logg',
               'log(g)',
               starnum,
               stats=stats)
    last_derived_ax = next(ax_iter)
    plot_1dpdf(last_derived_ax,
               pdf1d_hdu,
               'logL',
               'log(L)',
               starnum,
               stats=stats)

    # A more manual version of tight_layout
    plt.subplots_adjust(top=.95,
                        bottom=.05,
                        left=.125,
                        right=.925,
                        wspace=.5,
                        hspace=.5)

    # PLOT ALL THE BOXES AFTER CALLING TIGHT LAYOUT! Tight layout
    # changes the coordinates of the axes a little, but leaves the boxes
    # untouched. Therefore, we plot the boxes here by extracting the
    # coordinates of the axes after they have been modified by
    # tight_layout.

    def rectangle_around_axes(bottomleft_ax, topright_ax, pad, ls, label=None):
        """
        pad: tuple, (left, right, bottom, top)
        """
        left, bottom = bottomleft_ax.get_position().get_points()[0]
        right, top = topright_ax.get_position().get_points()[1]
        left -= pad[0]
        right += pad[1]
        bottom -= pad[2]
        top += pad[3]
        transf = plt.gcf().transFigure
        rec = Rectangle((left, bottom),
                        right - left,
                        top - bottom,
                        transform=transf,
                        fill=False,
                        lw=2,
                        ls=ls)
        rec = bottomleft_ax.add_patch(rec)
        rec.set_clip_on(False)

        if label:
            middle = (top + bottom) / 2.
            moreleft = left  # pad[0]
            bottomleft_ax.text(moreleft,
                               middle,
                               label,
                               transform=transf,
                               rotation='vertical',
                               fontstyle='oblique',
                               va='center',
                               ha='right')

    rectanglePadding = (0.03, 0.01, 0.03, 0.01)

    # Box around primaries
    tax = first_primary_ax
    rectangle_around_axes(first_primary_ax,
                          last_primary_ax,
                          pad=rectanglePadding,
                          ls='dashed',
                          label='Primary')
    tax.text(0.0,
             0.5,
             'Probability',
             transform=tax.transAxes,
             rotation='vertical',
             va='center',
             ha='right')

    # Box around secondaries
    tax = first_secondary_ax
    rectangle_around_axes(first_secondary_ax,
                          last_secondary_ax,
                          pad=rectanglePadding,
                          ls='dotted',
                          label='Secondary')
    tax.text(0.0,
             0.5,
             'Probability',
             transform=tax.transAxes,
             rotation='vertical',
             va='center',
             ha='right')

    # Box around deriveds
    tax = first_derived_ax
    rectangle_around_axes(first_derived_ax,
                          last_derived_ax,
                          pad=rectanglePadding,
                          ls='dashdot',
                          label='Derived')
    tax.text(0.0,
             0.5,
             'Probability',
             transform=tax.transAxes,
             rotation='vertical',
             va='center',
             ha='right')
Beispiel #3
0
def IAU_names_and_extra_info(obsdata, surveyname="PHAT", extraInfo=False):
    """
    Generates IAU approved names for the data using RA & DEC
    and extra information about the sources (ra, dec, photometry, etc.)

    Parameters
    ----------
    obsdata : class
        observations data
    surveyname : str
        name of survey [default = 'PHAT']
    extraInfo : bool
        set to get the HST specific PHAT software reduced survey information

    Returns
    -------
    r : dict
        A dict with a (name, ndarray) pair
    """
    r = {}

    go_name = False
    if "ra" in list(obsdata.data.keys()):
        go_name = True
        ra_str = "ra"
        dec_str = "dec"

    if "RA" in list(obsdata.data.keys()):
        go_name = True
        ra_str = "RA"
        dec_str = "DEC"

    if go_name:
        # generate the IAU names
        _tnames = []
        for i in range(len(obsdata)):
            c = ap_SkyCoord(
                ra=obsdata.data[ra_str][i] * ap_units.degree,
                dec=obsdata.data[dec_str][i] * ap_units.degree,
                frame="icrs",
            )
            _tnames.append(surveyname + " J" + c.ra.to_string(
                unit=ap_units.hourangle,
                sep="",
                precision=2,
                alwayssign=False,
                pad=True,
            ) + c.dec.to_string(sep="", precision=2, alwayssign=True, pad=True)
                           )
            r["Name"] = _tnames

            # other useful information
            r["RA"] = obsdata.data[ra_str]
            r["DEC"] = obsdata.data[dec_str]
            if extraInfo:
                r["field"] = obsdata.data["field"]
                r["inside_brick"] = obsdata.data["inside_brick"]
                r["inside_chipgap"] = obsdata.data["inside_chipgap"]
    else:
        r["Name"] = ["noname" for x in range(len(obsdata))]

    # include the observed filter fluxes
    for k, filtername in enumerate(obsdata.filters):
        obsfiltname = obsdata.filter_aliases[filtername]
        r[filtername] = (obsdata.data[obsfiltname] *
                         obsdata.vega_flux[k]).astype(float)

    return r
Beispiel #4
0
def IAU_names_and_extra_info(obsdata, surveyname='PHAT',extraInfo=False):
    """
    generates IAU approved names for the data using RA & DEC
      and extra information about the sources (ra, dec, photometry, etc.)

    keywords
    --------
    obsdata: Observations
    surveyname: string
          name of survey [default = 'PHAT']
    extraInfo: bool
          set to get the HST specific PHAT software reduced survey information

    returns
    -------
    r: dict
        returns a dict with a (name, ndarray) pair
    """
    r = {}

    go_name = False
    if 'ra' in list(obsdata.data.keys()):
        go_name = True
        ra_str = 'ra'
        dec_str = 'dec'

    if 'RA' in list(obsdata.data.keys()):
        go_name = True
        ra_str = 'RA'
        dec_str = 'DEC'

    if go_name:
        # generate the IAU names
        _tnames = []
        for i in range(len(obsdata)):
            c = ap_SkyCoord(ra=obsdata.data[ra_str][i]*ap_units.degree,
                            dec=obsdata.data[dec_str][i]*ap_units.degree,
                            frame='icrs')
            _tnames.append(surveyname + ' J' +
                           c.ra.to_string(unit=ap_units.hourangle,
                                          sep="",precision=2,
                                          alwayssign=False,pad=True) +
                           c.dec.to_string(sep="",precision=2,
                                           alwayssign=True,pad=True))
            r['Name'] = _tnames

            # other useful information
            r['RA'] = obsdata.data[ra_str]
            r['DEC'] = obsdata.data[dec_str]
            if extraInfo:
                r['field'] = obsdata.data['field']
                r['inside_brick'] = obsdata.data['inside_brick']
                r['inside_chipgap'] = obsdata.data['inside_chipgap']
    else:
        r['Name'] = ["noname" for x in range(len(obsdata))]

    # include the observed filter fluxes
    for k, filtername in enumerate(obsdata.filters):
        r[filtername] = (obsdata.data[filtername]*
                         obsdata.vega_flux[k]).astype(float)

    return r
Beispiel #5
0
def plot_beast_ifit(filters, waves, stats, pdf1d_hdu):

    # setup the plot grid
    gs = gridspec.GridSpec(4,
                           4,
                           height_ratios=[1.0, 1.0, 1.0, 1.0],
                           width_ratios=[1.0, 1.0, 1.0, 1.0])
    ax = []
    # plots for the 1D PDFs
    for j in range(2):
        for i in range(4):
            ax.append(plt.subplot(gs[j + 2, i]))
    # now for the big SED plot
    ax.append(plt.subplot(gs[0:2, 0:3]))

    # plot the SED
    #print(np.sort(stats.colnames))

    n_filters = len(filters)

    # get the observations
    waves *= 1e-4
    obs_flux = np.empty((n_filters), dtype=np.float)
    mod_flux = np.empty((n_filters, 3), dtype=np.float)
    mod_flux_nd = np.empty((n_filters, 3), dtype=np.float)
    mod_flux_wbias = np.empty((n_filters, 3), dtype=np.float)
    k = starnum

    c = ap_SkyCoord(ra=stats['RA'][k] * ap_units.degree,
                    dec=stats['DEC'][k] * ap_units.degree,
                    frame='icrs')
    corname = ('PHAT J' + c.ra.to_string(unit=ap_units.hourangle,
                                         sep="",
                                         precision=2,
                                         alwayssign=False,
                                         pad=True) +
               c.dec.to_string(sep="", precision=2, alwayssign=True, pad=True))

    for i, cfilter in enumerate(filters):
        obs_flux[i] = stats[cfilter][k]
        mod_flux[i, 0] = np.power(10.0, stats['log' + cfilter + '_wd_p50'][k])
        mod_flux[i, 1] = np.power(10.0, stats['log' + cfilter + '_wd_p16'][k])
        mod_flux[i, 2] = np.power(10.0, stats['log' + cfilter + '_wd_p84'][k])
        mod_flux_nd[i, 0] = np.power(10.0,
                                     stats['log' + cfilter + '_nd_p50'][k])
        mod_flux_nd[i, 1] = np.power(10.0,
                                     stats['log' + cfilter + '_nd_p16'][k])
        mod_flux_nd[i, 2] = np.power(10.0,
                                     stats['log' + cfilter + '_nd_p84'][k])
        if 'log' + cfilter + '_wd_bias_p50' in stats.colnames:
            mod_flux_wbias[i, 0] = np.power(
                10.0, stats['log' + cfilter + '_wd_bias_p50'][k])
            mod_flux_wbias[i, 1] = np.power(
                10.0, stats['log' + cfilter + '_wd_bias_p16'][k])
            mod_flux_wbias[i, 2] = np.power(
                10.0, stats['log' + cfilter + '_wd_bias_p84'][k])

    ax[8].plot(waves, obs_flux, 'ko', label='observed')

    if 'log' + filters[0] + '_wd_bias_p50' in stats.colnames:
        ax[8].plot(waves,
                   mod_flux_wbias[:, 0],
                   'b-',
                   label='stellar+dust+bias')
        ax[8].fill_between(waves,
                           mod_flux_wbias[:, 1],
                           mod_flux_wbias[:, 2],
                           color='b',
                           alpha=0.3)

    ax[8].plot(waves, mod_flux[:, 0], 'r-', label='stellar+dust')
    ax[8].fill_between(waves,
                       mod_flux[:, 1],
                       mod_flux[:, 2],
                       color='r',
                       alpha=0.2)

    ax[8].plot(waves, mod_flux_nd[:, 0], 'y-', label='stellar only')
    ax[8].fill_between(waves,
                       mod_flux_nd[:, 1],
                       mod_flux_nd[:, 2],
                       color='y',
                       alpha=0.1)

    ax[8].legend(loc='upper right', bbox_to_anchor=(1.25, 1.025))

    ax[8].set_ylabel(r'Flux [ergs s$^{-1}$ cm$^{-2}$ $\AA^{-1}$]')
    ax[8].set_yscale('log')

    ax[8].set_xscale('log')
    ax[8].text(0.5,
               -0.01,
               r'$\lambda$ [$\AA$]',
               transform=ax[8].transAxes,
               va='top')
    ax[8].set_xlim(0.2, 2.0)
    ax[8].set_xticks([0.2, 0.3, 0.4, 0.5, 0.8, 0.9, 1.0, 2.0])
    ax[8].get_xaxis().set_major_formatter(matplotlib.ticker.ScalarFormatter())

    ax[8].text(0.05,
               0.95,
               corname,
               transform=ax[8].transAxes,
               va='top',
               ha='left')

    # add the text results
    keys = ['Av', 'M_ini', 'logA', 'Rv', 'f_A', 'Z', 'logT', 'logg', 'logL']
    dispnames = [
        'A(V)', 'log(M)', 'log(t)', 'R(V)', r'f$_\mathcal{A}$', 'Z',
        r'log(T$_\mathrm{eff})$', 'log(g)', 'log(L)'
    ]
    laby = 0.72
    ty = np.linspace(laby - 0.07, 0.1, num=len(keys))
    ty[3:] -= 0.025
    ty[6:] -= 0.025
    tx = [1.12, 1.2, 1.3]
    for i in range(len(keys)):
        ax[8].text(tx[0],
                   ty[i],
                   dispnames[i],
                   ha='right',
                   transform=ax[8].transAxes)
        ax[8].text(tx[1],
                   ty[i],
                   disp_str(stats, starnum, keys[i]),
                   ha='center',
                   color='m',
                   transform=ax[8].transAxes)
        best_val = stats[keys[i] + '_Best'][k]
        if keys[i] == 'M_ini':
            best_val = np.log10(best_val)
        ax[8].text(tx[2],
                   ty[i],
                   '$' + "{0:.2f}".format(best_val) + '$',
                   ha='center',
                   color='c',
                   transform=ax[8].transAxes)
    ax[8].text(tx[0], laby, 'Param', ha='right', transform=ax[8].transAxes)
    ax[8].text(tx[1],
               laby,
               '50%$\pm$33%',
               ha='center',
               color='k',
               transform=ax[8].transAxes)
    ax[8].text(tx[2],
               laby,
               'Best',
               color='k',
               ha='center',
               transform=ax[8].transAxes)

    # now draw boxes around the different kinds of parameters
    tax = ax[8]

    # primary
    rec = Rectangle((tx[0] - 0.1, ty[2] - 0.02),
                    tx[2] - tx[0] + 0.15, (ty[0] - ty[2]) * 1.5,
                    fill=False,
                    lw=2,
                    transform=tax.transAxes,
                    ls='dashed')
    rec = tax.add_patch(rec)
    rec.set_clip_on(False)

    # secondary
    rec = Rectangle((tx[0] - 0.1, ty[5] - 0.02),
                    tx[2] - tx[0] + 0.15, (ty[3] - ty[5]) * 1.5,
                    fill=False,
                    lw=2,
                    transform=tax.transAxes,
                    ls='dotted')
    rec = tax.add_patch(rec)
    rec.set_clip_on(False)

    # derived
    rec = Rectangle((tx[0] - 0.1, ty[8] - 0.02),
                    tx[2] - tx[0] + 0.15, (ty[6] - ty[8]) * 1.5,
                    fill=False,
                    lw=2,
                    transform=tax.transAxes,
                    ls='dashdot')
    rec = tax.add_patch(rec)
    rec.set_clip_on(False)

    # padding for rectangles of 1D PDFs
    pad = 0.1

    # plot the primary parameter 1D PDFs
    plot_1dpdf(ax[0], pdf1d_hdu, 'Av', 'A(V)', starnum, stats=stats)
    plot_1dpdf(ax[1],
               pdf1d_hdu,
               'M_ini',
               'log(M)',
               starnum,
               logx=True,
               stats=stats)
    plot_1dpdf(ax[2], pdf1d_hdu, 'logA', 'log(t)', starnum, stats=stats)

    # draw a box around them and label
    tax = ax[0]
    rec = Rectangle((-1.75 * pad, -pad),
                    3 * (1.0 + pad) + 1.5 * pad,
                    1.0 + 1.5 * pad,
                    fill=False,
                    lw=2,
                    transform=tax.transAxes,
                    ls='dashed')
    rec = tax.add_patch(rec)
    rec.set_clip_on(False)

    tax.text(-2. * pad,
             0.5,
             'Primary',
             transform=tax.transAxes,
             rotation='vertical',
             fontstyle='oblique',
             va='center',
             ha='right')

    tax.text(0.0,
             0.5,
             'Probability',
             transform=tax.transAxes,
             rotation='vertical',
             va='center',
             ha='right')

    # plot the secondary parameter 1D PDFs
    plot_1dpdf(ax[4], pdf1d_hdu, 'Rv', 'R(V)', starnum, stats=stats)
    plot_1dpdf(ax[5],
               pdf1d_hdu,
               'f_A',
               r'f$_\mathcal{A}$',
               starnum,
               stats=stats)
    plot_1dpdf(ax[6], pdf1d_hdu, 'Z', 'Z', starnum, stats=stats)

    # draw a box around them
    tax = ax[4]
    rec = Rectangle((-1.75 * pad, -pad),
                    3 * (1.0 + pad) + 1.5 * pad,
                    1.0 + 1.5 * pad,
                    fill=False,
                    lw=2,
                    transform=tax.transAxes,
                    ls='dotted')
    rec = tax.add_patch(rec)
    rec.set_clip_on(False)

    tax.text(-2 * pad,
             0.5,
             'Secondary',
             transform=tax.transAxes,
             rotation='vertical',
             fontstyle='oblique',
             va='center',
             ha='right')

    tax.text(0.0,
             0.5,
             'Probability',
             transform=tax.transAxes,
             rotation='vertical',
             va='center',
             ha='right')

    # plot the derived parameter 1D PDFs
    plot_1dpdf(ax[3],
               pdf1d_hdu,
               'logT',
               r'log(T$_\mathrm{eff})$',
               starnum,
               stats=stats)
    plot_1dpdf(ax[7], pdf1d_hdu, 'logg', 'log(g)', starnum, stats=stats)

    # draw a box around them
    tax = ax[7]
    rec = Rectangle((-0.25 * pad, -pad),
                    1.0 + 0.5 * pad,
                    2 * (1.0 + 2. * pad) - 0.125 * pad,
                    fill=False,
                    lw=2,
                    transform=tax.transAxes,
                    ls='dashdot')
    rec = tax.add_patch(rec)
    rec.set_clip_on(False)

    tax.text(0.5,
             2 * (1.0 + 2 * pad) - 1.0 * pad,
             'Derived',
             transform=tax.transAxes,
             rotation='horizontal',
             fontstyle='oblique',
             va='bottom',
             ha='center')

    # optimize the figure layout
    plt.tight_layout(h_pad=2.0, w_pad=1.0)