コード例 #1
0
def test_2planet_nomass():
    """
    Compare multiplanet to rebound for planets with mass.
    """
    # generate a planet orbit
    mjup = u.Mjup.to(u.Msun)
    mass_b = 0 * mjup
    mass_c = 0 * mjup

    params = np.array([
        10, 0.1,
        np.radians(45),
        np.radians(45),
        np.radians(45), 0.5, 3, 0.1,
        np.radians(45),
        np.radians(190),
        np.radians(45), 0.2, 1, mass_b, mass_c, 1.5 - mass_b - mass_c
    ])
    tau_ref_epoch = 0

    epochs = np.linspace(0, 365.25 * 4,
                         100) + tau_ref_epoch  # nearly the full period, MJD

    # doesn't matter that this is right, just needs to be the same size. below doesn't include effect of c
    # just want to generate some measurements of plaent b to test compute model
    b_ra_model, b_dec_model, b_vz_model = kepler.calc_orbit(
        epochs,
        params[0],
        params[1],
        params[2],
        params[3],
        params[4],
        params[5],
        params[-2],
        params[-1],
        tau_ref_epoch=tau_ref_epoch)

    # generate some fake measurements of planet b, just to feed into system.py to test bookkeeping
    t = table.Table([
        epochs,
        np.ones(epochs.shape, dtype=int), b_ra_model,
        np.zeros(b_ra_model.shape), b_dec_model,
        np.zeros(b_dec_model.shape)
    ],
                    names=[
                        "epoch", "object", "raoff", "raoff_err", "decoff",
                        "decoff_err"
                    ])
    filename = os.path.join(orbitize.DATADIR, "rebound_2planet.csv")
    t.write(filename)

    # create the orbitize system and generate model predictions using the ground truth
    astrom_dat = read_input.read_file(filename)

    sys = system.System(2,
                        astrom_dat,
                        params[-1],
                        params[-2],
                        tau_ref_epoch=tau_ref_epoch,
                        fit_secondary_mass=True)

    # generate measurement
    radec_orbitize, _ = sys.compute_model(params)
    b_ra_orb = radec_orbitize[:, 0]
    b_dec_orb = radec_orbitize[:, 1]

    # now project the orbit with rebound
    b_manom = basis.tau_to_manom(epochs[0], params[0], params[-1] + params[-3],
                                 params[5], tau_ref_epoch)
    c_manom = basis.tau_to_manom(epochs[0], params[0 + 6],
                                 params[-1] + params[-2], params[5 + 6],
                                 tau_ref_epoch)

    sim = rebound.Simulation()
    sim.units = ('yr', 'AU', 'Msun')

    # add star
    sim.add(m=params[-1])

    # add two planets
    sim.add(m=mass_c,
            a=params[0 + 6],
            e=params[1 + 6],
            M=c_manom,
            omega=params[3 + 6],
            Omega=params[4 + 6] + np.pi / 2,
            inc=params[2 + 6])
    sim.add(m=mass_b,
            a=params[0],
            e=params[1],
            M=b_manom,
            omega=params[3],
            Omega=params[4] + np.pi / 2,
            inc=params[2])
    ps = sim.particles

    sim.move_to_com()

    # Use Wisdom Holman integrator (fast), with the timestep being < 5% of inner planet's orbital period
    sim.integrator = "ias15"
    sim.dt = ps[1].P / 1000.

    # integrate and measure star/planet separation
    b_ra_reb = []
    b_dec_reb = []

    for t in epochs:
        sim.integrate(t / 365.25)

        b_ra_reb.append(-(ps[2].x - ps[0].x))  # ra is negative x
        b_dec_reb.append(ps[2].y - ps[0].y)

    b_ra_reb = np.array(b_ra_reb)
    b_dec_reb = np.array(b_dec_reb)

    diff_ra = b_ra_reb - b_ra_orb / params[6 * 2]
    diff_dec = b_dec_reb - b_dec_orb / params[6 * 2]

    # should be as good as the one planet case
    assert np.all(np.abs(diff_ra) / (params[0] * params[6 * 2]) < 1e-9)
    assert np.all(np.abs(diff_dec) / (params[0] * params[6 * 2]) < 1e-9)
