Ejemplo n.º 1
0
def test_lnlike_grad(param, marginalize_over_inclination):

    # Generate a fake dataset
    np.random.seed(42)
    t = np.linspace(0, 3, 100)
    flux = np.random.randn(len(t))
    data_cov = 1.0

    with change_flags(compute_test_value="off"):
        if param in ["i", "p"]:
            if param == "i" and marginalize_over_inclination:
                return
            theano.gradient.verify_grad(
                lambda x: StarryProcess(
                    marginalize_over_inclination=marginalize_over_inclination,
                    normalized=False,
                ).log_likelihood(t, flux, data_cov, **{param: x}),
                (defaults[param],),
                n_tests=1,
                rng=np.random,
            )
        else:
            theano.gradient.verify_grad(
                lambda x: StarryProcess(
                    marginalize_over_inclination=marginalize_over_inclination,
                    normalized=False,
                    **{param: x}
                ).log_likelihood(t, flux, data_cov),
                (defaults[param],),
                n_tests=1,
                rng=np.random,
            )
Ejemplo n.º 2
0
def test_sample(tol=5):

    # Instantiate the two GPs
    a, b = gauss2beta(45, 1)
    sp1 = StarryProcess(r=10, a=a, b=b)
    a, b = gauss2beta(0, 1)
    sp2 = StarryProcess(r=10, a=a, b=b)

    # Sum them and draw a sample
    sp = sp1 + sp2
    y = sp.sample_ylm().eval()

    # Instantiate a starry map to compute
    # the longitudinally-averaged intensity
    map = starry.Map(15, lazy=False)
    map[:, :] = y
    lat = np.linspace(-90, 90, 300)
    lon = np.linspace(-180, 180, 600)
    lat_, lon_ = np.meshgrid(lat, lon)
    lat_ = lat_.flatten()
    lon_ = lon_.flatten()
    I = np.mean(map.intensity(lat=lat_, lon=lon_).reshape(len(lon), len(lat)),
                axis=0)

    # Get the 3 lowest local minima
    grad = np.gradient(I)
    idx = (grad[1:] > 0) & (grad[:-1] < 0)
    k = np.argsort(I[:-1][idx])[:3]
    min_lats = np.sort(lat[:-1][idx][k])

    # Now check that these are about (-45, 0, 45)
    assert np.abs(min_lats[0] - (-45)) < tol
    assert np.abs(min_lats[1]) < tol
    assert np.abs(min_lats[2] - 45) < tol
Ejemplo n.º 3
0
def test_variance():

    sp = StarryProcess(normalized=False)
    cov = sp.cov([0.0, 0.1]).eval()
    var = sp.cov([0.0]).eval()

    assert np.allclose(cov[0, 0], var)
Ejemplo n.º 4
0
 def _lnlike(r, a, b, c, n, i, p, t, flux, data_cov):
     gp = StarryProcess(
         r=r,
         a=a,
         b=b,
         c=c,
         n=n,
         marginalize_over_inclination=marginalize_over_inclination,
         normalized=False,
     )
     return gp.log_likelihood(t, flux, data_cov, p=p, i=i)
Ejemplo n.º 5
0
 def _sample(r, a, b, c, n, i, p, t):
     gp = StarryProcess(
         r=r,
         a=a,
         b=b,
         c=c,
         n=n,
         marginalize_over_inclination=marginalize_over_inclination,
         normalized=False,
     )
     gp.random.seed(seed)
     return tt.reshape(gp.sample(t, p=p, i=i), (-1,))
Ejemplo n.º 6
0
def get_numerical_mean_and_cov(t, nsamples=10000):
    """
    Compute the empirical covariance of the flux
    marginalized over inclination.

    """
    # Draw random Ylm samples
    sp = StarryProcess()
    mu = sp.mean_ylm.eval()
    cho_cov = sp.cho_cov_ylm.eval()
    y = mu[:, None] + np.dot(cho_cov, np.random.randn(256, nsamples))

    # Draw sin-distributed inclinations
    inc = np.arccos(np.random.random(nsamples)) * 180 / np.pi

    # Compute all the light curves
    map = starry.Map(sp._ydeg)
    f = np.zeros((nsamples, len(t)))
    for k in tqdm(range(nsamples)):
        map.inc = inc[k]
        A = map.design_matrix(theta=360 * t)
        f[k] = np.transpose(A @ y[:, k])

    # Return the empirical mean and covariance
    return np.mean(f, axis=0), np.cov(f.T)
