예제 #1
0
def depth2rp(P_days, depth, duration_days, Ms, Rs):
    '''Compute the planet radius from the transit depth and 
    duration using the analtyical treatment from Mandel & Agol 2002'''
    assert 0 < depth < 1

    # compute distance from centres at T0
    sma = rvs.semimajoraxis(P_days, Ms, 0)
    a_Rs = rvs.AU2m(sma) / rvs.Rsun2m(Rs)
    assert a_Rs > 1
    b = rvs.impactparam_T(P_days, Ms, Rs, duration_days)
    assert abs(b) <= 1
    inc = float(rvs.inclination(P_days, Ms, Rs, b))
    z = compute_distance_center(a_Rs, inc)

    # compute size ratio (p=rp/Rs)
    p_simple = unp.sqrt(depth)
    if z <= 1 - p_simple:
        p = p_simple

    else:
        ps = np.logspace(-6, 0, 1000)
        depths = p2depth_grazing(ps, z)
        if (np.nanmax(depths) < z) or (np.nanmin(depths) > z):
            p = p_simple
        else:
            fint = interp1d(ps, depths)
            p = float(fint(depth))

    # compute planet radius
    rp = rvs.m2Rearth(rvs.Rsun2m(p * Rs))
    return rp
예제 #2
0
    def compute_transit_prob(self):
        self.transit_prob, self.etransit_prob = np.zeros_like(self.sens), \
                                                       np.zeros_like(self.sens)
        self.logtransit_prob,self.elogtransit_prob = np.zeros_like(self.sens), \
                                                            np.zeros_like(self.sens)
        for i in range(self._xlen):
            for j in range(self._ylen):

                # compute transit probability in log-linear space
                Pmid = 10**(np.log10(self.logPgrid[i]) + \
                            np.diff(np.log10(self.logPgrid[:2])/2))
                rpmid = self.rpgrid[j] + np.diff(self.rpgrid)[0] / 2.
                sma = rvs.AU2m(
                    rvs.semimajoraxis(Pmid, unp.uarray(self.Ms, self.e_Ms), 0))
                transit_prob =  (rvs.Rsun2m(unp.uarray(self.Rs, self.e_Rs)) + \
                                 rvs.Rearth2m(rpmid)) / sma
                self.transit_prob[i, j] = unp.nominal_values(transit_prob)
                self.etransit_prob[i, j] = unp.std_devs(transit_prob)

                # compute transit probability in log-linear space
                rpmid = 10**(np.log10(self.logrpgrid[j]) + \
                             np.diff(np.log10(self.logrpgrid[:2])/2))
                transit_prob =  (rvs.Rsun2m(unp.uarray(self.Rs, self.e_Rs)) + \
                                               rvs.Rearth2m(rpmid)) / sma
                self.logtransit_prob[i, j] = unp.nominal_values(transit_prob)
                self.elogtransit_prob[i, j] = unp.std_devs(transit_prob)

        # correction from beta distribution fit (Kipping 2013)
        factor = 1.08
        self.transit_prob *= factor
        self.etransit_prob *= factor
        self.logtransit_prob *= factor
        self.elogtransit_prob *= factor
예제 #3
0
def sampleK218incdeg_uncorr(incbb, sig=1.5):
    '''Sample incc from a Gaussian but reject inclinations that result in a transit.'''
    #sig = 2.2 * 3  # 3sigma on mode of mutual inclination distribution from Fabrycky+2014
    smac = .06
    incc = incbb + np.random.randn() * sig
    b = rvs.impactparam_inc(smac / rvs.m2AU(rvs.Rsun2m(Rs)), incc)
    while abs(b) < 1:
        incc = incbb + np.random.randn() * sig
        b = rvs.impactparam_inc(smac / rvs.m2AU(rvs.Rsun2m(Rs)), incc)
    return incc
예제 #4
0
def _fit_params(params, bjd, fcorr, ef, Ms, Rs, Teff, Kep=False, TESS=False):
    '''Get best-fit parameters.'''
    assert params.shape == (4, )
    P, T0, depth, duration = params
    if Kep:
        u1, u2 = llnl.get_LDcoeffs_Kepler(Ms, Rs, Teff)
    elif TESS:
        u1, u2 = llnl.get_LDcoeffs_TESS(Ms, Rs, Teff)

    aRs = rvs.AU2m(rvs.semimajoraxis(P, Ms, 0)) / rvs.Rsun2m(Rs)
    rpRs = np.sqrt(depth)
    p0 = aRs, rpRs, 90.
    bnds = ((aRs * .9, 0, float(rvs.inclination(P, Ms, Rs, 1.1))),
            (aRs * 1.1, 1, float(rvs.inclination(P, Ms, Rs, -1.1))))
    try:
        popt, _ = curve_fit(transit_model_func_curve_fit(P, T0, u1, u2),
                            bjd,
                            fcorr,
                            p0=p0,
                            sigma=ef,
                            absolute_sigma=True,
                            bounds=bnds)
        aRs, rpRs, inc = popt
        depth = rpRs**2
        b = rvs.impactparam_inc(P, Ms, Rs, inc)
        duration = P / (np.pi * aRs) * np.sqrt((1 + np.sqrt(depth))**2 - b * b)
        return P, T0, depth, duration
    except RuntimeError:
        return params
예제 #5
0
def _is_Vshaped(params,
                bjd,
                fcorr,
                ef,
                Ms,
                Rs,
                Teff,
                Kep,
                TESS,
                duration_frac=.05):
    '''check if transit is V-shaped although this does not imply an EB 
    because inclined transiting planets can look like this as well.'''
    # fit transit model
    assert params.shape == (4, )
    P, T0, depth = params[:3]
    if Kep:
        u1, u2 = llnl.get_LDcoeffs_Kepler(Ms, Rs, Teff)
    elif TESS:
        u1, u2 = llnl.get_LDcoeffs_TESS(Ms, Rs, Teff)

    aRs = rvs.AU2m(rvs.semimajoraxis(P, Ms, 0)) / rvs.Rsun2m(Rs)
    rpRs = np.sqrt(depth)
    p0 = aRs, rpRs, 90.
    bnds = ((aRs * .9, 0, float(rvs.inclination(P, Ms, Rs, 1.1))),
            (aRs * 1.1, 1, float(rvs.inclination(P, Ms, Rs, -1.1))))
    try:
        popt, _ = curve_fit(transit_model_func_curve_fit(P, T0, u1, u2),
                            bjd,
                            fcorr,
                            p0=p0,
                            sigma=ef,
                            absolute_sigma=True,
                            bounds=bnds)
        aRs, rpRs, inc = popt
    except RuntimeError:
        return False, 0.

    # get ingress, egress times and duration
    transit_func = transit_model_func_curve_fit(P, T0, 0, 0)
    fmodel = transit_func(bjd, *popt)
    phase = foldAt(bjd, P, T0)
    phase[phase > .5] -= 1
    depth = fmodel.min()
    T1, T4 = phase[(phase<=0) & (fmodel==1)].max()*P, \
             phase[(phase>=0) & (fmodel==1)].min()*P
    in_ingress = (phase <= 0) & np.isclose(fmodel, depth, rtol=1e-4)
    T2 = phase[in_ingress].min() * P if in_ingress.sum() > 0 else (T4 -
                                                                   T1) * .1
    in_egress = (phase >= 0) & np.isclose(fmodel, depth, rtol=1e-4)
    T3 = phase[in_egress].max() * P if in_egress.sum() > 0 else (T4 - T1) * .1
    Tingress, Tegress, duration = T2 - T1, T4 - T3, T4 - T1
    Tedge = Tingress + Tegress

    # V-shaped if T2==T3 or if ingress+egress time is the same as the duration
    if T2 == T3:
        return True, duration
    elif np.isclose(Tedge, duration, rtol=duration_frac):
        return True, duration
    else:
        return False, duration