コード例 #2
0
def test_2planet_massive():
    """
    Compare multiplanet to rebound for planets with mass.
    """
    # generate a planet orbit
    mjup = u.Mjup.to(u.Msun)
    mass_b = 12 * mjup
    mass_c = 9 * mjup

    params = np.array([
        10, 0.1,
        np.radians(45),
        np.radians(45),
        np.radians(45), 0.5, 3, 0.1,
        np.radians(45),
        np.radians(190),
        np.radians(45), 0.2, 50, mass_b, mass_c, 1.5 - mass_b - mass_c
    ])
    params_noc = np.array([
        10, 0.1,
        np.radians(45),
        np.radians(45),
        np.radians(45), 0.5, 3, 0.1,
        np.radians(45),
        np.radians(190),
        np.radians(45), 0.2, 50, mass_b, 0, 1.5 - mass_b
    ])
    tau_ref_epoch = 0

    epochs = np.linspace(0, 365.25 * 10,
                         100) + tau_ref_epoch  # nearly the full period, MJD

    # doesn't matter that this is right, just needs to be the same size. below doesn't include effect of c
    # just want to generate some measurements of plaent b to test compute model
    b_ra_model, b_dec_model, b_vz_model = kepler.calc_orbit(
        epochs,
        params[0],
        params[1],
        params[2],
        params[3],
        params[4],
        params[5],
        params[-2],
        params[-1],
        tau_ref_epoch=tau_ref_epoch)

    # generate some fake measurements of planet b, just to feed into system.py to test bookkeeping
    t = table.Table([
        epochs,
        np.ones(epochs.shape, dtype=int), b_ra_model,
        np.zeros(b_ra_model.shape), b_dec_model,
        np.zeros(b_dec_model.shape)
    ],
                    names=[
                        "epoch", "object", "raoff", "raoff_err", "decoff",
                        "decoff_err"
                    ])
    filename = os.path.join(orbitize.DATADIR, "rebound_2planet_outer.csv")
    t.write(filename)

    #### TEST THE OUTER PLANET ####

    # create the orbitize system and generate model predictions using the ground truth
    astrom_dat = read_input.read_file(filename)

    sys = system.System(2,
                        astrom_dat,
                        params[-1],
                        params[-4],
                        tau_ref_epoch=tau_ref_epoch,
                        fit_secondary_mass=True)

    # generate measurement
    radec_orbitize, _ = sys.compute_model(params)
    b_ra_orb = radec_orbitize[:, 0]
    b_dec_orb = radec_orbitize[:, 1]
    # debug, generate measurement without c having any mass
    radec_orb_noc, _ = sys.compute_model(params_noc)
    b_ra_orb_noc = radec_orb_noc[:, 0]
    b_dec_orb_noc = radec_orb_noc[:, 1]

    # check that planet c's perturbation is imprinted (nonzero))
    #assert np.all(b_ra_orb_noc != b_ra_orb)

    # now project the orbit with rebound
    b_manom = basis.tau_to_manom(epochs[0], params[0], params[-1] + params[-3],
                                 params[5], tau_ref_epoch)
    c_manom = basis.tau_to_manom(epochs[0], params[0 + 6],
                                 params[-1] + params[-2], params[5 + 6],
                                 tau_ref_epoch)

    sim = rebound.Simulation()
    sim.units = ('yr', 'AU', 'Msun')

    # add star
    sim.add(m=params[-1])

    # add two planets
    sim.add(m=mass_c,
            a=params[0 + 6],
            e=params[1 + 6],
            M=c_manom,
            omega=params[3 + 6],
            Omega=params[4 + 6] + np.pi / 2,
            inc=params[2 + 6])
    sim.add(m=mass_b,
            a=params[0],
            e=params[1],
            M=b_manom,
            omega=params[3],
            Omega=params[4] + np.pi / 2,
            inc=params[2])
    ps = sim.particles

    sim.move_to_com()

    # Use Wisdom Holman integrator (fast), with the timestep being < 5% of inner planet's orbital period
    sim.integrator = "ias15"
    sim.dt = ps[1].P / 1000.

    # integrate and measure star/planet separation
    b_ra_reb = []
    b_dec_reb = []

    for t in epochs:
        sim.integrate(t / 365.25)

        b_ra_reb.append(-(ps[2].x - ps[0].x))  # ra is negative x
        b_dec_reb.append(ps[2].y - ps[0].y)

    b_ra_reb = np.array(b_ra_reb)
    b_dec_reb = np.array(b_dec_reb)

    diff_ra = b_ra_reb - b_ra_orb / params[6 * 2]
    diff_dec = b_dec_reb - b_dec_orb / params[6 * 2]

    # we placed the planets far apart to minimize secular interactions but there are still some, so relax precision
    assert np.all(np.abs(diff_ra) / (params[0]) < 1e-3)
    assert np.all(np.abs(diff_dec) / (params[0]) < 1e-3)

    ###### NOW TEST THE INNER PLANET #######

    # generate some fake measurements of planet c, just to feed into system.py to test bookkeeping
    t = table.Table([
        epochs,
        np.ones(epochs.shape, dtype=int) * 2, b_ra_model,
        np.zeros(b_ra_model.shape), b_dec_model,
        np.zeros(b_dec_model.shape)
    ],
                    names=[
                        "epoch", "object", "raoff", "raoff_err", "decoff",
                        "decoff_err"
                    ])
    filename = os.path.join(orbitize.DATADIR, "rebound_2planet_inner.csv")
    t.write(filename)

    # create the orbitize system and generate model predictions using the ground truth
    astrom_dat = read_input.read_file(filename)

    sys = system.System(2,
                        astrom_dat,
                        params[-1],
                        params[-2],
                        tau_ref_epoch=tau_ref_epoch,
                        fit_secondary_mass=True)

    # generate measurement
    radec_orbitize, _ = sys.compute_model(params)
    c_ra_orb = radec_orbitize[:, 0]
    c_dec_orb = radec_orbitize[:, 1]

    # start the REBOUND sim again
    sim = rebound.Simulation()
    sim.units = ('yr', 'AU', 'Msun')

    # add star
    sim.add(m=params[-1])

    # add two planets
    sim.add(m=mass_c,
            a=params[0 + 6],
            e=params[1 + 6],
            M=c_manom,
            omega=params[3 + 6],
            Omega=params[4 + 6] + np.pi / 2,
            inc=params[2 + 6])
    sim.add(m=mass_b,
            a=params[0],
            e=params[1],
            M=b_manom,
            omega=params[3],
            Omega=params[4] + np.pi / 2,
            inc=params[2])
    ps = sim.particles

    sim.move_to_com()

    # Use Wisdom Holman integrator (fast), with the timestep being < 5% of inner planet's orbital period
    sim.integrator = "ias15"
    sim.dt = ps[1].P / 1000.

    # integrate and measure star/planet separation
    c_ra_reb = []
    c_dec_reb = []

    for t in epochs:
        sim.integrate(t / 365.25)

        c_ra_reb.append(-(ps[1].x - ps[0].x))  # ra is negative x
        c_dec_reb.append(ps[1].y - ps[0].y)

    c_ra_reb = np.array(c_ra_reb)
    c_dec_reb = np.array(c_dec_reb)

    diff_ra = c_ra_reb - c_ra_orb / params[6 * 2]
    diff_dec = c_dec_reb - c_dec_orb / params[6 * 2]

    # planet is 3 times closer, so roughly 3 times larger secular errors.
    assert np.all(np.abs(diff_ra) / (params[0]) < 3e-3)
    assert np.all(np.abs(diff_dec) / (params[0]) < 3e-3)
