Beispiel #1
0
def plot_korbpost(outpath, truth=None,
                  xlabel='K$_\mathrm{orb}$ [m$\,$s$^{-1}$]'):

    Nobs = [20, 30, 45, 90]

    Korb_d = {}

    from betty.paths import BETTYDIR

    for N in Nobs:
        pklpath = os.path.join(
            BETTYDIR, f'test_HIP67522_rvspotorbit_Nobs{N}.pkl'
        )

        with open(pklpath, 'rb') as f:
            d = pickle.load(f)
            trace = d['trace']

        samples = trace['K_orb']
        Korb_d[N] = samples

    # make plot

    set_style()
    plt.close('all')

    f, ax = plt.subplots(figsize=(4,3))

    for N in Nobs:
        ls = ':' if N in [30, 90] else '-'

        ax.hist(Korb_d[N], bins=np.arange(0,220,20),
                weights=np.ones_like(Korb_d[N])*1/len(Korb_d[N]),
                zorder=-1, histtype='step', alpha=1, ls=ls,
                label='N$_\mathrm{obs}$='+f'{N}')

    from matplotlib.lines import Line2D
    handles, labels = ax.get_legend_handles_labels()
    new_handles = []
    for ix, h in enumerate(handles):
        ls = ':' if ix in [1, 3] else '-'
        new_handles.append(Line2D([], [], c=h.get_edgecolor(), ls=ls))

    ax.legend(loc='best', fontsize='small', handles=new_handles, labels=labels)

    if isinstance(xlabel, str):
        ax.set_xlabel(xlabel)

    if truth is not None:
        ymin, ymax = ax.get_ylim()
        ax.vlines(
            truth, ymin, ymax, colors='k', alpha=0.8,
            linestyles='--', zorder=-2, linewidths=1
        )
        ax.set_ylim((ymin, ymax))

    ax.set_ylabel('Posterior probability')

    savefig(f, outpath, writepdf=0)
Beispiel #2
0
def plot_spec_Prot_hist(Prot_source='M15', spec_source='cks'):
    """
    Prot_source (str): M13 or M15
    spec_source (str): always 'cks', because that's the only vsini source.
        [nb. this is the vsini dataset from J. Winn, received 2 Aug 2020]
    """

    if spec_source != 'cks':
        raise NotImplementedError

    mdf, cdf = _get_spec_vsini_phot_Prot_overlap(Prot_source=Prot_source)
    sel = cdf['id_kic'].isin(arr(mdf['id_kic']))
    scdf = cdf[~sel]

    print(f'{len(cdf)} with vsini')
    print(f'{len(mdf[(~pd.isnull(mdf.spec_Prot)) & (~pd.isnull(mdf.Prot))])} with vsini & M15 prot')
    print(f'{len(scdf)} with vsini & and no M15 prot')

    outdir = join(RESULTSDIR, 'spec_rot')

    set_style()

    f, ax = plt.subplots(figsize=(4,3))

    bins = np.arange(0, 52.5, 2.5)

    N_m = len(mdf)
    N_n = len(scdf)

    ax.hist(scdf.spec_Prot, bins=bins, cumulative=False, fill=False, density=False,
            weights=np.ones(N_n)/N_n,
            histtype='step', label=f'No M15 match ({len(scdf)})')

    ax.hist(mdf.spec_Prot, bins=bins, cumulative=False, fill=False, density=False,
            weights=np.ones(N_m)/N_m,
            histtype='step', label=f'Has M15 match ({len(mdf)})')

    # Create new legend handles but use the colors from the existing ones
    handles, labels = ax.get_legend_handles_labels()
    new_handles = [Line2D([], [], c=h.get_edgecolor()) for h in handles]
    ax.legend(handles=new_handles, labels=labels, fontsize='small')

    txt = (
        r'$\mu_{T_{\mathrm{eff}}} \pm \sigma_{T_{\mathrm{eff}}}$ '+' for P$_{\mathrm{rot}}^{\mathrm{spec}} < 25$ d:\n'
        'No M15: '+f'{int(scdf[scdf.spec_Prot<25].cks_steff.mean())} $\pm$ {int(scdf[scdf.spec_Prot<25].cks_steff.std())}\n'
        'Has M15: '+f'{int(mdf[mdf.spec_Prot<25].VIIs_Teff.mean())} $\pm$ {int(mdf[mdf.spec_Prot<25].VIIs_Teff.std())}\n'
    )
    ax.text(0.95, 0.50, txt,
            transform=ax.transAxes, ha='right', va='center',
            fontsize='small')

    ax.set_ylabel('Fraction per bin')
    ax.set_xlabel('CKS-VII P$_{\mathrm{rot}}^{\mathrm{spec}}$ [day]')

    outpath = join(
        outdir,
        f'spec_Prot_hist_prot{Prot_source}.png'
    )
    savefig(f, outpath, writepdf=0)
Beispiel #3
0
def plot_stsnr_vs_gyroage(Prot_source='M15', gyro_source='A19', cdpp_id='rms3'):
    """
    Prot_source: M13 or M15
    gyro_source: MH08 or A19
    cdpp_id: rms3, rms6, or rms12

    Makes a Berger+2020 style single-transit SNR vs age plot.  The method is
    identical to Berger+2020. CDPP is taken from Christiansen 2012.
    Single-transit SNR is calculated by doing (Rp/R*)^2 * (1/CDPP). This was
    cited as being from Petigura+2018. [.....]
    """
    mdf = get_merged_gyroage_CKS(Prot_source=Prot_source,
                                 gyro_source=gyro_source)
    mdf = _add_Christiansen12_CDPP(mdf)

    Rp = 1*u.Rearth
    Rstar = arr(mdf.VIIs_R)*u.Rsun
    Rp_Rs = (Rp/Rstar).cgs.value
    mdf['stsnr'] = (
        Rp_Rs**2
        *
        (1/arr(1e-6*mdf[cdpp_id]))
    )

    scols = ['gyroage_yr', 'stsnr']
    sdf = mdf[scols]

    outdir = join(
        RESULTSDIR, f'singletransitSNR_{Prot_source}rot_{gyro_source}age'
    )
    if not os.path.exists(outdir):
        os.mkdir(outdir)
    set_style()

    f, ax = plt.subplots(figsize=(4,3))

    ax.scatter(sdf.gyroage_yr, sdf.stsnr, s=2, c='k', zorder=3)

    agelabel = (f'Gyro-Age [{Prot_source} '+'P$_\mathrm{rot}$ +'
                +f'{gyro_source}; yr]')
    ax.set_xlabel(agelabel, fontsize='small')

    ax.set_ylabel(f'Single-transit SNR [C12 CDPP{cdpp_id.replace("rms","")}]',
                  fontsize='small')

    ax.set_xscale('log'); ax.set_yscale('log')

    outpath = join(outdir,
                   f'singletransitsnr_{cdpp_id}_rot{Prot_source}_gyro{gyro_source}.png')
    savefig(f, outpath, writepdf=0)
Beispiel #4
0
def plot_spec_vs_phot_Prot(Prot_source='M15', spec_source='cks'):
    """
    Prot_source (str): M13 or M15
    spec_source (str): always 'cks', because that's the only vsini source.
        [nb. this is the vsini dataset from J. Winn, received 2 Aug 2020]
    """

    if spec_source != 'cks':
        raise NotImplementedError

    mdf, _  = _get_spec_vsini_phot_Prot_overlap(Prot_source=Prot_source)

    outdir = join(RESULTSDIR, 'spec_rot')
    if not os.path.exists(outdir):
        os.mkdir(outdir)

    set_style()

    f, ax = plt.subplots(figsize=(4,3))
    ax.scatter(mdf.Prot, mdf.spec_Prot, s=2, c='k', zorder=3)
    _, xmax = ax.get_xlim()
    span = np.linspace(2, xmax, 100)
    ax.plot(span, span, zorder=-1, lw=1, ls='--', c='lightgray',
            label='$i=90^\circ$')
    ax.plot(span, span/np.sin(np.deg2rad(45)), zorder=-1, lw=1, ls=':', c='lightgray',
            label='$i=45^\circ$')
    ax.legend(fontsize='small')
    ax.set_xscale('log'); ax.set_yscale('log')
    ax.set_xlabel(f'{Prot_source} phot '+'P$_\mathrm{rot}$ [day]')
    ax.set_ylabel(f'CKS-VII spec '+'P$_\mathrm{rot}$ [day]')
    outpath = join(outdir, f'cks-VII_specrot_vs_{Prot_source}_prot.png')
    savefig(f, outpath, writepdf=0)

    sel = (mdf.Prot < 10)
    sdf = mdf[sel]
    sdf['specProt/photProt'] = sdf.spec_Prot/sdf.Prot
    sdf = sdf.sort_values(by='specProt/photProt', ascending=False)
    selcols = ['VIIp_KOI', 'Prot', 'spec_Prot']
    print(sdf[selcols][:20].to_string(index=False))
Beispiel #5
0
def plot_rp_vs_insol_scatter(active_targets=1, specialyoung=1, show_legend=1):

    set_style()

    #
    # columns described at
    # https://exoplanetarchive.ipac.caltech.edu/docs/API_exoplanet_columns.html
    #
    ea_tab = NasaExoplanetArchive.query_criteria(
        table="exoplanets", select="*", cache=True
    )

    #
    # get systems with finite ages (has a value, and +/- error bar)
    #
    has_age_value = ~ea_tab['st_age'].mask
    has_age_errs  = (~ea_tab['st_ageerr1'].mask) & (~ea_tab['st_ageerr2'].mask)
    has_rp_value = ~ea_tab['pl_rade'].mask
    has_rp_errs  = (~ea_tab['pl_radeerr1'].mask) & (~ea_tab['pl_radeerr2'].mask)
    rp_gt_0 = (ea_tab['pl_rade'] > 0)

    transits = (ea_tab['pl_tranflag']==1)

    sel = (
        has_age_value & has_age_errs & has_rp_value & has_rp_errs & transits &
        rp_gt_0
    )

    t = ea_tab[sel]
    tyoung = t[(t['st_age'] < 0.1*u.Gyr) & (t['st_age'] > 0*u.Gyr)]

    #
    # read params
    #
    age = t['st_age']
    age_perr = t['st_ageerr1']
    age_merr = np.abs(t['st_ageerr2'])
    age_errs = np.array([age_perr, age_merr]).reshape(2, len(age))

    rp = t['pl_rade']
    rp_perr = t['pl_radeerr1']
    rp_merr = t['pl_radeerr2']
    rp_errs = np.array([rp_perr, rp_merr]).reshape(2, len(age))
    # rp /= 11.2089 # used jupiter radii

    insol = t['pl_insol']

    #
    # plot age vs rp. (age is on y axis b/c it has the error bars, and I at
    # least skimmed the footnotes of Hogg 2010)
    #
    fig,ax = plt.subplots(figsize=(4,3))

    label = (
        'Exoplanet Archive'
    )
    print(f'Mean age unc: {np.mean(age_errs):.2f} Gyr')
    print(f'Median age unc: {np.median(age_errs):.2f} Gyr')


    ax.scatter(insol, rp, color='darkgray', s=3, zorder=1, marker='o',
               linewidth=0, label=label, alpha=1)

    #
    # targets
    #
    target_age = (np.array([3.5e7])*u.yr).to(u.Gyr)
    target_rp = (np.array([0.82])*u.Rjup).to(u.Rearth)
    target_rp_unc = (np.array([0.03, 0.09])*u.Rjup).to(u.Rearth)[:,None]
    target_period = (np.array([8.3])*u.day)

    from astropy import constants as const
    Teff = 6047*u.K
    Lstar = 4*np.pi*(1.022*u.Rsun)**2 * (const.sigma_sb * Teff**4)
    target_insol = (
        ( Lstar/(1*u.Lsun) ).cgs *
        ((( 17.54*1.022*u.Rsun )/(1*u.AU)).cgs)**(-2)
    )
    # insol/insolEarth = (L*/Lsun) * (AU/a)^2

    if active_targets:

        label = (
            'TOI$\,$837'
        )

        ax.plot(target_insol, target_rp, mew=0.5, markerfacecolor='yellow',
                markersize=15, marker='*', color='k', lw=0, label=label,
                zorder=10)

    if specialyoung:

        youngnames = tyoung['pl_hostname']

        markertypes= ['o', 'v', 'X', 's', 'P', 'd']
        zorders= [9, 8, 7, 6, 5, 4]

        for ix, y, z in zip(range(len(zorders)), np.unique(youngnames), zorders):

            s = (tyoung['pl_hostname'] == y)

            ax.plot(tyoung[s]['pl_orbper'], tyoung[s]['pl_rade'], mew=0.5,
                    markerfacecolor='white', markersize=7,
                    marker=markertypes[ix], color='k', lw=0, label=y,
                    zorder=z)

        # two extra systems...
        N_uniq = len(np.unique(youngnames))

        insol_67522 = (1.74) * (( (11.73*1.38*u.Rsun) / (1*u.AU) ).cgs)**(-2)

        ax.plot(insol_67522, 10.02, mew=0.5, markerfacecolor='white',
                markersize=7, marker=markertypes[N_uniq], color='k', lw=0,
                label='HIP 67522', zorder=2)

        # HD 63433 (TOI 1726, TIC 130181866) omitted -- 400 Myr is old!





    # flip default legend order
    if show_legend:
        handles, labels = ax.get_legend_handles_labels()
        leg = ax.legend(handles[::-1], labels[::-1], loc='upper right',
                        borderpad=0.3, handletextpad=0.5, fontsize=6,
                        framealpha=0)

        leg.get_frame().set_linewidth(0.5)

    ax.set_xlabel('Planet insolation [Earth flux]')
    ax.set_ylabel('Planet size [Earth radii]')

    #ax.set_xlim(list(ax.get_xlim())[::-1])
    ax.set_xlim([1e5, 0.1])

    format_ax(ax)

    # ax.set_ylim([0.13, 85])
    # ax.set_yscale('log')

    ax.set_xscale('log')
    # ax.tick_params(top=True, bottom=True, left=True, right=True, which='both')

    # ax.yaxis.set_major_formatter(StrMethodFormatter('{x:.2g}'))


    savstr = '_no_overplot' if not active_targets else '_toi837'
    if show_legend:
        savstr += '_yeslegend'
    else:
        savstr += '_nolegend'

    outpath = (
        '../results/rp_vs_insol_scatter/rp_vs_insol_scatter_{}{}.png'.
        format(today_YYYYMMDD(), savstr)
    )

    savefig(fig, outpath, writepdf=1, dpi=400)
