skyfielders / python-skyfield

Elegant astronomy for Python
MIT License
1.41k stars 211 forks source link

Generate topos for body other than Earth #79

Closed davidmikolas closed 4 years ago

davidmikolas commented 8 years ago

I wanted to address the question "How does the Earth move in the sky as seen from the Moon?" (http://astronomy.stackexchange.com/q/8100/7982) but body.topos() failed for bodies other than the earth (e.g. moon, mars). Is there a way to access at least the librations of the moon within Skyfield?

IDEAL: implement .topos() for "popular" solid bodies (e.g. moon, mars) Mars may not be possible because Mars rotation information is not part of the ephemerides, but lunar nutation is in most of them.

HELPFUL: at least a method to access the lunar libration information in the ephemeris when it is explicitly present.

Edit: at a bare minimum, at least give more info when the method fails on bodies that are not earth.

Question: is the majority of the effect (motion of Earth's apparent position in the lunar sky from lunar surface) just the result of the constant lunar rotation vs "non-constant" motion of the moon in it's elliptical orbit? ln that case I could approximate the motion of earth's position in the lunar sky for illustration just by using simple geometry and constant lunar rotation (e.g. Wikipedia's 27.321661 days).

import numpy as np
import matplotlib.pyplot as plt
from skyfield.api import load, now, JulianDate
import json

data = load('de405.bsp')  # de421 also tested

jd = JulianDate(utc=(2016,1,1))

earth = data['earth']
moon  = data['moon']

earth_0_0 = earth.topos(0.0, 0.0)
earth_pos = earth_0_0.at(jd).position.km
print "earth_pos: ", earth_pos

moon_0_0  = moon.topos(0.0, 0.0)    # also fails with ("0.0 N", "0.0 E")
moon_pos  = moon_0_0.at(jd).position.km
print "moon_pos: ", moon_pos

gives:

earth_pos:  [ -2.43910085e+07   1.33218189e+08   5.77225486e+07]
Traceback (most recent call last):
  File "moon_topos.py", line 18, in <module>
    moon_0_0  = moon.topos(0.0, 0.0)    # also fails with ("0.0 N", "0.0 E")
  File ".../anaconda2/anaconda/envs/scipyenv/lib/python2.7/site-packages/skyfield/jpllib.py", line 114, in topos
    assert self.code == 399
AssertionError
brandon-rhodes commented 8 years ago

Thanks for noticing this problem! I will at least plan, short-term, to get an informative exception message in place so that it is clear why Topos creation only works on Earth. Then, once Skyfield is giving a decent response to its users, we can expand outward to trying to get better behavior for whatever bodies we can support. I will have to look over the JPL HORIZONS service again to see if it can do the surfaces of other bodies — if so, the name of the ephemeris file in the output might point us at good data sources!

ghost commented 8 years ago

This may or may not be the same issue as https://github.com/skyfielders/python-skyfield/issues/27

davidmikolas commented 8 years ago

I realized I've actually asked two different questions.

The first question, getting body.topos()for solid bodies is not exactly the same as, but is in the same boat with #27 as @barrycarter mentioned.

The second question, "...a method to access the lunar libration information in the ephemeris..." I have broken out separately as #80.

brandon-rhodes commented 4 years ago

I have just released Skyfield 1.16 which implements support for lunar latitude/longitude locations. Try it out, and let me know if you run into any snags or problems with the implementation!

https://rhodesmill.org/skyfield/planetary.html