예제 #6
0
def _compute_sigrp(frac_sigRs=.1):
    '''
    Use the TESS parameters to estimate the measurement uncertainty on the 
    planet's radius. See http://adsabs.harvard.edu/abs/2008ApJ...689..499C 
    for equations.
    '''
    # Get the 3sigma results
    starnums, Nharps, Nnirps, Nspirou, texpharps, texpnirps, texpspirou, tobsharps, tobsnirps, tobsspirou, min_Nrv, bestspectrograph_Nrv, min_tobs, bestspectrograph_tobs = np.loadtxt(
        'Results/median_results_3sigma_mp.dat', delimiter=',').T

    # Get TESS parameters including photometric uncertainty
    inds = np.array([2, 3, 5, 6, 14])
    rp, P, K, Rs, logsigV = np.ascontiguousarray(get_TESS_data())[inds]

    # Compute transit depth uncertainty
    depth = compute_depth(rp, Rs)
    Gamma = compute_Gamma()
    T = compute_transit_duration(rp, P, K, Rs)
    Q = compute_Q(Gamma, T, depth, logsigV)
    sigdepth = compute_sigdepth(depth, Q)

    # compute corresponding planet radius uncertainty
    depth = unp.uarray(depth, sigdepth)
    Rs2 = rvs.m2Rearth(rvs.Rsun2m(unp.uarray(Rs, frac_sigRs * Rs)))
    rp2 = unp.sqrt(depth) * Rs2
    return rp, unp.std_devs(rp2)
예제 #7
0
    def __init__(self, folder, index, index2, Nyrs=1e6, Nout=500):

        self.index, self.index2, self.Nyrs, self.Nout = int(index), int(
            index2), int(Nyrs), int(Nout)
        self.Ms = 0.
        while self.Ms <= 0:
            self.Ms = Ms + np.random.randn() * .0032
        self.bjd0 = 2458354.101878819  # first TESS photometry epoch
        self.DONE = False

        # Setup simulation
        self.folder = folder
        self.outname = '%s/SimArchive/archived%.4d_%.4d' % (
            self.folder, self.index, self.index2)
        sim = setupsim(self, self.outname)
        self.mps, self.sma0, self.ecc0, self.inc0, self.omega0, self.Omega0, self.theta0 = get_initial_parameters(
            sim)
        self.inc0 += 90
        #self.Rhill = get_Rhill_init(self.mps, self.Ms, self.sma0)
        self.pickleobject()

        # Integrate simulation
        print 'Integrating system...'
        self.bjds,self.RVs,self.smas,self.eccs,self.incs,self.dist,self.stable = \
         integrate_sim(np.linspace(0, rvs.yrs2days(self.Nyrs), self.Nout) + self.bjd0, sim)
        self.bs = np.zeros(self.incs.shape)
        for i in range(self.bjds.size):
            self.bs[i] = rvs.impactparam_inc(rvs.AU2m(self.smas[i]) /
                                             rvs.Rsun2m(Rs),
                                             self.incs[i] + 90,
                                             ecc=self.eccs[i])
        self.DONE = True
        self.pickleobject()
예제 #8
0
def compute_transit_duration(rp, P, K, Rs, b=0):
    mp = np.array([runTESS.get_planet_mass(i) for i in rp])
    Ms = runTESS.get_stellar_mass(P, mp, K)
    sma = rvs.AU2m(rvs.semimajoraxis(P, Ms, mp))
    Rs2 = rvs.Rsun2m(Rs)
    tau0 = P * Rs2 / (2 * np.pi * sma)
    return 2. * tau0 * np.sqrt(1. - b**2)
예제 #9
0
def estimate_box_transit_model(P, T0, Rs, t, f, ef):
    '''Estimate the transit depth and duration given P and T0. Return 
    the box transit model.'''
    phase = foldAt(t, P, T0)
    phase[phase > .5] -= 1
    intransit_approx = (phase * P <= 15. / 60 / 24) & (phase * P >=
                                                       -15. / 60 / 24)
    depth = np.median(f[intransit_approx])
    duration = rvs.transit_width(P, Rs, Rs,
                                 rvs.m2Rearth(np.sqrt(depth) * rvs.Rsun2m(Rs)),
                                 0)
    model = llnl.box_transit_model((P, T0, depth, duration), t)
    return model
예제 #10
0
def optimize_singletransit_params(params,
                                  bjd,
                                  fcorr,
                                  ef,
                                  Ms,
                                  Rs,
                                  u1,
                                  u2,
                                  pltt=True):
    '''Get best-fit parameters using the periodic fit parameters for 
    initialization (i.e. P_input < P_singletransit).'''
    assert params.shape == (4, )
    P, T0, depth, duration = params
    if depth >= .9:  # sometimes the dimming is passed instead of depth
        return np.nan, np.nan, np.nan, np.nan, \
            np.repeat(np.nan, bjd.size), np.repeat(np.nan, 7)
    # focus on data centered around T0
    g = (bjd >= T0 - 10 * duration) & (bjd <= T0 + 10 * duration)
    bjdred, fcorrred, efred = bjd[g], fcorr[g], ef[g]

    # initialize
    aRs = rvs.AU2m(rvs.semimajoraxis(P, Ms, 0)) / rvs.Rsun2m(Rs)
    rpRs = np.sqrt(depth)
    p0 = P, T0, aRs, rpRs, 90.
    incs = np.array([
        float(rvs.inclination(P, Ms, Rs, 1)),
        float(rvs.inclination(P, Ms, Rs, -1))
    ])
    bnds = ((0, T0 - .2, 0, 0, incs.min()), (P * 100, T0 + .2, aRs * 100, 1,
                                             incs.max()))
    try:
        popt, _ = curve_fit(llnl.transit_model_func_curve_fit(u1, u2),
                            bjdred,
                            fcorrred,
                            p0=p0,
                            sigma=efred,
                            absolute_sigma=True,
                            bounds=bnds)
        P, T0, aRs, rpRs, inc = popt
        depth = rpRs**2
        b = rvs.impactparam_inc(P, Ms, Rs, inc)
        duration = P / (np.pi * aRs) * np.sqrt((1 + np.sqrt(depth))**2 - b * b)
        func = llnl.transit_model_func_curve_fit(u1, u2)
        fmodel = func(bjdred, P, T0, aRs, rpRs, inc)
        params = np.array([P, T0, aRs, rpRs, inc, u1, u2])
    except RuntimeError, ValueError:
        func = llnl.transit_model_func_curve_fit(u1, u2)
        fmodel = func(bjdred, P, T0, aRs, rpRs, 90.)
        P, T0, depth, duration = np.repeat(np.nan, 4)
        params = np.repeat(np.nan, 7)