Beispiel #6
0
telfmts_default['harps'] = telfmts_default['h']
telfmts_default['LICK'] = telfmts_default['l']
telfmts_default['HIRES_RJ'] = telfmts_default['j']
telfmts_default['HIRES'] = telfmts_default['j']
telfmts_default['HIRES_RK'] = telfmts_default['k']
telfmts_default['APF'] = telfmts_default['a']
telfmts_default['HARPS'] = telfmts_default['h']
telfmts_default['HARPS-N'] = telfmts_default['harps-n']
telfmts_default['PFS'] = telfmts_default['pfs']

cmap = nipy_spectral
default_colors = [
    'orange', 'purple', 'magenta', 'pink', 'green', 'grey', 'red'
]
from aesthetic.plot import set_style
set_style()

highlight_format = dict(marker='o',
                        ms=16,
                        mfc='none',
                        mew=2,
                        mec='gold',
                        zorder=99)

if not emcee.__version__ == "2.2.1":
    raise AssertionError('radvel requires emcee v2')


class args_object(object):
    """
    a minimal version of the "parser" object that lets you work with the
def plot_mass_vs_period_scatter(active_targets=1,
                                specialyoung=1,
                                show_legend=1):

    set_style()

    #
    # columns described at
    # https://exoplanetarchive.ipac.caltech.edu/docs/API_exoplanet_columns.html
    #
    ea_tab = NasaExoplanetArchive.query_criteria(table="exoplanets",
                                                 select="*",
                                                 cache=True)

    #
    # get systems with finite ages (has a value, and +/- error bar)
    #
    has_age_value = ~ea_tab['st_age'].mask
    has_age_errs = (~ea_tab['st_ageerr1'].mask) & (~ea_tab['st_ageerr2'].mask)
    has_rp_value = ~ea_tab['pl_rade'].mask
    has_rp_errs = (~ea_tab['pl_radeerr1'].mask) & (~ea_tab['pl_radeerr2'].mask)
    has_mp_value = ~ea_tab['pl_massj'].mask
    has_mp_errs = (~ea_tab['pl_massjerr1'].mask) & (
        ~ea_tab['pl_massjerr2'].mask)
    rp_gt_0 = (ea_tab['pl_rade'] > 0)
    mp_gt_0 = (ea_tab['pl_massj'] > 0)

    transits = (ea_tab['pl_tranflag'] == 1)

    sel = (
        has_age_value & has_age_errs & has_mp_value & mp_gt_0
        # has_rp_value & has_rp_errs & transits & rp_gt_0
    )

    t = ea_tab[sel]
    tyoung = t[(t['st_age'] < 0.1 * u.Gyr) & (t['st_age'] > 0 * u.Gyr)]

    #
    # read params
    #
    age = t['st_age']
    age_perr = t['st_ageerr1']
    age_merr = np.abs(t['st_ageerr2'])
    age_errs = np.array([age_perr, age_merr]).reshape(2, len(age))

    mp = t['pl_massj']
    # rp /= 11.2089 # used jupiter radii

    period = t['pl_orbper']

    #
    # plot age vs rp. (age is on y axis b/c it has the error bars, and I at
    # least skimmed the footnotes of Hogg 2010)
    #
    fig, ax = plt.subplots(figsize=(4, 3))

    label = ('Exoplanet Archive')
    print(f'Mean age unc: {np.mean(age_errs):.2f} Gyr')
    print(f'Median age unc: {np.median(age_errs):.2f} Gyr')

    ax.scatter(period,
               mp,
               color='darkgray',
               s=3,
               zorder=1,
               marker='o',
               linewidth=0,
               label=label,
               alpha=1)

    #
    # targets
    #
    target_age = (np.array([3.5e7]) * u.yr).to(u.Gyr)
    target_rp = (np.array([0.77]) * u.Rjup).to(u.Rearth)
    target_rp_unc = (np.array([0.07, 0.09]) * u.Rjup).to(u.Rearth)[:, None]
    target_period = (np.array([8.3]) * u.day)

    if active_targets:

        raise NotImplementedError('uber young planets dont have masses!')

        label = ('TOI$\,$837')

        ax.plot(target_period,
                target_rp,
                mew=0.5,
                markerfacecolor='yellow',
                markersize=15,
                marker='*',
                color='k',
                lw=0,
                label=label,
                zorder=10)

    if specialyoung:

        youngnames = tyoung['pl_hostname']

        markertypes = ['o', 'v', 'X', 's', 'P', 'd']
        zorders = [9, 8, 7, 6, 5, 4]

        for ix, y, z in zip(range(len(zorders)), np.unique(youngnames),
                            zorders):

            s = (tyoung['pl_hostname'] == y)

            ax.plot(tyoung[s]['pl_orbper'],
                    tyoung[s]['pl_rade'],
                    mew=0.5,
                    markerfacecolor='white',
                    markersize=7,
                    marker=markertypes[ix],
                    color='k',
                    lw=0,
                    label=y,
                    zorder=z)

        # two extra systems...
        N_uniq = len(np.unique(youngnames))

        ax.plot(6.9596,
                10.02,
                mew=0.5,
                markerfacecolor='white',
                markersize=7,
                marker=markertypes[N_uniq],
                color='k',
                lw=0,
                label='HIP 67522',
                zorder=2)

        # HD 63433 (TOI 1726, TIC 130181866) omitted -- 400 Myr is old!

    # flip default legend order
    if show_legend:
        handles, labels = ax.get_legend_handles_labels()
        leg = ax.legend(handles[::-1],
                        labels[::-1],
                        loc='upper right',
                        borderpad=0.3,
                        handletextpad=0.5,
                        fontsize=6,
                        framealpha=0)

        leg.get_frame().set_linewidth(0.5)

    ax.set_xlabel('Orbital period [days]')
    ax.set_ylabel('Planet mass [Jupiter masses]')

    ax.set_xlim([0.1, 1100])
    ax.set_ylim([0.001, 100])
    format_ax(ax)

    # ax.set_ylim([0.13, 85])
    ax.set_yscale('log')

    ax.set_xscale('log')
    # ax.tick_params(top=True, bottom=True, left=True, right=True, which='both')

    # ax.yaxis.set_major_formatter(StrMethodFormatter('{x:.2g}'))

    savstr = '_no_overplot' if not active_targets else '_toi837'
    if show_legend:
        savstr += '_yeslegend'
    else:
        savstr += '_nolegend'

    outpath = (
        '../results/mass_vs_period_scatter/mass_vs_period_scatter_{}{}.png'.
        format(today_YYYYMMDD(), savstr))

    savefig(fig, outpath, writepdf=1, dpi=400)
Beispiel #8
0
def plot_S21_prot_vs_teff(koiflag, ylim=None):
    # koiflag: 0 is confirmed.  1 is candidate.

    set_style()

    outdir = join(RESULTSDIR, f'S21_prot_vs_teff')
    if not os.path.exists(outdir):
        os.mkdir(outdir)

    Prot_source = 'S21'
    df = _get_Santos21_data()

    sel = np.zeros(len(df)).astype(bool)
    for f in koiflag:
        sel |= (df.flag4 == f)
    df = df[sel]

    reference_clusters = ['Pleiades', 'Praesepe']
    for scale in ['linear','log']:
        plt.close('all')
        f, ax = plt.subplots(figsize=(4,3))
        ax.scatter(df.Teff, df.Prot, s=2, c='k',
                   label=f'{Prot_source}', zorder=10)
        for ix, c in enumerate(reference_clusters):
            cdf = _get_Curtis20_data(c.lower())

            # data
            ax.scatter(cdf.Teff, cdf.Prot, s=1, c=f'C{ix}', label=c)

            # interpolated model
            InterpModel = (
                PleiadesInterpModel if c == 'Pleiades' else PraesepeInterpModel
            )
            _teff = np.linspace(4500, 6400, 300)
            _prot = InterpModel(_teff)
            ax.plot(_teff, _prot, lw=1, c=f'C{ix}')

        ax.legend(fontsize='x-small', loc='best')
        ax.set_xlabel('T$_\mathrm{eff}$ [K]')
        ax.set_ylabel(f'{Prot_source} '+'P$_\mathrm{rot}$ [day]')
        ax.set_xlim(ax.get_xlim()[::-1])
        ax.set_xlim([7000,4000])
        if isinstance(ylim, list):
            ax.set_ylim(ylim)
        ax.set_xscale('linear'); ax.set_yscale(scale)

        if koiflag == [0]:
            titlestr = 'Confirmed KOIs only'
        elif koiflag == [0,1]:
            titlestr = 'Confirmed + candidate KOIs'
        ax.set_title(titlestr)

        kstr = '_'.join(np.array(koiflag).astype(str))
        s = ''
        if isinstance(ylim, list):
            s += 'ylim'+'_'.join(np.array(ylim).astype(str))

        outpath = join(
            outdir, f'teff_vs_{Prot_source}_prot_{scale}_koiflag{kstr}{s}.png'
        )
        savefig(f, outpath, writepdf=0)

        #
        # print any KOIs below the cutoffs
        #
        sel = (df.Teff > 4500) & (df.Teff < 6400)
        sdf = df[sel]
        pleiades_model_prot = PleiadesInterpModel(sdf.Teff)
        praesepe_model_prot = PraesepeInterpModel(sdf.Teff)

        below_Pleiades = (sdf.Prot < pleiades_model_prot)
        below_Praesepe = (sdf.Prot < praesepe_model_prot)

        PRINT = 0
        if scale == 'linear' and isinstance(ylim, list):
            PRINT = 1

        if PRINT:
            print(42*'-')
            print(f'Below Pleaides, KOI flags {kstr}. N={len(sdf[below_Pleiades])}')
            print(sdf[below_Pleiades].sort_values(by='Prot'))
            print(11*'#')
            print(f'Below Praesepe, KOI flags {kstr}. N={len(sdf[below_Praesepe])}')
            print(sdf[below_Praesepe].sort_values(by='Prot'))
            print(42*'-')

        sdf['is_below_Praesepe'] = below_Praesepe.astype(int)
        sdf['is_below_Pleiades'] = below_Pleiades.astype(int)

        outcsvpath = join(
            DATADIR,
            f'Santos21_koiflag{kstr}_below_Praesepe_in_Prot_Teff_Teff_btwn_4500_6400.csv'
        )
        if not os.path.exists(outcsvpath):
            outdf = sdf[below_Praesepe].sort_values(by='Prot')
            outdf.to_csv(outcsvpath, index=False)
            print(f"Made {outcsvpath}")
        else:
            print(f"Found {outcsvpath} and did not overwrite.")
Beispiel #9
0
def plot_dilution_histogram(ap=None):
    '''
    Make the plot of log10(dilution [2px aperture]) vs log10(distance [pc]) for
    T<16 mag, d<2kpc cluster members.
    '''

    df = pd.read_csv('../../data/cg18_cdips_table1_subset_with_dilution.csv')

    sel = (df.parallax > 0.5) & (df.Tmag_pred < 16)  # d < 2kpc, T<16
    df = df[sel]

    dil_n_px = np.array(df['dilution_ap{:.2f}'.format(ap)])  # y
    dil_n_px[dil_n_px > 0.999] = 0.999

    set_style()
    plt.close('all')
    fig, ax = plt.subplots(figsize=(3, 3))

    ax.set_xscale('log')
    ax.set_xlabel('(Target flux)/(Total flux in aperture)'.format(ap))
    ax.set_ylabel('Relative probability')

    ax.set_xlim((10**(-2.05), 1.1))
    ax.tick_params(which='both', direction='in', zorder=0)

    xmin, xmax = 10**(-3), 10**1

    log_dil_n_px_bins = np.linspace(np.log10(xmin), np.log10(xmax), 17)

    x = 10**log_dil_n_px_bins
    y = np.histogram(np.log10(dil_n_px), log_dil_n_px_bins)[0]
    x = np.array(list(zip(x[:-1], x[1:]))).flatten()
    y = np.array(list(zip(y, y))).flatten()
    ax.plot(x, y, lw=1, color='black')
    inds = (x <= 0.1)
    ax.fill_between(x[inds],
                    y[inds],
                    np.zeros_like(y[inds]),
                    facecolor='none',
                    hatch='/',
                    edgecolor='gray',
                    lw=0)

    frac_not_ok = np.sum(y[inds]) / np.sum(y)
    nonrecov_str = r'$\approx$' + '{:d}%\ntoo crowded'.format(
        int(100 * frac_not_ok))
    recov_str = r'$\approx$' + '{:d}%\nrecoverable'.format(
        int(round(100 * (1 - frac_not_ok))))

    t = ax.text(10**(-0.5),
                11500,
                recov_str,
                verticalalignment='center',
                horizontalalignment='center',
                fontsize='medium')
    t.set_bbox(dict(facecolor='white', alpha=1, edgecolor='gray'))
    t = ax.text(10**(-1.5),
                11500,
                nonrecov_str,
                verticalalignment='center',
                horizontalalignment='center',
                fontsize='medium')
    t.set_bbox(dict(facecolor='white', alpha=1, edgecolor='gray'))

    #ax.set_xticklabels([])
    ax.set_yticklabels([])
    ax.yaxis.set_major_locator(plt.MaxNLocator(5))

    format_ax(ax)
    # ax.yaxis.set_ticks_position('both')
    # ax.xaxis.set_ticks_position('both')
    # ax.get_yaxis().set_tick_params(which='both', direction='in')
    # ax.get_xaxis().set_tick_params(which='both', direction='in')
    # ax.xaxis.set_tick_params(labelsize='small')
    # ax.yaxis.set_tick_params(labelsize='small')

    # ax.tick_params(which='both', direction='in', zorder=0)
    # ax.spines['right'].set_visible(False)
    # ax.spines['top'].set_visible(False)

    ax.set_ylim((0, max(ax.get_ylim())))

    outname = ('../../results/dilution_histogram/'
               'dil_Tmaglt16_dlt2kpc_cg18_ap{:.2f}px.png'.format(ap))

    savefig(fig, outname)
Beispiel #10
0
def plot_cks_rp_vs_prot(Prot_source='M15'):
    """
    Prot_source: M13 or M15

    Make scatter plots of {plantet radius, orbital period} against
    rotation periods in a few different projections.
    """

    mdf, fp18_df = get_merged_rot_CKS(Prot_source=Prot_source)
    Prot_key = 'Prot' if Prot_source in ['M13','M15','S21'] else 'spec_Prot'

    set_style()

    outdir = join(RESULTSDIR, f'cks_{Prot_source}_rotation_period')
    if not os.path.exists(outdir):
        os.mkdir(outdir)

    for scale in ['linear','log']:
        f, ax = plt.subplots(figsize=(4,3))
        ax.scatter(mdf.VIIp_Rp, mdf[Prot_key], s=2, c='k', zorder=3)
        ax.set_xlabel('CKS-VII R$_\mathrm{p}$ [R$_\oplus$]')
        ax.set_ylabel(f'{Prot_source} '+'P$_\mathrm{rot}$ [day]')
        ax.set_xscale(scale); ax.set_yscale(scale)
        outpath = join(outdir, f'cks-VII_rp_vs_{Prot_source}_prot_{scale}.png')
        savefig(f, outpath, writepdf=0)

    for scale in ['linear','log']:
        plt.close('all')
        f, ax = plt.subplots(figsize=(4,3))
        ax.scatter(mdf.VIIs_Teff, mdf[Prot_key], s=2, c='k',
                   label=f'CKS-VII $\otimes$ {Prot_source}', zorder=10)
        for ix, c in enumerate(['Pleiades', 'Praesepe']):
            cdf = _get_Curtis20_data(c.lower())
            ax.scatter(cdf.Teff, cdf.Prot, s=1, c=f'C{ix}', label=c)
        ax.legend(fontsize='x-small', loc='best')
        ax.set_xlabel('CKS-VII T$_\mathrm{eff}$ [K]')
        ax.set_ylabel(f'{Prot_source} '+'P$_\mathrm{rot}$ [day]')
        ax.set_xlim(ax.get_xlim()[::-1])
        ax.set_xlim([7000,4000])
        ax.set_xscale('linear'); ax.set_yscale(scale)
        outpath = join(outdir, f'cks-VII_teff_vs_{Prot_source}_prot_{scale}.png')
        savefig(f, outpath, writepdf=0)

    plt.close('all')
    f, ax = plt.subplots(figsize=(4,3))
    ax.scatter(mdf.VIIp_Per, mdf[Prot_key], s=2, c='k')
    ax.set_xlabel('CKS-VII P$_\mathrm{orb}$ [day]')
    ax.set_ylabel(f'{Prot_source} '+'P$_\mathrm{rot}$ [day]')
    ax.set_xscale('log'); ax.set_yscale('log')
    outpath = join(outdir, f'cks-VII_period_vs_{Prot_source}_prot.png')
    savefig(f, outpath, writepdf=0)

    plt.close('all')
    f, ax = plt.subplots(figsize=(4,3))
    sel = ~pd.isnull(mdf[Prot_key])
    N_withProt = len(mdf[sel])
    N_noProt = len(fp18_df) - N_withProt
    ax.scatter(mdf[sel].VIIp_Per, mdf[sel].VIIp_Rp, s=1.5, c='k', zorder=3,
               label=f'Yes {Prot_source} '+'P$_\mathrm{rot}$ '+f'({N_withProt})')
    ax.scatter(fp18_df.VIIp_Per, fp18_df.VIIp_Rp, s=1.5, c='darkgray', zorder=2,
               label=f'No {Prot_source} '+'P$_\mathrm{rot}$ '+f'({N_noProt})')
    ax.legend(fontsize='small')
    ax.set_xlabel('CKS-VII P$_\mathrm{orb}$ [day]')
    ax.set_ylabel('CKS-VII R$_\mathrm{p}$ [R$_\oplus$]')
    ax.set_xscale('log'); ax.set_yscale('log')
    outpath = join(outdir, f'cks-VII_period_vs_cks-VII_prad_{Prot_source}_match.png')
    savefig(f, outpath, writepdf=0)

    plt.close('all')
    f, ax = plt.subplots(figsize=(4,3))
    sel = ~pd.isnull(mdf[Prot_key])
    N_withProt = len(mdf[sel])
    N_noProt = len(fp18_df) - N_withProt

    hasrot = (fp18_df['VIIp_SimbadName'].isin(mdf[sel]['VIIp_SimbadName']))
    norot = ~hasrot

    ax.scatter(fp18_df[hasrot].VIIp_Per, fp18_df[hasrot].VIIp_Rp, s=1.5, c='darkgray',
               zorder=2,
               label=f'Yes {Prot_source} '+'P$_\mathrm{rot}$ '+f'({N_withProt})')
    ax.scatter(fp18_df[norot].VIIp_Per, fp18_df[norot].VIIp_Rp, s=1.5, c='k',
               zorder=3,
               label=f'No {Prot_source} '+'P$_\mathrm{rot}$ '+f'({N_noProt})')
    ax.legend(fontsize='small')
    ax.set_xlabel('CKS-VII P$_\mathrm{orb}$ [day]')
    ax.set_ylabel('CKS-VII R$_\mathrm{p}$ [R$_\oplus$]')
    ax.set_xscale('log'); ax.set_yscale('log')
    outpath = join(
        outdir,
        f'cks-VII_period_vs_cks-VII_prad_{Prot_source}_match_inverted.png'
    )
    savefig(f, outpath, writepdf=0)

    plt.close('all')
    f, ax = plt.subplots(figsize=(4.3,3))
    sel = ~pd.isnull(mdf[Prot_key])
    N_withProt = len(mdf[sel])
    N_noProt = len(fp18_df) - N_withProt

    l = f'Yes {Prot_source}'+' P$_\mathrm{rot}$ '+f'({N_withProt})'
    norm = mpl.colors.Normalize(vmin=5, vmax=25)
    cax = ax.scatter(mdf[sel].VIIp_Per, mdf[sel].VIIp_Rp, s=7,
                     c=mdf[sel][Prot_key],
                     cmap='plasma_r', zorder=3, label=l, norm=norm,
                     edgecolors='k', linewidths=0.2)

    ax.set_xlabel('CKS-VII P$_\mathrm{orb}$ [day]')
    ax.set_ylabel('CKS-VII R$_\mathrm{p}$ [R$_\oplus$]')
    ax.set_xscale('log'); ax.set_yscale('log')

    cbar = f.colorbar(cax, extend='both')
    cbar.set_label(f'{Prot_source}'+' P$_\mathrm{rot}$ [day]')
    cbar.minorticks_off()

    outpath = join(outdir, f'cks-VII_period_vs_cks-VII_prad_{Prot_source}-Protcolors.png')
    savefig(f, outpath, writepdf=0)
Beispiel #11
0
def plot_TIC268_nbhd_small(outdir=RESULTSDIR):

    set_style()

    df = get_cdips_catalog(ver=0.4)

    kc19_sel = ((df.cluster.str.contains('NGC_2516')) &
                (df.reference.str.contains('Kounkel_2019')))
    cg18_sel = ((df.cluster.str.contains('NGC_2516')) &
                (df.reference.str.contains('CantatGaudin_2018')))

    target_df = df[df.source_id == 5489726768531119616]  # TIC 2683...
    kc19_df = df[kc19_sel]
    cg18_df = df[cg18_sel]

    kc19_df = kc19_df[~(kc19_df.source_id.isin(cg18_df.source_id))]

    ##########

    # NGC 2516 rough
    bounds = {
        'parallax_lower': 1.5,
        'parallax_upper': 4.0,
        'ra_lower': 108,
        'ra_upper': 132,
        'dec_lower': -76,
        'dec_upper': -45
    }
    groupname = 'customngc2516'

    nbhd_df = query_neighborhood(bounds,
                                 groupname,
                                 n_max=6000,
                                 overwrite=False,
                                 manual_gmag_limit=17)

    sel_nbhd = ((~nbhd_df.source_id.isin(kc19_df.source_id))
                & (~nbhd_df.source_id.isin(cg18_df.source_id)))
    from copy import deepcopy
    orig_nbhd_df = deepcopy(nbhd_df)
    nbhd_df = nbhd_df[sel_nbhd]

    print(f'Got {len(nbhd_df)} neighbors')
    print(f'Got {len(cg18_df)} in core')
    print(f'Got {len(kc19_df)} in corona')

    ##########

    plt.close('all')

    f, axs = plt.subplots(figsize=(4, 3), ncols=2)

    xv, yv = 'ra', 'dec'
    axs[0].scatter(nbhd_df[xv],
                   nbhd_df[yv],
                   c='gray',
                   alpha=0.5,
                   zorder=2,
                   s=7,
                   rasterized=True,
                   linewidths=0,
                   label='Field',
                   marker='.')
    axs[0].scatter(kc19_df[xv],
                   kc19_df[yv],
                   c='lightskyblue',
                   alpha=0.9,
                   zorder=3,
                   s=7,
                   rasterized=True,
                   linewidths=0.15,
                   label='Corona',
                   marker='.',
                   edgecolors='k')
    axs[0].scatter(cg18_df[xv],
                   cg18_df[yv],
                   c='k',
                   alpha=0.9,
                   zorder=4,
                   s=7,
                   rasterized=True,
                   label='Core',
                   marker='.')
    axs[0].plot(target_df[xv],
                target_df[yv],
                alpha=1,
                mew=0.5,
                zorder=8,
                label='TOI 1937',
                markerfacecolor='lightskyblue',
                markersize=14,
                marker='*',
                color='black',
                lw=0)

    axs[0].set_xlabel(r'$\alpha$ [deg]')
    axs[0].set_ylabel(r'$\delta$ [deg]')
    axs[0].set_xlim([108, 132])
    axs[0].set_ylim([-76, -45])

    ##########

    get_yval = (lambda _df: np.array(_df['phot_g_mean_mag'] + 5 * np.log10(_df[
        'parallax'] / 1e3) + 5))
    get_xval = (lambda _df: np.array(_df['phot_bp_mean_mag'] - _df[
        'phot_rp_mean_mag']))

    axs[1].scatter(get_xval(nbhd_df),
                   get_yval(nbhd_df),
                   c='gray',
                   alpha=0.8,
                   zorder=2,
                   s=7,
                   rasterized=True,
                   linewidths=0,
                   label='Field',
                   marker='.')
    axs[1].scatter(get_xval(kc19_df),
                   get_yval(kc19_df),
                   c='lightskyblue',
                   alpha=1,
                   zorder=3,
                   s=7,
                   rasterized=True,
                   linewidths=0.15,
                   label='Corona',
                   marker='.',
                   edgecolors='k')
    axs[1].scatter(get_xval(cg18_df),
                   get_yval(cg18_df),
                   c='k',
                   alpha=0.9,
                   zorder=4,
                   s=7,
                   rasterized=True,
                   linewidths=0,
                   label='Core',
                   marker='.')
    axs[1].plot(get_xval(target_df),
                get_yval(target_df),
                alpha=1,
                mew=0.5,
                zorder=8,
                label='TOI 1937',
                markerfacecolor='lightskyblue',
                markersize=14,
                marker='*',
                color='black',
                lw=0)

    axs[1].set_ylim(axs[1].get_ylim()[::-1])

    axs[1].set_xlabel('Bp - Rp [mag]')
    axs[1].set_ylabel('Absolute G [mag]', labelpad=-6)

    ##########

    words = ['Field', 'Corona', 'Core', 'TOI1937'][::-1]
    colors = ['gray', 'lightskyblue', 'k', 'lightskyblue'][::-1]
    rainbow_text(0.98, 0.02, words, colors, size='medium', ax=axs[0])

    f.tight_layout(w_pad=2)

    outpath = os.path.join(outdir, 'small_ngc2516.png')
    savefig(f, outpath)
def plot_rp_vs_period_scatter(active_targets=1,
                              specialyoung=1,
                              show_legend=1,
                              showcandidates=0,
                              deemph837=0):

    set_style()

    #
    # columns described at
    # https://exoplanetarchive.ipac.caltech.edu/docs/API_exoplanet_columns.html
    #
    ea_tab = NasaExoplanetArchive.query_criteria(table="exoplanets",
                                                 select="*",
                                                 cache=True)

    #
    # get systems with finite ages (has a value, and +/- error bar)
    #
    has_age_value = ~ea_tab['st_age'].mask
    has_age_errs = (~ea_tab['st_ageerr1'].mask) & (~ea_tab['st_ageerr2'].mask)
    has_rp_value = ~ea_tab['pl_rade'].mask
    has_rp_errs = (~ea_tab['pl_radeerr1'].mask) & (~ea_tab['pl_radeerr2'].mask)
    rp_gt_0 = (ea_tab['pl_rade'] > 0)

    transits = (ea_tab['pl_tranflag'] == 1)

    sel = (has_age_value & has_age_errs & has_rp_value & has_rp_errs & transits
           & rp_gt_0)

    t = ea_tab[sel]
    tyoung = t[(t['st_age'] < 0.1 * u.Gyr) & (t['st_age'] > 0 * u.Gyr)]

    #
    # read params
    #
    age = t['st_age']
    age_perr = t['st_ageerr1']
    age_merr = np.abs(t['st_ageerr2'])
    age_errs = np.array([age_perr, age_merr]).reshape(2, len(age))

    rp = t['pl_rade']
    rp_perr = t['pl_radeerr1']
    rp_merr = t['pl_radeerr2']
    rp_errs = np.array([rp_perr, rp_merr]).reshape(2, len(age))
    # rp /= 11.2089 # used jupiter radii

    period = t['pl_orbper']

    #
    # plot age vs rp. (age is on y axis b/c it has the error bars, and I at
    # least skimmed the footnotes of Hogg 2010)
    #
    fig, ax = plt.subplots(figsize=(4, 3))

    label = ('Exoplanet Archive')
    print(f'Mean age unc: {np.mean(age_errs):.2f} Gyr')
    print(f'Median age unc: {np.median(age_errs):.2f} Gyr')

    ax.scatter(period,
               rp,
               color='darkgray',
               s=3,
               zorder=1,
               marker='o',
               linewidth=0,
               label=label,
               alpha=1)

    #
    # targets
    #
    target_age = (np.array([3.5e7]) * u.yr).to(u.Gyr)
    target_rp = (np.array([0.77]) * u.Rjup).to(u.Rearth)
    target_rp_unc = (np.array([0.07, 0.09]) * u.Rjup).to(u.Rearth)[:, None]
    target_period = (np.array([8.3]) * u.day)

    if active_targets:

        label = ('TOI$\,$837')
        mfc = 'yellow' if not deemph837 else 'white'
        ms = 15 if not deemph837 else 8

        ax.plot(target_period,
                target_rp,
                mew=0.5,
                markerfacecolor=mfc,
                markersize=ms,
                marker='*',
                color='k',
                lw=0,
                label=label,
                zorder=10)

    if specialyoung:

        youngnames = tyoung['pl_hostname']

        markertypes = ['o', 'v', 'X', 's', 'P', 'd']
        zorders = [9, 8, 7, 6, 5, 4]

        for ix, y, z in zip(range(len(zorders)), np.unique(youngnames),
                            zorders):

            s = (tyoung['pl_hostname'] == y)

            ax.plot(tyoung[s]['pl_orbper'],
                    tyoung[s]['pl_rade'],
                    mew=0.5,
                    markerfacecolor='white',
                    markersize=7,
                    marker=markertypes[ix],
                    color='k',
                    lw=0,
                    label=y,
                    zorder=z)

        # two extra systems...
        N_uniq = len(np.unique(youngnames))

        ax.plot(6.9596,
                10.02,
                mew=0.5,
                markerfacecolor='white',
                markersize=7,
                marker=markertypes[N_uniq],
                color='k',
                lw=0,
                label='HIP 67522',
                zorder=2)

        # HD 63433 (TOI 1726, TIC 130181866) omitted -- 400 Myr is old!

    if showcandidates:

        from cdips_followup.manage_candidates import get_candidate_params
        vdf, sdf, _age, _rp, _rp_unc, _period = (get_candidate_params(
            isvalidated=0, ismanualsubset=1))

        l = 'New Planet Candidates' if not deemph837 else 'Active Targets'
        ax.plot(_period,
                _rp,
                mew=0.5,
                markerfacecolor='lightskyblue',
                markersize=8,
                marker='*',
                color='k',
                lw=0,
                label=l,
                zorder=1)

    # flip default legend order
    if show_legend:
        handles, labels = ax.get_legend_handles_labels()
        leg = ax.legend(handles[::-1],
                        labels[::-1],
                        loc='upper right',
                        borderpad=0.3,
                        handletextpad=0.5,
                        fontsize=6,
                        framealpha=0)

        leg.get_frame().set_linewidth(0.5)

    ax.set_xlabel('Orbital period [days]')
    ax.set_ylabel('Planet size [Earth radii]')
    ax.set_xlim([0.1, 1100])
    format_ax(ax)
    ax.set_xscale('log')

    savstr = '_no_overplot' if not active_targets else '_toi837'
    if show_legend:
        savstr += '_yeslegend'
    else:
        savstr += '_nolegend'
    if showcandidates:
        savstr += '_showcandidates'
    if deemph837:
        savstr += '_deemph837'

    outpath = (
        '../results/rp_vs_period_scatter/rp_vs_period_scatter_{}{}.png'.format(
            today_YYYYMMDD(), savstr))

    savefig(fig, outpath, writepdf=1, dpi=400)
Beispiel #13
0
def plot_cdf_rp_agecut_KS_test(agecut=1e9, Prot_source='M15',
                               gyro_source='A19'):
    """
    Prot_source (str): M13 or M15
    gyro_source (str): MH08 or A19
    agecut (float): Age cut in years

    Plot CDF, do KS test, calculate p-values.
    """

    mdf = get_merged_gyroage_CKS(Prot_source=Prot_source,
                                 gyro_source=gyro_source)

    odf = mdf[(mdf.gyroage_yr > agecut) & (mdf.VIIp_Rp < 6)] # old
    ydf = mdf[(mdf.gyroage_yr <= agecut) & (mdf.VIIp_Rp < 6)] # young
    N_o = len(odf)
    N_y = len(ydf)

    #
    # make the plot!
    #
    outdir = join(
        RESULTSDIR, f'cdf_rp_agecut_KS_test'
    )
    if not os.path.exists(outdir):
        os.mkdir(outdir)
    set_style()

    f, ax = plt.subplots(figsize=(4,3))

    bins = np.linspace(mdf.VIIp_Rp.min(), mdf.VIIp_Rp.max(), 1000)

    cnt, bin_edges = np.histogram(arr(odf.VIIp_Rp), bins=bins, normed=True)
    cdf = np.cumsum(cnt)
    ax.plot(bin_edges[:-1], cdf/cdf[-1],
            label=f'Age > {agecut/1e9:.1f} Gyr ({N_o})')

    cnt, bin_edges = np.histogram(arr(ydf.VIIp_Rp), bins=bins, normed=True)
    cdf = np.cumsum(cnt)
    ax.plot(bin_edges[:-1], cdf/cdf[-1],
            label=f'Age < {agecut/1e9:.1f} Gyr ({N_y})')

    ax.set_xscale('log')

    from scipy.stats import ks_2samp
    D, p_value = ks_2samp(arr(odf.VIIp_Rp), arr(ydf.VIIp_Rp))

    txt = f'D={D:.2e}, p={p_value:.2e}'

    ax.text(0.05, 0.95, txt,
            transform=ax.transAxes, ha='left', va='top',
            fontsize='small')

    ax.legend(fontsize='small', loc='lower right')

    ax.set_xlabel('CKS-VII R$_\mathrm{p}$ [R$_\oplus$]')

    outpath = join(
        outdir,
        f'cdf_Rp_KS_cut{agecut/1e9:.1f}_prot{Prot_source}_gyro{gyro_source}.png'
    )
    savefig(f, outpath, writepdf=0)
Beispiel #14
0
def plot_hist_rp_agecut(agecut=1e9, Prot_source='M15', gyro_source='A19',
                        fix_ylim=None):
    """
    Prot_source (str): M13 or M15
    gyro_source (str): MH08 or A19
    agecut (float): Age cut in years

    Plot histogram. $$$?
    """

    mdf = get_merged_gyroage_CKS(Prot_source=Prot_source,
                                 gyro_source=gyro_source)

    odf = mdf[(mdf.gyroage_yr > agecut) & (mdf.VIIp_Rp < 6)] # old
    ydf = mdf[(mdf.gyroage_yr <= agecut) & (mdf.VIIp_Rp < 6)] # young
    N_o = len(odf)
    N_y = len(ydf)

    # Following Fulton et al 2017, we define a “super-Earth” as a
    # planet with a radius of 1–1.75 Re, and a “sub-Neptune” as
    # having a radius of 1.75–4.0 Re.

    # old: number of superNeptunes /  number of super Earths
    o_NsN = len(odf[(odf.VIIp_Rp > 1.75) & (odf.VIIp_Rp <= 4.00)])
    o_NsE = len(odf[(odf.VIIp_Rp > 1.00) & (odf.VIIp_Rp <= 1.75)])
    unc_o_NsN = np.sqrt(len(odf[(odf.VIIp_Rp > 1.75) & (odf.VIIp_Rp <= 4.00)]))
    unc_o_NsE = np.sqrt(len(odf[(odf.VIIp_Rp > 1.00) & (odf.VIIp_Rp <= 1.75)]))

    o_NsN_div_NsE = o_NsN / o_NsE
    unc_o_div = o_NsN_div_NsE * np.sqrt( (unc_o_NsN/o_NsN)**2 + (unc_o_NsE/o_NsE)**2 )

    # ditto for young
    y_NsN = len(ydf[(ydf.VIIp_Rp > 1.75) & (ydf.VIIp_Rp <= 4.00)])
    y_NsE = len(ydf[(ydf.VIIp_Rp > 1.00) & (ydf.VIIp_Rp <= 1.75)])
    unc_y_NsN = np.sqrt(len(ydf[(ydf.VIIp_Rp > 1.75) & (ydf.VIIp_Rp <= 4.00)]))
    unc_y_NsE = np.sqrt(len(ydf[(ydf.VIIp_Rp > 1.00) & (ydf.VIIp_Rp <= 1.75)]))

    y_NsN_div_NsE = y_NsN / y_NsE
    unc_y_div = y_NsN_div_NsE * np.sqrt( (unc_y_NsN/y_NsN)**2 + (unc_y_NsE/y_NsE)**2 )

    txt = (
        'N$_{\mathrm{subNeptune}}$/N$_{\mathrm{superEarth}}$:'
        +
        f'\nOld: {o_NsN_div_NsE:.2f} $\pm$ {unc_o_div:.2f}'
        +
        f'\nYoung: {y_NsN_div_NsE:.2f} $\pm$ {unc_y_div:.2f}'
    )

    #
    # make the plot!
    #
    outdir = join(
        RESULTSDIR, f'hist_rp_agecut'
    )
    if not os.path.exists(outdir):
        os.mkdir(outdir)
    set_style()

    f, ax = plt.subplots(figsize=(4,3))

    bins = np.arange(0, 6.25, 0.25)

    ax.hist(odf.VIIp_Rp, bins=bins, cumulative=False, fill=False, density=False,
            weights=np.ones(N_o)/N_o,
            histtype='step', label=f'Age > {agecut/1e9:.1f} Gyr ({N_o})')

    ax.hist(ydf.VIIp_Rp, bins=bins, cumulative=False, fill=False, density=False,
            weights=np.ones(N_y)/N_y,
            histtype='step', label=f'Age < {agecut/1e9:.1f} Gyr ({N_y})')

    if fix_ylim:
        ax.set_ylim([0,0.28])

    ymin, ymax = ax.get_ylim()
    ax.vlines(
        1.74, ymin, ymax, colors='darkgray', alpha=1,
        linestyles='--', zorder=-2, linewidths=0.5
    )
    ax.set_ylim((ymin, ymax))

    # Create new legend handles but use the colors from the existing ones
    handles, labels = ax.get_legend_handles_labels()
    new_handles = [Line2D([], [], c=h.get_edgecolor()) for h in handles]

    ax.legend(handles=new_handles, labels=labels, fontsize='small')

    ax.text(0.95, 0.50, txt,
            transform=ax.transAxes, ha='right', va='center',
            fontsize='small')

    ax.set_ylabel('Fraction per bin')
    ax.set_xlabel('CKS-VII R$_\mathrm{p}$ [R$_\oplus$]')

    outpath = join(
        outdir,
        f'hist_Rp_cut{agecut/1e9:.1f}_prot{Prot_source}_gyro{gyro_source}.png'
    )
    savefig(f, outpath, writepdf=0)
Beispiel #15
0
def calc_semiamplitude_period_recovery(N_samples,
                                       gammadot_limit,
                                       delta_time,
                                       t_observed,
                                       do_serial=0):

    np.random.seed(42)

    log_semiamplitude = np.random.uniform(np.log(1e1),
                                          np.log(1e7),
                                          size=N_samples)

    log_period = np.random.uniform(np.log(1e0), np.log(1e15), size=N_samples)

    cosi = np.random.uniform(0, 1, N_samples)
    i = np.arccos(cosi)
    sini = np.sin(i)

    phase = np.random.uniform(0, 1, N_samples)

    t_start = t_observed.min()

    t0s = t_start + phase * np.exp(log_period)

    outpath = os.path.join(rdir,
                           f'semiamplitude_period_recovery_{N_samples}.csv')

    if not os.path.exists(outpath):

        if do_serial:

            slopes, detectables = [], []

            ix = 0
            for logK, logP, t0, si in zip(log_semiamplitude, log_period, t0s,
                                          sini):

                if ix % 10 == 0:
                    print(f'{ix}/{N_samples}')

                task = (logK, logP, t0, si, t_observed, gammadot_limit)

                slope, isdetectable = rv_injection_worker(task)

                slopes.append(slope)
                detectables.append(isdetectable)

                ix += 1

        else:

            print(f'{datetime.now().isoformat()}: Beginning injection workers')

            tasks = [(logK, logP, t0, si, t_observed, gammadot_limit)
                     for logK, logP, t0, si in zip(log_semiamplitude,
                                                   log_period, t0s, sini)]

            nworkers = mp.cpu_count()
            maxworkertasks = 1000
            pool = mp.Pool(nworkers, maxtasksperchild=maxworkertasks)

            result = pool.map(rv_injection_worker, tasks)

            pool.close()
            pool.join()

            print(f'{datetime.now().isoformat()}: Finished injection workers')

            out = np.array(result, dtype=np.dtype('float,bool'))
            out.dtype.names = ['slopes', 'detectables']
            slopes = out['slopes']
            detectables = out['detectables']

        df = pd.DataFrame({
            'logK': log_semiamplitude,
            'logP': log_period,
            'phase': phase,
            'slope': slopes,
            'detectable': detectables
        })
        df.to_csv(outpath, index=False)
        print(f'saved {outpath}')

    else:
        df = pd.read_csv(outpath)

    #
    # make plots; convert to desired mass vs semimajor axis contours
    #

    from aesthetic.plot import set_style, savefig
    set_style()
    f, ax = plt.subplots()
    ax.scatter(df.logP, df.logK, c=df.detectable.astype(int), s=0.2)
    ax.set_xlabel('logP')
    ax.set_ylabel('logK')
    figpath = os.path.join(rdir, 'logP_vs_logK_detectable_check.png')
    savefig(f, figpath, writepdf=False, dpi=300)

    # NOTE: assuming log[k (m/s)]
    # NOTE: this is the Mstar >> Mcomp approximation. If this doesn't hold, it's an
    # implicit equation (the "binary mass function"). So in the large semimajor
    # axis regime, your resulting converted contours are slightly wrong.
    e = 0
    sini = 1
    Mstar = MSTAR * u.Msun

    msini_msun = sini * ((
        (np.exp(np.array(df.logK)) /
         (28.4329)) * (1 - e**2)**(1 / 2) * (Mstar.to(u.Msun).value)**(2 / 3) *
        ((np.exp(np.array(df.logP)) * u.day).to(u.yr).value)**(1 / 3)) *
                         u.Mjup).to(u.Msun).value

    log10msini = np.log10(msini_msun)

    per1 = np.exp(np.array(df.logP)) * u.day
    sma1 = ((per1**2 * const.G * (Mstar + msini_msun * u.Msun) /
             (4 * np.pi**2))**(1 / 3)).to(u.au).value

    log10sma1 = np.log10(sma1)

    plt.close('all')
    f, ax = plt.subplots()
    ax.scatter(log10sma1, log10msini, c=df.detectable.astype(int), s=0.2)
    ax.set_xlabel('log$_{10}$(semi-major axis [AU])')
    ax.set_ylabel('log$_{10}$(M$\sin i$ [M$_\odot$])')
    ax.set_xlim([-2, 5])
    ax.set_ylim([np.log10(0.001), np.log10(2)])
    figpath = os.path.join(rdir, 'log10sma_vs_log10msini_detectable_check.png')
    savefig(f, figpath, writepdf=False, dpi=300)
Beispiel #16
0
def plot_rp_vs_age_scatter(active_targets=0,
                           split_toi_ctoi=0,
                           hjs_only=0,
                           ismanualsubset=0,
                           isvalidated=0,
                           ispublictalk=0):

    #
    # columns described at
    # https://exoplanetarchive.ipac.caltech.edu/docs/API_exoplanet_columns.html
    #
    ea_tab = NasaExoplanetArchive.query_criteria(table="exoplanets",
                                                 select="*",
                                                 cache=True)

    #
    # get systems with finite ages (has a value, and +/- error bar)
    #
    has_age_value = ~ea_tab['st_age'].mask
    has_age_errs = (~ea_tab['st_ageerr1'].mask) & (~ea_tab['st_ageerr2'].mask)
    has_rp_value = ~ea_tab['pl_rade'].mask
    has_rp_errs = (~ea_tab['pl_radeerr1'].mask) & (~ea_tab['pl_radeerr2'].mask)

    transits = (ea_tab['pl_tranflag'] == 1)

    sel = (has_age_value & has_age_errs & has_rp_value & has_rp_errs
           & transits)

    t = ea_tab[sel]

    if hjs_only:
        is_hj = (t['pl_orbper'] < 10 * u.day) & (t['pl_rade'] > 7)
        t = t[is_hj]

    #
    # read params
    #
    age = t['st_age']
    age_perr = t['st_ageerr1']
    age_merr = np.abs(t['st_ageerr2'])
    age_errs = np.array([age_perr, age_merr]).reshape(2, len(age))

    rp = t['pl_rade']
    rp_perr = t['pl_radeerr1']
    rp_merr = t['pl_radeerr2']
    rp_errs = np.array([rp_perr, rp_merr]).reshape(2, len(age))

    #
    # plot age vs rp. (age is on y axis b/c it has the error bars, and I at
    # least skimmed the footnotes of Hogg 2010)
    #
    set_style()
    f, ax = plt.subplots(figsize=(4, 3))

    label = ('Exoplanet Archive, ' +
             r"$\langle \sigma_{{\mathrm{{age}}}} \rangle$ = " +
             "{:.1f} Gyr".format(np.median(age_errs)))
    color = 'C1'
    if hjs_only:
        label = ('Known hot Jupiters')
        rp /= 11.2089  # used jupiter radii
        color = 'C1'
    if ispublictalk:
        label = 'Known'
        color = 'lightgray'

    ax.scatter(age,
               rp,
               color=color,
               s=3,
               zorder=1,
               marker='o',
               linewidth=0,
               label=label,
               alpha=1)

    #
    # targets
    #
    from cdips_followup.manage_candidates import get_candidate_params

    vdf, sdf, target_age, target_rp, target_rp_unc, target_period = (
        get_candidate_params(isvalidated=isvalidated,
                             ismanualsubset=ismanualsubset))

    if active_targets:

        label = (r'Active targets, $\langle \sigma_{{\mathrm{{age}}}} \rangle$'
                 '< 0.1 Gyr')
        if hjs_only:
            label = ('Possible hot Jupiters')

        istoi = ~(sdf.toi == '--')

        if split_toi_ctoi:
            ax.scatter(target_age[istoi],
                       target_rp[istoi],
                       color='C0',
                       s=10,
                       zorder=3,
                       marker='s',
                       linewidth=0)
            ax.scatter(target_age[~istoi],
                       target_rp[~istoi],
                       color='C0',
                       s=25,
                       zorder=3,
                       marker='*',
                       linewidth=0,
                       label=label)
        elif hjs_only:
            hj = (target_rp > 7) & (target_rp < 29)
            ax.scatter(target_age[hj],
                       target_rp[hj] / 11.2089,
                       color='C0',
                       s=35,
                       zorder=3,
                       marker='*',
                       linewidth=0,
                       label=label)
        else:
            if isvalidated:
                if len(vdf) > 1:
                    raise NotImplementedError('might want to just assign ages')
                val_age = 4e7 / 1e9
                val_rp = np.array(vdf.rp)

                ax.plot(val_age,
                        val_rp,
                        mew=0.5,
                        markerfacecolor='yellow',
                        markersize=12,
                        marker='*',
                        color='k',
                        lw=0,
                        label='Validated',
                        zorder=4)

                ax.scatter(target_age,
                           target_rp,
                           s=40,
                           color='C0',
                           zorder=3,
                           marker='*',
                           linewidth=0,
                           label="Potential")

            else:
                ax.scatter(target_age,
                           target_rp,
                           color='C0',
                           s=25,
                           zorder=3,
                           marker='*',
                           linewidth=0,
                           label=label)

        sel = (~pd.isnull(target_age)) & (~pd.isnull(target_rp))
        print('{} targets w/ finite ages and radii'.format(len(
            target_age[sel])))
        print('{} targets w/ finite ages and radii that are TOIs'.format(
            len(target_age[sel & istoi])))
        print('{} targets w/ finite ages and radii that are not TOIs'.format(
            len(target_age[sel & ~istoi])))

        target_rp_rel_unc = target_rp_unc / target_rp

        ##########
        if hjs_only:
            # HACK: force to 10% relative uncertainty (eep)
            sel = target_rp_rel_unc > 0.1
            target_rp_unc[sel] = target_rp[sel] * 0.1 * (np.random.uniform(
                0.8, 1.2, size=len(target_rp[sel])))
        else:
            # HACK: for the one very small object...
            sel = target_rp_rel_unc > 0.33
            target_rp_unc[sel] = target_rp[sel] * 0.33
        ##########

        if hjs_only:
            pass
            #ax.errorbar(target_age[hj], target_rp[hj], yerr=target_rp_unc[hj],
            #            elinewidth=0.3, ecolor='k', capsize=0, capthick=0,
            #            linewidth=0, fmt='*', ms=0, zorder=2, color='black',
            #            alpha=0.5)
        else:
            if not ispublictalk:
                ax.errorbar(target_age,
                            target_rp,
                            yerr=target_rp_unc,
                            elinewidth=0.3,
                            ecolor='k',
                            capsize=0,
                            capthick=0,
                            linewidth=0,
                            fmt='*',
                            ms=0,
                            zorder=2,
                            color='black',
                            alpha=0.5)

    # flip default legend order
    handles, labels = ax.get_legend_handles_labels()
    if not hjs_only:
        leg = ax.legend(handles[::-1],
                        labels[::-1],
                        loc='lower left',
                        borderpad=0.3,
                        handletextpad=0.3,
                        fontsize='small',
                        framealpha=1)
    else:
        leg = ax.legend(handles[::-1],
                        labels[::-1],
                        loc='upper right',
                        borderpad=0.3,
                        handletextpad=0.3,
                        fontsize='small',
                        framealpha=0)

    leg.get_frame().set_linewidth(0.5)

    ax.set_xlabel('Planet age [billion years]')
    ax.set_ylabel('Planet size [Earth radii]')
    if hjs_only:
        ax.set_ylabel('Planet size [Jupiter radii]')

    ax.set_xlim([6e-3, 17])

    if not hjs_only:
        ax.set_ylim([0.13, 85])
        ax.set_yscale('log')
    if hjs_only:
        ax.set_ylim([0.1, 3])
        ax.set_yscale('linear')

    ax.set_xscale('log')

    if hjs_only:
        ax.xaxis.set_major_formatter(StrMethodFormatter('{x:.2g}'))
    else:
        ax.yaxis.set_major_formatter(StrMethodFormatter('{x:.2g}'))

    f.tight_layout()
    savstr = '_no_overplot' if not active_targets else '_active_targets'
    if split_toi_ctoi:
        savstr += '_split_ctoi'
    if hjs_only:
        savstr += '_onlyhjs'
    if ispublictalk:
        savstr += '_ispublic'
    if isvalidated:
        savstr += '_hasvalidated'

    outpath = (
        '../results/rp_vs_age_scatter/rp_vs_age_scatter_{}{}.png'.format(
            today_YYYYMMDD(), savstr))
    f.savefig(outpath, bbox_inches='tight', dpi=450)
    f.savefig(outpath.replace('.png', '.pdf'), bbox_inches='tight')
    print('made {}'.format(outpath))
Beispiel #17
0
def get_simulated_rvs(sigma_obs, N_obs, start_time, end_time, xoparams, xo_df,
                      makeplot=True):

    #
    # a GP model is not defined without data. so _time, _rv, and _rv_err are
    # fake data, got by multiplying the photometry by the expected spot-induced
    # RV amplitude.
    #
    eps = 1e-5
    _time = np.ascontiguousarray(xo_df.time, dtype=np.float64)
    _rv = np.ascontiguousarray(xo_df.rv, dtype=np.float64)
    _rv_err = np.ones_like(_rv)*30

    t_train = np.linspace(_time.min(), _time.max(), int(1e4))
    t_true = np.linspace(start_time.jd, end_time.jd, int(1e4))
    t_long = np.linspace(_time.min(), end_time.jd, int(1e4))
    np.random.seed(42)
    t_obs = np.sort(np.random.uniform(start_time.jd, end_time.jd, N_obs))
    assert np.all(np.diff(t_obs) > 0)

    with pm.Model() as model:

        mean = pm.Normal('mean', mu=np.mean(_rv), sd=np.std(_rv))
        upper_amp = 13.8 # 14 works
        log_amp = pm.Bound(pm.Normal, lower=10, upper=upper_amp)(
            'log_amp', mu=xoparams['log_amp'], sd=10
        )
        P_rot = pm.Normal('P_rot', mu=xoparams['P_rot'], sd=0.01)
        log_Q0 = pm.Bound(pm.Normal, upper=7, lower=0.7)(
            'log_Q0', mu=xoparams['log_Q0'], sd=2
        )
        log_deltaQ = pm.Normal('log_deltaQ', mu=xoparams['log_deltaQ'], sd=0.1)
        mix = pm.Uniform('mix', lower=1e-4, upper=1)

        kernel = xo.gp.terms.RotationTerm(
            log_amp=log_amp, period=P_rot, log_Q0=log_Q0, log_deltaQ=log_deltaQ, mix=mix
        )

        gp = xo.gp.GP(kernel, _time, _rv_err**2, mean=mean)
        gp.marginal('gp', observed=_rv)

        pm.Deterministic('pred_train', gp.predict(t_train))
        pm.Deterministic('pred_long', gp.predict(t_long))
        pm.Deterministic('pred_obs', gp.predict(t_obs))
        pm.Deterministic('pred_true', gp.predict(t_true))

        map_soln = xo.optimize(start=model.test_point)

    # gp model doesn't really work because i don't understand it. period etc
    # are fine; scale is wonky.
    rv_train = map_soln['pred_train']
    rv_long = map_soln['pred_long']
    rv_obs_spot = map_soln['pred_obs']
    rv_true_spot = map_soln['pred_true']
    print(map_soln)

    orbit = xo.orbits.KeplerianOrbit(
        period=xoparams['period'], b=xoparams['b'], t0=xoparams['t0'],
        ecc=xoparams['ecc'], omega=xoparams['omega'],
        m_star=xoparams['m_star'], r_star=xoparams['r_star']
    )

    np.random.seed(42)

    rv_true_kep = orbit.get_radial_velocity(t_true, K=xoparams['K_orb']).eval()

    rv_obs_kep = orbit.get_radial_velocity(t_obs, K=xoparams['K_orb']).eval()
    rv_obs_noise = np.random.normal(loc=0, scale=sigma_obs, size=len(t_obs))

    rv_true = rv_true_spot + rv_true_kep
    rv_obs = rv_obs_spot + rv_obs_kep + rv_obs_noise

    rv_err_obs = np.ones_like(t_obs)*sigma_obs

    if makeplot:

        ####################
        # plot #1: training data

        from cdips_followup.paths import RESULTSDIR

        set_style()
        plt.close('all')

        f, ax = plt.subplots(figsize=(8,3))
        ax.scatter(_time, _rv, s=0.5, c='k', label='train data', zorder=3)
        ax.plot(t_train, rv_train, label='gp fit', lw=0.3, zorder=1)
        ax.legend()
        ax.set_xlabel('time')
        ax.set_ylabel('RV [m/s]')
        figpath = os.path.join(RESULTSDIR, 'HIP_67522',
                               f'training_data_short_Nobs{N_obs}.png')
        savefig(f, figpath, writepdf=0)

        ####################
        # plot #2: training + predict

        set_style()
        plt.close('all')

        f, ax = plt.subplots(figsize=(4,3))
        ax.scatter(_time, _rv, s=1, c='k', label='train data', zorder=3)
        ax.plot(t_long, rv_long, label='gp fit', lw=0.5, zorder=1)
        ax.legend()
        ax.set_xlabel('time')
        ax.set_ylabel('RV [m/s]')
        figpath = os.path.join(RESULTSDIR, 'HIP_67522',
                               f'training_data_long_Nobs{N_obs}.png')
        savefig(f, figpath, writepdf=0)


        ####################
        # plot #3: generated data

        plt.close('all')
        t0 = t_true.min()

        f, axs = plt.subplots(nrows=3, figsize=(4,3), sharex=True)
        axs[0].plot(t_true-t0, rv_true_spot, c='C0', lw=1)
        axs[1].plot(t_true-t0, rv_true_kep, c='C1', lw=1)

        axs[2].errorbar(t_obs-t0, rv_obs, yerr=sigma_obs, fmt='none', ecolor='k',
                        alpha=1, elinewidth=1, capsize=1, zorder=12)
        axs[2].plot(t_true-t0, rv_true, c='C2', lw=1)
        axs[2].plot(t_true-t0, rv_true_kep, c='C1', lw=1)

        props = dict(boxstyle='square', facecolor='white', alpha=0.95, pad=0.1,
                     linewidth=0)
        axs[0].text(0.03, 0.05, 'Star', ha='left', va='bottom',
                    transform=axs[0].transAxes, bbox=props, zorder=2,
                    color='C0')
        axs[1].text(0.03, 0.05, 'Planet', ha='left', va='bottom',
                    transform=axs[1].transAxes, bbox=props, zorder=2,
                    color='C1')
        axs[2].text(0.03, 0.05, 'Sum', ha='left', va='bottom',
                    transform=axs[2].transAxes, bbox=props, zorder=15,
                    color='C2')

        axs[2].set_xlabel('Days from 2021-Apr-28')

        axs[0].set_ylim([-600, 600])
        axs[1].set_ylim([-120, 120])
        axs[2].set_ylim([-600, 600])
        f.text(-0.02,0.5, 'Radial velocity [m/s]', va='center', rotation=90)


        figpath = os.path.join(RESULTSDIR, 'HIP_67522', f'sim_spot_Nobs{N_obs}.png')
        savefig(f, figpath, writepdf=0)

    obs_df = pd.DataFrame({
        't_obs':t_obs,
        'rv_obs':rv_obs,
        'rv_err_obs':rv_err_obs
    })

    true_df = pd.DataFrame({
        'rv_true_spot':rv_true_spot,
        'rv_true_kep':rv_true_kep,
        'rv_true':rv_true,
        't_true':t_true
    })

    return obs_df, true_df
Beispiel #18
0
def plot_Prot_vs_eps(includefit=False, xscale=None):

    #
    # make the plot!
    #
    set_style()

    f, ax = plt.subplots(figsize=(4, 3))

    Porb_1937 = 0.947
    Prot_1937 = 6.5
    MpMs_1937 = ((1.79 * u.Mjup) / (1.045 * u.Msun)).cgs.value
    Rs_a_1937 = (1 / 4.26)  # from MIT report
    eps_1937 = MpMs_1937 * Rs_a_1937**5

    ax.scatter(df['epsilon'],
               df['P_rot'],
               zorder=2,
               c='k',
               alpha=0.9,
               s=9,
               linewidths=0,
               label='HJs (phot P$_\mathrm{rot}$)')
    # ax.scatter(
    #     d['Per'][sel1], d['SPer'][sel1], zorder=2, c='gray', alpha=0.9, s=9,
    #     linewidths=0,
    #     label='HJs ($\mathrm{R}_{\star} \geq 1.2 \mathrm{R}_{\odot}$)'
    # )
    ax.plot(eps_1937,
            Prot_1937,
            mew=0.5,
            zorder=3,
            markerfacecolor='yellow',
            markersize=18,
            marker='*',
            color='k',
            lw=0,
            label='TOI 1937b')

    # if includefit:

    #     x = np.hstack([d['Per'][sel0], Porb_1937])
    #     y = np.hstack([d['SPer'][sel0], Prot_1937])

    #     slope, intercept, rvalue, pvalue, stderr = linregress(x, y)

    #     label = f'Slope={slope:.1f}$\pm${stderr:.1f}, p={pvalue:.1e}'

    #     ax.plot(x, intercept + slope*x, label=label)

    # Shrink current axis by 20%
    box = ax.get_position()
    ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])

    # Put a legend to the right of the current axis
    ax.legend(loc='center left', bbox_to_anchor=(1, 0.5), handletextpad=0.1)

    ax.set_xlabel('$\epsilon \equiv (M_\mathrm{p}/M_{\star})(R_{\star}/a)^5$')
    ax.set_ylabel('Stellar spin period [days]')

    # ax.set_xlim([0.5, 4.2])
    ax.set_ylim([2, 28])

    extrastr = '_withfit' if includefit else '_nofit'

    if isinstance(xscale, str):
        ax.set_xscale(xscale)
        extrastr += f'_{xscale}'

    figpath = (f'../results/Prot_vs_eps/Prot_vs_eps_snrcut{extrastr}.png')
    savefig(f, figpath)
Beispiel #19
0
def plot_cks_rp_vs_gyroage(Prot_source='M15', gyro_source='A19'):
    """
    Prot_source: M13 or M15
    gyro_source: MH08 or A19 or SL20

    Make scatter plots of {plantet radius, orbital period} against
    gyrochronology ages in a few different projections.
    """
    mdf = get_merged_gyroage_CKS(Prot_source=Prot_source,
                                 gyro_source=gyro_source)

    outdir = join(RESULTSDIR, f'{Prot_source}rot_{gyro_source}gyroage')
    if not os.path.exists(outdir):
        os.mkdir(outdir)
    set_style()

    agelabel = (f'Gyro-Age [{Prot_source} '+'P$_\mathrm{rot}$ +'
                +f'{gyro_source}; yr]')

    for scale in ['linear','log']:
        f, ax = plt.subplots(figsize=(4,3))
        ax.scatter(mdf.VIIp_Rp, mdf.gyroage_yr, s=2, c='k', zorder=3)
        ax.set_xlabel('CKS-VII R$_\mathrm{p}$ [R$_\oplus$]')
        ax.set_ylabel(agelabel)
        ax.set_xscale(scale); ax.set_yscale('log')
        ylim = ax.get_ylim()
        ymax = 1.5e10
        ax.set_ylim([1e8, ymax])
        print(f'WRN! {len(mdf[mdf.gyroage_yr > ymax])} older than max plotted gyroage')
        outpath = join(outdir, f'cks-VII_rp_vs_gyroage_{scale}.png')
        savefig(f, outpath, writepdf=0)

    plt.close('all')
    f, ax = plt.subplots(figsize=(4,3))
    ax.scatter(mdf.VIIp_Per, mdf.gyroage_yr, s=2, c='k')
    ax.set_xlabel('CKS-VII P$_\mathrm{orb}$ [day]')
    ax.set_ylabel(agelabel)
    ax.set_xscale('log'); ax.set_yscale('log')
    ylim = ax.get_ylim()
    ymax = 1.5e10
    ax.set_ylim([ylim[0], ymax])
    outpath = join(outdir, 'cks-VII_period_vs_gyroage.png')
    savefig(f, outpath, writepdf=0)


    plt.close('all')
    f, ax = plt.subplots(figsize=(4.3,3))
    Prot_key = 'Prot' if Prot_source in ['M13','M15','S21'] else 'spec_Prot'
    sel = ~pd.isnull(mdf[Prot_key])

    norm = mpl.colors.Normalize(vmin=8.5, vmax=10)
    cax = ax.scatter(mdf[sel].VIIp_Per, mdf[sel].VIIp_Rp, s=7,
                     c=np.log10(mdf[sel].gyroage_yr),
                     cmap='plasma_r', zorder=3, norm=norm,
                     edgecolors='k', linewidths=0.2)

    ax.set_xlabel('CKS-VII P$_\mathrm{orb}$ [day]')
    ax.set_ylabel('CKS-VII R$_\mathrm{p}$ [R$_\oplus$]')
    ax.set_xscale('log'); ax.set_yscale('log')

    cbar = f.colorbar(cax, extend='both')
    cbar.set_label('log$_{10}$'+agelabel, fontsize='small')
    cbar.minorticks_off()

    outpath = join(outdir, 'cks-VII_period_vs_cks-VII_prad_gyroagecolors.png')
    savefig(f, outpath, writepdf=0)
Beispiel #20
0
def SpadaLanzafame20_gyro(BmV=None, Prot=None, makeplot=True):
    """
    Spada & Lanzafame 2020 give gyrochrones in B-V (and mass) vs age space.
    Will need to interpolate between them on a 2D grid.
    """

    sl20path = os.path.join(DATADIR, 'Spada_Lanzafame_2020_BmV_table.csv')
    df = pd.read_csv(sl20path, sep='&')

    from scipy.interpolate import interp2d, interp1d
    from scipy.optimize import newton

    df = df.sort_values(by='BmV')
    BmV_arr = np.array(df.BmV).astype(float)
    age_gyr = np.array(df.columns[1:-1]).astype(float)
    Prot_array = np.array(df[[
        c for c in df.columns if (c != 'BmV' and c != '4.57')
    ]]).astype(float)

    fn = interp2d(age_gyr,
                  BmV_arr,
                  Prot_array,
                  kind='cubic',
                  bounds_error=False,
                  fill_value=0)

    N_pts = 100
    BmV_new = np.linspace(min(BmV_arr), max(BmV_arr), N_pts)
    age_new = np.linspace(min(age_gyr), max(age_gyr), 2 * N_pts)
    Prot_new = fn(age_new, BmV_new)

    if makeplot:
        from aesthetic.plot import set_style, savefig
        set_style()
        fig, ax = plt.subplots(figsize=(4, 3))
        X, Y = np.meshgrid(BmV_new, age_new)
        #cmap = plt.cm.viridis
        cmap = plt.cm.Paired
        norm = mpl.colors.Normalize(vmin=np.nanmin(Prot_new),
                                    vmax=np.nanmax(Prot_new))
        im = ax.pcolormesh(X,
                           Y,
                           Prot_new.T,
                           cmap=cmap,
                           norm=norm,
                           shading='flat')  # vs 'gouraud'
        ax.set_xlabel('B-V')
        ax.set_ylabel('Age [Gyr]')
        cbar = fig.colorbar(im,
                            orientation='vertical',
                            extend='min',
                            label='Prot [day]')
        cbar.ax.tick_params(labelsize=6, direction='out')
        outpath = os.path.join(RESULTSDIR, 'SpadaLanzafame2020',
                               'interpolation_check.png')
        savefig(fig, outpath, writepdf=False)

    age_gyrs = []

    for _prot, _bmv in zip(Prot, BmV):

        nearest_BmV, idx = find_nearest(BmV_new,
                                        _bmv,
                                        verbose=True,
                                        return_index=True)

        # now it's a 1-dimensional optimization problem
        fn_1d = interp1d(age_new,
                         Prot_new[idx, :],
                         kind='quadratic',
                         bounds_error=False,
                         fill_value=0)

        interp_fn2 = lambda x: fn_1d(x) - _prot

        age_init_gyr = 2
        try:
            root_age_gyr = newton(interp_fn2, age_init_gyr)
        except:
            if _prot > max(Prot_new[idx, :]):
                root_age_gyr = 10
            else:
                root_age_gyr = 0

        age_gyrs.append(root_age_gyr)

    t_yr = np.array(age_gyrs) * 1e9

    return t_yr
Beispiel #21
0
def plot_TIC268_nbhd_full(outdir=RESULTSDIR):

    set_style()

    df = get_cdips_catalog(ver=0.4)

    kc19_sel = ((df.cluster.str.contains('NGC_2516')) &
                (df.reference.str.contains('Kounkel_2019')))
    cg18_sel = ((df.cluster.str.contains('NGC_2516')) &
                (df.reference.str.contains('CantatGaudin_2018')))

    target_df = df[df.source_id == 5489726768531119616]  # TIC 2683...
    kc19_df = df[kc19_sel]
    cg18_df = df[cg18_sel]

    ##########

    plt.close('all')

    params = ['ra', 'dec', 'parallax', 'pmra', 'pmdec']
    nparams = len(params)

    qlimd = {
        'ra': 0,
        'dec': 0,
        'parallax': 0,
        'pmra': 0,
        'pmdec': 0,
        'radial_velocity': 0
    }  # whether to limit axis by quantile

    ldict = {
        'ra': r'$\alpha$ [deg]',
        'dec': r'$\delta$ [deg]',
        'parallax': r'$\pi$ [mas]',
        'pmra': r'$\mu_{{\alpha}} \cos\delta$ [mas/yr]',
        'pmdec': r'$\mu_{{\delta}}$ [mas/yr]',
        'radial_velocity': 'RV [km/s]'
    }

    f, axs = plt.subplots(figsize=(6, 6), nrows=nparams - 1, ncols=nparams - 1)

    for i in range(nparams):
        for j in range(nparams):
            print(i, j)
            if j == nparams - 1 or i == nparams - 1:
                continue
            if j > i:
                axs[i, j].set_axis_off()
                continue

            xv = params[j]
            yv = params[i + 1]
            print(i, j, xv, yv)

            axs[i, j].scatter(kc19_df[xv],
                              kc19_df[yv],
                              c='gray',
                              alpha=0.9,
                              zorder=2,
                              s=5,
                              rasterized=True,
                              linewidths=0,
                              label='Core',
                              marker='.')
            axs[i, j].scatter(cg18_df[xv],
                              cg18_df[yv],
                              c='k',
                              alpha=0.9,
                              zorder=3,
                              s=5,
                              rasterized=True,
                              linewidths=0,
                              label='Corona')
            axs[i, j].plot(target_df[xv],
                           target_df[yv],
                           alpha=1,
                           mew=0.5,
                           zorder=8,
                           label='TOI 1937',
                           markerfacecolor='yellow',
                           markersize=14,
                           marker='*',
                           color='black',
                           lw=0)

            # set the axis limits as needed
            if qlimd[xv]:
                xlim = (np.nanpercentile(kc19_df[xv], 25),
                        np.nanpercentile(kc19_df[xv], 75))
                axs[i, j].set_xlim(xlim)
            if qlimd[yv]:
                ylim = (np.nanpercentile(kc19_df[yv], 25),
                        np.nanpercentile(kc19_df[yv], 75))
                axs[i, j].set_ylim(ylim)

            # fix labels
            if j == 0:
                axs[i, j].set_ylabel(ldict[yv])
                if not i == nparams - 2:
                    # hide xtick labels
                    labels = [
                        item.get_text()
                        for item in axs[i, j].get_xticklabels()
                    ]
                    empty_string_labels = [''] * len(labels)
                    axs[i, j].set_xticklabels(empty_string_labels)

            if i == nparams - 2:
                axs[i, j].set_xlabel(ldict[xv])
                if not j == 0:
                    # hide ytick labels
                    labels = [
                        item.get_text()
                        for item in axs[i, j].get_yticklabels()
                    ]
                    empty_string_labels = [''] * len(labels)
                    axs[i, j].set_yticklabels(empty_string_labels)

            if (not (j == 0)) and (not (i == nparams - 2)):
                # hide ytick labels
                labels = [
                    item.get_text() for item in axs[i, j].get_yticklabels()
                ]
                empty_string_labels = [''] * len(labels)
                axs[i, j].set_yticklabels(empty_string_labels)
                # hide xtick labels
                labels = [
                    item.get_text() for item in axs[i, j].get_xticklabels()
                ]
                empty_string_labels = [''] * len(labels)
                axs[i, j].set_xticklabels(empty_string_labels)

    # axs[2,2].legend(loc='best', handletextpad=0.1, fontsize='medium', framealpha=0.7)
    # leg = axs[2,2].legend(bbox_to_anchor=(0.8,0.8), loc="upper right",
    #                       handletextpad=0.1, fontsize='medium',
    #                       bbox_transform=f.transFigure)

    for ax in axs.flatten():
        format_ax(ax)

    f.tight_layout(h_pad=0.1, w_pad=0.1)

    outpath = os.path.join(outdir, 'full_kinematics.png')
    savefig(f, outpath)
def plot_mass_vs_age_scatter(active_targets=1,
                             specialyoung=1,
                             showcandidates=0,
                             show_legend=0):

    set_style()

    #
    # columns described at
    # https://exoplanetarchive.ipac.caltech.edu/docs/API_exoplanet_columns.html
    #
    ea_tab = NasaExoplanetArchive.query_criteria(table="exoplanets",
                                                 select="*",
                                                 cache=True)

    #
    # get systems with finite ages (has a value, and +/- error bar)
    #
    has_age_value = ~ea_tab['st_age'].mask
    has_age_errs = (~ea_tab['st_ageerr1'].mask) & (~ea_tab['st_ageerr2'].mask)
    has_rp_value = ~ea_tab['pl_rade'].mask
    has_rp_errs = (~ea_tab['pl_radeerr1'].mask) & (~ea_tab['pl_radeerr2'].mask)
    rp_gt_0 = (ea_tab['pl_rade'] > 0)
    m_gt_0 = (ea_tab['pl_bmassj'] > 0) & (np.abs(ea_tab['pl_bmassjerr1']) > 0)
    has_m_errs = (~ea_tab['pl_bmassjerr1'].mask) & (
        ~ea_tab['pl_bmassjerr2'].mask)

    transits = (ea_tab['pl_tranflag'] == 1)

    sel = (has_age_value & has_age_errs & has_rp_value & has_rp_errs & transits
           & rp_gt_0 & m_gt_0 & has_m_errs)

    t = ea_tab[sel]
    tyoung = t[(t['st_age'] < 0.1 * u.Gyr) & (t['st_age'] > 0 * u.Gyr)]

    #
    # read params
    #
    age = t['st_age']
    age_perr = t['st_ageerr1']
    age_merr = np.abs(t['st_ageerr2'])
    age_errs = np.array([age_perr, age_merr]).reshape(2, len(age))

    rp = t['pl_rade']
    rp_perr = t['pl_radeerr1']
    rp_merr = t['pl_radeerr2']
    rp_errs = np.array([rp_perr, rp_merr]).reshape(2, len(age))
    # rp /= 11.2089 # used jupiter radii

    mass = t['pl_bmassj']

    ##########################################
    fig, ax = plt.subplots(figsize=(4, 3))

    label = ('Exoplanet Archive')
    print(f'Mean age unc: {np.mean(age_errs):.2f} Gyr')
    print(f'Median age unc: {np.median(age_errs):.2f} Gyr')
    print(42 * '-')
    print('Ages below 700 Myr:')
    _t = t[(t['st_age'] < 0.7 * u.Gyr) & (t['st_age'] > 0 * u.Gyr)]
    _t.sort('st_age')
    print(_t['st_age', 'pl_hostname', 'pl_rade', 'pl_orbper'])
    print(42 * '-')

    ax.scatter(age,
               mass,
               color='darkgray',
               s=3,
               zorder=1,
               marker='o',
               linewidth=0,
               label=label,
               alpha=1)

    #
    # targets
    #
    target_age = (np.array([3.5e7]) * u.yr).to(u.Gyr)
    target_rp = (np.array([0.77]) * u.Rjup).to(u.Rearth)
    target_rp_unc = (np.array([0.07, 0.09]) * u.Rjup).to(u.Rearth)[:, None]

    if active_targets:

        label = ('TOI$\,$837')

        ax.plot(target_age,
                target_mass,
                mew=0.5,
                markerfacecolor='yellow',
                markersize=15,
                marker='*',
                color='k',
                lw=0,
                label=label,
                zorder=3)

    if specialyoung:

        youngnames = tyoung['pl_hostname']

        markertypes = ['o', 'v', 'X', 's', 'P', 'd']

        for ix, y in enumerate(np.unique(youngnames)):

            s = (tyoung['pl_hostname'] == y)

            ax.plot(tyoung[s]['st_age'],
                    tyoung[s]['pl_rade'],
                    mew=0.5,
                    markerfacecolor='white',
                    markersize=7,
                    marker=markertypes[ix],
                    color='k',
                    lw=0,
                    label=y,
                    zorder=2)

        # two extra systems...
        N_uniq = len(np.unique(youngnames))

        ax.plot(1.5e7 / 1e9,
                10.02,
                mew=0.5,
                markerfacecolor='white',
                markersize=7,
                marker=markertypes[N_uniq],
                color='k',
                lw=0,
                label='HIP 67522',
                zorder=2)

        # HD 63433 (TOI 1726, TIC 130181866) omitted -- 400 Myr is old!

    if showcandidates:

        from cdips_followup.manage_candidates import get_candidate_params
        vdf, sdf, _age, _rp, _rp_unc, _period = (get_candidate_params(
            isvalidated=0, ismanualsubset=1))

        ax.plot(_age,
                _rp,
                mew=0.5,
                markerfacecolor='lightskyblue',
                markersize=8,
                marker='*',
                color='k',
                lw=0,
                label='New Planet Candidates',
                zorder=1)

    # flip default legend order
    if show_legend:
        handles, labels = ax.get_legend_handles_labels()
        leg = ax.legend(handles[::-1],
                        labels[::-1],
                        loc='upper right',
                        borderpad=0.3,
                        handletextpad=0.5,
                        fontsize=6,
                        framealpha=0)

        leg.get_frame().set_linewidth(0.5)

    ax.set_xlabel('Age [billion years]')
    ax.set_ylabel(r'Planet mass [M$_\mathrm{Jup}$]')
    ax.set_xlim([6e-3, 17])
    ax.set_ylim([0.001, 1e2])
    format_ax(ax)
    ax.set_xscale('log')
    ax.set_yscale('log')

    savstr = '_no_overplot' if not active_targets else '_toi837'
    if showcandidates:
        savstr += '_showcandidates'
    if show_legend:
        savstr += '_yeslegend'
    else:
        savstr += '_nolegend'

    outpath = (
        '../results/mass_vs_age_scatter/mass_vs_age_scatter_{}{}.png'.format(
            today_YYYYMMDD(), savstr))

    savefig(fig, outpath, writepdf=1, dpi=400)
Beispiel #23
0
def plot_Porb_Prot(snr_cutoff=2, includefit=False):

    sel = (((d['SPer'] / d['E_SPer']) > snr_cutoff) & (d['SPer'] < 30))
    sel0 = (((d['SPer'] / d['E_SPer']) > snr_cutoff)
            & (d['R_'] < 1.2)
            & (d['SPer'] < 30))
    sel1 = (((d['SPer'] / d['E_SPer']) > snr_cutoff)
            & (d['R_'] >= 1.2)
            & (d['SPer'] < 30))
    sel2 = (((d['SPer'] / d['E_SPer']) > snr_cutoff)
            & (d['R_'] < 1.2)
            & (d['SPer'] < 8))
    sel3 = (((d['SPer'] / d['E_SPer']) > snr_cutoff)
            & (d['R_'] < 1.2)
            & (d['Per'] < 1))

    print(d['ID'][sel2])
    print(d['ID'][sel3])

    #
    # make the plot!
    #
    set_style()

    f, ax = plt.subplots(figsize=(4, 3))

    Porb_1937 = 0.947
    Prot_1937 = 6.5

    ax.scatter(d['Per'][sel0],
               d['SPer'][sel0],
               zorder=2,
               c='k',
               alpha=0.9,
               s=9,
               linewidths=0,
               label='HJs ($\mathrm{R}_{\star} < 1.2 \mathrm{R}_{\odot}$)')
    ax.scatter(d['Per'][sel1],
               d['SPer'][sel1],
               zorder=2,
               c='gray',
               alpha=0.9,
               s=9,
               linewidths=0,
               label='HJs ($\mathrm{R}_{\star} \geq 1.2 \mathrm{R}_{\odot}$)')
    ax.plot(Porb_1937,
            Prot_1937,
            mew=0.5,
            zorder=3,
            markerfacecolor='yellow',
            markersize=18,
            marker='*',
            color='k',
            lw=0,
            label='TOI 1937b (1.1$\mathrm{R}_{\odot}$)')

    if includefit:

        x = np.hstack([d['Per'][sel0], Porb_1937])
        y = np.hstack([d['SPer'][sel0], Prot_1937])

        slope, intercept, rvalue, pvalue, stderr = linregress(x, y)

        label = f'Slope={slope:.1f}$\pm${stderr:.1f}, p={pvalue:.1e}'

        ax.plot(x, intercept + slope * x, label=label)

    # Shrink current axis by 20%
    box = ax.get_position()
    ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])

    # Put a legend to the right of the current axis
    ax.legend(loc='center left', bbox_to_anchor=(1, 0.5), handletextpad=0.1)

    ax.set_xlabel('Planet orbital period [days]')
    ax.set_ylabel('Stellar spin period [days]')

    ax.set_xlim([0.5, 4.2])
    ax.set_ylim([2, 28])

    extrastr = '_withfit' if includefit else '_nofit'
    figpath = (
        f'../results/Porb_Prot/Porb_Prot_snrcut{snr_cutoff}{extrastr}.png')
    savefig(f, figpath)