コード例 #1
0
def plot_exoplanetarchive_Rp_vs_P_age_cuts(whichcut='none'):

    tab = NasaExoplanetArchive.get_confirmed_planets_table(all_columns=True)

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

    xval = nparr(tab['pl_orbper'])
    yval = nparr(tab['pl_rade'])

    age = nparr(tab['st_age'])
    age_perr = nparr(tab['st_ageerr1'])
    age_merr = nparr(tab['st_ageerr2'])

    age_err = np.maximum(age_perr, np.abs(age_merr))

    transits = nparr(tab['pl_tranflag']).astype(bool)

    sel = (np.isfinite(xval) & (xval > 0)
           & np.isfinite(yval) & (yval > 0)
           & transits)
    if whichcut in [
            'finiteage', 'sigmatau_by_tau_pt5', 'sigmatau_by_tau_pt2',
            'age_lt_1Gyr', 'age_gt_10Gyr', 'age_gt_8Gyr', 'age_lt_500Myr',
            'age_lt_100Myr'
    ]:
        sel &= np.isfinite(age)
        sel &= (age > 0)
        sel &= np.isfinite(age_perr)
        sel &= (age_perr > 0)
        sel &= np.isfinite(age_merr)
        sel &= (np.abs(age_merr) > 0)
    if whichcut == 'sigmatau_by_tau_pt5':
        sel &= (age_err / age < 0.5)
    if whichcut == 'sigmatau_by_tau_pt2':
        sel &= (age_err / age < 0.2)
    if whichcut.endswith('Gyr'):
        cutval = int(whichcut.split('Gyr')[0].split('_')[-1])
        if '_gt_' in whichcut:
            sel &= age > cutval
        elif '_lt_' in whichcut:
            sel &= age < cutval
    if whichcut.endswith('Myr'):
        cutval_Myr = int(whichcut.split('Myr')[0].split('_')[-1])
        cutval = (cutval_Myr / 1e3)
        if '_gt_' in whichcut:
            sel &= age > cutval
        elif '_lt_' in whichcut:
            sel &= age < cutval

    ax.scatter(xval[sel],
               yval[sel],
               rasterized=True,
               alpha=0.8,
               zorder=3,
               c='k',
               lw=0,
               s=6)

    ax.set_xlabel('Orbital period [days]')
    ax.set_ylabel('Radius [$R_\oplus$]')

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

    ax.set_xlim((0.09, 3.1e3))
    ax.set_ylim((0.25, 25))

    datestr = datetime.today().isoformat().split('T')[0]

    if whichcut == 'none':
        txtstr = ('{} transiting\n{}\nExoplanet Archive'.format(
            len(xval[sel]), datestr))
    elif whichcut == 'finiteage':
        txtstr = ('{} transiting, w/ "age"\n{}\nExoplanet Archive'.format(
            len(xval[sel]), datestr))
    elif whichcut == 'sigmatau_by_tau_pt5':
        selectionstr = r'$\sigma_\tau / \tau < 0.5$'
        txtstr = ('{} transiting, w/ {}\n{}\nExoplanet Archive'.format(
            len(xval[sel]), selectionstr, datestr))
    elif whichcut == 'sigmatau_by_tau_pt2':
        selectionstr = r'$\sigma_\tau / \tau < 0.2$'
        txtstr = ('{} transiting, w/ {}\n{}\nExoplanet Archive'.format(
            len(xval[sel]), selectionstr, datestr))
    elif whichcut.endswith('Gyr'):
        if '_gt_' in whichcut:
            selectionstr = r'$\tau > {}$ Gyr'.format(cutval)
        elif '_lt_' in whichcut:
            selectionstr = r'$\tau < {}$ Gyr'.format(cutval)
        txtstr = ('{} transiting, w/ {}\n{}\nExoplanet Archive'.format(
            len(xval[sel]), selectionstr, datestr))
    elif whichcut.endswith('Myr'):
        if '_gt_' in whichcut:
            selectionstr = r'$\tau > {}$ Myr'.format(cutval_Myr)
        elif '_lt_' in whichcut:
            selectionstr = r'$\tau < {}$ Myr'.format(cutval_Myr)
        txtstr = ('{} transiting, w/ {}\n{}\nExoplanet Archive'.format(
            len(xval[sel]), selectionstr, datestr))

    ax.text(0.98,
            0.02,
            txtstr,
            ha='right',
            va='bottom',
            fontsize='small',
            transform=ax.transAxes)

    savdir = '../results/exoplanet_archive_age_cut_plots/'
    savpath = os.path.join(
        savdir, 'exoplanetarchive_Rp_vs_P_cut{}.png'.format(whichcut))
    f.savefig(savpath, bbox_inches='tight', dpi=400)
    print('made {}'.format(savpath))

    return tab