예제 #11
0
def sampleK218cincdeg(smac, eccc):
    '''Sample the orbital inclination from its eccentrcitity (<i^2>=<e^2>/4)
    ensuring that the planet does not transit. 
    smac in AU.'''
    b, ind = 0, 0
    while abs(b) < 1:
        incc = incb + np.rad2deg(np.sqrt(eccc**2 / 4.)) * np.random.choice(
            [-1, 1])
        # Add noise to inc if cannot find solution
        if ind > 100:
            incc += np.random.randn() * ind / 100.
        b = rvs.impactparam_inc(smac / rvs.m2AU(rvs.Rsun2m(Rs)), incc)
        ind += 1
    return incc
예제 #12
0
def get_LDcoeffs_TESS(Ms, Rs, Teff, Z=0):
    '''Interpolate Claret 2017 grid of limb darkening coefficients to a
    given star.'''
    # get LD coefficient grid (Z is always 0 for some reason)
    clarlogg, clarTeff, clarZ, clar_a, clar_b = \
                                    np.loadtxt('LDcoeffs/claret17.tsv',
                                               delimiter=';', skiprows=37).T

    # interpolate to get the stellar LD coefficients
    logg = np.log10(6.67e-11 * rvs.Msun2kg(Ms) * 1e2 / rvs.Rsun2m(Rs)**2)
    lint_a = lint(np.array([clarTeff, clarlogg]).T, clar_a)
    lint_b = lint(np.array([clarTeff, clarlogg]).T, clar_b)

    return float(lint_a(Teff, logg)), float(lint_b(Teff, logg))
예제 #13
0
def create_input_file(g, rp, Rs, cloudP, outfile='GCM/terminator/GCM.dat'):
    '''
    Create ExoTransmit input file.

    Parameters
    ----------
    `outfile': str
        Name of the output file containing the transmission spectrum
    `g': scalar
        Planetary surface gravity in m/s^2
    `rp': scalar
        Planetary radius in Earth radii
    `Rs': scalar
        Stellar radius in Solar radii
    `cloudP': scalar
	Pressure level of the grey cloud deck in Pascals

    '''
    # create subdirectories if necessary
    dirs = outfile.split('/')[:-1]
    for i in range(len(dirs)):
        try:
            dirr = '/'.join(dirs[:i + 1])
            os.mkdir('%s/Spectra/%s' % (path2exotransmit, dirr))
        except OSError:
            pass

    # get template
    fname = '%s/userInput_template.in' % path2exotransmit
    f = open(fname, 'r')
    h = f.readlines()
    f.close()

    h[3] = '%s\n' % path2exotransmit
    h[5] = '/T_P/%s\n' % TPfile
    h[7] = '/EOS/%s\n' % EOSfile
    h[9] = '/Spectra/%s\n' % outfile
    h[11] = '%.2f\n' % g
    h[13] = '%.2e\n' % rvs.Rearth2m(rp)
    h[15] = '%.2e\n' % rvs.Rsun2m(Rs)
    h[17] = '%.2e\n' % cloudP
    h[19] = '1.0\n'

    # write file
    f = open('%s/%s' % (path2exotransmit, userfile), 'w')
    f.write(''.join(h))
    f.close()
예제 #14
0
def get_LDcoeffs_Kepler(Ms, Rs, Teff, Z=0):
    '''Interpolate Claret+2012 grid of limb darkening coefficients to a
    given star.'''
    # get LD coefficient grid (Z is always 0 for some reason)
    clarlogg, clarTeff, clarZ, clar_a, clar_b = \
                                    np.loadtxt('LDcoeffs/claret12.tsv',
                                               delimiter=';', skiprows=43,
                                               usecols=(0,1,2,3,4)).T

    # interpolate to get the stellar LD coefficients
    logg = np.log10(6.67e-11 * rvs.Msun2kg(Ms) * 1e2 / rvs.Rsun2m(Rs)**2)
    logg = 5. if logg > 5 else float(logg)
    logg = 3.5 if logg < 3.5 else float(logg)
    lint_a = lint(np.array([clarTeff, clarlogg]).T, clar_a)
    lint_b = lint(np.array([clarTeff, clarlogg]).T, clar_b)

    return float(lint_a(Teff, logg)), float(lint_b(Teff, logg))
예제 #15
0
def _draw_prot(Ms, Rs, fname):
    '''
    Draw a rotation period and compute vsini or use the existing parameters 
    for this system.
    '''
    # If a simulation of this system exists, read in those parameters
    fs = np.array(
        glob.glob('%s_*_%s' % (fname.split('_')[0], fname.split('_')[-1])))
    if fs.size > 0:
        Prot, vsini = np.loadtxt(fs[0], usecols=(11, 12))

    # Otherwise sample new rotation information
    else:
        Prot = draw_prot_empirical(Ms)
        I = abs(np.arccos(np.random.uniform(-1, 1)))
        vsini = 2 * np.pi * rvs.Rsun2m(Rs) * 1e-3 * np.sin(I) / rvs.days2sec(
            Prot)
    return Prot, vsini
예제 #16
0
def fit_params(params, bjd, fcorr, ef, Ms, Rs, Teff, Kep=False, TESS=False):
    '''Get best-fit parameters.'''
    assert params.shape == (4, )
    P, T0, depth, duration = params
    if depth >= .9:  # sometimes the dimming is passed instead of depth
        return np.nan, np.nan, np.nan, np.nan, \
               np.repeat(np.nan, bjd.size), np.repeat(np.nan, 7)
    if Kep:
        u1, u2 = get_LDcoeffs_Kepler(Ms, Rs, Teff)
    if TESS:
        u1, u2 = get_LDcoeffs_TESS(Ms, Rs, Teff)
    assert np.all(np.isfinite([u1, u2]))
    aRs = rvs.AU2m(rvs.semimajoraxis(P, Ms, 0)) / rvs.Rsun2m(Rs)
    rpRs = np.sqrt(depth)
    p0 = P, T0, aRs, rpRs, 90.
    incs = np.array([
        float(rvs.inclination(P, Ms, Rs, 1)),
        float(rvs.inclination(P, Ms, Rs, -1))
    ])
    bnds = ((P * .9, T0 - P * 1.1, aRs * .9, 0, incs.min()),
            (P * 1.1, T0 + P * 1.1, aRs * 1.1, 1, incs.max()))
    try:
        popt, _ = curve_fit(transit_model_func_curve_fit(u1, u2),
                            bjd,
                            fcorr,
                            p0=p0,
                            sigma=ef,
                            absolute_sigma=True,
                            bounds=bnds)
        P, T0, aRs, rpRs, inc = popt
        depth = rpRs**2
        b = rvs.impactparam_inc(P, Ms, Rs, inc)
        duration = P / (np.pi * aRs) * np.sqrt((1 + np.sqrt(depth))**2 - b * b)
        func = transit_model_func_curve_fit(u1, u2)
        fmodel = func(bjd, P, T0, aRs, rpRs, inc)
        params = np.array([P, T0, aRs, rpRs, inc, u1, u2])
    except RuntimeError, ValueError:
        func = transit_model_func_curve_fit(u1, u2)
        fmodel = func(bjd, P, T0, aRs, rpRs, 90.)
        P, T0, depth, duration = np.repeat(np.nan, 4)
        params = np.repeat(np.nan, 7)
