Exemplo n.º 1
0
def make_data(t, log_S0, log_w0, log_Q, logsig, 
              t0=5.0, r=0.1, d=1.0, tin=0.1, a=2.0):
    
    transit = utils.theano_transit(t, 
                                   t0, 
                                   r, 
                                   d, 
                                   tin)
    kernel = xo.gp.terms.SHOTerm(
        log_S0 = log_S0,
        log_w0 = log_w0,
        log_Q = log_Q
    )
    J = 4
    
    q = np.array([1, a])
    Q = q[:, None]*q[None, :]
    diag = np.exp(2*logsig)*np.ones((2, len(t)))
    kernel = xo.gp.terms.KroneckerTerm(kernel, Q)
    gp = GP(kernel, t, diag, J=J)
    n = gp.dot_l(np.random.randn(2*len(t), 1)).eval()
    transit = tt.reshape(tt.tile(transit, (2, 1)).T, 
                         (1, 2*transit.shape[0])).T
    n += transit.eval()
    return n, np.sum([n[i::2].T[0] for i in range(len(q))], axis=0)/2
Exemplo n.º 2
0
def run_mcmc_1d(t, data, logS0_init, 
                logw0_init, logQ_init, 
                logsig_init, t0_init, 
                r_init, d_init, tin_init):
    
    with pm.Model() as model:
        #logsig = pm.Uniform("logsig", lower=-20.0, upper=0.0, testval=logsig_init)

        # The parameters of the SHOTerm kernel
        #logS0 = pm.Uniform("logS0", lower=-50.0, upper=0.0, testval=logS0_init)
        #logQ = pm.Uniform("logQ", lower=-50.0, upper=20.0, testval=logQ_init)
        #logw0 = pm.Uniform("logw0", lower=-50.0, upper=20.0, testval=logw0_init)
        
        # The parameters for the transit mean function
        t0 = pm.Uniform("t0", lower=t[0], upper=t[-1], testval=t0_init)
        r = pm.Uniform("r", lower=0.0, upper=1.0, testval=r_init)
        d = pm.Uniform("d", lower=0.0, upper=10.0, testval=d_init)
        tin = pm.Uniform("tin", lower=0.0, upper=10.0, testval=tin_init)
            
        # Deterministics
        # mean = pm.Deterministic("mean", utils.transit(t, t0, r, d, tin))
        transit = utils.theano_transit(t, t0, r, d, tin)

        # Set up the Gaussian Process model
        kernel = xo.gp.terms.SHOTerm(
            log_S0 = logS0_init,
            log_w0 = logw0_init,
            log_Q=logQ_init
        )
    
        diag = np.exp(2*logsig_init)*tt.ones((1, len(t)))
        gp = GP(kernel, t, diag, J=2)

        # Compute the Gaussian Process likelihood and add it into the
        # the PyMC3 model as a "potential"
        pm.Potential("loglike", gp.log_likelihood(data - transit))

        # Compute the mean model prediction for plotting purposes
        #pm.Deterministic("mu", gp.predict())
        map_soln = xo.optimize(start=model.test_point, verbose=False)
        
    with model:
        map_soln = xo.optimize(start=model.test_point)
        
    with model:
        trace = pm.sample(
            tune=500,
            draws=500,
            start=map_soln,
            cores=2,
            chains=2,
            step=xo.get_dense_nuts_step(target_accept=0.9),
        )
    return trace