コード例 #2
0
def _get_period_guess_given_plname(plname):

    from astroquery.mast import Catalogs

    res = Catalogs.query_object(plname, catalog="TIC", radius=0.5*1/3600)

    if len(res) != 1:
        raise ValueError('for {}, got result:\n{}'.format(plname, repr(res)))

    ticid = int(res["ID"])
    litdir = '../data/literature_physicalparams/{}/'.format(ticid)
    if not os.path.exists(litdir):
        os.mkdir(litdir)
    litpath = os.path.join(litdir,'params.csv')

    try:
        lpdf = pd.read_csv(litpath)
        period_guess = float(lpdf['period_day'])

    except FileNotFoundError:

        from astrobase.services.mast import tic_objectsearch

        ticres = tic_objectsearch(ticid)

        with open(ticres['cachefname'], 'r') as json_file:
            data = json.load(json_file)

        ra = data['data'][0]['ra']
        dec = data['data'][0]['dec']

        targetcoordstr = '{} {}'.format(ra, dec)

        # attempt to get physical parameters of planet -- period, a/Rstar, and
        # inclination -- for the initial guesses.
        from astroquery.nasa_exoplanet_archive import NasaExoplanetArchive
        eatab = NasaExoplanetArchive.get_confirmed_planets_table()

        pl_coords = eatab['sky_coord']
        tcoord = SkyCoord(targetcoordstr, frame='icrs', unit=(u.deg, u.deg))

        print('got match w/ separation {}'.format(
            np.min(tcoord.separation(pl_coords).to(u.arcsec))))
        pl_row = eatab[np.argmin(tcoord.separation(pl_coords).to(u.arcsec))]

        # all dimensionful
        period = pl_row['pl_orbper'].value
        incl = pl_row['pl_orbincl'].value
        semimaj_au = pl_row['pl_orbsmax']
        rstar = pl_row['st_rad']
        a_by_rstar = (semimaj_au / rstar).cgs.value

        litdf = pd.DataFrame(
            {'period_day':period,
             'a_by_rstar':a_by_rstar,
             'inclination_deg':incl
            }, index=[0]
        )
        # get the fixed physical parameters from the data. period_day,
        # a_by_rstar, and inclination_deg are comma-separated in this file.
        litdf.to_csv(litpath, index=False, header=True, sep=',')
        lpdf = pd.read_csv(litpath, sep=',')
        period_guess = float(lpdf['period_day'])

    return period_guess