예제 #17
0
def estimate_Nrv_TESS(planetindex,
                      band_strs,
                      R,
                      aperture_m,
                      QE=.1,
                      Z=0,
                      sigmaRV_activity=0,
                      sigmaRV_planets=0,
                      sigmaRV_noisefloor=.5,
                      testingseed=False,
                      testplanet_sigmaKfrac=0,
                      systnum=0,
                      verbose=True):
    '''
    Estimate the number of RVs required to measure the mass of a transiting 
    TESS planet at a particular detection significance with a particular 
    instrument.

    Parameters
    ----------
    `planetindex': scalar
        Index of the TESS planet from the results of the predicted TESS planets 
        from Sullivan et al 2015
    `band_strs': list of strs
        A list of the spectral bands that span the wavelength coverage of the 
        spectrograph used to measure the radial velocities of the TESS star. 
        All band_strs entries must be in 
        ['U','B','V','R','I','Y','J','H','K']
        and at least one of ['V','I','J','K'] must be included for scaling of 
        the TESS stars from Sullivan
    `R': scalar
        The spectral resolution of the spectrograph (lambda / d_lambda)
    `aperture_m': float
        The telescope's aperture diameter in meters
    `QE': scalar
        The quantum efficiency of the detector (0<QE<=1)
    `Z': scalar
        The assumed metallicity ([Fe/H]) of the TESS star in solar units
    `sigmaRV_activity': scalar
        An additive source of RV uncertainty from RV activity or jitter in m/s. 
        To be added in quadrature to the photon-noise RV precision derived for 
        the TESS star
    `sigmaRV_planets': scalar
        An additive source of RV uncertainty from unseen planets in m/s. 
        To be added in quadrature to the photon-noise RV precision derived for 
        the TESS star
    `testingseed': boolean
        If True, use a seed for the random number generator used to draw the stellar 
        rotation period, RV activity, and RV from planets. Useful for testing
    `testplanet_sigmaKfrac': scalar
        If 0, assume we are calculating a TESS planet and use its mass to 
        determine the required constraint on the K measurement uncertainty 
        (sigmaK). Otherwise, set this value to the fractional K measurement 
        uncertainty as is done for test cases (e.g. 0.33 for GJ1132)
    `systnum': scalar
        System index used when saving the simulation results
    `verbose': boolean
        If True, results for this star are printed to screen

    Returns
    -------
    `Nrv': int
        The number of radial velocity measurements required to detect the TESS 
        planet's mass at a given significance
    `texp': float
        The exposure time in minutes for each radial velocity measurement
    `tobserving': float
        The total observing time in hours including a constant estimate of 
        overheads
    `sigmaRV_phot': float
        The photon-noise limit on the RV measurement precision in m/s
    `sigmaRV_eff': float
        The effective RV measurement precision from the combined effects of 
        photon-noise, instrument stability, multiple planets, and stellar 
        activity in m/s

    '''
    # Read-in TESS data for this planetary system
    ra,dec,rp,P,S,K,Rs,Teff,Vmag,Imag,Jmag,Kmag,dist,_,_,_,mult = \
                                                            get_TESS_data()
    nplanets, planetindex = ra.size, int(planetindex)
    assert 0 <= planetindex < nplanets
    ra, dec = ra[planetindex], dec[planetindex]
    rp,P,S,K,Rs,Teff,Vmag,Imag,Jmag,Kmag,dist,mult = rp[planetindex], \
                                                     P[planetindex], \
                                                     S[planetindex], \
                                                     K[planetindex], \
                                                     Rs[planetindex], \
                                                     Teff[planetindex], \
                                                     Vmag[planetindex], \
                                                     Imag[planetindex], \
                                                     Jmag[planetindex], \
                                                     Kmag[planetindex], \
                                                     dist[planetindex], \
                                                     mult[planetindex]
    mult = 1. if mult == 0 else mult

    # Compute parameters of interest
    mp = get_planet_mass(rp)
    Ms = get_stellar_mass(P, mp, K)
    logg = np.log10(G * rvs.Msun2kg(Ms) / rvs.Rsun2m(Rs)**2 * 1e2)

    # Round Teff and logg
    Teffs = np.append(np.arange(23e2, 7e3, 1e2), np.arange(7e3, 121e2, 2e2))
    Teff_round = Teffs[abs(Teffs - Teff) == np.min(abs(Teffs - Teff))][0]
    loggs = np.arange(0, 6.1, .5)
    logg_round = loggs[abs(loggs - logg) == np.min(abs(loggs - logg))][0]

    # Get the stellar magnitudes in the desired bands scaled to the results
    # from Sullivan
    known_mags = [Vmag, Imag, Jmag, Kmag]
    band_strs_tmp = list(np.append(band_strs, 'B'))
    mags = _get_magnitudes(band_strs_tmp, known_mags, Teff_round, logg_round,
                           Z, Ms)
    mags, Bmag = mags[:-1], float(mags[-1])
    B_V = Bmag - Vmag

    # compute vsini
    if testingseed:
        np.random.seed(1)
    fname = 'Results/star%.4d/TESSplanet%.4d_%s_%.4d.dat' % (
        planetindex, planetindex, ''.join(band_strs), systnum)
    Prot, vsini = _draw_prot(Ms, Rs, fname)

    # Estimate Nrv for this TESS planet
    startheta = mags, float(Teff_round), float(logg_round), Z, vsini, Ms, \
                Prot, B_V
    planettheta = rp, mp, K, P, mult
    instrumenttheta = band_strs, R, aperture_m, QE
    Nrv,NrvGP,texp,tobs,tobsGP,sigK_target,sig_phot,sig_act,sig_planets,sig_eff = \
                                        estimate_Nrv(startheta, planettheta,
                                                     instrumenttheta, fname=fname,
                                                     sigmaRV_activity=sigmaRV_activity,
                                                     sigmaRV_planets=sigmaRV_planets,
                                                     sigmaRV_noisefloor=sigmaRV_noisefloor,
                                                     testplanet_sigmaKfrac=testplanet_sigmaKfrac)

    if verbose:
        print '\n%40s = %.3f m/s' % ('Photon-noise limited RV uncertainty',
                                     sig_phot)
        print '%40s = %.3f m/s' % ('Effective RV uncertainty', sig_eff)
        print '%40s = %.3f' % ('Target fractional K uncertainty',
                               sigK_target / K)
        print '%40s = %i' % ('Number of RVs', Nrv)
        print '%40s = %i' % ('Number of RVs (GP)', NrvGP)
        print '%40s = %.3f minutes' % ('Exposure time', texp)
        print '%40s = %.3f hours' % ('Total observing time', tobs)
        print '%40s = %.3f hours' % ('Total observing time (GP)', tobsGP)

    # Save values
    save_results(planetindex, band_strs, mags, ra, dec, P, rp, mp, K, S, Ms,
                 Rs, Teff, dist, Prot, vsini, Z, sig_act, sig_planets, R,
                 aperture_m, QE, sigK_target / K, sig_phot, sig_eff, texp,
                 tobs, Nrv, tobsGP, NrvGP, fname)
예제 #18
0
def rpRs2rp(rpRs, Rs):
    rp = rvs.m2Rearth(rvs.Rsun2m(rpRs * Rs))
    return unp.nominal_values(rp), unp.std_devs(rp)
예제 #19
0
def compute_depth(rp, Rs):
    return (rvs.Rearth2m(rp) / rvs.Rsun2m(Rs))**2
def sample_planet_params(self, index, postGAIA=True):
    '''sample distribution of planet parameters from observables and stellar pdfs'''
    # get stellar parameters PDFs either from derived from GAIA distances
    # or from original Kepler parameters (approximate distributions as skewnormal)
    g = int(index)
    print self.KepIDs[g]
    if postGAIA:
        path = '../GAIAMdwarfs/Gaia-DR2-distances_custom/DistancePosteriors/'
        try:
            samp_Rs, samp_Teff, samp_Ms = np.loadtxt('%s/KepID_allpost_%i' %
                                                     (path, self.KepIDs[g]),
                                                     delimiter=',',
                                                     usecols=(9, 10, 11)).T
        except IOError:
            samp_Rs, samp_Teff, samp_Ms = np.zeros(1000), np.zeros(
                1000), np.zeros(1000)

        if np.all(np.isnan(samp_Rs)) or np.all(np.isnan(samp_Teff)) or np.all(
                np.isnan(samp_Ms)):
            samp_Rs, samp_Teff, samp_Ms = np.zeros(1000), np.zeros(
                1000), np.zeros(1000)

        samp_Rs = resample_PDF(samp_Rs[np.isfinite(samp_Rs)],
                               samp_Rs.size,
                               sig=1e-3)
        samp_Teff = resample_PDF(samp_Teff[np.isfinite(samp_Teff)],
                                 samp_Teff.size,
                                 sig=5)
        samp_Ms = resample_PDF(samp_Ms[np.isfinite(samp_Ms)],
                               samp_Ms.size,
                               sig=1e-3)
    else:
        _, _, samp_Rs = get_samples_from_percentiles(self.Rss1[g],
                                                     self.ehi_Rss1[g],
                                                     self.elo_Rss1[g],
                                                     Nsamp=1e3)
        _, _, samp_Teff = get_samples_from_percentiles(self.Teffs1[g],
                                                       self.ehi_Teffs1[g],
                                                       self.elo_Teffs1[g],
                                                       Nsamp=1e3)
        _, _, samp_Ms = get_samples_from_percentiles(self.Mss1[g],
                                                     self.ehi_Mss1[g],
                                                     self.elo_Mss1[g],
                                                     Nsamp=1e3)

    # sample rp/Rs distribution from point estimates
    _, _, samp_rpRs = get_samples_from_percentiles(self.rpRs[g],
                                                   self.ehi_rpRs[g],
                                                   self.elo_rpRs[g],
                                                   Nsamp=samp_Rs.size)

    # compute planet radius PDF
    samp_rp = rvs.m2Rearth(rvs.Rsun2m(samp_rpRs * samp_Rs))
    v = np.percentile(samp_rp, (16, 50, 84))
    rps = v[1], v[2] - v[1], v[1] - v[0]

    # compute semi-major axis PDF
    samp_Ps = np.random.normal(self.Ps[g], self.e_Ps[g], samp_Ms.size)
    samp_as = rvs.semimajoraxis(samp_Ps, samp_Ms, 0)
    v = np.percentile(samp_as, (16, 50, 84))
    smas = v[1], v[2] - v[1], v[1] - v[0]

    # compute equilibrium T PDF (Bond albedo=0)
    samp_Teq = samp_Teff * np.sqrt(
        .5 * rvs.Rsun2m(samp_Rs) / rvs.AU2m(samp_as))
    v = np.percentile(samp_Teq, (16, 50, 84))
    Teqs = v[1], v[2] - v[1], v[1] - v[0]

    # compute insolation
    samp_F = samp_Rs**2 * (samp_Teff / 5778.)**4 / samp_as**2
    v = np.percentile(samp_F, (16, 50, 84))
    Fs = v[1], v[2] - v[1], v[1] - v[0]

    return rps, smas, Teqs, Fs
예제 #21
0
def compute_logg(Ms, Rs):
    G = 6.67e-11
    return unp.log10(G * rvs.Msun2kg(Ms) * 1e2 / rvs.Rsun2m(Rs)**2)
