Exemplo n.º 1
0
def manual_fitting(tic_id, sector, days, flux, t0_guess, period_guess,
                   star_radius, star_mass, x_fold):
    with pm.Model() as model:
        lower_log = np.log(np.std(flux)) - 1
        logs = pm.Uniform("logs",
                          lower=lower_log,
                          upper=0,
                          testval=np.log(np.std(flux)))
        mean_flux = pm.Normal("mean_flux", mu=0, sd=np.std(flux))
        u = xo.distributions.QuadLimbDark("u")
        period = pm.Uniform("period",
                            lower=period_guess * 0.9,
                            upper=period_guess * 1.1,
                            testval=period_guess)

        t0 = pm.Uniform("t0", lower=t0_guess - 0.2, upper=t0_guess + 0.2)

        r, b = xo.distributions.get_joint_radius_impact(min_radius=0.0005,
                                                        max_radius=0.5,
                                                        testval_r=0.015)

        orbit = xo.orbits.KeplerianOrbit(period=period,
                                         t0=t0,
                                         b=b,
                                         r_star=star_radius,
                                         m_star=star_mass)

        # The light curve model is computed using "starry"
        star = xo.StarryLightCurve(u)
        light_curve = star.get_light_curve(orbit=orbit, r=r, t=days)
        # The returned light curve will always have the shape (ntime, nplanet)
        # but we only have one planet so we can "squeeze" the result
        # 1e2 it is because it's the percentage.

        light_curve = tt.squeeze(star.get_light_curve(
            orbit=orbit, r=r, t=days)) * 1e2 + mean_flux

        # Finally, this is the likelihoood for the observations
        pm.Normal("obs", mu=light_curve, sd=tt.exp(logs), observed=flux)
        with model:
            transit_model = xo.utils.eval_in_model(light_curve)
        inds = np.argsort(x_fold)

        p = plotting_folded(days, flux, tic_id, sector, x_fold)

        p.line(x_fold[inds],
               transit_model[inds],
               legend="initial model",
               line_width=3,
               line_alpha=0.6,
               line_color="black")

        # output_file("test.html", title="test.py example")

        show(p)
    return model, light_curve
Exemplo n.º 2
0
    def _build_model(self, gp_timescale_prior=10, fractional_prior_width=10):
        time = np.asarray(self.lc.time, np.float64)
        lc_flux = np.asarray(self.lc.flux, np.float64)
        lc_flux_err = np.asarray(self.lc.flux_err, np.float64)

        # Covariance matrix diagonal


        with pm.Model() as model:

            mean = pm.Normal("mean", mu=np.nanmean(lc_flux), sd=np.nanstd(lc_flux))

            # Star Priors
            # ---------------------
            M_star = pm.Normal("M_star", mu=self.host.mass.value, sd=self.host.mass_error[1])
            R_star = pm.Normal("R_star", mu=self.host.radius.value, sd=self.host.radius_error[1])
            T_star = pm.Normal("T_star", mu=self.host.temperature.value, sd=self.host.temperature_error[1])


            # EB Model
            # ---------------------
            rprs = pm.Normal("rprs", mu=self.planet.rprs, sd=self.planet.rprs_error[1])
            pm.Potential("rprs_prior", tt.switch(rprs > 0, 0, np.inf))

            logP = pm.Normal("logP", mu=np.log(self.planet.period.value), sd=0.01)
            period = pm.Deterministic("period", pm.math.exp(logP))

            t0 = pm.Normal("t0", mu=self.planet.t0, sd=self.planet.t0_error[1])
            r = pm.Deterministic("r", rprs * R_star)
            logr = pm.Deterministic("logr", tt.log(rprs * R_star))
            inclination = pm.Normal("inclination", mu=self.planet.inclination, sd=self.planet.inclination_error[1])
            pm.Potential("r_prior", -logr)
            albedo = pm.Uniform("albedo", lower=0, upper=1)

            # Transit
            transit_orbit = xo.orbits.KeplerianOrbit(period=period, t0=t0, incl=inclination)
            u = xo.distributions.QuadLimbDark("u", testval=np.asarray([0.4, 0.3]))
            transit = xo.StarryLightCurve(u).get_light_curve(
                                                    orbit=transit_orbit, r=r, t=time)
            transit = pm.math.sum(transit, axis=-1)


            # Secondary Eclipse
            eclipse_orbit = xo.orbits.KeplerianOrbit(period=period, t0=t0 + period/2, incl=inclination)
            eclipse = xo.StarryLightCurve([0, 0]).get_light_curve(
                                        orbit=eclipse_orbit, r=r, t=time)
            eclipse = pm.math.sum(eclipse, axis=-1)


            # Reflection
            re = pm.Deterministic('re', albedo * (rprs/transit_orbit.a)**2)
            reflection = -re * tt.cos(2 * np.pi * ((time - t0) / period)) + re
            reflection += ((eclipse)/r**2) * (2 * re)# + (2 * re)


            # Thermal
            teq = pm.Deterministic('teq', T_star * tt.sqrt(0.5*(1/transit_orbit.a)))
            norm = pm.Deterministic("norm", tt.sum(blackbody_theano(bandpass[:, 0], teq) * bandpass[:, 1])/self.host.norm)
            thermal = ((eclipse)/r**2) * norm + norm
            dT = pm.Uniform('dT', lower=0, upper=1000)
            phase_shift = pm.Normal('phase_shift', mu=0, sd=0.1)
            A1 = ((dT)**4/teq**4)
            thermal_cosine = -(A1 * norm) * tt.cos(2 * np.pi * ((time - t0) / period) + phase_shift) - (A1 * norm)
            thermal += thermal_cosine
            pm.Deterministic('thermal_cosine', thermal_cosine)


            # Doppler
            dp = pm.Uniform('dp', lower=0, upper=0.0001)
            doppler = pm.Deterministic('doppler', dp * np.sin((2 * np.pi * (time-t0))/(period)))

            # Elipsoidal
            ep = pm.Uniform('ep', lower=0, upper=0.0001)
            elipsoidal = pm.Deterministic('elipsoidal', -ep * np.cos((2 * np.pi * (time-t0))/(0.5 * period)))

            # Build the light curve
            eb_model =  transit + reflection + thermal + doppler + elipsoidal
            eb_model = ((eb_model + 1)/(1 + norm + (2 * re)))
            eb_model *= mean




            # GP and Motion Fitting
            # ---------------------
            # Create a Gaussian Process to model the long-term stellar variability
            # log(sigma) is the amplitude of variability, estimated from the raw flux scatter
            logsigma = pm.Normal("logsigma", mu=np.log(np.std(lc_flux)), sd=3)
            # log(rho) is the timescale of variability with a user-defined prior
            logrho = pm.Normal("logrho", mu=np.log(gp_timescale_prior),
                               sd=np.log(fractional_prior_width*gp_timescale_prior))
            # Enforce that the scale of variability should be no shorter than 0.5 days
            pm.Potential("logrho_prior", tt.switch(logrho > np.log(self.planet.period.value * 1.1), 0, np.inf))
            # log(s2) is a jitter term to compensate for underestimated flux errors
            # We estimate the magnitude of jitter from the CDPP (normalized to the flux)
            logs2 = pm.Normal("logs2", mu=np.log(self._logs2_prior), sd=3)
            kernel = xo.gp.terms.Matern32Term(log_sigma=logsigma, log_rho=logrho)

            # Store the GP and cadence mask to aid debugging
            model.gp = xo.gp.GP(kernel, time, self._diag + tt.exp(logs2))

            # The motion model regresses against the design matrix
            A = tt.dot(self.design_matrix.T, model.gp.apply_inverse(self.design_matrix))
            # To ensure the weights can be solved for, we need to perform ridge regression
            # to avoid an ill-conditioned matrix A. Here we define the size of the diagonal
            # along which we will add small values
            ridge = np.array(range(self.design_matrix.shape[1]))
            # Cast the ridge indices into tensor space
            ridge = tt.cast(ridge, 'int64')
            # Apply ridge regression by adding small numbers along the diagonal
            A = tt.set_subtensor(A[ridge, ridge], A[ridge, ridge] + 1e-6)

            # Corrected flux, with the EB model removed.
            cflux = np.reshape(lc_flux, (lc_flux.shape[0], 1))
            cflux -= tt.reshape(eb_model, (eb_model.shape[0], 1))

            B = tt.dot(self.design_matrix.T, model.gp.apply_inverse(cflux))
            weights = tt.slinalg.solve(A, B)
            motion_model = pm.Deterministic("motion_model", tt.dot(self.design_matrix, weights)[:, 0])
            pm.Deterministic("weights", weights)


            # Observables
            # ---------------------
            # Track Quanities
            pm.Deterministic("eb_model", eb_model)
            pm.Deterministic("thermal", thermal)
            pm.Deterministic("reflection", reflection)
            pm.Deterministic("transit", transit)
