コード例 #1
0
def test_gradients(plot=False):
    """Test the gradients in the `System` class."""
    # Limb-darkened star
    A = Primary(lmax=3)
    A[1] = 0.4
    A[2] = 0.26
    A[3] = -0.25
    A.r_m = 1e11

    # Dipole-map hot jupiter
    b = Secondary(lmax=2)
    b.r = 0.09
    b.a = 60
    b.inc = 89.943
    b.porb = 50
    b.prot = 2.49
    b.lambda0 = 89.9
    b.ecc = 0.3
    b.w = 89
    b.L = 1.75e-3
    b[1, 0] = 0.5
    b[2, 1] = 0.1
    b[2, 2] = -0.05

    # Dipole-map hot jupiter
    c = Secondary(lmax=1)
    c.r = 0.12
    c.a = 80
    c.inc = 89.95
    c.porb = 100
    c.prot = 7.83
    c.lambda0 = 85
    c.ecc = 0.29
    c.w = 87.4
    c.L = 1.5e-3
    c[1, 0] = 0.4

    # Instantiate the system
    # We're adding a ton of light travel delay
    # and a finite exposure time: this is a
    # comprehensive test of the main `starry` features
    system = System(A, b, c)
    system.exposure_time = 0.02

    # Light curves and gradients of this object
    object = system

    # Let's plot transit, eclipse, and a PPO
    for t1, t2, figname in zip([-0.425, 25.1, -2.6], [0.0, 25.75, -2.0], [
            "gradients_transit.png", "gradients_eclipse.png",
            "gradients_ppo.png"
    ]):

        # Time arrays
        time = np.linspace(t1, t2, 500)
        time_num = np.linspace(t1, t2, 50)

        # Set up the plot
        if plot:
            fig = pl.figure(figsize=(6, 10))
            fig.subplots_adjust(hspace=0, bottom=0.05, top=0.95)

        # Run!
        system.compute(time, gradient=True)
        flux = np.array(object.lightcurve)
        grad = dict(object.gradient)

        # Numerical flux
        system.compute(time_num, gradient=True)
        flux_num = np.array(object.lightcurve)

        # Plot it
        if plot:
            ax = pl.subplot2grid((18, 3), (0, 0), rowspan=5, colspan=3)
            ax.plot(time, flux, color='C0')
            ax.plot(time_num, flux_num, 'o', ms=3, color='C1')
            ax.set_yticks([])
            ax.set_xticks([])
            [i.set_linewidth(0.) for i in ax.spines.values()]
            col = 0
            row = 0
        eps = 1e-8
        error_rel = []
        for key in grad.keys():
            if key.endswith('.y') or key.endswith('.u'):
                for i, gradient in enumerate(grad[key]):
                    if plot:
                        axg = pl.subplot2grid((18, 3), (5 + row, col),
                                              colspan=1)
                        axg.plot(time, gradient, lw=1, color='C0')
                    if key.endswith('.y'):
                        y0 = eval(key)
                        y = np.array(y0)
                        y[i + 1] += eps
                        exec(key[0] + "[:, :] = y")
                        system.compute(time)
                        exec(key[0] + "[:, :] = y0")
                    else:
                        u0 = eval(key)
                        u = np.array(u0)
                        u[i] += eps
                        exec(key[0] + "[:] = u")
                        system.compute(time)
                        exec(key[0] + "[:] = u0")
                    numgrad = (object.lightcurve - flux) / eps
                    error_rel.append(np.max(abs(numgrad - gradient)))
                    if plot:
                        axg.plot(time, numgrad, lw=1, alpha=0.5, color='C1')
                        axg.set_ylabel(r"$%s_%d$" % (key, i), fontsize=5)
                        axg.margins(None, 0.5)
                        axg.set_xticks([])
                        axg.set_yticks([])
                        [i.set_linewidth(0.) for i in axg.spines.values()]
                        if row < 12:
                            row += 1
                        else:
                            row = 0
                            col += 1
            else:
                if plot:
                    axg = pl.subplot2grid((18, 3), (5 + row, col), colspan=1)
                    axg.plot(time, grad[key], lw=1, color='C0')
                exec(key + " += eps")
                system.compute(time)
                exec(key + " -= eps")
                numgrad = (object.lightcurve - flux) / eps
                error_rel.append(np.max(abs(numgrad - grad[key])))
                if plot:
                    axg.plot(time, numgrad, lw=1, alpha=0.5, color='C1')
                    axg.margins(None, 0.5)
                    axg.set_xticks([])
                    axg.set_yticks([])
                    axg.set_ylabel(r"$%s$" % key, fontsize=5)
                    [i.set_linewidth(0.) for i in axg.spines.values()]
                    if row < 12:
                        row += 1
                    else:
                        row = 0
                        col += 1

        # Generous error tolerance
        assert np.all(np.array(error_rel) < 1e-5)

        # Save the figure
        if plot:
            fig.savefig(figname, bbox_inches='tight', dpi=300)
            pl.close()
コード例 #2
0
# Limb-darkened star
star = Primary()
star[1] = 0.4
star[2] = 0.26
star.r_m = 0