def get_Kepler_Mdwarf_planets(fname):
    '''
    I have a list of Kepler M dwarfs with stellar parameters based on GAIA 
    distances. I also have a list of confirmed Kepler planets from the NASA 
    exoplanet archive. Match the two lists to get the empirical population of 
    Kepler M dwarf planets with high precision radii and updated stellar parameters. 
    '''

    # get Kepler Mdwarfs parameters from GAIA
    dG = np.loadtxt(KepMdwarffile, delimiter=',')
    KepID, isMdwarf, badGAIA, bad2MASS, baddistpost, badTeff, ra_deg, dec_deg, GBPmag, e_GBPmag, GRPmag, e_GRPmag, Kepmag, Jmag, e_Jmag, Hmag, e_Hmag, Kmag, e_Kmag, parallax_mas, e_parallax, dist_pc, ehi_dist, elo_dist, mu, ehi_mu, elo_mu, AK, e_AK, BCK, e_BCK, MK, ehi_MK, elo_MK, Rs_RSun, ehi_Rs, elo_Rs, Teff_K, ehi_Teff, elo_Teff, Ms_MSun, ehi_Ms, elo_Ms, logg_dex, ehi_logg, elo_logg = dG.T

    # get planet transits parameters from NASA exoplanet archive
    dK = np.genfromtxt(
        'Keplertargets/NASAarchive_confirmed_Keplerlowmassstars.csv',
        delimiter=',',
        skip_header=66)
    loc_rowid, kepid, kepler_name, koi_disposition, koi_score, koi_period, koi_period_err1, koi_period_err2, koi_time0, koi_time0_err1, koi_time0_err2, koi_impact, koi_impact_err1, koi_impact_err2, koi_duration, koi_duration_err1, koi_duration_err2, koi_depth, koi_depth_err1, koi_depth_err2, koi_ror, koi_ror_err1, koi_ror_err2, koi_prad, koi_prad_err1, koi_prad_err2, koi_incl, koi_incl_err1, koi_incl_err2, koi_dor, koi_dor_err1, koi_dor_err2, koi_limbdark_mod, koi_ldm_coeff4, koi_ldm_coeff3, koi_ldm_coeff2, koi_ldm_coeff1, koi_model_snr, koi_steff, koi_steff_err1, koi_steff_err2, koi_slogg, koi_slogg_err1, koi_slogg_err2, koi_smet, koi_smet_err1, koi_smet_err2, koi_srad, koi_srad_err1, koi_srad_err2, koi_kepmag, koi_jmag, koi_hmag, koi_kmag = dK.T

    # match stellar parameters to confirmed Kepler stars
    Nplanets = kepid.size
    self = KepConfirmedMdwarfPlanets(fname, Nplanets)
    self._initialize_arrays()
    for i in range(Nplanets):

        print float(i) / Nplanets
        g = np.in1d(KepID, kepid[i])
        print g.sum()

        # stellar parameters (both pre (1) and post-GAIA (2))
        self.KepIDs[i] = kepid[i]
        self.isMdwarf[i] = isMdwarf[g] if g.sum() == 1 else np.nan
        self.badGAIA[i] = badGAIA[g] if g.sum() == 1 else np.nan
        self.bad2MASS[i] = bad2MASS[g] if g.sum() == 1 else np.nan
        self.baddistpost[i] = baddistpost[g] if g.sum() == 1 else np.nan
        self.badTeff[i] = badTeff[g] if g.sum() == 1 else np.nan
        self.Jmags[i] = Jmag[g] if g.sum() == 1 else np.nan
        self.e_Jmags[i] = e_Jmag[g] if g.sum() == 1 else np.nan
        self.Hmags[i] = Hmag[g] if g.sum() == 1 else np.nan
        self.e_Hmags[i] = e_Hmag[g] if g.sum() == 1 else np.nan
        self.Kmags[i] = Kmag[g] if g.sum() == 1 else np.nan
        self.e_Kmags[i] = e_Kmag[g] if g.sum() == 1 else np.nan
        self.pars[i] = parallax_mas[g] if g.sum() == 1 else np.nan
        self.e_pars[i] = e_parallax[g] if g.sum() == 1 else np.nan
        self.mus[i] = mu[g] if g.sum() == 1 else np.nan
        self.ehi_mus[i] = ehi_mu[g] if g.sum() == 1 else np.nan
        self.elo_mus[i] = elo_mu[g] if g.sum() == 1 else np.nan
        self.dists[i] = dist_pc[g] if g.sum() == 1 else np.nan
        self.ehi_dists[i] = ehi_dist[g] if g.sum() == 1 else np.nan
        self.elo_dists[i] = elo_dist[g] if g.sum() == 1 else np.nan
        self.AKs[i] = AK[g] if g.sum() == 1 else np.nan
        self.e_AKs[i] = e_AK[g] if g.sum() == 1 else np.nan
        self.BCKs[i] = BCK[g] if g.sum() == 1 else np.nan
        self.e_BCKs[i] = e_BCK[g] if g.sum() == 1 else np.nan
        self.MKs[i] = MK[g] if g.sum() == 1 else np.nan
        self.ehi_MKs[i] = ehi_MK[g] if g.sum() == 1 else np.nan
        self.elo_MKs[i] = elo_MK[g] if g.sum() == 1 else np.nan

        # pre-GAIA
        self.Rss1[i] = koi_srad[i]
        self.ehi_Rss1[i] = koi_srad_err1[
            i] if koi_srad_err1[i] > 0 else koi_srad[i] * .07
        self.elo_Rss1[i] = abs(
            koi_srad_err2[i]) if koi_srad_err2[i] < 0 else koi_srad[i] * .08
        self.Teffs1[i] = koi_steff[i]
        self.ehi_Teffs1[i] = koi_steff_err1[
            i] if koi_steff_err1[i] > 0 else koi_steff[i] * .02
        self.elo_Teffs1[i] = abs(
            koi_steff_err2[i]) if koi_steff_err2[i] < 0 else koi_steff[i] * .02
        self.loggs1[i] = koi_slogg[i]
        self.ehi_loggs1[i] = koi_slogg_err1[
            i] if koi_slogg_err1[i] > 0 else koi_slogg[i] * .009
        self.elo_loggs1[i] = abs(
            koi_slogg_err2[i]
        ) if koi_slogg_err2[i] < 0 else koi_slogg[i] * .006
        _, _, samp_Rs = get_samples_from_percentiles(self.Rss1[i],
                                                     self.ehi_Rss1[i],
                                                     self.elo_Rss1[i],
                                                     Nsamp=1e3)
        _, _, samp_logg = get_samples_from_percentiles(self.loggs1[i],
                                                       self.ehi_loggs1[i],
                                                       self.elo_loggs1[i],
                                                       Nsamp=1e3)
        samp_Ms = rvs.kg2Msun(10**samp_logg * rvs.Rsun2m(samp_Rs)**2 * 1e-2 /
                              G)
        v = np.percentile(samp_Ms, (16, 50, 84))
        self.Mss1[i], self.ehi_Mss1[i], self.elo_Mss1[i] = v[
            1], v[2] - v[1], v[1] - v[0]
        self.FeHs1[i] = koi_smet[i]
        self.ehi_FeHs1[i] = koi_smet_err1[i]
        self.elo_FeHs1[i] = abs(koi_smet_err1[i])

        # post-GAIA
        self.Rss2[i] = Rs_RSun[g] if g.sum() == 1 else np.nan
        self.ehi_Rss2[i] = ehi_Rs[g] if g.sum() == 1 else np.nan
        self.elo_Rss2[i] = elo_Rs[g] if g.sum() == 1 else np.nan
        self.Teffs2[i] = Teff_K[g] if g.sum() == 1 else np.nan
        self.ehi_Teffs2[i] = ehi_Teff[g] if g.sum() == 1 else np.nan
        self.elo_Teffs2[i] = elo_Teff[g] if g.sum() == 1 else np.nan
        self.Mss2[i] = Ms_MSun[g] if g.sum() == 1 else np.nan
        self.ehi_Mss2[i] = ehi_Ms[g] if g.sum() == 1 else np.nan
        self.elo_Mss2[i] = elo_Ms[g] if g.sum() == 1 else np.nan
        self.loggs2[i] = logg_dex[g] if g.sum() == 1 else np.nan
        self.ehi_loggs2[i] = ehi_logg[g] if g.sum() == 1 else np.nan
        self.elo_loggs2[i] = elo_logg[g] if g.sum() == 1 else np.nan

        # planet parameters
        self.Ps[i] = koi_period[i]
        self.e_Ps[i] = np.abs([koi_period_err1[i], koi_period_err2[i]]).mean()
        self.T0s[i] = koi_time0[i]
        self.e_T0s[i] = np.abs([koi_time0_err1[i], koi_time0_err2[i]]).mean()
        self.Ds[i] = koi_duration[i]
        self.e_Ds[i] = np.abs([koi_duration_err1[i],
                               koi_duration_err2[i]]).mean()
        self.Zs[i] = koi_depth[i]
        self.e_Zs[i] = np.abs([koi_depth_err1[i], koi_depth_err2[i]]).mean()
        self.aRs[i] = koi_dor[i]
        self.e_aRs[i] = np.abs([koi_dor_err1[i], koi_dor_err2[i]]).mean()
        self.rpRs[i] = koi_ror[i]
        self.ehi_rpRs[i] = koi_ror_err1[i]
        self.elo_rpRs[i] = abs(koi_ror_err2[i])
        self.bs[i] = koi_impact[i]
        self.ehi_bs[i] = koi_impact_err1[i]
        self.elo_bs[i] = abs(koi_impact_err2[i])

        # completeness parameters
        self.CDPPs[i] = get_fitted_cdpp(self.KepIDs[i], self.Ds[i])
        self.data_spans[i] = data_spanC[kepidC == self.KepIDs[i]]
        self.SNRtransits[i] = self.Zs[i] / self.CDPPs[i] * np.sqrt(
            get_Ntransits(self.KepIDs[i], self.Ps[i]))

        # computed planet parameters
        if self.isMdwarf[i]:
            rps1, smas1, Teqs1, Fs1 = sample_planet_params(self,
                                                           i,
                                                           postGAIA=False)
            self.rps1[i], self.ehi_rps1[i], self.elo_rps1[i] = rps1
            self.smas1[i], self.ehi_smas1[i], self.elo_smas1[i] = smas1
            self.Teqs1[i], self.ehi_Teqs1[i], self.elo_Teqs1[i] = Teqs1
            self.Fs1[i], self.ehi_Fs1[i], self.elo_Fs1[i] = Fs1
            rps2, smas2, Teqs2, Fs2 = sample_planet_params(self,
                                                           i,
                                                           postGAIA=True)
            self.rps2[i], self.ehi_rps2[i], self.elo_rps2[i] = rps2
            self.smas2[i], self.ehi_smas2[i], self.elo_smas2[i] = smas2
            self.Teqs2[i], self.ehi_Teqs2[i], self.elo_Teqs2[i] = Teqs2
            self.Fs2[i], self.ehi_Fs2[i], self.elo_Fs2[i] = Fs2

    # save Kepler M dwarf planet population
    self._pickleobject()