#            pm.Normal("obs", mu=eb_model, sd=lc_flux_err, observed=lc_flux)

            # Likelihood to optimize
            pm.Potential("obs", model.gp.log_likelihood(lc_flux - (motion_model + eb_model)))

            return model
Exemplo n.º 3
0
    def build_model(mask=None, start=None):
        ''' Build a PYMC3 model

        Parameters
        ----------
        mask : np.ndarray
            Boolean array to mask cadences. Cadences that are False will be excluded
            from the model fit
        start : dict
            MAP Solution from exoplanet

        Returns
        -------
        model : pymc3.model.Model
            A pymc3 model
        map_soln : dict
            Best fit solution
        '''

        if mask is None:
            mask = np.ones(len(time), dtype=bool)

        with pm.Model() as model:

            # Parameters for the stellar properties
            mean = pm.Normal("mean", mu=0.0, sd=10.0)
            u_star = xo.distributions.QuadLimbDark("u_star")

            m_star = pm.Normal("m_star", mu=M_star[0], sd=M_star[1])
            r_star = pm.Normal("r_star", mu=R_star[0], sd=R_star[1])
            t_star = pm.Normal("t_star", mu=T_star[0], sd=T_star[1])

            # Prior to require physical parameters
            pm.Potential("m_star_prior", tt.switch(m_star > 0, 0, -np.inf))
            pm.Potential("r_star_prior", tt.switch(r_star > 0, 0, -np.inf))

            # Orbital parameters for the planets
            logP = pm.Normal("logP",
                             mu=np.log(period_value),
                             sd=0.01,
                             shape=shape)
            t0 = pm.Normal("t0", mu=t0_value, sd=0.01, shape=shape)
            b = pm.Uniform("b", lower=0, upper=1, testval=0.5, shape=shape)
            logr = pm.Normal("logr",
                             sd=1.0,
                             mu=0.5 * np.log(np.array(depth_value)) +
                             np.log(R_star[0]),
                             shape=shape)
            r_pl = pm.Deterministic("r_pl", tt.exp(logr))
            ror = pm.Deterministic("ror", r_pl / r_star)

            # Tracking planet parameters
            period = pm.Deterministic("period", tt.exp(logP))

            # Orbit model
            orbit = xo.orbits.KeplerianOrbit(r_star=r_star,
                                             m_star=m_star,
                                             period=period,
                                             t0=t0,
                                             b=b)

            incl = pm.Deterministic('incl', orbit.incl)
            a = pm.Deterministic('a', orbit.a)
            teff = pm.Deterministic('teff', t_star * tt.sqrt(0.5 * (1 / a)))

            # Compute the model light curve using starry
            light_curves = xo.StarryLightCurve(u_star).get_light_curve(
                orbit=orbit, r=r_pl, t=time[mask], texp=texp) * 1e3
            light_curve = pm.math.sum(light_curves, axis=-1) + mean
            pm.Deterministic("light_curves", light_curves)

            # GP
            # --------
            logs2 = pm.Normal("logs2",
                              mu=np.log(1e-4 * np.var(raw_flux[mask])),
                              sd=10)
            logsigma = pm.Normal("logsigma",
                                 mu=np.log(np.std(raw_flux[mask])),
                                 sd=10)
            logrho = pm.Normal("logrho", mu=np.log(150), sd=10)
            kernel = xo.gp.terms.Matern32Term(log_rho=logrho,
                                              log_sigma=logsigma)
            gp = xo.gp.GP(kernel, time[mask],
                          tt.exp(logs2) + raw_flux_err[mask]**2)

            # Motion model
            #------------------
            A = tt.dot(X_pld[mask].T, gp.apply_inverse(X_pld[mask]))
            B = tt.dot(X_pld[mask].T, gp.apply_inverse(raw_flux[mask, None]))
            C = tt.slinalg.solve(A, B)
            motion_model = pm.Deterministic("motion_model",
                                            tt.dot(X_pld[mask], C)[:, 0])

            # Likelihood
            #------------------
            pm.Potential("obs",
                         gp.log_likelihood(raw_flux[mask] - motion_model))

            # gp predicted flux
            gp_pred = gp.predict()
            pm.Deterministic("gp_pred", gp_pred)
            pm.Deterministic("weights", C)

            # Optimize
            #------------------
            if start is None:
                start = model.test_point

            map_soln = xo.optimize(start=start, vars=[logrho, logsigma])
            map_soln = xo.optimize(start=start, vars=[logr])
            map_soln = xo.optimize(start=map_soln, vars=[logs2])
            map_soln = xo.optimize(start=map_soln,
                                   vars=[logrho, logsigma, logs2, logr])
            map_soln = xo.optimize(start=map_soln, vars=[mean, logr])
            map_soln = xo.optimize(start=map_soln, vars=[logP, t0])
            map_soln = xo.optimize(start=map_soln, vars=[b])
            map_soln = xo.optimize(start=map_soln, vars=[u_star])
            map_soln = xo.optimize(start=map_soln,
                                   vars=[logrho, logsigma, logs2])
            map_soln = xo.optimize(start=map_soln)

            return model, map_soln, gp