Exemplo n.º 3
0
def gp_fit(t, y, yerr, t_grid, integrated=False, exp_time=60.):
    # optimize kernel hyperparameters and return fit + predictions
    with pm.Model() as model:
        logS0 = pm.Normal("logS0", mu=0.4, sd=5.0, testval=np.log(np.var(y)))
        logw0 = pm.Normal("logw0", mu=-3.9, sd=0.1)
        logQ = pm.Normal("logQ", mu=3.5, sd=5.0)

        # Set up the kernel and GP
        kernel = terms.SHOTerm(log_S0=logS0, log_w0=logw0, log_Q=logQ)
        if integrated:
            kernel_int = terms.IntegratedTerm(kernel, exp_time)
            gp = GP(kernel_int, t, yerr**2)
        else:
            gp = GP(kernel, t, yerr**2)

        # Add a custom "potential" (log probability function) with the GP likelihood
        pm.Potential("gp", gp.log_likelihood(y))

    with model:
        map_soln = xo.optimize(start=model.test_point)
        mu, var = xo.eval_in_model(gp.predict(t_grid, return_var=True),
                                   map_soln)
        sd = np.sqrt(var)
        y_pred = xo.eval_in_model(gp.predict(t), map_soln)

    return map_soln, mu, sd, y_pred
Exemplo n.º 4
0
def gp_predict(t,
               y,
               yerr,
               t_grid,
               logS0=0.4,
               logw0=-3.9,
               logQ=3.5,
               integrated=False,
               exp_time=60.):
    # take kernel hyperparameters as fixed inputs, train + predict
    with pm.Model() as model:
        kernel = terms.SHOTerm(log_S0=logS0, log_w0=logw0, log_Q=logQ)
        if integrated:
            kernel_int = terms.IntegratedTerm(kernel, exp_time)
            gp = GP(kernel_int, t, yerr**2)
        else:
            gp = GP(kernel, t, yerr**2)
        gp.condition(y)
        mu, var = xo.eval_in_model(gp.predict(t_grid, return_var=True))
        sd = np.sqrt(var)
        y_pred = xo.eval_in_model(gp.predict(t))

    return y_pred, mu, sd
Exemplo n.º 5
0
def multi_gp_predict(t, y, yerr, t_grid, integrated=False, exp_time=60.):
    # this code is GARBAGE. but in principle does gp_predict() for a full comb of modes.
    a_max = 0.55  # amplitude of central mode in m/s
    nu_max = 3.1e-3  # peak frequency in Hz
    c_env = 0.331e-3  # envelope width in Hz
    delta_nu = 0.00013  # Hz
    gamma = 1. / (2 * 24. * 60. * 60.)  # s^-1 ; 2-day damping timescale
    freq_grid = np.arange(nu_max - 0.001, nu_max + 0.001,
                          delta_nu)  # magic numbers
    amp_grid = a_max**2 * np.exp(-(freq_grid - nu_max)**2 /
                                 (2. * c_env**2))  # amplitudes in m/s
    driving_amp_grid = np.sqrt(amp_grid * gamma * dt)
    log_S0_grid = [
        np.log(d**2 / (dt * o)) for o, d in zip(omega_grid, driving_amp_grid)
    ]
    with pm.Model() as model:
        kernel = None
        for o, lS in zip(omega_grid, log_S0_grid):
            if kernel is None:
                kernel = terms.SHOTerm(log_S0=lS,
                                       log_w0=np.log(o),
                                       log_Q=np.log(o / gamma))
            else:
                kernel += terms.SHOTerm(log_S0=lS,
                                        log_w0=np.log(o),
                                        log_Q=np.log(o / gamma))
        if integrated:
            kernel_int = terms.IntegratedTerm(kernel, exp_time)
            gp = GP(kernel_int, t, yerr**2)
        else:
            gp = GP(kernel, t, yerr**2)
        gp.condition(y)
        mu, var = xo.eval_in_model(gp.predict(t_grid, return_var=True))
        sd = np.sqrt(var)
        y_pred = xo.eval_in_model(gp.predict(t))
    return y_pred, mu, sd
Exemplo n.º 6
0
        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)
        gp = GP(kernel, t, yerr**2, mean=mean)

        # Condition the GP on the observations and add the marginal likelihood
        # to the model
        gp.marginal("gp", observed=y)

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

    with model:
        mu, var = xo.eval_in_model(
            gp.predict(true_t, return_var=True, predict_mean=True), map_soln)

    # Plot the prediction and the 1-sigma uncertainty
    plt.errorbar(t, y, yerr=yerr, fmt=".k", capsize=0, label="data")
    plt.plot(true_t, true_y, "k", lw=1.5, alpha=0.3, label="truth")