コード例 #3
0
ファイル: utils.py プロジェクト: benhord/transit_tools
def known_pls(name=None, ra=None, dec=None, radius=5.0, table='ps',
              values='all', verbose=False):
    #!!Reduce number of columns queried with each iteration for shorter 
    #  runtime!!
    #!!Allow to search for planets that are not confirmed on the archive!!
    #!!Allow user to pass values through as list to be queried for more 
    #  specific query values!!
    #!!Not working with object parsing!!
    """
    A function to gather information on any known planets in a given system. 
    Queries the NASA Exoplanet Archive for objects and their known parameters.

    Parameters
    ----------
    name : str
       Common name of the system being checked. Optional if RA/Dec are provided.
    ra : float
       RA in decimal degrees. Optional if name is provided. If provided, Dec is
       also required.
    dec : float
       Dec in decimal degrees. Optional if name is provided. If provided, RA is
       also required.
    radius : float
       Radius in arcseconds around which the provided RA and Dec will be searched
       for planets.
    table : str
       Specifies the table to search for planet parameters. See documentation on
       the Exoplanet Archive website for a full list of possible tables and their
       contents. Default is the 'exoplanets' table, which is the default for the
       Exoplanet Archive.
    values : str
       Specifies how many values are collected. Current supported options are
       'minimum' and 'all'.
    verbose : bool
       Flag to determine whether some of the parameters of the known planets in
       the system are printed.

    Returns
    -------
    info : list of dicts
       List containing a dictionary of all known planet parameters for each 
       planet in the queried system.
    """
    if not name and (not ra or not dec):
        raise ValueError('Either name or both RA & Dec must be provided')

    if values == 'minimum':
        select = ('pl_name, pl_orbper, pl_orbpererr1, pl_orbpererr2, ' +
                  'pl_tranmid, pl_tranmiderr1, pl_tranmiderr2, pl_trandur, ' +
                  'pl_trandurerr1, pl_trandurerr2, pl_trandep, pl_trandeperr1,' +
                  ' pl_trandeperr2, pl_ratdor, pl_ratdorerr1, pl_ratdorerr2, ' +
                  'pl_ratror, pl_ratrorerr1, pl_ratrorerr2, pl_radj, ' +
                  'pl_radjerr1, pl_radjerr2, pl_bmassj, pl_bmassjerr1, ' +
                  'pl_bmassjerr2, pl_hostname')
    else:
        select = '*'
        
    
    if name is not None:
        results = nea.query_object(str(name), table=table, select=select)

    elif ra is not None and dec is not None:
        results = nea.query_region(
            coordinates=coord.SkyCoord(ra * u.deg, dec * u.deg),
            radius = radius * u.arcsec,
            table=table,
            select=select
            )
    
    pls = len(results)
    if verbose:
        print(str(pls) + ' known planets found in system')
        print('Gathering info for each planet...')
        
    if pls > 0:
        names = results.colnames
        info = [dict(zip(names, row)) for row in results]

        for i in range(pls):
            info[i]['t0'] = (Time(val=info[i]['pl_tranmid'].value,
                                  format='jd').to_value(format='mjd') - 56999.5)
        
        query_fault = False
    else:
        query_fault = True
                
    if verbose and not query_fault:
        for i in range(pls):
            try:
                pl = info[i]
                print(pl['pl_name'])
                print('Period = %.5f +%.5f %.5f %s' %
                      (pl['pl_orbper'].value,
                       pl['pl_orbpererr1'].value,
                       pl['pl_orbpererr2'].value,
                       pl['pl_orbper'].unit))
                print('t0 = %.5f +2457000 BTJD +%.5f %.5f' %
                      (pl['t0'],
                       pl['pl_tranmiderr1'].value,
                       pl['pl_tranmiderr2'].value))
                print('Duration = %.5f +%.5f %.5f %s' %
                      (pl['pl_trandur'].value,
                       pl['pl_trandurerr1'].value,
                       pl['pl_trandurerr2'].value,
                       pl['pl_trandur'].unit))
                print('Transit depth = %.5f +%.5f -%.5f' %
                      (pl['pl_trandep'].value,
                       pl['pl_trandeperr1'].value,
                       pl['pl_trandeperr2'].value))
                print('a/Rs = %.5f +%.5f %.5f' %
                      (pl['pl_ratdor'],
                       pl['pl_ratdorerr1'],
                       pl['pl_ratdorerr2']))
                print('Rp/Rs = %.5f +%.5f %.5f' %
                      (pl['pl_ratror'],
                       pl['pl_ratrorerr1'],
                       pl['pl_ratrorerr2']))
                print('Radius = %.5f +%.5f %.5f %s' %
                      (pl['pl_radj'].value,
                       pl['pl_radjerr1'].value,
                       pl['pl_radjerr2'].value,
                       pl['pl_radj'].unit))
                print('Mass = %.5f +%.5f %.5f %s' %
                      (pl['pl_bmassj'].value,
                       pl['pl_bmassjerr1'].value,
                       pl['pl_bmassjerr2'].value,
                       pl['pl_bmassj'].unit))
                print('')
            except:
                continue

    elif verbose and query_fault:
        print('Known planet found but parameters were not found in Exoplanet ' +
              'Archive for some reason.')
        info = None
                
    return info
コード例 #4
0
    sd18_glat = arr(sd18['b']) * u.rad

    f_glon = np.isfinite(sd18_glon)
    f_glat = np.isfinite(sd18_glat)
    goodflag = (sd18['flag'] == 0)

    good_sd18_inds = (f_glon) & (f_glat)  #& (goodflag)

    c_sd18 = SkyCoord(sd18_glon[good_sd18_inds],
                      sd18_glat[good_sd18_inds],
                      frame='galactic')

    c_sd18 = c_sd18.icrs

    # crossmatch vs exoarchive by ra and dec.
    ea_tab = NasaExoplanetArchive.get_confirmed_planets_table(
        all_columns=True, show_progress=True)

    ea_rad = arr(ea_tab['ra']) * u.deg
    ea_dec = arr(ea_tab['dec']) * u.deg

    c_ea = SkyCoord(ra=ea_rad, dec=ea_dec)

    seplimit = 10 * u.arcsec

    # do the crossmatch. the first extra step helps by cacheing a kdtree.
    c_ea_sub = c_ea[:10]
    idx_ea_sub, idx_sd18, d2d, _ = c_sd18.search_around_sky(c_ea_sub, seplimit)

    print('beginning crossmatch')
    idx_ea, idx_sd18, d2d, _ = c_sd18.search_around_sky(c_ea, seplimit)
    print('completed crossmatch')
