Ejemplo n.º 1
0
# The first term is :class:`exoplanet.gp.terms.SHOterm` with $Q=1/\sqrt{2}$ and the second is regular :class:`exoplanet.gp.terms.SHOterm`.
# This model has g free parameters: $S_1$, $\omega_1$, $S_2$, $\omega_2$, $Q$, and a constant mean value.
# Most of the parameters will have weakly informative inverse Gamma priors (see [this blog post](https://betanalpha.github.io/assets/case_studies/gp_part3/part3.html#4_adding_an_informative_prior_for_the_length_scale) for a discussion of these priors) where the parameters are chosen to have reasonable tail probabilities.
# Using *exoplanet*, this is how you would build this model:

# %%
import pymc3 as pm
import theano.tensor as tt
from exoplanet.gp import terms, GP
from exoplanet import estimate_inverse_gamma_parameters

with pm.Model() as model:

    mean = pm.Normal("mean", mu=0.0, sigma=1.0)
    S1 = pm.InverseGamma(
        "S1", **estimate_inverse_gamma_parameters(0.5 ** 2, 10.0 ** 2)
    )
    S2 = pm.InverseGamma(
        "S2", **estimate_inverse_gamma_parameters(0.25 ** 2, 1.0 ** 2)
    )
    w1 = pm.InverseGamma(
        "w1", **estimate_inverse_gamma_parameters(2 * np.pi / 10.0, np.pi)
    )
    w2 = pm.InverseGamma(
        "w2", **estimate_inverse_gamma_parameters(0.5 * np.pi, 2 * np.pi)
    )
    log_Q = pm.Uniform("log_Q", lower=np.log(2), upper=np.log(10))

    # Set up the kernel an GP
    kernel = terms.SHOTerm(S_tot=S1, w0=w1, Q=1.0 / np.sqrt(2))
    kernel += terms.SHOTerm(S_tot=S2, w0=w2, log_Q=log_Q)
Ejemplo n.º 2
0
def build_model(mask=None, start=None):

    with pm.Model() as model:

        # The baseline flux
        mean = pm.Normal("mean", mu=0.0, sd=0.00001)

        # The time of a reference transit for each planet
        t0 = pm.Normal("t0", mu=t0s, sd=1.0, shape=1)

        # The log period; also tracking the period itself
        logP = pm.Normal("logP", mu=np.log(periods), sd=0.01, shape=1)

        rho_star = pm.Normal("rho_star", mu=0.14, sd=0.01, shape=1)
        r_star = pm.Normal("r_star", mu=2.7, sd=0.01, shape=1)

        period = pm.Deterministic("period", pm.math.exp(logP))

        # The Kipping (2013) parameterization for quadratic limb darkening paramters
        u = xo.distributions.QuadLimbDark("u", testval=np.array([0.3, 0.2]))

        r = pm.Uniform("r", lower=0.01, upper=0.3, shape=1, testval=0.15)

        b = xo.distributions.ImpactParameter("b", ror=r, shape=1, testval=0.5)

        # Transit jitter & GP parameters
        logs2 = pm.Normal("logs2", mu=np.log(np.var(y)), sd=10)
        logw0 = pm.Normal("logw0", mu=0, sd=10)
        logSw4 = pm.Normal("logSw4", mu=np.log(np.var(y)), sd=10)

        # Set up a Keplerian orbit for the planets
        orbit = xo.orbits.KeplerianOrbit(period=period,
                                         t0=t0,
                                         b=b,
                                         rho_star=rho_star,
                                         r_star=r_star)

        # Compute the model light curve using starry
        light_curves = xo.LimbDarkLightCurve(u).get_light_curve(orbit=orbit,
                                                                r=r,
                                                                t=t)
        light_curve = pm.math.sum(light_curves, axis=-1) + mean

        # Here we track the value of the model light curve for plotting
        # purposes
        pm.Deterministic("light_curves", light_curves)

        S1 = pm.InverseGamma(
            "S1", **estimate_inverse_gamma_parameters(0.5**2, 10.0**2))
        S2 = pm.InverseGamma(
            "S2", **estimate_inverse_gamma_parameters(0.25**2, 1.0**2))
        w1 = pm.InverseGamma(
            "w1", **estimate_inverse_gamma_parameters(2 * np.pi / 10.0, np.pi))
        w2 = pm.InverseGamma(
            "w2", **estimate_inverse_gamma_parameters(0.5 * np.pi, 2 * np.pi))
        log_Q = pm.Uniform("log_Q", lower=np.log(2), upper=np.log(10))

        # Set up the kernel an GP
        kernel = terms.SHOTerm(S_tot=S1, w0=w1, Q=1.0 / np.sqrt(2))
        kernel += terms.SHOTerm(S_tot=S2, w0=w2, log_Q=log_Q)
        gp = GP(kernel, t, yerr**2, mean=mean)

        gp.marginal("gp", observed=y)
        pm.Deterministic("gp_pred", gp.predict())

        # The likelihood function assuming known Gaussian uncertainty
        pm.Normal("obs", mu=light_curve, sd=yerr, observed=y)

        # Fit for the maximum a posteriori parameters given the simuated
        # dataset
        map_soln = xo.optimize(start=model.test_point)

        return model, map_soln