예제 #23
0
def identify_EBs(params,
                 bjd,
                 fcorr,
                 ef,
                 Ms,
                 Rs,
                 Teff,
                 SNRthresh=3.,
                 rpmax=30,
                 detthresh=5,
                 Kep=False,
                 TESS=False):
    '''For each proposed planet in params, run through a variety of checks to 
    vetting the planetary candidates and identify EB false positives.'''
    assert len(params.shape) == 2
    Nplanets = params.shape[0]
    paramsout, isEB, maybeEB = np.zeros_like(params), np.zeros(Nplanets), \
                               np.zeros(Nplanets)
    EBconditions = np.zeros((Nplanets, 5)).astype(bool)
    EBcondition_labels = np.array([
        'rpRs > 0.5',
        'rp>%.1f' % rpmax, 'secondary eclipse detected', 'transit is V-shaped',
        'transit duration is too long for a planet'
    ])
    for i in range(Nplanets):

        # get best fit parameters
        paramsout[i] = _fit_params(params[i],
                                   bjd,
                                   fcorr,
                                   ef,
                                   Ms,
                                   Rs,
                                   Teff,
                                   Kep=Kep,
                                   TESS=TESS)

        # ensure the planet is not too big
        rpRs = np.sqrt(params[i, 2])
        isEB[i] = 1 if rpRs > .5 else isEB[i]
        EBconditions[i, 0] = True if rpRs > .5 else False
        rp = rvs.m2Rearth(rvs.Rsun2m(rpRs * Rs))
        isEB[i] = 1 if rp > rpmax else isEB[i]
        EBconditions[i, 1] = True if rp > rpmax else False

        # check for secondary eclipse
        eclipse = _is_eclipse(params[i], bjd, fcorr, ef, detthresh)
        isEB[i] = 1 if eclipse else isEB[i]
        EBconditions[i, 2] = True if eclipse else False

        # check for ellipsoidal variations
        #ellipsoidal = _is_ellipsoidal()
        #isEB[i] = 1 if ellipsoidal else isEB[i]
        # how can I do this without knowing the parameters of the binary?

        # flag V-shaped transits (does not implies an EB)
        Vshaped, duration = _is_Vshaped(params[i], bjd, fcorr, ef, Ms, Rs,
                                        Teff, Kep, TESS)
        maybeEB[i] = 1 if Vshaped else maybeEB[i]
        EBconditions[i, 3] = True if Vshaped else False

        # is duration reasonable? # Gunther+2016
        EBduration = _is_EB_duration(duration, paramsout[i, 0], Ms, Rs)
        isEB[i] = 1 if EBduration else isEB[i]
        EBconditions[i, 4] = True if EBduration else False

    # save planet and EB parameters
    maybeEB[isEB == 1] = 1
    isEB, maybeEB = isEB.astype(bool), maybeEB.astype(bool)
    params, EBparams, maybeEBparams = params[np.invert(isEB)], params[isEB], \
                                      params[maybeEB]
    return params, EBparams, maybeEBparams, EBconditions, EBcondition_labels
예제 #24
0
def run_mcmc(params,
             bjd,
             fcorr,
             ef,
             Ms,
             eMs,
             Rs,
             eRs,
             Teff,
             eTeff,
             u1,
             u2,
             nwalkers=200,
             burnin=500,
             nsteps=400,
             pltt=True):
    assert params.shape == (4, )
    params_optimized = np.zeros(5)
    nwalkers, burnin, nsteps = int(nwalkers), int(burnin), int(nsteps)
    params_results = np.zeros((3, 5))

    # get optimized parameters and get the LC around T0
    bjdred, fcorrred, efred, fmodel_opt, theta = \
                            optimize_singletransit_params(params, bjd, fcorr,
                                                          ef, Ms, Rs, u1, u2,
                                                          pltt=1)
    params_opt = theta[:5]
    print params, params_opt

    # run MCMC on transit LC
    initialize = [1, 1e-3, 1, 1e-2, 1]
    print 'Running MCMC on single-transit model'
    sampler, samples = run_emcee(params_opt,
                                 bjd,
                                 bjdred,
                                 fcorrred,
                                 efred,
                                 initialize,
                                 u1,
                                 u2,
                                 Ms,
                                 Rs,
                                 a=2,
                                 nwalkers=nwalkers,
                                 burnin=burnin,
                                 nsteps=nsteps,
                                 zeroplanetmodel=False)
    results = get_results(samples)
    params_results = results
    func = llnl.transit_model_func_curve_fit(u1, u2)
    fmodel_mcmc = func(bjdred, *params_results[0])

    # estimate single transit P, aRs, rpRs, and inc
    Nsamp = samples.shape[0]
    samp_Ms = np.random.randn(Nsamp) * eMs + Ms
    samp_Rs = np.random.randn(Nsamp) * eRs + Rs
    samp_rho = rvs.Msun2kg(samp_Ms) / rvs.Rsun2m(samp_Rs)**3
    samp_aRs = samples[:, 2]
    v = np.percentile(samp_aRs, (16, 50, 84))
    aRs_est = [v[1], v[2] - v[1], v[1] - v[0]]
    samp_rpRs = samples[:, 3]
    v = np.percentile(samp_rpRs, (16, 50, 84))
    rpRs_est = [v[1], v[2] - v[1], v[1] - v[0]]
    samp_inc = samples[:, 4]
    v = np.percentile(samp_inc, (16, 50, 84))
    inc_est = [v[1], v[2] - v[1], v[1] - v[0]]
    #samp_P=rvs.sec2days(np.sqrt(4*np.pi*np.pi/(6.67e-11*samp_rho)*samp_aRs**3))
    samp_P = samples[:, 0]
    v = np.percentile(samp_P, (16, 50, 84))
    P_est = [v[1], v[2] - v[1], v[1] - v[0]]

    # estimate F
    samp_Teff = np.random.randn(Nsamp) * eTeff + Teff
    samp_Ls = compute_Ls(samp_Rs, samp_Teff)
    samp_F = compute_F(samp_Ls, rvs.semimajoraxis(samp_P, samp_Ms, 0))
    v = np.percentile(samp_F, (16, 50, 84))
    F_est = [v[1], v[2] - v[1], v[1] - v[0]]

    # plotting
    if pltt:
        t0 = 2457000
        plt.figure(1)
        plt.plot(bjdred - t0, fcorrred, '.')
        plt.plot(bjdred - t0, fmodel_opt, '-', lw=3, label='optimized')
        plt.plot(bjdred - t0, fmodel_mcmc, '-', lw=2, label='MCMC model')
        plt.legend(loc='upper left')
        plt.figure(2)
        plt.hist(samp_P, bins=30)
        plt.show()

    return bjd, fcorr, ef, params_opt, fmodel_opt, samples, params_results, fmodel_mcmc, samp_P, P_est, samp_F, F_est, aRs_est, rpRs_est, inc_est