Exemplo n.º 7
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
Exemplo n.º 8
0
def load_models(t, data1, data2, logS0_init, 
                logw0_init, logQ_init, 
                logsig_init, t0_init, 
                r_init, d_init, tin_init, a):
    
    with pm.Model() as model1d:
        logsig = pm.Uniform("logsig", lower=-20.0, upper=0.0, testval=logsig_init)

        # The parameters of the SHOTerm kernel
        #logS0 = pm.Uniform("logS0", lower=-50.0, upper=0.0, testval=logS0_init)
        #logQ = pm.Uniform("logQ", lower=-50.0, upper=20.0, testval=logQ_init)
        #logw0 = pm.Uniform("logw0", lower=-50.0, upper=20.0, testval=logw0_init)
        
        # The parameters for the transit mean function
        t0 = pm.Uniform("t0", lower=t[0], upper=t[-1], testval=t0_init)
        r = pm.Uniform("r", lower=0.0, upper=1.0, testval=r_init)
        d = pm.Uniform("d", lower=0.0, upper=10.0, testval=d_init)
        tin = pm.Uniform("tin", lower=0.0, upper=10.0, testval=tin_init)
            
        # Deterministics
        # mean = pm.Deterministic("mean", utils.transit(t, t0, r, d, tin))
        transit = utils.theano_transit(t, t0, r, d, tin)

        # Set up the Gaussian Process model
        kernel = xo.gp.terms.SHOTerm(
            log_S0 = logS0_init,
            log_w0 = logw0_init,
            log_Q=logQ_init
        )
    
        diag = np.exp(2*logsig_init)*tt.ones(len(t))
        gp = GP(kernel, t, diag, J=2)

        # Compute the Gaussian Process likelihood and add it into the
        # the PyMC3 model as a "potential"
        pm.Potential("loglike", gp.log_likelihood(data1 - transit))

        # Compute the mean model prediction for plotting purposes
        #pm.Deterministic("mu", gp.predict())
        #map_soln = xo.optimize(start=model1d.test_point, verbose=False)
        
    with pm.Model() as model2d:
        #logsig = pm.Uniform("logsig", lower=-20.0, upper=0.0, testval=logsig_init)

        # The parameters of the SHOTerm kernel
        #logS0 = pm.Uniform("logS0", lower=-50.0, upper=0.0, testval=logS0_init)
        #logQ = pm.Uniform("logQ", lower=-50.0, upper=20.0, testval=logQ_init)
        #logw0 = pm.Uniform("logw0", lower=-50.0, upper=20.0, testval=logw0_init)
    
        a = pm.Uniform("a", lower=1.0, upper=10.0, testval=2.0)
    
        # The parameters for the transit mean function
        t0 = pm.Uniform("t0", lower=t[0], upper=t[-1], testval=t0_init)
        r = pm.Uniform("r", lower=0.0, upper=1.0, testval=r_init)
        d = pm.Uniform("d", lower=0.0, upper=10.0, testval=d_init)
        tin = pm.Uniform("tin", lower=0.0, upper=10.0, testval=tin_init)
            
        # Deterministics
        # mean = pm.Deterministic("mean", utils.transit(t, t0, r, d, tin))
        transit = utils.theano_transit(t, t0, r, d, tin)
        transit = tt.reshape(tt.tile(transit, (2, 1)).T, (1, 2*transit.shape[0])).T

        # Set up the Gaussian Process model
        kernel = xo.gp.terms.SHOTerm(
            log_S0 = logS0_init,
            log_w0 = logw0_init,
            log_Q=logQ_init
        )
    
        q = tt.stack(1, a)
        Q = q[:, None]*q[None, :]
        kernel = xo.gp.terms.KroneckerTerm(kernel, Q)
        diag = np.exp(2*logsig_init)*tt.ones((2, len(t)))
        gp = GP(kernel, t, diag, J=4)

        # Compute the Gaussian Process likelihood and add it into the
        # the PyMC3 model as a "potential"
        pm.Potential("loglike", gp.log_likelihood((data2 - transit).T))

        # Compute the mean model prediction for plotting purposes
        #pm.Deterministic("mu", gp.predict())
        #map_soln = xo.optimize(start=model2d.test_point, verbose=False)
    return model1d, model2d