Exemplo n.º 4
0
                pop_sd = pm.Deterministic('pop_sd', T.sqrt(T.exp(log_pop_var)))
                
            else:
                pop_sd = np.sqrt(2)*ttv_rms_amp[npl]
            
            # transit times
            tt_offset = pm.StudentT('tt_offset', nu=2, shape=len(fixed_ephem))
            
            poly_omc  = pm.Deterministic('poly_omc', C0*Leg0 + C1*Leg1 + C2*Leg2)
            omc_trend = pm.Deterministic('omc_trend', poly_omc + sin_omc)
            
            transit_times = pm.Deterministic('tts', fixed_ephem + omc_trend + tt_offset*pop_sd)
            
                        
            # set up stellar model and planetary orbit
            exoSLC = exo.StarryLightCurve(u)
            orbit  = exo.orbits.TTVOrbit(transit_times=[transit_times], transit_inds=[fixed_inds], 
                                         b=b[npl], r_star=Rstar, m_star=Mstar)

            # track period and epoch
            T0 = pm.Deterministic('T0', orbit.t0)
            P  = pm.Deterministic('P', orbit.period)
            
            # nuissance parameters (one mean flux; variance by quarter)
            flux0 = pm.Normal('flux0', mu=np.ones(len(wq)), sd=np.sqrt(vbq_all[wq])/4, shape=len(wq))
            logvar = pm.Normal('logvar', mu=np.log(vbq_all[wq]), sd=np.log(4)*np.ones(len(wq)), shape=len(wq))

            
            # build the GP kernel using a different noise model for each season
            logSw4 = [None]*4
            logw0  = [None]*4
Exemplo n.º 5
0
    periods = []

    for npl, p in enumerate(planets):
        use = (p.tts > tmin) * (p.tts < tmax)

        if np.sum(use) > 0:
            transit_times.append(p.tts[use])
            transit_inds.append(np.arange(np.sum(use), dtype="int"))

            radii.append(p.radius / RSRE)
            impacts.append(p.impact)
            periods.append(p.period)

    # model the transits
    if len(transit_times) > 0:
        exoSLC = exo.StarryLightCurve(UCOEFFS)
        orbit = exo.orbits.TTVOrbit(transit_times=transit_times,
                                    transit_inds=transit_inds,
                                    period=periods,
                                    b=impacts,
                                    r_star=RSTAR,
                                    m_star=MSTAR)

        light_curves = exoSLC.get_light_curve(orbit=orbit,
                                              r=radii,
                                              t=xtime,
                                              oversample=1)
        model_flux = 1.0 + pm.math.sum(light_curves, axis=-1).eval()

    else:
        model_flux = np.ones_like(yflux)
Exemplo n.º 6
0
    def build_model(x, y, yerr, period_prior, t0_prior, depth, minimum_period=2, maximum_period=30, r_star_prior=5.0, t_star_prior=5000, m_star_prior=None, start=None):
        """Build an exoplanet model for a dataset and set of planets

        Paramters
        ---------
        x : array-like
            The time series (in days); this should probably be centered
        y : array-like
            The relative fluxes (in parts per thousand)
        yerr : array-like
            The uncertainties on ``y``
        period_prior : list
            The literature values for periods of the planets (in days)
        t0_prior : list
            The literature values for phases of the planets in the same
            coordinates as `x`
        rprs_prior : list
            The literature values for the ratio of planet radius to star
            radius
        start : dict
            A dictionary of model parameters where the optimization
            should be initialized

        Returns:
            A PyMC3 model specifying the probabilistic model for the light curve

        """

        model = BoxLeastSquares(x, y)
        results = model.autopower(0.16, minimum_period=minimum_period, maximum_period=maximum_period)
        if period_prior is None:
            period_prior = results.period[np.argmax(results.power)]
        if t0_prior is None:
            t0_prior = results.transit_time[np.argmax(results.power)]
        if depth is None:
            depth = results.depth[np.argmax(results.power)]

        period_prior = np.atleast_1d(period_prior)
        t0_prior = np.atleast_1d(t0_prior)
        # rprs_prior = np.atleast_1d(rprs_prior)

        with pm.Model() as model:

            # Set model variables
            model.x = np.asarray(x, dtype=np.float64)
            model.y = np.asarray(y, dtype=np.float64)
            model.yerr = np.asarray(yerr + np.zeros_like(x), dtype=np.float64)

            '''Stellar Parameters'''
            # The baseline (out-of-transit) flux for the star in ppt
            mean = pm.Normal("mean", mu=0.0, sd=10.0)

            try:
                r_star_mu = target_list[target_list['ID'] == ticid]['rad'].values[0]
            except:
                r_star_mu = r_star_prior
            if m_star_prior is None:
                try:
                    m_star_mu = target_list[target_list['ID'] == ticid]['mass'].values[0]
                except:
                    m_star_mu = 1.2
                if np.isnan(m_star_mu):
                    m_star_mu = 1.2
            else:
                m_star_mu = m_star_prior
            r_star = pm.Normal("r_star", mu=r_star_mu, sd=1.)
            m_star = pm.Normal("m_star", mu=m_star_mu, sd=1.)
            t_star = pm.Normal("t_star", mu=t_star_prior, sd=200)
            rho_star_mu = ((m_star_mu*u.solMass).to(u.g) / ((4/3) * np.pi * ((r_star_mu*u.solRad).to(u.cm))**3)).value
            rho_star = pm.Normal("rho_star", mu=rho_star_mu, sd=.25)

            '''Orbital Parameters'''
            # The time of a reference transit for each planet
            t0 = pm.Normal("t0", mu=t0_prior, sd=2., shape=1)
            period = pm.Uniform("period", testval=period_prior,
                                lower=minimum_period,
                                upper=maximum_period,
                                shape=1)

            b = pm.Uniform("b", testval=0.5, shape=1)

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

            # track additional orbital parameters
            a = pm.Deterministic("a", model.orbit.a)
            incl = pm.Deterministic("incl", model.orbit.incl)

            '''Planet Parameters'''
            # quadratic limb darkening paramters
            u_ld = xo.distributions.QuadLimbDark("u_ld")

            estimated_rpl = r_star*(depth)**(1/2)

            # logr = pm.Normal("logr", testval=np.log(estimated_rpl), sd=1.)
            r_pl = pm.Uniform("r_pl",
                              testval=estimated_rpl,
                              lower=0.,
                              upper=1.)

            # r_pl = pm.Deterministic("r_pl", tt.exp(logr))
            rprs = pm.Deterministic("rprs", r_pl / r_star)
            teff = pm.Deterministic('teff', t_star * tt.sqrt(0.5*(1/a)))

            # Compute the model light curve using starry
            model.light_curves = xo.StarryLightCurve(u_ld).get_light_curve(
                                    orbit=model.orbit, r=r_pl, t=model.x)

            model.light_curve = pm.math.sum(model.light_curves, axis=-1) + mean


            pm.Normal("obs",
                      mu=model.light_curve,
                      sd=model.yerr,
                      observed=model.y)

            # Fit for the maximum a posteriori parameters, I've found that I can get
            # a better solution by trying different combinations of parameters in turn
            if start is None:
                start = model.test_point
            map_soln = xo.optimize(start=start, vars=[period, t0])
            map_soln = xo.optimize(start=map_soln, vars=[r_pl, mean])
            map_soln = xo.optimize(start=map_soln, vars=[period, t0, mean])
            map_soln = xo.optimize(start=map_soln, vars=[r_pl, mean])
            map_soln = xo.optimize(start=map_soln)
            model.map_soln = map_soln

        return model