Ejemplo n.º 7
0
def plot_trace(results, **kwargs):
    """
    Plot the nested sampling trace.

    """
    # Get kwargs
    kwargs = update_with_defaults(**kwargs)
    gen_kwargs = kwargs["generate"]
    labels = ["r", "a", "b", "c", "n", "bm", "blv"]

    # Get truths
    try:
        a, b = StarryProcess().latitude._transform.transform(
            gen_kwargs["latitude"]["mu"], gen_kwargs["latitude"]["sigma"])
    except:
        a = np.nan
        b = np.nan
    truths = [
        gen_kwargs["radius"]["mu"],
        a,
        b,
        gen_kwargs["contrast"]["mu"],
        gen_kwargs["nspots"]["mu"],
        np.nan,
        np.nan,
    ]
    ndim = results.samples.shape[-1]
    fig, _ = dyplot.traceplot(results,
                              truths=truths[:ndim],
                              labels=labels[:ndim])
    return fig
Ejemplo n.º 8
0
def test_norm(ftol=0.05):
    # GP mean
    mu = 0.75

    # Dimension of the problem
    K = 3

    # Number of samples in numerical estimate
    M = 100000

    # Random covariance matrix
    np.random.seed(0)
    L = 0.1 * np.tril(0.25 * np.random.randn(K, K) + np.eye(K))
    cov = L @ L.T

    # Compute the series approximation to the normalized covariance
    cov_norm = StarryProcess()._normalize(mu, cov).eval()

    # Compute it by sampling
    u = np.random.randn(K, M)
    x = mu + L @ u
    xnorm = x / np.mean(x, axis=0).reshape(1, -1)
    cov_norm_num = np.cov(xnorm)

    # Fractional error
    error = np.abs((cov_norm - cov_norm_num) / cov_norm)
    try:
        assert np.all(error < ftol)
    except AssertionError as e:
        print(cov_norm)
        print(cov_norm_num)
        raise e
Ejemplo n.º 9
0
def test_sample_conditional():

    # Sample the flux from the prior
    sp = StarryProcess(normalized=False, marginalize_over_inclination=False)
    t = np.linspace(0, 2, 300)
    flux = sp.sample(t, p=1.0, i=60.0).eval().reshape(-1)

    # Now sample the ylms conditioned on the flux
    data_cov = 1e-6
    y = sp.sample_ylm_conditional(t, flux, data_cov, p=1.0, i=60.0).eval()
    map = starry.Map(15, inc=60, lazy=False)
    map[:, :] = y.reshape(-1)
    flux_pred = map.flux(theta=360 * t)

    # The computed flux should match the data pretty well
    chisq = np.sum((flux - flux_pred)**2 / data_cov)
    assert chisq / len(t) < 1
Ejemplo n.º 10
0
    def compile(self):

        # Compile the GP
        print("Compiling. This may take up to one minute...")
        r = tt.dscalar()
        a = tt.dscalar()
        b = tt.dscalar()
        c = tt.dscalar()
        n = tt.dscalar()
        self.gp = StarryProcess(ydeg=self.ydeg, r=r, a=a, b=b, c=c, n=n)
        self.gp.random.seed(238)
        self.sample_function = theano.function(
            [r, a, b, c, n],
            [self.gp.sample_ylm(nsamples=self.nmaps)],
            no_default_updates=True,
        )
        self._compiled = True
        print("Done!")
Ejemplo n.º 11
0
def get_loglike_function(ydeg, marginalize_over_inclination=False):
    t = tt.dvector()
    return theano.function(
        [t],
        StarryProcess(
            ydeg=ydeg,
            marginalize_over_inclination=marginalize_over_inclination,
        ).log_likelihood(t, tt.ones_like(t), 1.0),
    )
Ejemplo n.º 12
0
def test_inclination(nsamples=10000, plot=False, rtol=1e-4, ftol=0.25):
    """
    Test the inclination marginalization algorithm.

    """
    # Time array
    t = np.linspace(0, 1, 1000)

    # Compute the analytic moments
    sp = StarryProcess(normalized=False, marginalize_over_inclination=True)
    mean = sp.mean(t).eval()
    cov = sp.cov(t).eval()

    # Compute the numerical moments
    np.random.seed(0)
    mean_num, cov_num = get_numerical_mean_and_cov(t, nsamples=nsamples)

    # Visualize
    if plot:

        # The radial kernel
        plt.figure()
        plt.plot(cov[0])
        plt.plot(cov_num[0])

        # The full covariance
        fig, ax = plt.subplots(1, 3)
        vmin = np.min(cov)
        vmax = np.max(cov)
        im = ax[0].imshow(cov, vmin=vmin, vmax=vmax)
        plt.colorbar(im, ax=ax[0])
        im = ax[1].imshow(cov_num, vmin=vmin, vmax=vmax)
        plt.colorbar(im, ax=ax[1])
        im = ax[2].imshow(np.log10(np.abs((cov - cov_num) / cov)))
        plt.colorbar(im, ax=ax[2])
        plt.show()

    # Check
    rerr = np.abs(cov[0] - cov_num[0])
    assert np.max(rerr) < rtol, "relative error too large"

    ferr = np.abs((cov[0] - cov_num[0]) / cov[0, 0])
    assert np.max(ferr) < ftol, "fractional error too large"