コード例 #5
0
def plot_rp_vs_age_scatter(active_targets=1, specialyoung=1):

    #
    # 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]
    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

    #
    # 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(age,
               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]

    if active_targets:

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

        ax.plot(target_age,
                target_rp,
                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!

    # flip default legend order
    handles, labels = ax.get_legend_handles_labels()
    leg = ax.legend(handles[::-1],
                    labels[::-1],
                    loc='upper left',
                    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('Planet size [Earth radii]')

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

    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'

    outpath = (
        '../results/rp_vs_age_scatter/rp_vs_age_scatter_{}{}.png'.format(
            today_YYYYMMDD(), savstr))

    savefig(fig, outpath, writepdf=1, dpi=400)
コード例 #6
0
# Licensed under a 3-clause BSD style license - see LICENSE.rst

import numpy as np

import astropy.units as u
from astropy.table import Column, Table, unique, vstack
from astroquery.nasa_exoplanet_archive import NasaExoplanetArchive

exo = NasaExoplanetArchive.get_confirmed_planets_table(all_columns=True)

# We don't need the planets for this project that don't have a distance,
# know radius or orbital period

planet_filter = np.logical_or.reduce(
    (exo['st_dist'] == 0, exo['pl_radj'] == 0, exo['pl_orbper'] == 0))
to_remove_idx = np.where(planet_filter)[0]

exo.remove_rows(to_remove_idx)

# We currently can't yet unique a Table that has mixins, but we don't need the
# mixins here anyway, so copy what we need to a new table

hosts = unique(Table(exo['pl_hostname', 'ra', 'dec', 'st_dist', 'st_teff']))

exoplanets = Table(exo['pl_hostname', 'pl_name', 'pl_orbper', 'pl_radj',
                       'pl_orbsmax', 'pl_orbeccen'])

# Add the Solar System manually

hosts.add_row(['Sun', 0, 0, 0, 5777])
コード例 #7
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)
コード例 #8
0
def plot_rp_vs_age_scatter(active_targets=1, specialyoung=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

    #
    # 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')
    print(42*'-')
    print('Ages below 500 Myr:')
    _t = t[(t['st_age'] < 0.5*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*1e9, 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]

    if active_targets:

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

        ax.plot(target_age*1e9, target_rp, mew=0.5, markerfacecolor=mfc,
                markersize=ms, 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']*1e9, 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, 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(_age*1e9, _rp, mew=0.5, markerfacecolor='lightskyblue', markersize=8,
                marker='*', color='k', lw=0, label=l,
                zorder=1)

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

    leg.get_frame().set_linewidth(0.5)

    ax.set_xlabel('Age [years]')
    ax.set_ylabel('Planet size [Earth radii]')
    ax.set_xlim([6e-3*1e9, 17*1e9])
    format_ax(ax)
    ax.set_xscale('log')

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

    outpath = (
        '../results/rp_vs_age_scatter/rp_vs_age_scatter_{}{}.png'.
        format(today_YYYYMMDD(), savstr)
    )

    savefig(fig, outpath, writepdf=1, dpi=400)
コード例 #9
0
import numpy as np
import matplotlib.pyplot as plt
import os

pwd = os.getcwd()
plt.ion()

from astroquery.nasa_exoplanet_archive import NasaExoplanetArchive

pl = NasaExoplanetArchive.get_confirmed_planets_table()
pl.keys()

jup_to_sun = 1.89813e30 / 1.989e33

m = pl['pl_bmassj'].value  # [M_J]
mu = pl['pl_bmassjerr1'].value  # upper bound
ml = pl['pl_bmassjerr2'].value  # lower
pl['pl_bmassjlim'].value  # whether the mass is M sin i

d = pl['st_dist'].value  # [pc]
du = pl['st_disterr1'].value  # upper
dl = pl['st_disterr2'].value  # lower

#m *= jup_to_sun # [M_\odot]
#mu *= jup_to_sun
#ml *= jup_to_sun

bins = np.logspace(-3, np.log10(50), 100)
hist, bin_edges = np.histogram(m, bins)
hist, bin_edges
print(np.sum(hist), 'planets in bins.\n', len(m), 'planets in dataset.')
コード例 #10
0
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)
コード例 #11
0
import os
import pandas as pd
import numpy as np
from astroquery.nasa_exoplanet_archive import NasaExoplanetArchive as query

# reads a data file (.csv) from a designated file path
params_df = pd.read_csv("\\path\\to\\data")

# retrieves data from the archive through astroquery
exoplanet_archive_table = query.get_confirmed_planets_table()

# pl_hostname refers to the the planet's star host names
# pl_pnum refers to the number of planets around the host
star_names = exoplanet_archive_table["pl_hostname"]
num_of_planets = exoplanet_archive_table["pl_pnum"]


def create_new_df(names, num_of_planets):
    """Creates a new pandas DataFrame that will be used to add to an existing
       data set

    Arguments:
        names {astropy.table.column.MaskedColumn} -- a column of host star names
        num_of_planets {astropy.table.column.MaskedColumn} -- a column of the
            number of planets for each star in the names column

    Returns:
        pandas.DataFrame -- consisting of the star names and number of planets
            as two columns
    """
    names_df = pd.Series(data=star_names)
コード例 #12
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))
コード例 #13
0
def calculate_pdots(signifiant_trends=1):

    if signifiant_trends:
        datapath = '../data/Knutson_2014_tables7_and_8_joined.csv'
    else:
        datapath = '../data/Knutson_2014_tables7_and_8_joined_limits.csv'

    df = pd.read_csv(datapath)
    k14_plnames = nparr(df.planet)

    gamma_dot_value = nparr(df.gammadot) * (u.m / u.s) / u.day
    gamma_dot_perr = nparr(df.gammadot_pluserr) * (u.m / u.s) / u.day
    gamma_dot_merr = nparr(df.gammadot_minuserr) * (u.m / u.s) / u.day
    gamma_dot_upper_limit = (gamma_dot_value + 1 * gamma_dot_perr)
    gamma_dot_lower_limit = (gamma_dot_value - 1 * gamma_dot_merr)

    #
    # get orbital periods for all the planets
    # manual periods:
    #   * XO-2b fails because host star is binary; planets are known around both
    #   components.
    #   * HAT-P-10 = WASP-11
    #
    t = NasaExoplanetArchive.get_confirmed_planets_table(all_columns=False)
    ea_df = t.to_pandas()
    selcols = ['pl_name', 'pl_orbper']
    ea_seldf = ea_df[selcols]

    mdf = df.merge(ea_seldf, left_on='planet', right_on='pl_name', how='left')
    if signifiant_trends:
        mdf.loc[mdf['planet'] == 'XO-2 b', 'pl_orbper'] = 2.615862
        mdf.loc[mdf['planet'] == 'HAT-P-10 b', 'pl_orbper'] = 3.7224690
    else:
        badnames = ['GJ436 b', 'HD149026 b']
        badnameperiods = [2.643904, '2.87588874']
        for n, per in zip(badnames, badnameperiods):
            mdf.loc[mdf['planet'] == n, 'pl_orbper'] = per

    #
    # calculate Pdot
    #
    P = nparr(mdf['pl_orbper']) * u.day
    dP_dt_value = gamma_dot_value * P / c.c
    dP_dt_upper_limit = gamma_dot_upper_limit * P / c.c
    dP_dt_lower_limit = gamma_dot_lower_limit * P / c.c

    #
    # insert into data frame and save
    #
    mdf['Pdot'] = dP_dt_value.to(u.millisecond / u.year)
    mdf['Pdot_upper_limit'] = dP_dt_upper_limit.to(u.millisecond / u.year)
    mdf['Pdot_lower_limit'] = dP_dt_lower_limit.to(u.millisecond / u.year)
    mdf['Pdot_perr'] = (dP_dt_upper_limit.to(u.millisecond / u.year) -
                        dP_dt_value.to(u.millisecond / u.year))
    mdf['Pdot_merr'] = (dP_dt_value.to(u.millisecond / u.year) -
                        dP_dt_lower_limit.to(u.millisecond / u.year))

    if signifiant_trends:
        outpath = '../results/knutson_significant_population_pdots.csv'
    else:
        outpath = '../results/knutson_limit_population_pdots.csv'
    mdf.to_csv(outpath, sep=';', index=False)
    print('made {}'.format(outpath))

    return mdf