def run_gp_single(Sgv, wgv, S1v, w1v, Q1v, opt=opt):

    if (opt == 1):
        print('Running Gp Single Optimiziation', 'Sgv', Sgv, 'wgv', wgv, 'S1v',
              S1v, 'w1v', w1v, 'Q1v', Q1v)
    with pm.Model() as model:

        logs2 = pm.Normal("logs2",
                          mu=2 * np.log(np.mean(yerr)),
                          sigma=100.0,
                          testval=100)

        logSg = pm.Normal("logSg", mu=Sgv, sigma=100.0, testval=Sgv)
        logwg = pm.Normal("logwg", mu=wgv, sigma=100.0, testval=wgv)
        logS1 = pm.Normal("logS1", mu=S1v, sigma=100.0, testval=S1v)
        logw1 = pm.Normal("logw1", mu=w1v, sigma=100.0, testval=w1v)
        logQ1 = pm.Normal("logQ1", mu=Q1v, sigma=100.0, testval=Q1v)

        # Set up the kernel an GP
        bg_kernel = terms.SHOTerm(log_S0=logSg,
                                  log_w0=logwg,
                                  Q=1.0 / np.sqrt(2))
        star_kernel1 = terms.SHOTerm(log_S0=logS1, log_w0=logw1, log_Q=logQ1)
        kernel = star_kernel1 + bg_kernel

        gp = GP(kernel, t, yerr**2 + pm.math.exp(logs2))
        gp_star1 = GP(star_kernel1, t, yerr**2 + pm.math.exp(logs2))
        gp_bg = GP(bg_kernel, t, yerr**2 + pm.math.exp(logs2))

        # Condition the GP on the observations and add the marginal likelihood
        # to the model
        gp.marginal("gp", observed=y)

    with model:
        val = gp.kernel.psd(omega)

        psd_init = xo.eval_in_model(val)

        bg_val = gp_bg.kernel.psd(omega)
        star_val_1 = gp_star1.kernel.psd(omega)

        bg_psd_init = xo.eval_in_model(bg_val)
        star_1_psd_init = xo.eval_in_model(star_val_1)

        #     print('done_init_plot')

        map_soln = model.test_point

        if (opt == 1):
            map_soln = xo.optimize(start=map_soln, vars=[logSg])
            #ask about this, do i need to scale when I show this?
            map_soln = xo.optimize(start=map_soln, vars=[logwg])
            map_soln = xo.optimize(start=map_soln, vars=[logw1])
            map_soln = xo.optimize(start=map_soln, vars=[logS1])
            map_soln = xo.optimize(start=map_soln)

            print(map_soln.values())
            mu, var = xo.eval_in_model(gp.predict(t, return_var=True),
                                       map_soln)

            plt.figure()
            plt.errorbar(t, y, yerr=yerr, fmt=".k", capsize=0, label="data")
            sd = np.sqrt(var)
            art = plt.fill_between(t, mu + sd, mu - sd, color="C1", alpha=0.3)
            art.set_edgecolor("none")
            plt.plot(t, mu, color="C1", label="prediction")

            plt.legend(fontsize=12)
            plt.xlabel("t")
            plt.ylabel("y")
            plt.xlim(0, 10)
            _ = plt.ylim(-2.5, 2.5)

        psd_final = xo.eval_in_model(gp.kernel.psd(omega), map_soln)

        bg_psd_fin = xo.eval_in_model(bg_val, map_soln)
        star_1_psd_fin = xo.eval_in_model(star_val_1, map_soln)
    return psd_init, star_1_psd_init, bg_psd_init, psd_final, star_1_psd_fin, bg_psd_fin, map_soln