Ejemplo n.º 13
0
def test_jacobian():

    # Compile the Jacobian
    _a = tt.dscalar()
    _b = tt.dscalar()
    log_jac = theano.function([_a, _b], StarryProcess(a=_a, b=_b).log_jac())

    # Log probability
    def log_prob(p):
        if np.any(p < 0):
            return -np.inf
        elif np.any(p > 1):
            return -np.inf
        else:
            return log_jac(*p)

    # Run the sampler
    ndim, nwalkers, nsteps = 2, 50, 10000
    p0 = np.random.random(size=(nwalkers, ndim))
    sampler = emcee.EnsembleSampler(nwalkers, ndim, log_prob)
    sampler.run_mcmc(p0, nsteps)

    # Transform to latitude params
    a, b = sampler.chain.T.reshape(2, -1)
    mu, sigma = beta2gauss(a, b)

    # Compute the 2d histogram
    m1, m2 = 0, 80
    s1, s2 = 0, 45
    hist, _, _ = np.histogram2d(mu, sigma, range=((m1, m2), (s1, s2)))
    hist /= np.max(hist)

    # Check that the variation is less than 10% across the domain
    std = 1.4826 * mad(hist.flatten())
    mean = np.mean(hist.flatten())
    assert std / mean < 0.1
fig, ax = plt.subplots(
    3,
    nsamples + 1,
    figsize=(12, 5),
    gridspec_kw={
        "height_ratios": [1, 1, 1],
        "width_ratios": np.append(np.ones(nsamples), 0.1),
    },
)


for n, c in enumerate([0.1, -0.1]):

    # Draw samples
    sp = StarryProcess(marginalize_over_inclination=False, c=c, **kwargs)
    y = sp.sample_ylm(nsamples=nsamples).eval()
    flux = 1e3 * sp.flux(y, t, i=inc).eval()

    for k in range(nsamples):
        sp.visualize(y[k], ax=ax[n, k], vmin=0.8, vmax=1.2)
        ax[n, k].set_ylim(-1.5, 2.25)
        ax[n, k].set_rasterization_zorder(1)
        ax[2, k].plot(t, flux[k], color=color[n], lw=0.75)

        if k == 0:
            ax[2, k].spines["top"].set_visible(False)
            ax[2, k].spines["right"].set_visible(False)
            ax[2, k].set_xlabel("rotations", fontsize=8)
            ax[2, k].set_ylabel("flux [ppt]", fontsize=8)
            ax[2, k].set_xticks([0, 0.25, 0.5, 0.75, 1.0])
Ejemplo n.º 15
0
def plot_latitude_pdf(results, **kwargs):
    """
    Plot posterior draws from the latitude hyperdistribution.

    """
    # Get kwargs
    kwargs = update_with_defaults(**kwargs)
    plot_kwargs = kwargs["plot"]
    gen_kwargs = kwargs["generate"]
    mu_true = gen_kwargs["latitude"]["mu"]
    sigma_true = gen_kwargs["latitude"]["sigma"]
    nlat_pts = plot_kwargs["nlat_pts"]
    nlat_samples = plot_kwargs["nlat_samples"]

    # Resample to equal weight
    samples = np.array(results.samples)
    try:
        weights = np.exp(results["logwt"] - results["logz"][-1])
    except:
        weights = results["weights"]
    samples = dyfunc.resample_equal(samples, weights)

    # Function to compute the pdf for a draw
    _draw_pdf = lambda x, a, b: StarryProcess(a=a, b=b).latitude.pdf(x)
    _x = tt.dvector()
    _a = tt.dscalar()
    _b = tt.dscalar()

    # The true pdf
    draw_pdf = theano.function([_x, _a, _b], _draw_pdf(_x, _a, _b))
    x = np.linspace(-89.9, 89.9, nlat_pts)
    if np.isfinite(sigma_true):
        pdf_true = 0.5 * (Normal.pdf(x, mu_true, sigma_true) +
                          Normal.pdf(x, -mu_true, sigma_true))
    else:
        # Isotropic (special case)
        pdf_true = 0.5 * np.cos(x * np.pi / 180) * np.pi / 180

    # Draw sample pdfs
    pdf = np.empty((nlat_samples, nlat_pts))
    for k in range(nlat_samples):
        idx = np.random.randint(len(samples))
        pdf[k] = draw_pdf(x, samples[idx, 1], samples[idx, 2])

    # Plot
    fig, ax = plt.subplots(1)
    for k in range(nlat_samples):
        ax.plot(x, pdf[k], "C0-", lw=1, alpha=0.05, zorder=-1)
    ax.plot(x, pdf_true, "C1-", label="truth")
    ax.plot(x, np.nan * x, "C0-", label="samples")
    ax.legend(loc="upper right")
    ax.set_xlim(-90, 90)
    xticks = [-90, -75, -60, -45, -30, -15, 0, 15, 30, 45, 60, 75, 90]
    ax.set_xticks(xticks)
    ax.set_xticklabels(["{:d}$^\circ$".format(xt) for xt in xticks])
    ax.set_xlabel("latitude", fontsize=16)
    ax.set_ylabel("probability", fontsize=16)
    # Constrain y lims?
    mx1 = np.max(pdf_true)
    mx2 = np.sort(pdf.flatten())[int(0.9 * len(pdf.flatten()))]
    mx = max(2.0 * mx1, 1.2 * mx2)
    ax.set_ylim(-0.1 * mx, mx)
    ax.set_rasterization_zorder(1)
    return fig