コード例 #14
0
    def get_data(self,
                 by_method: bool = True,
                 by_class: bool = True,
                 cache: bool = True):
        """
        Get the current total number of confirmed exoplanets from the
        NASA Exoplanet Archive. Additionally, also get the number of
        exoplanets grouped by detection method or by planet class (if
        desired).

        Args:
            by_method: Whether or not to also return the exoplanet count
                grouped by detection method.
            by_class: Whether or not to also return the exoplanet count
                grouped by (approximate) planet class.
            cache: Whether or not to cache results or use cached
                results.

        Returns:
            A dictionary with keys `{"total", "by_method", "by_class"}`
            which holds the respective count of exoplanets.
        """

        # Instantiate the dictionary that will hold the results
        exoplanet_count = dict()

        # Get the confirmed exoplanets form the NASA Exoplanet Archive.
        # In case we do not have internet access (and thus get an URLError),
        # the function ends here already (i.e., self.data will remain None).
        try:
            confirmed_exoplanets = \
                NasaExoplanetArchive.get_confirmed_planets_table(cache=cache)
        except URLError:
            return

        # Get the total count of all confirmed planets
        exoplanet_count['total'] = len(confirmed_exoplanets)

        # Get count by detection method
        if by_method:
            exoplanet_count['by_method'] = \
                dict(Counter(list(confirmed_exoplanets['pl_discmethod'])))

        # Get count by planet class (by looping over all confirmed exoplanets
        # and classifying each of them based on its respective mass and radius)
        if by_class:

            # Initialize the sub-dictionary that will hold the counts per class
            exoplanet_count['by_class'] = dict()

            # Loop over all confirmed exoplanets and classify them individually
            for i in range(len(confirmed_exoplanets)):

                # Get the mass and radius and cast to a astropy.units.Quantity
                # Note: The NASA Exoplanet Archive usually returns values in
                #       Jupiter units.
                mass = float(
                    str(confirmed_exoplanets[i]['pl_bmassj']).split()[0])
                mass = u.Quantity(mass, u.jupiterMass)
                radius = float(
                    str(confirmed_exoplanets[i]['pl_radj']).split()[0])
                radius = u.Quantity(radius, u.jupiterRad)

                # Classify the exoplanet based on these values
                planet_class = get_exoplanet_class(mass=mass, radius=radius)

                # Increase the count for the planet class
                if planet_class in exoplanet_count['by_class'].keys():
                    exoplanet_count['by_class'][planet_class] += 1
                else:
                    exoplanet_count['by_class'][planet_class] = 1

        # Store away the data retrieved by this method
        self.data = exoplanet_count