def run_gp_binary(Sg, wg, S1, w1, Q1, S2, w2, Q2, opt=opt):
    with pm.Model() as model:

        logs2 = pm.Normal("logs2",
                          mu=2 * np.log(np.mean(yerr)),
                          sigma=100.0,
                          testval=-100)

        mean = pm.Normal("mean", mu=np.mean(y), sigma=1.0)
        logSg = pm.Normal("logSg", mu=0.0, sigma=15.0, testval=Sg)
        logwg = pm.Normal("logwg",
                          mu=0.0,
                          sigma=15.0,
                          testval=wg - np.log(1e6))
        logS1 = pm.Normal("logS1", mu=0.0, sigma=15.0, testval=S1)
        logw1 = pm.Normal("logw1",
                          mu=0.0,
                          sigma=15.0,
                          testval=w1 - np.log(1e6))
        logQ1 = pm.Normal("logQ1", mu=0.0, sigma=15.0, testval=Q1)

        logS2 = pm.Normal("logS2", mu=0.0, sigma=15.0, testval=S2)
        logw2 = pm.Normal("logw2",
                          mu=0.0,
                          sigma=15.0,
                          testval=w2 - np.log(1e6))
        logQ2 = pm.Normal("logQ2", mu=0.0, sigma=15.0, testval=Q2)

        # Set up the kernel an GP
        bg_kernel = terms.SHOTerm(log_S0=logSg,
                                  log_w0=logwg,
                                  Q=1.0 / np.sqrt(2))
        star_kernel1 = terms.SHOTerm(log_S0=logS1, log_w0=logw1, log_Q=logQ1)
        star_kernel2 = terms.SHOTerm(log_S0=logS2, log_w0=logw2, log_Q=logQ2)
        kernel = star_kernel1 + star_kernel2 + bg_kernel

        gp = GP(kernel, t, yerr**2 + pm.math.exp(logs2), mean=mean)
        gp_star1 = GP(star_kernel1, t, yerr**2 + pm.math.exp(logs2), mean=mean)
        gp_bg = GP(bg_kernel, t, yerr**2 + pm.math.exp(logs2), mean=mean)
        gp_star2 = GP(star_kernel2, t, yerr**2 + pm.math.exp(logs2), mean=mean)

        # Condition the GP on the observations and add the marginal likelihood
        # to the model
        gp.marginal("gp", observed=y)

    with model:
        val = gp.kernel.psd(omega)

        psd_init = xo.eval_in_model(val)

        bg_val = gp_bg.kernel.psd(omega)
        star_val_1 = gp_star1.kernel.psd(omega)
        star_val_2 = gp_star2.kernel.psd(omega)

        bg_psd_init = xo.eval_in_model(bg_val)
        star_1_psd_init = xo.eval_in_model(star_val_1)
        star_2_psd_init = xo.eval_in_model(star_val_2)

        #     print('done_init_plot')

        map_soln = model.test_point

        if (opt == 1):
            print('running opt')
            map_soln = xo.optimize(start=map_soln, vars=[logSg])
            #ask about this, do i need to scale when I show this?
            map_soln = xo.optimize(start=map_soln, vars=[logwg])
            #map_soln = xo.optimize(start=map_soln, vars=[logS1,logw1])
            #map_soln = xo.optimize(start=map_soln, vars=[logS2,logw2])

        psd_final = xo.eval_in_model(gp.kernel.psd(omega), map_soln)

        bg_psd_fin = xo.eval_in_model(bg_val, map_soln)
        star_1_psd_fin = xo.eval_in_model(star_val_1, map_soln)
        star_2_psd_fin = xo.eval_in_model(star_val_2, map_soln)
    return psd_init, star_1_psd_init, star_2_psd_init, bg_psd_init, psd_final, star_1_psd_fin, star_2_psd_fin, bg_psd_fin, map_soln