Ejemplo n.º 16
0
    def _run(self, doc=None):

        # Get current document if needed
        if doc is None:
            doc = curdoc()

        # Compile if needed
        if not self._compiled:
            self.compile()

        print("Rendering...")

        # The GP samples
        self.Samples = Samples(
            self.ydeg,
            self.npix,
            self.npts,
            self.nmaps,
            self.throttle_time,
            self.nosmooth,
            self.gp,
            self.sample_function,
        )

        # The integrals
        sp = StarryProcess(ydeg=self.ydeg)
        pdf = lambda x, mu, sigma: sp.latitude._pdf(x, *gauss2beta(mu, sigma))
        pdf_gauss = lambda x, mu, sigma: 0.5 * (Normal.pdf(x, -mu, sigma) +
                                                Normal.pdf(x, mu, sigma))
        npts = 300
        T = spot_transform(self.ydeg, npts)
        self.Latitude = Integral(
            params["latitude"],
            self.Samples.callback,
            funcs=[pdf, pdf_gauss],
            labels=["pdf", "laplace"],
            xlabel="latitude distribution",
            ylabel="probability",
            distribution=True,
            legend_location="top_left",
        )
        self.Size = Integral(
            params["size"],
            self.Samples.callback,
            funcs=[
                lambda x, r: T @ (1 / (1 + np.exp(-300 * np.pi / 180 *
                                                  (np.abs(x) - r))) - 1),
                lambda x, r: (1 / (1 + np.exp(-300 * np.pi / 180 *
                                              (np.abs(x) - r))) - 1),
            ],
            labels=["ylm", "true"],
            xlabel="spot profile",
            ylabel="intensity",
            npts=npts,
        )
        self.Contrast = Integral(params["contrast"], self.Samples.callback)

        # Tell the GP about the sliders
        self.Samples.Latitude = self.Latitude
        self.Samples.Size = self.Size
        self.Samples.Contrast = self.Contrast

        # Settings
        ControlPanel = column(
            Div(text="<h1>settings</h1>", css_classes=["control-title"]),
            self.Contrast.layout,
            self.Samples.slider,
            row(
                self.Samples.smooth_button,
                self.Samples.auto_button,
                self.Samples.seed_button,
                self.Samples.reset_button,
                sizing_mode="scale_both",
                css_classes=["button-row"],
            ),
            Div(text=description, css_classes=["control-description"]),
            sizing_mode="scale_both",
        )

        # Full layout
        layout = column(
            row(
                self.Latitude.layout,
                self.Size.layout,
                ControlPanel,
                sizing_mode="scale_both",
            ),
            self.Samples.layout,
            style(),
            sizing_mode="scale_both",
        )

        print("Done rendering.")

        # Remove the loading screen
        doc.remove_root(self.layout)

        # Add the interface
        self.layout = layout
        doc.add_root(self.layout)
Ejemplo n.º 17
0
def test_null_limb_darkening():

    t = np.linspace(0, 1, 300)
    cov1 = StarryProcess(udeg=0).cov(t).eval()
    cov2 = StarryProcess(udeg=2).cov(t, u=[0.0, 0.0]).eval()
    assert np.allclose(cov1, cov2)
