In [9]:
from io import StringIO
import numpy as np
import rebound
epoch_of_elements = 53371.0 # [MJD, days]
c = StringIO(u"""
# id e q[AU] i[deg] Omega[deg] argperi[deg] t_peri[MJD, days] epoch_of_observation[MJD, days]
168026 12.181214 15.346358 136.782470 37.581438 268.412314 54776.806093 55516.41727
21170 2.662235 2.013923 140.646538 23.029490 46.292039 54336.126288 53673.44043
189298 15.503013 11.550314 20.042232 203.240743 150.855761 55761.641176 55718.447145
72278 34.638392 24.742323 157.984412 126.431540 178.612758 54382.158401 54347.240445
109766 8.832472 9.900228 144.857801 243.102255 271.345342 55627.501618 54748.37722
""")
comets = np.loadtxt(c) # load the table into a numpy array
We want to add these comits to a REBOUND simulation(s). The first thing to do is set the units, which have to be consistent throughout. Here we have a table in AU and days, so we'll use the gaussian gravitational constant (AU, days, solar masses).
In [10]:
sim = rebound.Simulation()
k = 0.01720209895 # Gaussian constant
sim.G = k**2
We also set the simulation time to the epoch at which the elements are valid:
In [11]:
sim.t = epoch_of_elements
We then add the giant planets in our Solar System to the simulation. You could for example query JPL HORIZONS for the states of the planets at each comet's corresponding epoch of observation (see Horizons.ipynb). Here we set up toy masses and orbits for Jupiter & Saturn:
In [12]:
sim.add(m=1.) # Sun
sim.add(m=1.e-3, a=5.) # Jupiter
sim.add(m=3.e-4, a=10.) # Saturn
Let's write a function that takes a comet from the table and adds it to our simulation:
In [13]:
def addOrbit(sim, comet_elem):
tracklet_id, e, q, inc, Omega, argperi, t_peri, epoch_of_observation = comet_elem
sim.add(primary=sim.particles[0],
a = q/(1.-e),
e = e,
inc = inc*np.pi/180., # have to convert to radians
Omega = Omega*np.pi/180.,
omega = argperi*np.pi/180.,
T = t_peri # time of pericenter passage
)
By default, REBOUND adds and outputs particles in Jacobi orbital elements. Typically orbital elements for comets are heliocentric. Mixing the two will give you relative errors in elements, positions etc. of order the mass ratio of Jupiter to the Sun ($\sim 0.001$) which is why we pass the additional primary=sim.particles[0]
argument to the add()
function. If this level of accuracy doesn't matters to you, you can ignore the primary
argument.
We can now set up the first comet and quickly plot to see what the system looks like:
In [14]:
addOrbit(sim, comets[0])
%matplotlib inline
fig = rebound.OrbitPlot(sim, trails=True)
Now we just integrate until whatever final time we’re interested in. Here it's the epoch at which we observe the comet, which is the last column in our table:
In [15]:
tfinal = comets[0][-1]
sim.integrate(tfinal)
fig = rebound.OrbitPlot(sim, trails=True)
REBOUND automatically find out if you want to integrate forward or backward in time.
For fun, let's add all the coments to a simulation:
In [16]:
sim = rebound.Simulation()
sim.G = k**2
sim.t = epoch_of_elements
sim.add(m=1.) # Sun
sim.add(m=1.e-3, a=5.) # Jupiter
sim.add(m=3.e-4, a=10.) # Saturn
for comet in comets:
addOrbit(sim, comet)
fig = rebound.OrbitPlot(sim, trails=True)
In [ ]: