matthewholman / assist

ASSIST is a software package for ephemeris-quality integrations of test particles.
https://assist.readthedocs.io/
GNU General Public License v3.0
24 stars 10 forks source link

Fixes #106: Adds support for DE440.bsp #107

Open akoumjian opened 4 months ago

akoumjian commented 4 months ago

A pull request to address https://github.com/matthewholman/assist/issues/106 , adding support for the spice kernel version of DE440.

Overview of Changes

Verification

I have added unit tests for initializing the spk files, loading the constant data, and joining masses to the targets from the loaded constant data.

I have also added a couple of identical unit tests for Apophis and 5303->Ceres to make sure tolerances were kept between the two implementations. I manually checked most of the other unit tests as well, but didn't want to duplicate each one until I received opinions on how to structure the unit tests. I could update them all to be parameterized (using each coefficients file in turn) from command line arguments if that seems better.

Earth & Moon Residuals

There is still a disagreement on order 1e-15 AU for the Earth and Moon ephemeris. This difference causes the SPICE and ASCII implementations to perform differently. In particular with the Apophis unit test, the SPICE implementation has a delta from JPL small body of ~47m, whereas the ASCII implementation is now ~93m.

The ASCII file contains data for Moon (Earth geocenter frame) and EMB (SSB frame). The SPICE file contains data for Moon (EMB frame), Earth (EMB frame) and EMB (SSB frame). As far as I can tell, this means I cannot use an identical implementation, as the lunar frames are different. For the SPICE implementation, I believe I should be able to simply add the vectors (e.g. Moon (SSB) = EMB (SSB) + Moon (EMB) ).

I have verified that the following values are identical and not the source of the disagreement:

I'd love suggestions on how to get these number into total agreement. In the case of the ASCII file, Is it possible that using the Earth-Moon mass ratio to calculate the Moon (SSB) and Earth (SSB) vectors is not as accurate? I can explore this more unless you have an idea.

Differences in Coefficient Values between ASCII and SPICE

This is a bit of a separate topic, and potentially a big one. After a lot of digging, I believe that there is a difference in the double values loaded directly from the two files into the memory maps. These differences are quite small and likely below the usable precision of the coefficients. However, the residuals are enough to affect the results without applying the solution I describe below.

Here is a table of coefficients for the Sun at J2000. The left column is the value extracted from the plaintext readable ASCII version. The second column is the residual of the binary to its ASCII version (they are identical, as expected). The third column is the residual of the SPICE kernel to the ASCII file. The rightmost column is the relative size of the residual from the SPICE file to the ASCII file.

| ascp01950.440                  | linux_p1550p2650.440         | de440.bsp                    | Relative Residual             |
|--------------------------------|------------------------------|------------------------------|------------------------------|
| -1.06808883301021694e+06       | 0.0                          | 2.328306e-10                 | -2.180086e-16                |
| 6.43167333734120621e+03        | 0.0                          | 0.0                          | 0.0                          |
| 2.01221489458825502e+01        | 0.0                          | 3.552714e-15                 | 1.765547e-16                 |
| -5.05048275205624633e-02       | 0.0                          | 0.0                          | 0.0                          |
| 3.66293150750863095e-03        | 0.0                          | 4.336809e-19                 | 1.183724e-16                 |
| 6.87050023573884547e-05        | 0.0                          | 0.0                          | 0.0                          |
| 1.04739050584889000e-07        | 0.0                          | -3.970467e-23                | -3.789536e-16                |
| -9.62554122375419690e-08       | 0.0                          | 0.0                          | 0.0                          |
| 1.41137100915376000e-08        | 0.0                          | -4.963084e-24                | -3.516580e-16                |
| -1.97668373379263398e-09       | 0.0                          | 0.0                          | 0.0                          |
| 5.86673164381741959e-11        | 0.0                          | 0.0                          | 0.0                          |
| -3.95512524278347497e+05       | 0.0                          | 0.0                          | 0.0                          |
| -8.09283375554062332e+03       | 0.0                          | 0.0                          | 0.0                          |
| 1.80149861187318088e+01        | 0.0                          | -3.552714e-15                | -1.971910e-16                |
| -8.42604441851760450e-02       | 0.0                          | 0.0                          | 0.0                          |
| 1.13093369546329297e-04        | 0.0                          | 2.710505e-20                 | 2.396787e-16                 |
| 5.03867718918667103e-05        | 0.0                          | 0.0                          | 0.0                          |
| 5.93445081607049939e-06        | 0.0                          | 0.0                          | 0.0                          |
| -9.87525623150012930e-08       | 0.0                          | 0.0                          | 0.0                          |
| 2.33800156279631085e-08        | 0.0                          | 0.0                          | 0.0                          |
| 1.59321012060578690e-10        | 0.0                          | 0.0                          | 0.0                          |
| 1.56840618138031596e-11        | 0.0                          | 3.231174e-27                 | 2.061263e-16                 |
| -1.37831006431904796e+05       | 0.0                          | -2.910383e-11                | 2.110000e-16                 |
| -3.63161643242317587e+03       | 0.0                          | -4.547474e-13                | 1.252283e-16                 |
| 7.26636726809482969e+00        | 0.0                          | 0.0                          | 0.0                          |
| -4.21481400983880414e-02       | 0.0                          | 0.0                          | 0.0                          |
| -9.53718391925790533e-05       | 0.0                          | 0.0                          | 0.0                          |
| 1.45128782935172393e-05        | 0.0                          | 0.0                          | 0.0                          |
| 3.09572793936219392e-06        | 0.0                          | 4.235165e-22                 | 1.368724e-16                 |
| -4.05084185115523090e-08       | 0.0                          | 0.0                          | 0.0                          |
| 1.10153616306458299e-08        | 0.0                          | -1.654361e-24                | -1.502505e-16                |
| 2.91662353472744123e-10        | 0.0                          | -5.169879e-26                | -1.772404e-16                |
| 1.67388559412173401e-12        | 0.0                          | -4.038968e-28                | -2.412458e-16                |

I wanted to make sure that the disagreement didn't have to do with the way that ASSIST was memory mapping the files. I used Brandon Rhode's jplephem to separately load the coefficient values from the SPICE file and it is reading them identically to the ASSIST implementation.

Precision

You may notice that the residuals of SPICE to the ASCII are consistently relative to the base value on order of 1e-16. This could be explained by one or two units of precision difference for the float significand in the two files. I couldn't locate how precise they ought to be (e.g., are the real values using the full precision offered by the double). Perhaps someone more familiar with the specification knows. The SPICE file appears to have a higher precision than the ASCII.

Amelioration

I was able to get identical behavior from both implementations by using a truncate_double function. This function masks the bits to a desired precision of the float significand. After manually exploring different levels of truncation, I found that masking down to 40 bits eliminated the difference between the coefficient values. Interestingly, adding this truncation also appears to put the unit tests in closer agreement with the JPL Small Body Code, at least for the Apophis and Ceres unit tests. Truncating lower than 40 bits causes them to agree less with JPL Small Body Code, as one might expect.

While the truncation offers a solution for agreement between SPICE and ASCII, I am concerned and curious about why it makes them agree more with Horizons and Small Body. Does this imply that small body, for example, are using truncated or different values than are located in the spice kernels? I don't know, but I want to find out.