コード例 #15
0
def plot_population():
    """This plots the exoplanet population to create a plot of selectable planets
    in the exoplanet population

    It is based off a Gist by Brett Morris (github bmorris3), pulling it from
    Notebook form and adding an interactive plot.

    Jens Hoeijmakers, 04-05-2020"""
    import numpy as np
    import matplotlib.pyplot as plt
    import astropy.units as u
    from astroquery.nasa_exoplanet_archive import NasaExoplanetArchive


    #First establish the rules that a planet must satisfy in order to be printed / highlighted.
    teq_min = 1000 * u.K
    teq_max = 1300 * u.K
    rad_min = 2 * u.R_earth
    rad_max = 4 * u.R_earth
    gaia_mag_limit = 13
    P_min = 0.0 * u.day
    P_max = 1.0 * u.day

    #Read the archive and compute the equilibrium temperature.
    #TO DO: SOME PLANETS FALL OUT BECAUSE THEY DONT HAVE A STELLAR EFFECTIVE TEMPERATURE AND/OR STELLAR RADIUS.
    #HOWEVER THESE CAN BE APPROXIMATED FROM THE SPECTRAL TYPE. FOR EACH MISSING VALUE, I NEED TO LOOK UP WHAT A STAR WITH
    #THAT SPECTRAL TYPE TYPICALLY HAS FOR VALUES OF R_S AND T_EFF, AND REPLACE THOSE.
    table = NasaExoplanetArchive.get_confirmed_planets_table(all_columns=True)#This is an astropy table.
    transiting = table[(table['pl_tranflag'].data).astype(bool)]#Select only the transiting ones, and put them in a new table.
    rp = transiting['pl_radj']#Short-hand for planet radii.
    equilibrium_temperature = (transiting['st_teff'] * np.sqrt(transiting['st_rad'] / 2 / transiting['pl_orbsmax'])).decompose()#Compute T_eq.
    g = transiting['gaia_gmag'].quantity#Short-hand for the Gaia magnitude.
    P = transiting['pl_orbper']
    transiting['teq'] = equilibrium_temperature

    #Create boolean arrays for selecting the rows in the table, based on the above rules.
    temp_constraints = (equilibrium_temperature < teq_max) & (equilibrium_temperature > teq_min)
    rad_constraints = (rp < rad_max) & (rp > rad_min)
    gmag_constaints = (g < gaia_mag_limit)
    P_constraints = (P > P_min) & (P < P_max)
    targets = transiting[temp_constraints & rad_constraints & gmag_constaints]#These are the highlighted planets.
    targets = transiting[P_constraints]
    targets.sort('gaia_gmag')
    targets['r_earth'] = targets['pl_radj'].to(u.R_earth)
    targets[['pl_name', 'gaia_gmag', 'teq', 'r_earth', 'pl_orbper','st_rad','st_teff','st_spstr']].pprint(max_lines=1000)



    #Now we move on to plotting the population

    #These are rules for the planets that will be plotted as gray background points.
    has_rp = (rp > 0.0)#There needs to be a radius
    has_rs = (transiting['st_rad'] > 0)#...a stellar radius
    has_teff = (transiting['st_teff'] > 0)#... a stellar T_eff
    # is_spt = (transiting['st_spstr'].astype(str) == 'K2 V')#Test for being a particular spectral type. Will be needed to fill in systems with missing effective temperatures.
    systems_to_plot = transiting[has_rp & has_rs & has_teff]#Only transiting planets here.

    fig,ax = plt.subplots()
    sc = plt.scatter(systems_to_plot['teq'],systems_to_plot['pl_radj'].to(u.R_earth),c='gray',s=20,alpha=0.5)
    sct=plt.scatter(targets['teq'],targets['pl_radj'].to(u.R_earth),c='orange',s=20,alpha=0.5)
    ax.set_ylabel('Radius ($R_E$)')
    ax.set_xlabel('Equilibrium temperature (K)')
    ax.set_title('Temperature versus Radius')
    ax.set_xlim(ax.get_xlim()[::-1])


    #And this is all annotation, taken from :
    annot = ax.annotate("", xy=(0,0), xytext=(20,20),textcoords="offset points",bbox=dict(boxstyle="round", fc="w"),arrowprops=dict(arrowstyle="->"))
    annot.set_visible(False)
    names = systems_to_plot['pl_name']
    gmags = systems_to_plot['gaia_gmag']
    Ps = systems_to_plot['pl_orbper']
    def update_annot_new(ind):
        pos = sc.get_offsets()[ind["ind"][0]]
        annot.xy = pos
        text=''
        n_in = len(ind["ind"])
        prefix=''#This becomes a newline if the forloop is run through more than once.
        for n in ind["ind"]:
            text+=prefix+names[n]+'\n'
            text+='     G = %s \n'%np.round(gmags[n],2)
            text+='     P = %s'%np.round(Ps[n],2)
            prefix='\n'
        # text = "{}, {}".format(" ".join(list(map(str,ind["ind"])))," ".join([names[n] for n in ind["ind"]]))
        annot.set_text(text)
        annot.get_bbox_patch().set_alpha(0.4)
    def newhover(event):
        vis = annot.get_visible()
        if event.inaxes == ax:
            cont, ind = sc.contains(event)
            if cont:
                update_annot_new(ind)
                annot.set_visible(True)
                fig.canvas.draw_idle()
            else:
                if vis:
                    annot.set_visible(False)
                    fig.canvas.draw_idle()
    fig.canvas.mpl_connect("motion_notify_event", newhover)
    plt.show()