Exemplo n.º 11
0
import theano.tensor as tt
from exoplanet.gp import terms, GP

with pm.Model() as model:

    mean = pm.Normal("mean", mu=0.0, sigma=1.0)
    logS1 = pm.Normal("logS1", mu=0.0, sigma=15.0, testval=np.log(np.var(y)))
    logw1 = pm.Normal("logw1", mu=0.0, sigma=15.0, testval=np.log(3.0))
    logS2 = pm.Normal("logS2", mu=0.0, sigma=15.0, testval=np.log(np.var(y)))
    logw2 = pm.Normal("logw2", mu=0.0, sigma=15.0, testval=np.log(3.0))
    logQ = pm.Normal("logQ", mu=0.0, sigma=15.0, testval=0)

    # Set up the kernel an GP
    kernel = terms.SHOTerm(log_S0=logS1, log_w0=logw1, Q=1.0 / np.sqrt(2))
    kernel += terms.SHOTerm(log_S0=logS2, log_w0=logw2, log_Q=logQ)
    gp = GP(kernel, t, yerr**2, mean=mean)

    # Condition the GP on the observations and add the marginal likelihood
    # to the model
    gp.marginal("gp", observed=y)

# %% [markdown]
# A few comments here:
#
# 1. The `term` interface in *exoplanet* only accepts keyword arguments with names given by the `parameter_names` property of the term. But it will also interpret keyword arguments with the name prefaced by `log_` to be the log of the parameter. For example, in this case, we used `log_S0` as the parameter for each term, but `S0=tt.exp(log_S0)` would have been equivalent. This is useful because many of the parameters are required to be positive so fitting the log of those parameters is often best.
# 2. The third argument to the :class:`exoplanet.gp.GP` constructor should be the *variance* to add along the diagonal, not the standard deviation as in the original [celerite implementation](https://celerite.readthedocs.io).
# 3. Finally, the :class:`exoplanet.gp.GP` constructor takes an optional argument `J` which specifies the width of the problem if it is known at compile time. Just to be confusing, this is actually two times the `J` from [the celerite paper](https://arxiv.org/abs/1703.09710). There are various technical reasons why this is difficult to work out in general and this code will always work if you don't provide a value for `J`, but you can get much better performance (especially for small `J`) if you know what it will be for your problem. In general, most terms cost `J=2` with the exception of a :class:`exoplanet.gp.terms.RealTerm` (which costs `J=1`) and a :class:`exoplanet.gp.terms.RotationTerm` (which costs `J=4`).
#
# To start, let's fit for the maximum a posteriori (MAP) parameters and look the the predictions that those make.