Exemplo n.º 7
0
    def build_model(mask=None, start=None):
        if mask is None:
            mask = np.ones(len(x), dtype=bool)
        with pm.Model() as model:

            # Parameters for the stellar properties
            mean = pm.Normal("mean", mu=0.0, sd=10.0)
            u_star = xo.distributions.QuadLimbDark("u_star")

            m_star = pm.Normal("m_star", mu=M_star[0], sd=M_star[1])
            r_star = pm.Normal("r_star", mu=R_star[0], sd=R_star[1])
            t_star = pm.Normal("t_star", mu=T_star[0], sd=T_star[1])

            # Prior to require physical parameters
            pm.Potential("m_star_prior", tt.switch(m_star > 0, 0, -np.inf))
            pm.Potential("r_star_prior", tt.switch(r_star > 0, 0, -np.inf))

            # Orbital parameters for the planets
            logP = pm.Normal("logP",
                             mu=np.log(period_value),
                             sd=0.01,
                             shape=shape)
            t0 = pm.Normal("t0", mu=t0_value, sd=0.01, shape=shape)
            b = pm.Uniform("b", lower=0, upper=1, testval=0.5, shape=shape)
            logr = pm.Normal("logr",
                             sd=1.0,
                             mu=0.5 * np.log(np.array(depth_value)) +
                             np.log(R_star[0]),
                             shape=shape)
            r_pl = pm.Deterministic("r_pl", tt.exp(logr))
            ror = pm.Deterministic("ror", r_pl / r_star)

            # Tracking planet parameters
            period = pm.Deterministic("period", tt.exp(logP))

            # Orbit model
            orbit = xo.orbits.KeplerianOrbit(r_star=r_star,
                                             m_star=m_star,
                                             period=period,
                                             t0=t0,
                                             b=b)

            incl = pm.Deterministic('incl', orbit.incl)
            a = pm.Deterministic('a', orbit.a)

            teff = pm.Deterministic('teff', t_star * tt.sqrt(0.5 * (1 / a)))

            # Compute the model light curve using starry
            light_curves = xo.StarryLightCurve(u_star).get_light_curve(
                orbit=orbit, r=r_pl, t=x[mask], texp=texp) * 1e3
            light_curve = pm.math.sum(light_curves, axis=-1) + mean
            pm.Deterministic("light_curves", light_curves)

            pm.Normal('obs', mu=light_curve, sd=yerr[mask], observed=y[mask])

            # Optimize
            #------------------
            if start is None:
                start = model.test_point
            map_soln = xo.optimize(start=start, vars=[logr])
            map_soln = xo.optimize(start=map_soln, vars=[b])
            map_soln = xo.optimize(start=map_soln, vars=[logP, t0])
            map_soln = xo.optimize(start=map_soln, vars=[u_star])
            map_soln = xo.optimize(start=map_soln, vars=[logr])
            map_soln = xo.optimize(start=map_soln, vars=[b])
            map_soln = xo.optimize(start=map_soln, vars=[mean])
            map_soln = xo.optimize(start=map_soln)
            return model, map_soln