Ejemplo n.º 3
0
def build_model(mask):
    with pm.Model() as model:
        # Systemic parameters
        mean_lc = pm.Normal("mean_lc", mu=0.0, sd=5.0)
        mean_rv = pm.Normal("mean_rv", mu=0.0, sd=50.0)
        u1 = xo.QuadLimbDark("u1")
        u2 = xo.QuadLimbDark("u2")

        # Parameters describing the primary
        M1 = pm.Lognormal("M1", mu=0.0, sigma=10.0, testval=0.696)
        R1 = pm.Lognormal("R1", mu=0.0, sigma=10.0, testval=0.687)

        # Secondary ratios
        k = pm.Lognormal("k", mu=0.0, sigma=10.0,
                         testval=0.9403)  # radius ratio
        q = pm.Lognormal("q", mu=0.0, sigma=10.0, testval=0.9815)  # mass ratio
        s = pm.Lognormal("s", mu=np.log(0.5),
                         sigma=10.0)  # surface brightness ratio

        # Prior on flux ratio
        pm.Normal(
            "flux_prior",
            mu=lit_flux_ratio[0],
            sigma=lit_flux_ratio[1],
            observed=k**2 * s,
        )

        # Parameters describing the orbit
        b = xo.ImpactParameter("b", ror=k, testval=1.5)
        period = pm.Lognormal("period", mu=np.log(lit_period), sigma=1.0)
        t0 = pm.Normal("t0", mu=lit_t0, sigma=1.0)

        # Parameters describing the eccentricity: ecs = [e * cos(w), e * sin(w)]
        ecs = xo.UnitDisk("ecs", testval=np.array([1e-5, 0.0]))
        ecc = pm.Deterministic("ecc", tt.sqrt(tt.sum(ecs**2)))
        omega = pm.Deterministic("omega", tt.arctan2(ecs[1], ecs[0]))

        # Build the orbit
        R2 = pm.Deterministic("R2", k * R1)
        M2 = pm.Deterministic("M2", q * M1)
        orbit = xo.orbits.KeplerianOrbit(
            period=period,
            t0=t0,
            ecc=ecc,
            omega=omega,
            b=b,
            r_star=R1,
            m_star=M1,
            m_planet=M2,
        )

        # Track some other orbital elements
        pm.Deterministic("incl", orbit.incl)
        pm.Deterministic("a", orbit.a)

        # Noise model for the light curve
        sigma_lc = pm.InverseGamma("sigma_lc",
                                   testval=1.0,
                                   **xo.estimate_inverse_gamma_parameters(
                                       0.1, 2.0))
        S_tot_lc = pm.InverseGamma("S_tot_lc",
                                   testval=2.5,
                                   **xo.estimate_inverse_gamma_parameters(
                                       1.0, 5.0))
        ell_lc = pm.InverseGamma("ell_lc",
                                 testval=2.0,
                                 **xo.estimate_inverse_gamma_parameters(
                                     1.0, 5.0))
        kernel_lc = xo.gp.terms.SHOTerm(S_tot=S_tot_lc,
                                        w0=2 * np.pi / ell_lc,
                                        Q=1.0 / 3)

        # Noise model for the radial velocities
        sigma_rv1 = pm.InverseGamma("sigma_rv1",
                                    testval=1.0,
                                    **xo.estimate_inverse_gamma_parameters(
                                        0.5, 5.0))
        sigma_rv2 = pm.InverseGamma("sigma_rv2",
                                    testval=1.0,
                                    **xo.estimate_inverse_gamma_parameters(
                                        0.5, 5.0))
        S_tot_rv = pm.InverseGamma("S_tot_rv",
                                   testval=2.5,
                                   **xo.estimate_inverse_gamma_parameters(
                                       1.0, 5.0))
        ell_rv = pm.InverseGamma("ell_rv",
                                 testval=2.0,
                                 **xo.estimate_inverse_gamma_parameters(
                                     1.0, 5.0))
        kernel_rv = xo.gp.terms.SHOTerm(S_tot=S_tot_rv,
                                        w0=2 * np.pi / ell_rv,
                                        Q=1.0 / 3)

        # Set up the light curve model
        lc = xo.SecondaryEclipseLightCurve(u1, u2, s)

        def model_lc(t):
            return (
                mean_lc + 1e3 *
                lc.get_light_curve(orbit=orbit, r=R2, t=t, texp=texp)[:, 0])

        # Condition the light curve model on the data
        gp_lc = xo.gp.GP(kernel_lc,
                         x[mask],
                         tt.zeros(mask.sum())**2 + sigma_lc**2,
                         mean=model_lc)
        gp_lc.marginal("obs_lc", observed=y[mask])

        # Set up the radial velocity model
        def model_rv1(t):
            return mean_rv + 1e-3 * orbit.get_radial_velocity(t)

        def model_rv2(t):
            return mean_rv - 1e-3 * orbit.get_radial_velocity(t) / q

        # Condition the radial velocity model on the data
        gp_rv1 = xo.gp.GP(kernel_rv,
                          x_rv,
                          tt.zeros(len(x_rv))**2 + sigma_rv1**2,
                          mean=model_rv1)
        gp_rv1.marginal("obs_rv1", observed=y1_rv)
        gp_rv2 = xo.gp.GP(kernel_rv,
                          x_rv,
                          tt.zeros(len(x_rv))**2 + sigma_rv2**2,
                          mean=model_rv2)
        gp_rv2.marginal("obs_rv2", observed=y2_rv)

        # Optimize the logp
        map_soln = model.test_point

        # First the RV parameters
        map_soln = xo.optimize(map_soln, [mean_rv, q])
        map_soln = xo.optimize(
            map_soln, [mean_rv, sigma_rv1, sigma_rv2, S_tot_rv, ell_rv])

        # Then the LC parameters
        map_soln = xo.optimize(map_soln, [mean_lc, R1, k, s, b])
        map_soln = xo.optimize(map_soln, [mean_lc, R1, k, s, b, u1, u2])
        map_soln = xo.optimize(map_soln, [mean_lc, sigma_lc, S_tot_lc, ell_lc])
        map_soln = xo.optimize(map_soln, [t0, period])

        # Then all the parameters together
        map_soln = xo.optimize(map_soln)

        model.gp_lc = gp_lc
        model.model_lc = model_lc
        model.gp_rv1 = gp_rv1
        model.model_rv1 = model_rv1
        model.gp_rv2 = gp_rv2
        model.model_rv2 = model_rv2

        model.x = x[mask]
        model.y = y[mask]

    return model, map_soln
Ejemplo n.º 4
0
        ecc=ecc,
        omega=omega,
        b=b,
        r_star=R1,
        m_star=M1,
        m_planet=M2,
    )

    # Track some other orbital elements
    pm.Deterministic("incl", orbit.incl)
    pm.Deterministic("a", orbit.a)

    # Noise model for the light curve
    sigma_lc = pm.InverseGamma("sigma_lc",
                               testval=1.0,
                               **xo.estimate_inverse_gamma_parameters(
                                   0.1, 2.0))
    S_tot_lc = pm.InverseGamma("S_tot_lc",
                               testval=2.5,
                               **xo.estimate_inverse_gamma_parameters(
                                   1.0, 5.0))
    ell_lc = pm.InverseGamma("ell_lc",
                             testval=2.0,
                             **xo.estimate_inverse_gamma_parameters(1.0, 5.0))
    kernel_lc = xo.gp.terms.SHOTerm(S_tot=S_tot_lc,
                                    w0=2 * np.pi / ell_lc,
                                    Q=1.0 / 3)

    # Noise model for the radial velocities
    sigma_rv1 = pm.InverseGamma("sigma_rv1",
                                testval=1.0,
                                **xo.estimate_inverse_gamma_parameters(