# %%
Exemplo n.º 12
0
    def model_offsets(self):
        """
        Define the GP offset model.

        """

        stdev = self.stdev
        # stdev = 2.0
        nsteps = len(self.steps)
        with pm.Model() as model:

            # Parameters
            logsigma = pm.Normal("logsigma", mu=0.0, sd=15.0)
            logrho = pm.Normal("logrho", mu=0.0, sd=5.0)

            # Define step variables
            step1 = pm.Normal("step1", mu=self.steps[0], sd=stdev)
            steps = step1
            if nsteps > 1:
                step2 = pm.Normal("step2", mu=self.steps[1], sd=stdev)
                steps = [step1, step2]
            if nsteps > 2:
                step3 = pm.Normal("step3", mu=self.steps[2], sd=stdev)
                steps = [step1, step2, step3]
            if nsteps > 3:
                step4 = pm.Normal("step4", mu=self.steps[3], sd=stdev)
                steps = [step1, step2, step3, step4]
            if nsteps > 4:
                step5 = pm.Normal("step5", mu=self.steps[4], sd=stdev)
                steps = [step1, step2, step3, step4, step5]
            if nsteps > 5:
                step6 = pm.Normal("step6", mu=self.steps[5], sd=stdev)
                steps = [step1, step2, step3, step4, step5, step6]
            if nsteps > 6:
                step7 = pm.Normal("step7", mu=self.steps[6], sd=stdev)
                steps = [step1, step2, step3, step4, step5, step6, step7]
            if nsteps > 7:
                step8 = pm.Normal("step8", mu=self.steps[7], sd=stdev)
                steps = [
                    step1, step2, step3, step4, step5, step6, step7, step8
                ]
            if nsteps > 8:
                step9 = pm.Normal("step9", mu=self.steps[8], sd=stdev)
                steps = [
                    step1, step2, step3, step4, step5, step6, step7, step8,
                    step9
                ]
            if nsteps > 9:
                step10 = pm.Normal("step10", mu=self.steps[9], sd=stdev)
                steps = [
                    step1, step2, step3, step4, step5, step6, step7, step8,
                    step9, step10
                ]
            if nsteps > 10:
                step11 = pm.Normal("step11", mu=self.steps[10], sd=stdev)
                steps = [
                    step1, step2, step3, step4, step5, step6, step7, step8,
                    step9, step10, step11
                ]
            if nsteps > 11:
                step12 = pm.Normal("step12", mu=self.steps[11], sd=stdev)
                steps = [
                    step1, step2, step3, step4, step5, step6, step7, step8,
                    step9, step10, step11, step12
                ]
            if nsteps > 12:
                step13 = pm.Normal("step13", mu=self.steps[12], sd=stdev)
                steps = [
                    step1, step2, step3, step4, step5, step6, step7, step8,
                    step9, step10, step11, step12, step13
                ]
            if nsteps > 13:
                step14 = pm.Normal("step14", mu=self.steps[13], sd=stdev)
                steps = [
                    step1, step2, step3, step4, step5, step6, step7, step8,
                    step9, step10, step11, step12, step13, step14
                ]

            # The step model
            mu = step_model(self.t, self.gap_times, steps)

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

            # Set up the kernel an GP
            kernel = terms.Matern32Term(log_sigma=logsigma, log_rho=logrho)
            gp = GP(kernel, self.t, self.yerr**2)

            # Add a custom "potential" (log probability function) with the GP
            # likelihood
            pm.Potential("gp", gp.log_likelihood(self.y - mu))

        self.gp = gp
        self.model = model
        return model