コード例 #3
0
def test_1planet():
    """
    Sanity check that things agree for 1 planet case
    """
    # generate a planet orbit
    sma = 1
    ecc = 0.1
    inc = np.radians(45)
    aop = np.radians(45)
    pan = np.radians(45)
    tau = 0.5
    plx = 1
    mtot = 1
    tau_ref_epoch = 0
    mjup = u.Mjup.to(u.Msun)
    mass_b = 12 * mjup

    epochs = np.linspace(0, 300,
                         100) + tau_ref_epoch  # nearly the full period, MJD

    ra_model, dec_model, vz_model = kepler.calc_orbit(
        epochs,
        sma,
        ecc,
        inc,
        aop,
        pan,
        tau,
        plx,
        mtot,
        tau_ref_epoch=tau_ref_epoch)

    # generate some fake measurements just to feed into system.py to test bookkeeping
    t = table.Table([
        epochs,
        np.ones(epochs.shape, dtype=int), ra_model,
        np.zeros(ra_model.shape), dec_model,
        np.zeros(dec_model.shape)
    ],
                    names=[
                        "epoch", "object", "raoff", "raoff_err", "decoff",
                        "decoff_err"
                    ])
    filename = os.path.join(orbitize.DATADIR, "rebound_1planet.csv")
    t.write(filename)

    # create the orbitize system and generate model predictions using the ground truth
    astrom_dat = read_input.read_file(filename)

    sys = system.System(1, astrom_dat, mtot, plx, tau_ref_epoch=tau_ref_epoch)

    params = np.array([sma, ecc, inc, aop, pan, tau, plx, mtot])
    radec_orbitize, _ = sys.compute_model(params)
    ra_orb = radec_orbitize[:, 0]
    dec_orb = radec_orbitize[:, 1]

    # now project the orbit with rebound
    manom = basis.tau_to_manom(epochs[0], sma, mtot, tau, tau_ref_epoch)

    sim = rebound.Simulation()
    sim.units = ('yr', 'AU', 'Msun')

    # add star
    sim.add(m=mtot - mass_b)

    # add one planet
    sim.add(m=mass_b,
            a=sma,
            e=ecc,
            M=manom,
            omega=aop,
            Omega=pan + np.pi / 2,
            inc=inc)
    ps = sim.particles

    sim.move_to_com()

    # Use Wisdom Holman integrator (fast), with the timestep being < 5% of inner planet's orbital period
    sim.integrator = "ias15"
    sim.dt = ps[1].P / 1000.

    # integrate and measure star/planet separation
    ra_reb = []
    dec_reb = []

    for t in epochs:
        sim.integrate(t / 365.25)

        ra_reb.append(-(ps[1].x - ps[0].x))  # ra is negative x
        dec_reb.append(ps[1].y - ps[0].y)

    ra_reb = np.array(ra_reb)
    dec_reb = np.array(dec_reb)

    diff_ra = ra_reb - ra_orb / plx
    diff_dec = dec_reb - dec_orb / plx

    assert np.all(np.abs(diff_ra) < 1e-9)
    assert np.all(np.abs(diff_dec) < 1e-9)