Ejemplo n.º 18
0
class Application(object):
    def __init__(
        self,
        ydeg=15,
        npix=100,
        npts=300,
        nmaps=5,
        throttle_time=0.40,
        load_timeout=1.0,
        nosmooth=False,
    ):
        self.ydeg = ydeg
        self.npix = npix
        self.npts = npts
        self.nmaps = nmaps
        self.throttle_time = throttle_time
        self.load_timeout = load_timeout
        self.nosmooth = nosmooth
        self._compiled = False

    def compile(self):

        # Compile the GP
        print("Compiling. This may take up to one minute...")
        r = tt.dscalar()
        a = tt.dscalar()
        b = tt.dscalar()
        c = tt.dscalar()
        n = tt.dscalar()
        self.gp = StarryProcess(ydeg=self.ydeg, r=r, a=a, b=b, c=c, n=n)
        self.gp.random.seed(238)
        self.sample_function = theano.function(
            [r, a, b, c, n],
            [self.gp.sample_ylm(nsamples=self.nmaps)],
            no_default_updates=True,
        )
        self._compiled = True
        print("Done!")

    def run(self, doc=None):

        # Get current document if needed
        if doc is None:
            doc = curdoc()
        doc.title = "starry process"
        doc.template = TEMPLATE

        # Show the loading screen
        self.layout = Div(text=LOADING_SCREEN, css_classes=["body-wrapper"])
        doc.add_root(self.layout)

        # Set a delay timer for safety; when it's done, load the widgets
        doc.add_timeout_callback(lambda: self._run(doc),
                                 int(1000 * self.load_timeout))

    def _run(self, doc=None):

        # Get current document if needed
        if doc is None:
            doc = curdoc()

        # Compile if needed
        if not self._compiled:
            self.compile()

        print("Rendering...")

        # The GP samples
        self.Samples = Samples(
            self.ydeg,
            self.npix,
            self.npts,
            self.nmaps,
            self.throttle_time,
            self.nosmooth,
            self.gp,
            self.sample_function,
        )

        # The integrals
        sp = StarryProcess(ydeg=self.ydeg)
        pdf = lambda x, mu, sigma: sp.latitude._pdf(x, *gauss2beta(mu, sigma))
        pdf_gauss = lambda x, mu, sigma: 0.5 * (Normal.pdf(x, -mu, sigma) +
                                                Normal.pdf(x, mu, sigma))
        npts = 300
        T = spot_transform(self.ydeg, npts)
        self.Latitude = Integral(
            params["latitude"],
            self.Samples.callback,
            funcs=[pdf, pdf_gauss],
            labels=["pdf", "laplace"],
            xlabel="latitude distribution",
            ylabel="probability",
            distribution=True,
            legend_location="top_left",
        )
        self.Size = Integral(
            params["size"],
            self.Samples.callback,
            funcs=[
                lambda x, r: T @ (1 / (1 + np.exp(-300 * np.pi / 180 *
                                                  (np.abs(x) - r))) - 1),
                lambda x, r: (1 / (1 + np.exp(-300 * np.pi / 180 *
                                              (np.abs(x) - r))) - 1),
            ],
            labels=["ylm", "true"],
            xlabel="spot profile",
            ylabel="intensity",
            npts=npts,
        )
        self.Contrast = Integral(params["contrast"], self.Samples.callback)

        # Tell the GP about the sliders
        self.Samples.Latitude = self.Latitude
        self.Samples.Size = self.Size
        self.Samples.Contrast = self.Contrast

        # Settings
        ControlPanel = column(
            Div(text="<h1>settings</h1>", css_classes=["control-title"]),
            self.Contrast.layout,
            self.Samples.slider,
            row(
                self.Samples.smooth_button,
                self.Samples.auto_button,
                self.Samples.seed_button,
                self.Samples.reset_button,
                sizing_mode="scale_both",
                css_classes=["button-row"],
            ),
            Div(text=description, css_classes=["control-description"]),
            sizing_mode="scale_both",
        )

        # Full layout
        layout = column(
            row(
                self.Latitude.layout,
                self.Size.layout,
                ControlPanel,
                sizing_mode="scale_both",
            ),
            self.Samples.layout,
            style(),
            sizing_mode="scale_both",
        )

        print("Done rendering.")

        # Remove the loading screen
        doc.remove_root(self.layout)

        # Add the interface
        self.layout = layout
        doc.add_root(self.layout)
Ejemplo n.º 19
0
p = 1.0
tmax = 10.0
npts = 1000
inc = 60.0
kwargs = dict(r=15)
seed = 0