예제 #25
0
    def get_data(self):
        self.fs = np.array(
            glob.glob('%s/%s_%i/*LC*' %
                      (self.folder, self.prefix, self.epicnum)))
        # remove planet search result (i.e. with index -99)
        if np.any(
                np.in1d(
                    self.fs, '%s/%s_%i/%sLC_-00099' %
                    (self.folder, self.prefix, self.epicnum, self.prefix))):
            g = np.where(
                np.in1d(
                    self.fs, '%s/%s_%i/LC_-00099' %
                    (self.folder, self.prefix, self.epicnum)))[0][0]
            self.fs = np.delete(self.fs, g)
        if self.fs.size == 0:
            return None
        self.Nsim = 0
        d = loadpickle(self.fs[0])
        self.Kepmag, self.logg, self.Ms, self.Rs, self.Teff = d.Kepmag, \
                                                              d.logg, \
                                                              d.Ms, d.Rs, \
                                                              d.Teff
        self.e_logg, self.e_Ms, self.e_Rs, self.e_Teff = d.e_logg, \
                                                         d.e_Ms, d.e_Rs, \
                                                         d.e_Teff
        Nmax = 20
        self.Nplanets_true, self.Nplanets_found = np.zeros(0), np.zeros(0)
        self.Ps, self.rps, self.isdet = np.zeros((0, Nmax)), np.zeros(
            (0, Nmax)), np.zeros((0, Nmax))
        self.Psfound, self.rpsfound, self.isFP = np.zeros((0, Nmax)), np.zeros(
            (0, Nmax)), np.zeros((0, Nmax))
        for i in range(self.fs.size):

            print float(i) / self.fs.size
            d = loadpickle(self.fs[i])

            if d.DONE:
                self.Nsim += 1
                self.Nplanets_true = np.append(self.Nplanets_true,
                                               d.Ptrue.size)
                filler = np.repeat(np.nan, Nmax - self.Nplanets_true[-1])
                Pin = np.append(d.Ptrue, filler)
                rpin = np.append(d.rptrue, filler)
                isdetin = np.append(d.is_detected, filler)

                self.Ps = np.append(self.Ps, Pin.reshape(1, Nmax), axis=0)
                self.rps = np.append(self.rps, rpin.reshape(1, Nmax), axis=0)
                self.isdet = np.append(self.isdet,
                                       isdetin.reshape(1, Nmax),
                                       axis=0)

                # get false positives TEMP because d.is_FP doesnt exist yet until
                # the simulation is rerun
                params = d.params_guess
                self.Nplanets_found = np.append(self.Nplanets_found,
                                                params.shape[0])
                filler2 = np.repeat(np.nan, Nmax - self.Nplanets_found[-1])
                Pinfound = np.append(params[:, 0], filler2)
                rpinfound = np.append(
                    rvs.m2Rearth(rvs.Rsun2m(np.sqrt(params[:, 2]) * d.Rs)),
                    filler2)
                self.Psfound = np.append(self.Psfound,
                                         Pinfound.reshape(1, Nmax),
                                         axis=0)
                self.rpsfound = np.append(self.rpsfound,
                                          rpinfound.reshape(1, Nmax),
                                          axis=0)

                is_FPin = np.array([
                    int(
                        np.invert(
                            np.any(np.isclose(d.Ptrue, params[i, 0],
                                              rtol=.02))))
                    for i in range(params.shape[0])
                ]).astype(bool)
                self.isFP = np.append(self.isFP,
                                      np.append(is_FPin,
                                                filler2).reshape(1, Nmax),
                                      axis=0)

        # trim excess planets
        end = np.where(np.all(np.isnan(self.Ps), axis=0))[0][0]
        self.Ps = self.Ps[:, :end]
        self.rps = self.rps[:, :end]
        self.isdet = self.isdet[:, :end]
        #end2 = np.where(np.all(np.isnan(self.PsFP), axis=0))[0][0]
        self.Psfound = self.Psfound[:, :end]
        self.rpsfound = self.rpsfound[:, :end]
        self.isFP = self.isFP[:, :end]
예제 #26
0
def run_emcee(theta,
              bjd,
              bjdred,
              fred,
              efred,
              initialize,
              u1,
              u2,
              Ms,
              Rs,
              nwalkers=200,
              burnin=200,
              nsteps=400,
              a=2,
              zeroplanetmodel=False):
    '''Run mcmc on an input light curve with no transit model.'''
    # get limits on P and aRs
    P, T0 = theta[:2]
    Plim = np.max([T0 - bjd.min(), bjd.max() - T0])
    aRslim = rvs.AU2m(rvs.semimajoraxis(Plim, Ms, 0)) / rvs.Rsun2m(Rs)
    print 'Plim = %.4f' % Plim
    print 'aRslim = %.4f' % aRslim

    # initialize chains
    assert len(theta) == len(initialize)
    assert len(theta) == 5
    theta[0], theta[2] = Plim + 10, aRslim + 10
    p0 = []
    for i in range(nwalkers):
        p0.append(theta + initialize * np.random.randn(len(theta)))

    # initialize sampler
    P = theta[0]
    inclims = np.array([
        float(rvs.inclination(P, Ms, Rs, 1)),
        float(rvs.inclination(P, Ms, Rs, -1))
    ])
    args = (theta, bjdred, fred, efred, Plim, aRslim, inclims, u1, u2,
            zeroplanetmodel)
    sampler = emcee.EnsembleSampler(nwalkers,
                                    len(theta),
                                    lnprob,
                                    args=args,
                                    a=a)

    # run burnin
    print 'Running burnin...'
    t0 = time.time()
    p0, _, _ = sampler.run_mcmc(p0, burnin)
    print 'Burnin acceptance fraction is %.4f' % np.mean(
        sampler.acceptance_fraction)
    print 'Burnin took %.4f minutes\n' % ((time.time() - t0) / 60.)
    sampler.reset()

    # run MCMC
    print 'Running full MCMC...'
    p0, _, _ = sampler.run_mcmc(p0, nsteps)
    samples = sampler.chain.reshape((-1, len(theta)))
    print "Mean acceptance fraction: %.4f" % np.mean(
        sampler.acceptance_fraction)
    print 'Full MCMC took %.4f minutes' % ((time.time() - t0) / 60.)

    return sampler, samples