Exemplo n.º 8
0
    def build_GPmodel(self, mask=None, start=None, pl=True):
        """from exoplanet"""

        # Find rotation period
        rotper, ls_results = self.find_rotper(self.time, self.flux)

        if mask is None:
            mask = np.ones(len(self.time), dtype=bool)

        with pm.Model() as GPmodel:

            # Parameters for the stellar properties
            mean = pm.Normal("mean", mu=0.0, sd=10.0)

            u_star = xo.distributions.QuadLimbDark("u_star")

            # Stellar parameters from Huang et al (2018)
            M_star_huang = 1.094, 0.039
            R_star_huang = 1.10, 0.023
            BoundedNormal = pm.Bound(pm.Normal, lower=0, upper=3)

            if self.vet == False and self.EB == False:
                # Orbital parameters for the planets
                logP = pm.Normal("logP", mu=np.log(self.bls_period), sd=1)
                t0 = pm.Normal("t0", mu=self.bls_t0, sd=1)
                # Tracking planet parameters
                period = pm.Deterministic("period", tt.exp(logP))
                m_star = BoundedNormal("m_star",
                                       mu=M_star_huang[0],
                                       sd=M_star_huang[1])
                r_star = BoundedNormal("r_star",
                                       mu=R_star_huang[0],
                                       sd=R_star_huang[1])
                b = pm.Uniform("b", lower=0, upper=0.9)
                BoundedNormal_logr = pm.Bound(pm.Normal, lower=-5, upper=0)
                logr = BoundedNormal_logr(
                    'logr',
                    mu=0.5 * np.log(np.array(self.bls_depth)) +
                    np.log(R_star_huang[0]),
                    sd=1.0)
                r_pl = pm.Deterministic("r_pl", tt.exp(logr))
                ror = pm.Deterministic("ror", r_pl / r_star)

                # This is the eccentricity prior from Kipping (2013):
                # https://arxiv.org/abs/1306.4982
                BoundedBeta = pm.Bound(pm.Beta, lower=0, upper=1 - 1e-5)
                ecc = BoundedBeta("ecc", alpha=0.867, beta=3.03, testval=0.1)
                omega = xo.distributions.Angle("omega")

            # Even-Odd Test
            elif self.vet == True and self.EB == False:
                logP_even = pm.Normal("logP_even",
                                      mu=np.log(2 * self.bls_period),
                                      sd=1)
                t0_even = pm.Normal("t0_even", mu=self.bls_t0, sd=1)
                period_even = pm.Deterministic("period_even",
                                               tt.exp(logP_even))
                m_star_even = BoundedNormal("m_star_even",
                                            mu=M_star_huang[0],
                                            sd=M_star_huang[1])
                r_star_even = BoundedNormal("r_star_even",
                                            mu=R_star_huang[0],
                                            sd=R_star_huang[1])
                b_even = pm.Uniform("b_even", lower=0, upper=0.9)
                BoundedNormal_logr_even = pm.Bound(pm.Normal,
                                                   lower=-5,
                                                   upper=0)
                logr_even = BoundedNormal_logr_even(
                    'logr_even',
                    mu=0.5 * np.log(np.array(self.bls_depth)) +
                    np.log(R_star_huang[0]),
                    sd=1.0)
                r_pl_even = pm.Deterministic("r_pl_even", tt.exp(logr_even))
                ror_even = pm.Deterministic("ror_even",
                                            r_pl_even / r_star_even)
                # This is the eccentricity prior from Kipping (2013):
                # https://arxiv.org/abs/1306.4982
                BoundedBeta_even = pm.Bound(pm.Beta, lower=0, upper=1 - 1e-5)
                ecc_even = BoundedBeta_even("ecc_even",
                                            alpha=0.867,
                                            beta=3.03,
                                            testval=0.1)
                omega_even = xo.distributions.Angle("omega_even")

                logP_odd = pm.Normal("logP_odd",
                                     mu=np.log(2 * self.bls_period),
                                     sd=1)
                t0_odd = pm.Normal("t0_odd",
                                   mu=self.bls_period + self.bls_t0,
                                   sd=1)
                period_odd = pm.Deterministic("period_odd", tt.exp(logP_odd))
                m_star_odd = BoundedNormal("m_star_odd",
                                           mu=M_star_huang[0],
                                           sd=M_star_huang[1])
                r_star_odd = BoundedNormal("r_star_odd",
                                           mu=R_star_huang[0],
                                           sd=R_star_huang[1])
                b_odd = pm.Uniform("b_odd", lower=0, upper=0.9)
                BoundedNormal_logr_odd = pm.Bound(pm.Normal, lower=-5, upper=0)
                logr_odd = BoundedNormal_logr_odd(
                    'logr_odd',
                    mu=0.5 * np.log(np.array(self.bls_depth)) +
                    np.log(R_star_huang[0]),
                    sd=1.0)
                r_pl_odd = pm.Deterministic("r_pl_odd", tt.exp(logr_odd))
                ror_odd = pm.Deterministic("ror_odd", r_pl_odd / r_star_odd)
                # This is the eccentricity prior from Kipping (2013):
                # https://arxiv.org/abs/1306.4982
                BoundedBeta_odd = pm.Bound(pm.Beta, lower=0, upper=1 - 1e-5)
                ecc_odd = BoundedBeta_odd("ecc_odd",
                                          alpha=0.867,
                                          beta=3.03,
                                          testval=0.1)
                omega_odd = xo.distributions.Angle("omega_odd")

            #EB modeling
            else:
                logP_1 = pm.Normal("logP_1",
                                   mu=np.log(self.bls_period),
                                   sd=0.1)
                t0_1 = pm.Normal("t0_1", mu=self.bls_t0, sd=0.1)
                period_1 = pm.Deterministic("period_1", tt.exp(logP_1))
                m_star_1 = BoundedNormal("m_star_1",
                                         mu=M_star_huang[0],
                                         sd=M_star_huang[1])
                r_star_1 = BoundedNormal("r_star_1",
                                         mu=R_star_huang[0],
                                         sd=R_star_huang[1])
                b_1 = pm.Uniform("b_1", lower=0, upper=0.9)
                BoundedNormal_logr_1 = pm.Bound(pm.Normal, lower=-5, upper=0)
                logr_1 = BoundedNormal_logr_1(
                    'logr_1',
                    mu=0.5 * np.log(np.array(self.bls_depth)) +
                    np.log(R_star_huang[0]),
                    sd=1.0)
                r_pl_1 = pm.Deterministic("r_pl_1", tt.exp(logr_1))
                ror_1 = pm.Deterministic("ror_1", r_pl_1 / r_star_1)
                # This is the eccentricity prior from Kipping (2013):
                # https://arxiv.org/abs/1306.4982
                BoundedBeta_1 = pm.Bound(pm.Beta, lower=0, upper=1 - 1e-5)
                ecc_1 = BoundedBeta_1("ecc_1",
                                      alpha=0.867,
                                      beta=3.03,
                                      testval=0.1)
                omega_1 = xo.distributions.Angle("omega_1")

                logP_2 = pm.Normal("logP_2",
                                   mu=np.log(self.bls_period),
                                   sd=0.1)
                t0_2 = pm.Normal("t0_2",
                                 mu=self.bls_t0 + (self.bls_period / 2),
                                 sd=0.1)
                period_2 = pm.Deterministic("period_2", tt.exp(logP_2))
                m_star_2 = BoundedNormal("m_star_2",
                                         mu=M_star_huang[0],
                                         sd=M_star_huang[1])
                r_star_2 = BoundedNormal("r_star_2",
                                         mu=R_star_huang[0],
                                         sd=R_star_huang[1])
                b_2 = pm.Uniform("b_2", lower=0, upper=0.9)
                BoundedNormal_logr_2 = pm.Bound(pm.Normal, lower=-5, upper=0)
                logr_2 = BoundedNormal_logr_2(
                    'logr_2',
                    mu=0.5 * np.log(np.array(self.bls_depth)) +
                    np.log(R_star_huang[0]),
                    sd=1.0)
                r_pl_2 = pm.Deterministic("r_pl_2", tt.exp(logr_2))
                ror_2 = pm.Deterministic("ror_2", r_pl_2 / r_star_2)
                # This is the eccentricity prior from Kipping (2013):
                # https://arxiv.org/abs/1306.4982
                BoundedBeta_2 = pm.Bound(pm.Beta, lower=0, upper=1 - 1e-5)
                ecc_2 = BoundedBeta_2("ecc_2",
                                      alpha=0.867,
                                      beta=3.03,
                                      testval=0.1)
                omega_2 = xo.distributions.Angle("omega_2")

            # The parameters of the RotationTerm kernel
            logamp = pm.Normal("logamp",
                               mu=np.log(np.var(self.flux[mask])),
                               sd=5.0)
            logrotperiod = pm.Normal("logrotperiod", mu=np.log(rotper), sd=5.0)
            logQ0 = pm.Normal("logQ0", mu=1.0, sd=10.0)
            logdeltaQ = pm.Normal("logdeltaQ", mu=2.0, sd=10.0)
            mix = pm.Uniform("mix", lower=0, upper=1.0)

            # Transit jitter & GP parameters
            logs2 = pm.Normal("logs2",
                              mu=2 * np.log(np.min(self.flux_err[mask])),
                              sd=5.0)

            # Track the rotation period as a deterministic
            rotperiod = pm.Deterministic("rotation_period",
                                         tt.exp(logrotperiod))

            # GP model for the light curve
            kernel = xo.gp.terms.RotationTerm(log_amp=logamp,
                                              period=rotperiod,
                                              log_Q0=logQ0,
                                              log_deltaQ=logdeltaQ,
                                              mix=mix)
            gp = xo.gp.GP(kernel,
                          self.time[mask],
                          ((self.flux_err[mask])**2 + tt.exp(logs2)),
                          J=4)

            if self.vet == False and self.EB == False:
                # Orbit model
                orbit = xo.orbits.KeplerianOrbit(r_star=r_star,
                                                 m_star=m_star,
                                                 period=period,
                                                 t0=t0,
                                                 b=b,
                                                 ecc=ecc,
                                                 omega=omega)
                if pl is True:  #r = r_pl
                    # Compute the model light curve using starry
                    light_curves = xo.StarryLightCurve(u_star).get_light_curve(
                        orbit=orbit, r=r_pl, t=self.time[mask], texp=0.021)
                else:  #r = 0 (no planet model)
                    light_curves = xo.StarryLightCurve(u_star).get_light_curve(
                        orbit=orbit, r=0, t=self.time[mask], texp=0.021)

                light_curve = pm.math.sum(light_curves, axis=-1)
                pm.Deterministic("light_curves", light_curves)

                # Compute the Gaussian Process likelihood and add it into the
                # the PyMC3 model as a "potential"
                pm.Potential(
                    "loglike",
                    gp.log_likelihood(self.flux[mask] - mean - light_curve))

                # Compute the mean model prediction for plotting purposes
                pm.Deterministic("pred", gp.predict())
                pm.Deterministic(
                    "loglikelihood",
                    gp.log_likelihood(self.flux[mask] - mean - light_curve))

                # Fit for the maximum a posteriori parameters, I've found that I can get
                # a better solution by trying different combinations of parameters in turn
                if start is None:
                    start = GPmodel.test_point
                # Optimize to find the maximum a posteriori parameters
                map_soln = xo.optimize(start=start, vars=[mean])
                map_soln = xo.optimize(start=map_soln, vars=[b])
                map_soln = xo.optimize(start=map_soln, vars=[logP, t0])
                map_soln = xo.optimize(start=map_soln, vars=[u_star])
                map_soln = xo.optimize(start=map_soln, vars=[logr])
                map_soln = xo.optimize(start=map_soln, vars=[b])
                map_soln = xo.optimize(start=map_soln, vars=[ecc, omega])
                map_soln = xo.optimize(start=map_soln, vars=[mean])
                map_soln = xo.optimize(start=map_soln,
                                       vars=[logs2, logQ0, logdeltaQ])
                map_soln = xo.optimize(start=map_soln, vars=[logamp])
                map_soln = xo.optimize(start=map_soln, vars=[logrotperiod])
                map_soln = xo.optimize(start=map_soln, vars=[mean])
                map_soln = xo.optimize(start=map_soln, vars=[mix])
                map_soln = xo.optimize(start=map_soln,
                                       vars=[logs2, logQ0, logdeltaQ])
                map_soln = xo.optimize(start=map_soln)

            # Even-Odd Test
            elif self.vet == True and self.EB == False:
                orbit_even = xo.orbits.KeplerianOrbit(r_star=r_star_even,
                                                      m_star=m_star_even,
                                                      period=period_even,
                                                      t0=t0_even,
                                                      b=b_even,
                                                      ecc=ecc_even,
                                                      omega=omega_even)

                orbit_odd = xo.orbits.KeplerianOrbit(r_star=r_star_odd,
                                                     m_star=m_star_odd,
                                                     period=period_odd,
                                                     t0=t0_odd,
                                                     b=b_odd,
                                                     ecc=ecc_odd,
                                                     omega=omega_odd)

                if pl is True:  #r = r_pl
                    # Compute the model light curve using starry
                    light_curves_even = xo.StarryLightCurve(
                        u_star).get_light_curve(orbit=orbit_even,
                                                r=r_pl_even,
                                                t=self.time[mask],
                                                texp=0.021)
                    light_curves_odd = xo.StarryLightCurve(
                        u_star).get_light_curve(orbit=orbit_odd,
                                                r=r_pl_odd,
                                                t=self.time[mask],
                                                texp=0.021)

                else:  #r = 0 (no planet model)
                    light_curves_even = xo.StarryLightCurve(
                        u_star).get_light_curve(orbit=orbit_even,
                                                r=0,
                                                t=self.time[mask],
                                                texp=0.021)
                    light_curves_odd = xo.StarryLightCurve(
                        u_star).get_light_curve(orbit=orbit_odd,
                                                r=0,
                                                t=self.time[mask],
                                                texp=0.021)

                light_curve_even = pm.math.sum(light_curves_even, axis=-1)
                light_curve_odd = pm.math.sum(light_curves_odd, axis=-1)

                pm.Deterministic("light_curves_even", light_curves_even)
                pm.Deterministic("light_curves_odd", light_curves_odd)

                # Compute the Gaussian Process likelihood and add it into the
                # the PyMC3 model as a "potential"
                pm.Potential(
                    "loglike",
                    gp.log_likelihood(self.flux[mask] - mean -
                                      (light_curve_even + light_curve_odd)))

                # Compute the mean model prediction for plotting purposes
                pm.Deterministic("pred", gp.predict())
                pm.Deterministic(
                    "loglikelihood",
                    gp.log_likelihood(self.flux[mask] - mean -
                                      (light_curve_even + light_curve_odd)))

                # Fit for the maximum a posteriori parameters, I've found that I can get
                # a better solution by trying different combinations of parameters in turn
                if start is None:
                    start = GPmodel.test_point
                # Optimize to find the maximum a posteriori parameters
                map_soln = xo.optimize(start=start, vars=[mean])
                map_soln = xo.optimize(start=map_soln, vars=[b_even])
                map_soln = xo.optimize(start=map_soln, vars=[b_odd])
                map_soln = xo.optimize(start=map_soln,
                                       vars=[logP_even, t0_even])
                map_soln = xo.optimize(start=map_soln, vars=[logP_odd, t0_odd])
                map_soln = xo.optimize(start=map_soln, vars=[u_star])
                map_soln = xo.optimize(start=map_soln, vars=[logr_even])
                map_soln = xo.optimize(start=map_soln, vars=[logr_odd])
                map_soln = xo.optimize(start=map_soln, vars=[b_even])
                map_soln = xo.optimize(start=map_soln, vars=[b_odd])
                map_soln = xo.optimize(start=map_soln,
                                       vars=[ecc_even, omega_even])
                map_soln = xo.optimize(start=map_soln,
                                       vars=[ecc_odd, omega_odd])
                map_soln = xo.optimize(start=map_soln, vars=[mean])
                map_soln = xo.optimize(start=map_soln,
                                       vars=[logs2, logQ0, logdeltaQ])
                map_soln = xo.optimize(start=map_soln, vars=[logamp])
                map_soln = xo.optimize(start=map_soln, vars=[logrotperiod])
                map_soln = xo.optimize(start=map_soln, vars=[mean])
                map_soln = xo.optimize(start=map_soln, vars=[mix])
                map_soln = xo.optimize(start=map_soln,
                                       vars=[logs2, logQ0, logdeltaQ])
                map_soln = xo.optimize(start=map_soln)

            # EB modeling
            else:
                orbit_1 = xo.orbits.KeplerianOrbit(r_star=r_star_1,
                                                   m_star=m_star_1,
                                                   period=period_1,
                                                   t0=t0_1,
                                                   b=b_1,
                                                   ecc=ecc_1,
                                                   omega=omega_1)

                orbit_2 = xo.orbits.KeplerianOrbit(r_star=r_star_2,
                                                   m_star=m_star_2,
                                                   period=period_2,
                                                   t0=t0_2,
                                                   b=b_2,
                                                   ecc=ecc_2,
                                                   omega=omega_2)

                if pl is True:  #r = r_pl
                    # Compute the model light curve using starry
                    light_curves_1 = xo.StarryLightCurve(
                        u_star).get_light_curve(orbit=orbit_1,
                                                r=r_pl_1,
                                                t=self.time[mask],
                                                texp=0.021)
                    light_curves_2 = xo.StarryLightCurve(
                        u_star).get_light_curve(orbit=orbit_2,
                                                r=r_pl_2,
                                                t=self.time[mask],
                                                texp=0.021)

                else:  #r = 0 (no planet model)
                    light_curves_1 = xo.StarryLightCurve(
                        u_star).get_light_curve(orbit=orbit_1,
                                                r=0,
                                                t=self.time[mask],
                                                texp=0.021)
                    light_curves_2 = xo.StarryLightCurve(
                        u_star).get_light_curve(orbit=orbit_2,
                                                r=0,
                                                t=self.time[mask],
                                                texp=0.021)

                light_curve_1 = pm.math.sum(light_curves_1, axis=-1)
                light_curve_2 = pm.math.sum(light_curves_2, axis=-1)

                pm.Deterministic("light_curves_1", light_curves_1)
                pm.Deterministic("light_curves_2", light_curves_2)

                # Compute the Gaussian Process likelihood and add it into the
                # the PyMC3 model as a "potential"
                pm.Potential(
                    "loglike",
                    gp.log_likelihood(self.flux[mask] - mean -
                                      (light_curve_1 + light_curve_2)))

                # Compute the mean model prediction for plotting purposes
                pm.Deterministic("pred", gp.predict())
                pm.Deterministic(
                    "loglikelihood",
                    gp.log_likelihood(self.flux[mask] - mean -
                                      (light_curve_1 + light_curve_2)))

                # Fit for the maximum a posteriori parameters, I've found that I can get
                # a better solution by trying different combinations of parameters in turn
                if start is None:
                    start = GPmodel.test_point
                # Optimize to find the maximum a posteriori parameters
                map_soln = xo.optimize(start=start, vars=[mean])
                map_soln = xo.optimize(start=map_soln, vars=[b_1])
                map_soln = xo.optimize(start=map_soln, vars=[b_2])
                map_soln = xo.optimize(start=map_soln, vars=[logP_1, t0_1])
                map_soln = xo.optimize(start=map_soln, vars=[logP_2, t0_2])
                map_soln = xo.optimize(start=map_soln, vars=[u_star])
                map_soln = xo.optimize(start=map_soln, vars=[logr_1])
                map_soln = xo.optimize(start=map_soln, vars=[logr_2])
                map_soln = xo.optimize(start=map_soln, vars=[b_1])
                map_soln = xo.optimize(start=map_soln, vars=[b_2])
                map_soln = xo.optimize(start=map_soln, vars=[ecc_1, omega_1])
                map_soln = xo.optimize(start=map_soln, vars=[ecc_2, omega_2])
                map_soln = xo.optimize(start=map_soln, vars=[mean])
                map_soln = xo.optimize(start=map_soln,
                                       vars=[logs2, logQ0, logdeltaQ])
                map_soln = xo.optimize(start=map_soln, vars=[logamp])
                map_soln = xo.optimize(start=map_soln, vars=[logrotperiod])
                map_soln = xo.optimize(start=map_soln, vars=[mean])
                map_soln = xo.optimize(start=map_soln, vars=[mix])
                map_soln = xo.optimize(start=map_soln,
                                       vars=[logs2, logQ0, logdeltaQ])
                map_soln = xo.optimize(start=map_soln)

        return GPmodel, map_soln