Exemplo n.º 13
0
    def run_inference(self, prior_d, pklpath, make_threadsafe=True):

        # if the model has already been run, pull the result from the
        # pickle. otherwise, run it.
        if os.path.exists(pklpath):
            d = pickle.load(open(pklpath, 'rb'))
            self.model = d['model']
            self.trace = d['trace']
            self.map_estimate = d['map_estimate']
            return 1

        with pm.Model() as model:

            # Fixed data errors.
            sigma = self.y_err

            # Define priors and PyMC3 random variables to sample over.
            # Start with the transit parameters.
            mean = pm.Normal("mean",
                             mu=prior_d['mean'],
                             sd=1e-2,
                             testval=prior_d['mean'])

            t0 = pm.Normal("t0",
                           mu=prior_d['t0'],
                           sd=5e-3,
                           testval=prior_d['t0'])

            period = pm.Normal('period',
                               mu=prior_d['period'],
                               sd=5e-3,
                               testval=prior_d['period'])

            u = xo.distributions.QuadLimbDark("u", testval=prior_d['u'])

            r = pm.Normal("r",
                          mu=prior_d['r'],
                          sd=0.20 * prior_d['r'],
                          testval=prior_d['r'])

            b = xo.distributions.ImpactParameter("b",
                                                 ror=r,
                                                 testval=prior_d['b'])

            orbit = xo.orbits.KeplerianOrbit(period=period,
                                             t0=t0,
                                             b=b,
                                             mstar=self.mstar,
                                             rstar=self.rstar)

            mu_transit = pm.Deterministic(
                'mu_transit',
                xo.LimbDarkLightCurve(u).get_light_curve(
                    orbit=orbit, r=r, t=self.x_obs,
                    texp=self.t_exp).T.flatten())

            mean_model = mu_transit + mean

            if self.modelcomponents == ['transit']:

                mu_model = pm.Deterministic('mu_model', mean_model)

                likelihood = pm.Normal('obs',
                                       mu=mu_model,
                                       sigma=sigma,
                                       observed=self.y_obs)

            if 'gprot' in self.modelcomponents:

                # Instantiate the GP parameters.

                P_rot = pm.Normal("P_rot",
                                  mu=prior_d['P_rot'],
                                  sigma=1.0,
                                  testval=prior_d['P_rot'])

                amp = pm.Uniform('amp', lower=5, upper=40, testval=10)

                mix = xo.distributions.UnitUniform("mix")

                log_Q0 = pm.Normal("log_Q0",
                                   mu=1.0,
                                   sd=10.0,
                                   testval=prior_d['log_Q0'])

                log_deltaQ = pm.Normal("log_deltaQ",
                                       mu=2.0,
                                       sd=10.0,
                                       testval=prior_d['log_deltaQ'])

                kernel = terms.RotationTerm(
                    period=P_rot,
                    amp=amp,
                    mix=mix,
                    log_Q0=log_Q0,
                    log_deltaQ=log_deltaQ,
                )

                gp = GP(kernel, self.x_obs, sigma**2, mean=mean_model)

                # Condition the GP on the observations and add the marginal likelihood
                # to the model. Needed before calling "gp.predict()".
                # NOTE: This formally is the definition of the likelihood?  It
                # would be good to figure out how this works under the hood...
                gp.marginal("transit_obs", observed=self.y_obs)

                # Compute the mean model prediction for plotting purposes
                mu_gprot = pm.Deterministic("mu_gprot", gp.predict())
                mu_model = pm.Deterministic("mu_model", mu_gprot + mean_model)

            # Optimizing
            start = model.test_point
            if 'transit' in self.modelcomponents:
                map_estimate = xo.optimize(start=start,
                                           vars=[r, b, period, t0])
            if 'gprot' in self.modelcomponents:
                map_estimate = xo.optimize(
                    start=map_estimate,
                    vars=[P_rot, amp, mix, log_Q0, log_deltaQ])
            map_estimate = xo.optimize(start=map_estimate)
            # map_estimate = pm.find_MAP(model=model)

            # Plot the simulated data and the maximum a posteriori model to
            # make sure that our initialization looks ok.
            self.y_MAP = (map_estimate['mean'] + map_estimate['mu_transit'])
            if 'gprot' in self.modelcomponents:
                self.y_MAP += map_estimate['mu_gprot']

            if make_threadsafe:
                pass
            else:
                # as described in
                # https://github.com/matplotlib/matplotlib/issues/15410
                # matplotlib is not threadsafe. so do not make plots before
                # sampling, because some child processes tries to close a
                # cached file, and crashes the sampler.

                print(map_estimate)

                if self.PLOTDIR is None:
                    raise NotImplementedError
                outpath = os.path.join(self.PLOTDIR,
                                       'test_{}_MAP.png'.format(self.modelid))
                plot_MAP_data(self.x_obs, self.y_obs, self.y_MAP, outpath)

            # sample from the posterior defined by this model.
            trace = pm.sample(
                tune=self.N_samples,
                draws=self.N_samples,
                start=map_estimate,
                cores=self.N_cores,
                chains=self.N_chains,
                step=xo.get_dense_nuts_step(target_accept=0.9),
            )

        with open(pklpath, 'wb') as buff:
            pickle.dump(
                {
                    'model': model,
                    'trace': trace,
                    'map_estimate': map_estimate
                }, buff)

        self.model = model
        self.trace = trace
        self.map_estimate = map_estimate