# Dipole-map hot jupiter
planet = Secondary()
planet.r = 0.1
planet.a = 60
planet.inc = 89.5
planet.porb = 50
planet.prot = 2.49
planet.lambda0 = 89.9
planet.ecc = 0.3
planet.w = 89
planet.L = 1e-3
planet[1, 0] = 0.5

# Instantiate the system
system = System(star, planet)
system.exposure_time = 0

# Set up the plot
fig = pl.figure(figsize=(8, 8))
fig.subplots_adjust(hspace=0, bottom=0.05, top=0.95)

# Compute the flux during transit and during secondary eclipse
titles = ['Transit', 'Secondary Eclipse']
for i, time in enumerate([time_transit, time_secondary]):
コード例 #3
0
def test_light_travel():
    """Run the test."""
    # No delay
    star = Primary()
    star[1] = 0.40
    star[2] = 0.26
    star.r_m = 0
    planet = Secondary()
    planet.L = 1e-3
    planet.r = 0.1
    planet.porb = 10
    planet.prot = 10
    planet.a = 22
    planet[1, 0] = 0.5
    system = System(star, planet)
    time = np.concatenate(
        (np.linspace(0, 0.5, 10000,
                     endpoint=False), np.linspace(0.5,
                                                  4.5,
                                                  100,
                                                  endpoint=False),
         np.linspace(4.5, 5.5, 10000,
                     endpoint=False), np.linspace(5.5,
                                                  9.5,
                                                  100,
                                                  endpoint=False),
         np.linspace(9.5, 10, 10000)))
    phase = time / 10.
    system.compute(time)
    transit = phase[np.argmax(planet.Z)]
    eclipse = phase[np.argmin(planet.Z)]
    assert transit == 0
    assert eclipse == 0.5

    # Let's give the system a real length scale now
    star.r_m = 6.95700e8
    eps = 1e-3
    time = np.concatenate(
        (np.linspace(0, 0.5, 100000, endpoint=False),
         np.linspace(0.5, 5 - eps, 100, endpoint=False),
         np.linspace(5 - eps, 5 + eps, 1000000, endpoint=False),
         np.linspace(5 + eps, 9.5, 100,
                     endpoint=False), np.linspace(9.5, 10, 100000)))
    phase = time / planet.porb
    system.compute(time)
    transit = phase[np.argmin(np.abs(planet.X) + (planet.Z < 0))]
    eclipse = phase[np.argmin(np.abs(planet.X) + (planet.Z > 0))]
    assert transit == 0.999940999409994
    assert eclipse == 0.5000590894

    # Run some extra tests
    c = 299792458.
    RSUN = 6.957e8
    time = np.concatenate(
        (np.linspace(0, 0.5, 100000,
                     endpoint=False), np.linspace(0.5,
                                                  4.5,
                                                  100,
                                                  endpoint=False),
         np.linspace(4.5, 5.5, 100000,
                     endpoint=False), np.linspace(5.5,
                                                  9.5,
                                                  100,
                                                  endpoint=False),
         np.linspace(9.5, 10, 100000)))
    phase = time / planet.porb

    # Test this on an inclined orbit
    planet.inc = 30
    system.compute(time)
    transit = phase[np.argmax(planet.Z)]
    eclipse = phase[np.argmin(planet.Z)]
    delay_starry = (0.5 - (transit - eclipse)) * planet.porb * 86400
    a = planet.a * star.r_m
    delay_analytic = 2 * a / c * np.sin(planet.inc * np.pi / 180)
    assert np.abs(1 - delay_starry / delay_analytic) < 0.01

    # Test this on an orbit with nonzero Omega
    planet.inc = 90
    planet.Omega = 90
    system.compute(time)
    transit = phase[np.argmax(planet.Z)]
    eclipse = phase[np.argmin(planet.Z)]
    delay_starry = (0.5 - (transit - eclipse)) * planet.porb * 86400
    a = planet.a * star.r_m
    delay_analytic = 2 * a / c
    assert np.abs(1 - delay_starry / delay_analytic) < 0.01

    # Compute the light travel time from the secondary
    # eclipse to the barycenter for an eccentric orbit.
    # First, compute the phase of secondary eclipse
    # with no light travel time delay:
    planet.inc = 90
    planet.Omega = 0
    planet.w = 30
    planet.ecc = 0.25
    star.r_m = 0
    system.compute(time)
    eclipse0 = phase[np.argmin(planet.Z)]
    z0 = planet.Z[np.argmin(planet.Z)]
    # Now, compute the phase w/ the delay
    star.r_m = 6.95700e8
    system.compute(time)
    eclipse = phase[np.argmin(planet.Z)]
    # Compute the light travel time to the barycenter in days:
    travel_time_starry = (eclipse - eclipse0) * planet.porb * 86400
    # Compute the analytic light travel time to the barycenter in days:
    travel_time_analytic = (0 - z0) * star.r_m / c
    assert np.abs(1 - travel_time_starry / travel_time_analytic) < 0.01