# Plotting settings
nimg = 5
pad = 85
vmin = -0.15
vmax = 0.075

# Spatial covariance
np.random.seed(seed)
sp = StarryProcess(ydeg=ydeg, seed=seed, **kwargs)
cov_y = sp.cov_ylm.eval()
Ly = np.tril(cho_factor(cov_y, lower=True)[0])
Ny = Ly.shape[0]

# Temporal covariance
t = np.linspace(0, tmax, npts)
kernel = lambda t1, t2: np.exp(-((t1 - t2)**2) / (2 * tau))
Nt = len(t)
eps = 1e-12
cov_t = kernel(t.reshape(1, -1), t.reshape(-1, 1))
Lt = np.tril(cho_factor(cov_t + eps * np.eye(Nt), lower=True)[0])

# Sample the map and the flux
# These operations are identical to the extremely memory
# intensive, excrutiatingly slow operations
Ejemplo n.º 20
0
def test_profile_marg(gradient, profile, ydeg=15, npts=1000):

    # Free parameters
    r = tt.dscalar()
    a = tt.dscalar()
    b = tt.dscalar()
    c = tt.dscalar()
    n = tt.dscalar()
    p = tt.dscalar()
    t = tt.dvector()
    flux = tt.dvector()
    data_cov = tt.dscalar()

    # Compute the mean and covariance
    gp = StarryProcess(
        r=r, a=a, b=b, c=c, n=n, marginalize_over_inclination=True
    )

    # Compile the function
    if gradient:
        g = lambda f, x: tt.grad(f, x)
    else:
        g = lambda f, x: f
    func = theano.function(
        [r, a, b, c, n, p, t, flux, data_cov],
        [
            g(gp.log_likelihood(t, flux, data_cov, p=p), a)
        ],  # wrt a for definiteness
        profile=profile,
    )

    # Run it
    t = np.linspace(0, 1, npts)
    flux = np.random.randn(npts)
    data_cov = 1.0

    run = lambda: func(
        defaults["r"],
        defaults["a"],
        defaults["b"],
        defaults["c"],
        defaults["n"],
        defaults["p"],
        t,
        flux,
        data_cov,
    )

    if profile:

        # Profile the full function
        run()
        print(func.profile.summary())

    else:

        # Time the execution
        number = 100
        time = timeit.timeit(run, number=number) / number
        print("time elapsed: {:.4f} s".format(time))
        if (gradient and time > 0.2) or (not gradient and time > 0.1):
            warnings.warn("too slow! ({:.4f} s)".format(time))
Ejemplo n.º 21
0
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
from starry_process import StarryProcess, gauss2beta
import os

# GP settings
r = 15  # spot radius in degrees
mu, sig = 30, 5  # spot latitude and std. dev. in degrees
c = 0.05  # spot contrast
n = 20  # number of spots
t = np.linspace(0, 1.5, 1000)
a, b = gauss2beta(mu, sig)

# Covariance of the original process
sp = StarryProcess(r=r, a=a, b=b, c=c, n=n, normalized=False)
Sigma = sp.cov(t).eval()

# Covariance of the normalized process
sp_norm = StarryProcess(r=r, a=a, b=b, c=c, n=n, normalized=True)
Sigma_norm = sp_norm.cov(t).eval()

# Figure setup
fig, ax = plt.subplots(1, 2, figsize=(12, 6))
vmin = Sigma_norm.min()
vmax = Sigma_norm.max()