コード例 #4
0
def calc_orbit(
    epochs, sma, ecc, inc, aop, pan, tau, plx, mtot, tau_ref_epoch=58849, 
    m_pl=None, output_star=False
):
    """
    Solves for position for a set of input orbital elements using rebound.

    Args:
        epochs (np.array): MJD times for which we want the positions of the planet
        sma (np.array): semi-major axis of orbit [au]
        ecc (np.array): eccentricity of the orbit [0,1]
        inc (np.array): inclination [radians]
        aop (np.array): argument of periastron [radians]
        pan (np.array): longitude of the ascending node [radians]
        tau (np.array): epoch of periastron passage in fraction of orbital period 
            past MJD=0 [0,1]
        plx (np.array): parallax [mas]
        mtot (np.array): total mass of the two-body orbit (M_* + M_planet) 
            [Solar masses]
        tau_ref_epoch (float, optional): reference date that tau is defined with
            respect to
        m_pl (np.array, optional): mass of the planets[units]
        output_star (bool): if True, also return the position of the star
            relative to the barycenter.

    Returns:
        3-tuple:

            raoff (np.array): array-like (n_dates x n_orbs) of RA offsets between 
                the bodies (origin is at the other body) [mas]

            deoff (np.array): array-like (n_dates x n_orbs) of Dec offsets between 
                the bodies [mas]
                
            vz (np.array): array-like (n_dates x n_orbs) of radial velocity of 
                one of the bodies (see `mass_for_Kamp` description)  [km/s]

    .. Note:: 
    
        return is in format [raoff[planet1, planet2,...,planetn], 
        deoff[planet1, planet2,...,planetn], vz[planet1, planet2,...,planetn]
    """
    
    sim = rebound.Simulation()      #creating the simulation in Rebound
    sim.units = ('AU','yr','Msun')  #converting units for uniformity
    sim.G = 39.476926408897626      #Using a more accurate value in order to minimize differences from prev. Kepler solver
    ps = sim.particles              #for easier calls

    tx = len(epochs)                #keeping track of how many time steps
    te = epochs-epochs[0]           #days

    indv = len(sma)                 #number of planets orbiting the star
    num_planets = np.arange(0,indv) #creates an array of indeces for each planet that exists

    if m_pl is None:                #if no planet masses are input, planet masses set ot zero and mass of star is equal to mtot
        sim.add(m = mtot)
        m_pl = np.zeros(len(sma))
        m_star = mtot
    else:                           #mass of star is always (mass of system)-(sum of planet masses) 
        m_star = mtot - sum(m_pl)
        sim.add(m = m_star)

    #for each planet, create a body in the Rebound sim
    for i in num_planets:
        #calculating mean anomaly
        m_interior = m_star + sum(m_pl[0:i+1])
        mnm = basis.tau_to_manom(epochs[0], sma[i], m_interior, tau[i], tau_ref_epoch) 
        #adding each planet
        sim.add(m = m_pl[i], a = sma[i], e = ecc[i], inc = inc[i], Omega = pan[i] + np.pi/2, omega =aop[i], M =mnm)

    sim.move_to_com()
    sim.integrator = "ias15" 
    sim.dt = ps[1].P/100.       #good rule of thumb: timestep should be at most 10% of the shortest orbital period

    if output_star:
        ra_reb = np.zeros((tx, indv+1))   #numpy.zeros(number of [arrays], size of each array)
        dec_reb = np.zeros((tx, indv+1))
        vz = np.zeros((tx, indv+1))
        for j,t in enumerate(te):
            sim.integrate(t/365.25)
            #for the star and each planet in each epoch denoted by j,t find the RA, Dec, and RV
            com = sim.calculate_com()
            ra_reb[j,0] = -(ps[0].x-com.x)# ra is negative x
            dec_reb[j,0] = ps[0].y-com.y
            vz[j,0] = ps[0].vz
            for i in num_planets:
                ra_reb[j,i+1] = -(ps[int(i+1)].x - ps[0].x) # ra is negative x
                dec_reb[j,i+1] = ps[int(i+1)].y - ps[0].y
                vz[j,i+1] = ps[int(i+1)].vz
    else:
        ra_reb = np.zeros((tx, indv))   #numpy.zeros(number of [arrays], size of each array)
        dec_reb = np.zeros((tx, indv))
        vz = np.zeros((tx, indv))
        #integrate at each epoch
        for j,t in enumerate(te):
            sim.integrate(t/365.25)
            #for each planet in each epoch denoted by j,t find the RA, Dec, and RV
            for i in num_planets:
                ra_reb[j,i] = -(ps[int(i+1)].x - ps[0].x) # ra is negative x
                dec_reb[j,i] = ps[int(i+1)].y - ps[0].y
                vz[j,i] = ps[int(i+1)].vz
    

    #adjusting for parallax
    raoff = plx*ra_reb
    deoff = plx*dec_reb

    #for formatting purposes
    if len(sma)==1:
        raoff = raoff.reshape(tx,)
        deoff = deoff.reshape(tx,)
        vz = vz.reshape(tx,)
        return raoff, deoff, vz
    else: 
        return raoff, deoff, vz