Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when using earth from jup210.bsp #145

Open
JoshPaterson opened this issue Dec 5, 2017 · 7 comments
Assignees

Comments

@JoshPaterson
Copy link
Contributor

@JoshPaterson JoshPaterson commented Dec 5, 2017

When I run:

from skyfield.api import load
ts = load.timescale()

jupiter_ephemeris = load('jup310.bsp')
earth = jupiter_ephemeris['earth']
jupiter = jupiter_ephemeris['jupiter']

t = ts.utc(2017)
earth.at(t).observe(jupiter).apparent()

I get this error:

KeyError: "kernel 'jup310.bsp' is missing 'SATURN BARYCENTER' - the targets it supports are: 0 
SOLAR SYSTEM BARYCENTER, 514 THEBE, 3 EARTH BARYCENTER, 515 ADRASTEA, 5 JUPITER 
BARYCENTER, 516 METIS, 599 JUPITER, 10 SUN, 399 EARTH, 501 IO, 502 EUROPA, 503 
GANYMEDE, 504 CALLISTO, 505 AMALTHEA"

It appears the problem is in line 47 in relativity.py, and occurs because the function add_deflection tries to include the deflection of Saturn, but jup310.bsp does not contain a segment for Saturn.

I was able to get around this by using the earth segment from another ephemeris that did include Saturn.

A possible solution might be to add another except statement to the try-except block in line 46 in relativity.py catching if the ephemeris doesn't contain Saturn. If this situation should produce this error perhaps a more specific error message telling the user to use earth from a different ephemeris could be added.

@brandon-rhodes brandon-rhodes self-assigned this Dec 6, 2017
@JoshPaterson

This comment has been minimized.

Copy link
Contributor Author

@JoshPaterson JoshPaterson commented Dec 8, 2017

This same error occurs when using ephemerides of moons of other planets, like ura112.bsp:

from skyfield.api import load
ts = load.timescale()
ura_ephem = load(r'https://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/satellites/ura112.bsp')
earth = ura_ephem['earth']
uranus = ura_ephem['uranus']

earth.at(t).observe(uranus).apparent()

Except this time it's Jupiter that's missing:

KeyError: "kernel 'ura112.bsp' is missing 'JUPITER BARYCENTER' - the targets it supports are: 0 
SOLAR SYSTEM BARYCENTER, 3 EARTH BARYCENTER, 7 URANUS BARYCENTER, 10 SUN, 716 
CALIBAN, 717 SYCORAX, 718 PROSPERO, 719 SETEBOS, 720 STEPHANO, 721 TRINCULO, 722 
FRANCISCO, 723 MARGARET, 724 FERDINAND, 399 EARTH, 799 URANUS"
@barrycarter

This comment has been minimized.

Copy link

@barrycarter barrycarter commented Dec 11, 2017

I'm probably missing something, but the way CSPICE (https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/index.html) does things is to load multiple BSPs and treat the combination of loaded BSPs as the "ephemeris". It appears that skyfield is doing things on a per-BSP-file basis?

Or can the load() command take multiple arguments?

My technique in CSPICE is to load all the kernels I might need, since loading a kernel is inexpensive (it doesn't load the whole file into memory or anything). See https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/IDL/icy/standard.html for an example

@brandon-rhodes

This comment has been minimized.

Copy link
Member

@brandon-rhodes brandon-rhodes commented Jan 15, 2018

Well, that's interesting! Thanks for the report, @JoshPaterson. Skyfield's attempt to be extra-special-finicky-exact makes it impossible for its apparent-coordinate routines to complete unless it knows where all of the big bodies in the Solar System are — even if an object is close enough in to the observer that it by definition can't be deflecting the light.

  1. I should probably build in some rough checks to that routine to say something like "if both the observer and object are safely inside (or both safely outside) the orbit of Saturn, skip Saturn's deflection effect."

  2. In the meantime, I should add to the next version a convention for combining ephemerides. In the meantime, Josh, you can do this:

jupiter_ephemeris = load('jup310.bsp')
main_ephemeris = load('de421.bsp')
jupiter_ephemeris.segments.extend(main_ephemeris.segments)

The resulting jupiter_ephemeris should complete the operation without error!

@JoshPaterson

This comment has been minimized.

Copy link
Contributor Author

@JoshPaterson JoshPaterson commented Jan 21, 2018

Thanks for that method of combining ephemerides! Since jupiter_ephemeris and main_ephemeris both contain segments for earth, which one is used in the combined ephemeris?

@barrycarter

This comment has been minimized.

Copy link

@barrycarter barrycarter commented Jan 21, 2018

@JoshPaterson I think jupiter_ephemeris does not initially contain segments for Earth (which I think was sort of the whole problem), until you run this line:

jupiter_ephemeris.segments.extend(main_ephemeris.segments)

At that point, the jupiter_ephemeris simply has the exact same Earth segments as main_ephemeris since you added them explicitly. There's only set of segments for Earth, and it's originally in main_ephemeris

@brandon-rhodes

This comment has been minimized.

Copy link
Member

@brandon-rhodes brandon-rhodes commented Jan 23, 2018

@JoshPaterson Good question! The official behavior of libraries like SPICE is, I believe, that the first matching segment is chosen — so you can control which is used by the order in which you append the ephemerides, so that the Earth you want to use comes first.

But it looks like Skyfield doesn't guarantee this: when trying to build a series of segments for predicting the Solar System position of a body, it builds a dictionary for quick reference, and allows later segments to override earlier ones:

segment_dict = dict((segment.target, segment) for segment in segments)

I'll try to get this fixed today, and also add an official way of combining two ephemerides so you'll have an alternative to appending their segments manually. Thanks for pointing out the need for predictable behavior in this case!

(@barrycarter I think Josh's errors involved missing Saturns and Jupiters, not missing Earths?)

@JoshPaterson

This comment has been minimized.

Copy link
Contributor Author

@JoshPaterson JoshPaterson commented Feb 18, 2018

While looking through the SPK documentation I found this section which might be relevant to this issue:

https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/spk.html#Segment%20Order%20and%20Priority

However, segment order does imply priority. For a given target body, segment priority increases with distance from the start of the file: segments closer to the end of the file have higher priority than segments for the same target body that occur earlier in the file. When a data request for a specified target body is made, the segment for that target body with highest priority, and whose time interval includes the request time, will be selected to satisfy the request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.