# Original
im = ax[0].imshow(Sigma, cmap="viridis", vmin=vmin, vmax=vmax)
divider = make_axes_locatable(ax[0])
cax = divider.append_axes("right", size="5%", pad=0.1)
Ejemplo n.º 22
0
def plot_samples():

    # Settings
    nsamples = 5
    norm = Normalize(vmin=0.5, vmax=1.1)
    incs = [15, 30, 45, 60, 75, 90]
    t = np.linspace(0, 4, 1000)
    cmap = plt.get_cmap("plasma_r")
    color = lambda i: cmap(0.1 + 0.8 * i / (len(incs) - 1))
    map = starry.Map(15, lazy=False)
    kwargs = [
        dict(r=10, a=0.40, b=0.27, c=0.1, n=10, seed=0),
        dict(r=10, a=0.31, b=0.36, c=0.1, n=10, seed=1),
        dict(r=30, a=0.28, b=0.0, c=0.05, n=10, seed=2),
        dict(r=10, a=0.06, b=0.0, c=0.1, n=20, seed=3),
    ]

    # One figure per `kwargs`
    for n in range(len(kwargs)):

        # Set up the plot
        fig, ax = plt.subplots(
            2,
            nsamples + 1,
            figsize=(12, 2.5),
            gridspec_kw={
                "height_ratios": np.array([1, 0.5]),
                "width_ratios": np.append(np.ones(nsamples), 0.1),
            },
        )

        # Draw samples
        sp = StarryProcess(marginalize_over_inclination=False, **kwargs[n])
        y = sp.sample_ylm(nsamples=nsamples).eval()

        # Normalize so that the background photosphere
        # has unit intensity (for plotting)
        y[:, 0] += 1
        y *= np.pi

        # Visualize each sample
        for k in range(nsamples):
            map[:, :] = y[k]
            map.show(ax=ax[0, k], projection="moll", norm=norm)
            ax[0, k].set_ylim(-1.5, 2.25)
            ax[0, k].set_rasterization_zorder(1)
            for i, inc in enumerate(incs):
                map.inc = inc
                flux = map.flux(theta=360.0 * t)
                flux -= np.mean(flux)
                flux *= 1e3
                ax[1, k].plot(t, flux, color=color(i), lw=0.75)
            if k == 0:
                ax[1, k].spines["top"].set_visible(False)
                ax[1, k].spines["right"].set_visible(False)
                ax[1, k].set_xlabel("rotations", fontsize=8)
                ax[1, k].set_ylabel("flux [ppt]", fontsize=8)
                ax[1, k].set_xticks([0, 1, 2, 3, 4])
                for tick in (ax[1, k].xaxis.get_major_ticks() +
                             ax[1, k].yaxis.get_major_ticks()):
                    tick.label.set_fontsize(6)
                ax[1, k].tick_params(direction="in")
            else:
                ax[1, k].axis("off")

        # Appearance tweaks
        cax = inset_axes(ax[0, -1],
                         width="70%",
                         height="50%",
                         loc="lower center")
        cbar = fig.colorbar(ax[0, k].images[0],
                            cax=cax,
                            orientation="vertical")
        cbar.set_label("intensity", fontsize=8)
        cbar.set_ticks([0.5, 0.75, 1])
        cbar.ax.tick_params(labelsize=6)
        ax[0, -1].axis("off")
        lax = inset_axes(ax[1, -1],
                         width="80%",
                         height="100%",
                         loc="center right")
        for i, inc in enumerate(incs):
            lax.plot(0,
                     0,
                     color=color(i),
                     lw=1,
                     label=r"{}$^\circ$".format(inc))
        lax.legend(loc="center left", fontsize=5, frameon=False)
        lax.axis("off")
        ax[1, -1].axis("off")
        dy = max([max(np.abs(ax[1, k].get_ylim())) for k in range(nsamples)])
        for k in range(nsamples):
            ax[1, 0].set_ylim(-dy, dy)

        # We're done
        fig.savefig("samples_{}.png".format(n), bbox_inches="tight", dpi=100)
Ejemplo n.º 23
0
def plot_corner(results, transform_beta=False, **kwargs):
    """
    Plot the posterior corner plot.

    """
    # Get kwargs
    kwargs = update_with_defaults(**kwargs)
    gen_kwargs = kwargs["generate"]
    sample_kwargs = kwargs["sample"]
    plot_kwargs = kwargs["plot"]
    span = [
        (sample_kwargs["rmin"], sample_kwargs["rmax"]),
        (sample_kwargs["amin"], sample_kwargs["amax"]),
        (sample_kwargs["bmin"], sample_kwargs["bmax"]),
        (sample_kwargs["cmin"], sample_kwargs["cmax"]),
        (sample_kwargs["nmin"], sample_kwargs["nmax"]),
        0.995,
        0.995,
    ]
    labels = [
        r"$r$",
        r"$a$",
        r"$b$",
        r"$c$",
        r"$n$",
        r"$\mu_b$",
        r"$\ln\sigma^2_b$",
    ]

    # Get truths
    sp = StarryProcess()
    try:
        a, b = gauss2beta(gen_kwargs["latitude"]["mu"],
                          gen_kwargs["latitude"]["sigma"])
    except:
        a = np.nan
        b = np.nan
    truths = [
        gen_kwargs["radius"]["mu"],
        a,
        b,
        gen_kwargs["contrast"]["mu"],
        gen_kwargs["nspots"]["mu"],
        np.nan,
        np.nan,
    ]

    samples = np.array(results.samples)
    ndim = samples.shape[-1]

    if transform_beta:

        # Transform from `a, b` to `mode, std`
        a = samples[:, 1]
        b = samples[:, 2]
        mu, sigma = beta2gauss(a, b)
        samples[:, 1] = mu
        samples[:, 2] = sigma
        labels[1] = r"$\mu_\phi$"
        labels[2] = r"$\sigma_\phi$"
        if np.isfinite(gen_kwargs["latitude"]["sigma"]):
            truths[1] = gen_kwargs["latitude"]["mu"]
            truths[2] = gen_kwargs["latitude"]["sigma"]
        else:
            truths[1] = np.nan
            truths[2] = np.nan
        span[1] = (0, 90)
        span[2] = (0, 45)

    # Get sample weights
    try:
        weights = np.exp(results["logwt"] - results["logz"][-1])
    except:
        weights = results["weights"]

    fig = corner(samples[:, :ndim],
                 plot_datapoints=False,
                 plot_density=False,
                 truths=truths[:ndim],
                 labels=labels[:ndim],
                 range=span[:ndim],
                 fill_contours=True,
                 weights=weights,
                 smooth=2.0,
                 smooth1d=2.0,
                 bins=100,
                 hist_kwargs=dict(lw=1),
                 truth_color="#ff7f0e",
                 **plot_kwargs)

    return fig