コード例 #16
0
from astropy.visualization import astropy_mpl_style, quantity_support

plt.style.use(astropy_mpl_style)
quantity_support()
from astropy.coordinates import get_sun
from astroquery.nasa_exoplanet_archive import NasaExoplanetArchive
from astroquery.exoplanet_orbit_database import ExoplanetOrbitDatabase
#primary_eclipse_time = Time(2452826.628514, format='jd')
#orbital_period = 3.52474859 * u.day
#eclipse_duration = 0.1277 * u.day
#
#hd209458 = EclipsingSystem(primary_eclipse_time=primary_eclipse_time,
#                           orbital_period=orbital_period, duration=eclipse_duration,
#                           name='HD 209458 b')

planet_properties = NasaExoplanetArchive.query_planet('TRAPPIST-1 b',
                                                      all_columns=True)

# get relevant planet properties
epoch = Time(planet_properties['pl_tranmid'], format='jd')
period = planet_properties['pl_orbper']
transit_duration = planet_properties['pl_trandur'] * u.day

# Create an EclipsingSystem object for HD 209458
#from astroplan import EclipsingSystem
trappist1b = astroplan.EclipsingSystem(primary_eclipse_time=epoch,
                                       orbital_period=period,
                                       duration=transit_duration)

# Calculate next three mid-transit times which occur after ``obs_time``
obs_time = Time('2017-01-01 12:00')
trappist1b.next_primary_eclipse_time(obs_time, n_eclipses=3)
コード例 #17
0
def plot_rp_vs_age_scatter(active_targets=0):

    # columns described at
    # https://exoplanetarchive.ipac.caltech.edu/docs/API_exoplanet_columns.html
    ea_tab = NasaExoplanetArchive.get_confirmed_planets_table(
        all_columns=True, show_progress=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]

    #
    # 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 all "good cols". (age is on y axis b/c it has the error bars, and
    # I at least skimmed the footnotes of Hogg 2010)
    f, ax = plt.subplots(figsize=(4, 3))

    # squares
    label = ('NASA Exoplanet Archive, ' +
             r"$\langle \sigma_{{\mathrm{{age}}}} \rangle$ = " +
             "{:.1f} Gyr".format(np.median(age_errs)))
    ax.scatter(age,
               rp,
               color='gray',
               s=3,
               zorder=1,
               marker='o',
               linewidth=0,
               label=label,
               alpha=1)

    # targets
    tdf = pd.read_csv(
        os.path.join(
            os.path.expanduser("~"),
            'Dropbox/proj/cdips_followup/results/20190926_2020A_targets_age_rp.csv'
        ))

    badids = [
        4827527233363019776, 2919143383943171200, 3340674976430098688,
        5561614350584396800, 5618515825371166464
    ]
    tdf = tdf[~tdf['source_id'].isin(badids)]

    target_age = 10**(np.array(tdf['age'])) / (1e9)
    target_rp = np.array(tdf['rplanet'])
    target_rp_unc = np.array(tdf['rplanet_unc'])

    if active_targets:
        ax.scatter(
            target_age,
            target_rp,
            color='black',
            s=25,
            zorder=3,
            marker='*',
            linewidth=0,
            label=
            r'Active targets, $\langle \sigma_{{\mathrm{{age}}}} \rangle$ < 0.1 Gyr'
        )

        target_rp_rel_unc = target_rp_unc / target_rp

        ##########
        # HACK: force to 30% relative uncertainty for TOI-520, b/c fits did not
        # converge
        sel = target_rp_rel_unc > 0.5
        target_rp_unc[sel] = target_rp[sel] * 0.3
        ##########

        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)

    ## error bars
    #ax.errorbar(age, rp, yerr=age_errs, xerr=rp_errs,
    #            elinewidth=0.3, ecolor='k', capsize=0, capthick=0, linewidth=0,
    #            fmt='s', ms=0, zorder=2, alpha=0.05)

    # flip default legend order
    handles, labels = ax.get_legend_handles_labels()
    ax.legend(handles[::-1],
              labels[::-1],
              loc='lower left',
              borderpad=0.1,
              handletextpad=0.1,
              fontsize='small',
              framealpha=1)

    ax.set_xlabel('Age [Gyr]')
    ax.set_ylabel('Planet radius [R$_\oplus$]')

    ax.get_yaxis().set_tick_params(which='both', direction='in')
    ax.get_xaxis().set_tick_params(which='both', direction='in')

    ax.set_ylim([0.13, 85])

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

    f.tight_layout()
    savstr = '_no_overplot' if not active_targets else '_active_targets'

    outpath = '../results/rp_vs_age_scatter{}.png'.format(savstr)
    f.savefig(outpath, bbox_inches='tight', dpi=450)
    f.savefig(outpath.replace('.png', '.pdf'), bbox_inches='tight')
    print('made {}'.format(outpath))