Exemplo n.º 9
0
    def recreate_mod(self):
        '''
        '''
        with pm.Model() as self.model:

            # Parameters for the stellar properties
            mean = pm.Normal("mean", mu=self.soln['mean'], sd=10.0)
            u_star = xo.distributions.QuadLimbDark("u_star")
            # Stellar parameters from Huang et al (2018)
            M_star_huang = 1.094, 0.039
            R_star_huang = 1.10, 0.023
            BoundedNormal = pm.Bound(pm.Normal, lower=0, upper=3)

            if self.do_even_odd == False:
                logP = pm.Normal("logP", mu=self.soln['logP'], sd=1)
                t0 = pm.Normal("t0", mu=self.soln['t0'], sd=1)
                period = pm.Deterministic("period", tt.exp(logP))
                m_star = BoundedNormal("m_star", mu=self.soln['m_star'], sd=M_star_huang[1])
                r_star = BoundedNormal("r_star", mu=self.soln['r_star'], sd=R_star_huang[1])
                b = pm.Uniform("b", lower=0, upper=0.9, testval=self.soln['b'])
                BoundedNormal_logr = pm.Bound(pm.Normal, lower=-5, upper=0)
                logr = BoundedNormal_logr('logr', mu=self.soln['logr'], sd=1.0)
                r_pl = pm.Deterministic("r_pl", tt.exp(logr))
                ror = pm.Deterministic("ror", r_pl / r_star)
                BoundedBeta = pm.Bound(pm.Beta, lower=0, upper=1-1e-5)
                ecc = BoundedBeta("ecc", alpha=0.867, beta=3.03, testval=self.soln['ecc'])
                omega = xo.distributions.Angle("omega")

            # Even-Odd Test
            else:
                logP_even = pm.Normal("logP_even", mu=self.soln['logP_even'], sd=1)
                t0_even = pm.Normal("t0_even", mu=self.soln['t0_even'], sd=1)
                period_even = pm.Deterministic("period_even", tt.exp(logP_even))
                m_star_even = BoundedNormal("m_star_even", mu=self.soln['m_star_even'], sd=M_star_huang[1])
                r_star_even = BoundedNormal("r_star_even", mu=self.soln['r_star_even'], sd=R_star_huang[1])
                b_even = pm.Uniform("b_even", lower=0, upper=0.9, testval=self.soln['b_even'])
                BoundedNormal_logr = pm.Bound(pm.Normal, lower=-5, upper=0)
                logr_even = BoundedNormal_logr('logr_even', mu=self.soln['logr_even'], sd=1.0)
                r_pl_even = pm.Deterministic("r_pl_even", tt.exp(logr_even))
                ror_even = pm.Deterministic("ror_even", r_pl_even / r_star_even)
                BoundedBeta = pm.Bound(pm.Beta, lower=0, upper=1-1e-5)
                ecc_even = BoundedBeta("ecc_even", alpha=0.867, beta=3.03, testval=self.soln['ecc_even'])
                omega_even = xo.distributions.Angle("omega_even")

                logP_odd = pm.Normal("logP_odd", mu=self.soln['logP_odd'], sd=1)
                t0_odd = pm.Normal("t0_odd", mu=self.soln['t0_odd'], sd=1)
                period_odd = pm.Deterministic("period_odd", tt.exp(logP_odd))
                m_star_odd = BoundedNormal("m_star_odd", mu=self.soln['m_star_odd'], sd=M_star_huang[1])
                r_star_odd = BoundedNormal("r_star_odd", mu=self.soln['r_star_odd'], sd=R_star_huang[1])
                b_odd = pm.Uniform("b_odd", lower=0, upper=0.9, testval=self.soln['b_odd'])
                logr_odd = BoundedNormal_logr('logr_odd', mu=self.soln['logr_odd'], sd=1.0)
                r_pl_odd = pm.Deterministic("r_pl_odd", tt.exp(logr_odd))
                ror_odd = pm.Deterministic("ror_odd", r_pl_odd / r_star_odd)
                ecc_odd = BoundedBeta("ecc_odd", alpha=0.867, beta=3.03, testval=self.soln['ecc_odd'])
                omega_odd = xo.distributions.Angle("omega_odd")

            # The parameters of the RotationTerm kernel
            logamp = pm.Normal("logamp", mu=self.soln['logamp'], sd=5.0)
            logrotperiod = pm.Normal("logrotperiod", mu=self.soln['logrotperiod'], sd=5.0)
            logQ0 = pm.Normal("logQ0", mu=self.soln['logQ0'], sd=10.0)
            logdeltaQ = pm.Normal("logdeltaQ", mu=self.soln['logdeltaQ'], sd=10.0)
            mix = pm.Uniform("mix", lower=0, upper=1.0, testval=self.soln['mix'])

            # Transit jitter & GP parameters
            logs2 = pm.Normal("logs2", mu=self.soln['logs2'], sd=5.0)

            # Track the rotation period as a deterministic
            rotperiod = pm.Deterministic("rotation_period", tt.exp(logrotperiod))

            # GP model for the light curve
            kernel = xo.gp.terms.RotationTerm(log_amp=logamp, period=rotperiod, log_Q0=logQ0, log_deltaQ=logdeltaQ, mix=mix)
            gp = xo.gp.GP(kernel, self.time[self.mask], ((self.flux_err[self.mask])**2 + tt.exp(logs2)), J=4)


            if self.do_even_odd == False:
                # Orbit model
                orbit = xo.orbits.KeplerianOrbit(r_star=r_star, m_star=m_star, period=period, t0=t0, b=b, ecc=ecc, omega=omega)
                light_curves = xo.StarryLightCurve(u_star).get_light_curve(orbit=orbit, r=r_pl, t=self.time[self.mask], texp=0.021)

                light_curve = pm.math.sum(light_curves, axis=-1)
                pm.Deterministic("light_curves", light_curves)

                # Compute the Gaussian Process likelihood and add it into the
                # the PyMC3 model as a "potential"
                pm.Potential("loglike", gp.log_likelihood(self.flux[self.mask] - mean - light_curve))

                # Compute the mean model prediction for plotting purposes
                pm.Deterministic("pred", gp.predict())
                pm.Deterministic("loglikelihood", gp.log_likelihood(self.flux[self.mask] - mean - light_curve))


            else:
                orbit_even = xo.orbits.KeplerianOrbit(r_star=r_star_even, m_star=m_star_even, period=period_even, t0=t0_even, b=b_even, ecc=ecc_even, omega=omega_even)

                orbit_odd = xo.orbits.KeplerianOrbit(r_star=r_star_odd, m_star=m_star_odd, period=period_odd, t0=t0_odd, b=b_odd, ecc=ecc_odd, omega=omega_odd)

                light_curves_even = xo.StarryLightCurve(u_star).get_light_curve(orbit=orbit_even, r=r_pl_even, t=self.time[self.mask], texp=0.021)
                light_curves_odd = xo.StarryLightCurve(u_star).get_light_curve(orbit=orbit_odd, r=r_pl_odd, t=self.time[self.mask], texp=0.021)

                light_curve_even = pm.math.sum(light_curves_even, axis=-1)
                light_curve_odd = pm.math.sum(light_curves_odd, axis=-1)

                pm.Deterministic("light_curves_even", light_curves_even)
                pm.Deterministic("light_curves_odd", light_curves_odd)

                # Compute the Gaussian Process likelihood and add it into the
                # the PyMC3 model as a "potential"
                pm.Potential("loglike", gp.log_likelihood(self.flux[self.mask] - mean - (light_curve_even + light_curve_odd)))

                # Compute the mean model prediction for plotting purposes
                pm.Deterministic("pred", gp.predict())
                pm.Deterministic("loglikelihood", gp.log_likelihood(self.flux[self.mask] - mean - (light_curve_even + light_curve_odd)))