Ejemplo n.º 24
0
fig, ax = plt.subplots(
    2 * len(kwargs),
    nsamples + 1,
    figsize=(12, 2.5 * len(kwargs)),
    gridspec_kw={
        "height_ratios": np.tile([1, 0.5], len(kwargs)),
        "width_ratios": np.append(np.ones(nsamples), 0.1),
    },
)
ax = np.swapaxes(np.swapaxes(ax.T.reshape(nsamples + 1, len(kwargs), 2), 0, 2),
                 0, 1)

for n in range(len(kwargs)):

    # Draw samples
    sp = StarryProcess(marginalize_over_inclination=False, **kwargs[n])
    y = sp.sample_ylm(nsamples=nsamples).eval()

    # Normalize so that the background photosphere
    # has unit intensity (for plotting)
    y[:, 0] += 1
    y *= np.pi

    for k in range(nsamples):
        map[:, :] = y[k]
        map.show(ax=ax[n, 0, k], projection="moll", norm=norm)
        ax[n, 0, k].set_ylim(-1.5, 2.25)
        ax[n, 0, k].set_rasterization_zorder(1)
        for i, inc in enumerate(incs):
            map.inc = inc
            flux = map.flux(theta=360.0 * t)
Ejemplo n.º 25
0
import matplotlib.pyplot as plt
from starry_process import StarryProcess, gauss2beta
import theano
import theano.tensor as tt
from tqdm import tqdm
import os

# Compile the function to get the covariance matrix
r = tt.dscalar()
a = tt.dscalar()
b = tt.dscalar()
c = tt.dscalar()
n = tt.dscalar()
get_cov = theano.function(
    [r, a, b, c, n],
    StarryProcess(ydeg=20, epsy=1e-12, epsy15=0, r=r, a=a, b=b, c=c,
                  n=n).cov_ylm,
)

# Plot the condition number for 100 prior samples
C = lambda cov, l: np.linalg.cond(cov[:(l + 1)**2, :(l + 1)**2])
ls = np.arange(1, 21)
nsamples = 100

fig, ax = plt.subplots(1)
np.random.seed(0)
for j in tqdm(range(nsamples), disable=bool(int(os.getenv("NOTQDM", "0")))):
    r = np.random.uniform(10, 45)
    c = np.random.random()
    n = np.random.uniform(1, 50)
    mu = np.random.uniform(0, 85)
    sigma = np.random.uniform(5, 40)
Ejemplo n.º 26
0
map = starry.Map(15, lazy=False)

fig, ax = plt.subplots(
    2,
    nsamples + 1,
    figsize=(12, 2.5),
    gridspec_kw={
        "height_ratios": [1, 0.5],
        "width_ratios": np.append(np.ones(nsamples), 0.1),
    },
)

# Draw samples from a sum of two StarryProcess instances
sp = StarryProcess(marginalize_over_inclination=False,
                   r=10,
                   mu=60,
                   sigma=3,
                   c=0.15)
sp += StarryProcess(marginalize_over_inclination=False,
                    r=20,
                    mu=0,
                    sigma=3,
                    n=5,
                    c=0.1)
y = sp.sample_ylm(nsamples=nsamples).eval()

# Normalize so that the background photosphere
# has unit intensity (for plotting)
y[:, 0] += 1
y *= np.pi
Ejemplo n.º 27
0
def test_likelihood():
    t = np.linspace(0, 1, 100)
    flux = np.random.randn(100)
    sp = StarryProcess(r=10) + StarryProcess(r=20)
    ll = sp.log_likelihood(t, flux, 1.0).eval()
    assert np.isfinite(ll)