Closed zaltanar closed 3 years ago
I manage to make a working (no error) code by substracting two apparent (earth -> body) - (earth + wgs). But i have some differences between results. I don't know from where the differences come. 30mas maximum (for the moon), i may live with it, but i don't know from where these differences come.
from skyfield.api import load, wgs84
planets = load('data/de440.bsp')
timescale = load.timescale()
t0 = timescale.now()
sun = planets["SUN"]
mercury = planets["MERCURY"]
venus = planets["VENUS"]
earth = planets["EARTH"]
moon = planets["MOON"]
mars = planets["MARS BARYCENTER"]
jupiter = planets["JUPITER BARYCENTER"]
saturn = planets["SATURN BARYCENTER"]
uranus = planets["URANUS BARYCENTER"]
neptune = planets["NEPTUNE BARYCENTER"]
toulouse = earth + wgs84.latlon(43.6167, 5.7667)
bodies = [sun, mercury, venus, moon, mars, jupiter, saturn, uranus, neptune]
# Precompute for optimisation
earth_astrometric = [earth.at(t0).observe(o) for o in bodies]
earth_apparent = [o.apparent() for o in earth_astrometric]
# Compute Vector Earth -> Toulouse and Vector substraction (Geocentric - Eartg/Tls)
tls_earth_astrometric = earth.at(t0).observe(toulouse)
tls_earth_apparent = tls_earth_astrometric.apparent()
tls_astrometric = [o - tls_earth_astrometric for o in earth_astrometric]
tls_apparent = [o - tls_earth_apparent for o in earth_apparent]
#Compute all
tls_all_astrometric = [toulouse.at(t0).observe(o) for o in bodies]
tls_all_apparent = [o.apparent() for o in tls_all_astrometric]
for i in range(0, len(bodies) -1 ):
print(bodies[i])
print(tls_astrometric[i].position)
print(tls_all_astrometric[i].position)
print(tls_apparent[i].position)
print(tls_all_apparent[i].position)
Thank you for providing a working example! One source of difference could be light travel time. An observer at the geocenter sees a slightly earlier Moon, whose light left earlier, than does an observer up on the planet's surface. But the difference is maybe not big enough to explain 30mas? If the Moon moves through 360° in 29 days, and if the Earth's radius is 0.02 light seconds, then the error from light travel time would be:
360 * 60 * 60 * 1000 / 29 / 24 / 60 / 60 * 0.02 = 10.3 mas
It is also possible that Earth deflection is the difference — but that would appear only in apparent positions. Are you seeing a 30mas difference for both astrometric and apparent positions, or only apparent ones?
For the moment, Astrometric seems more precise, but i can't exclude a 10 mas error.
At first i thought about atmospheric, but then i remember that it's only for alt/az.
Thanks, i will run more precise tests tonight to measure this.
Diurnal aberration can add up to 320 mas at the equator.
@mkbrewer — Wow, is the effect that large? Thanks, that's probably the difference, then. I’ve never run the numbers to compute it; with the speed of a point on the equator amounting to only around 1/100th of the speed of the Earth in its orbit, I had not realized that in absolute terms it amounted to several hundred mas.
Equation (7.50) on page 267 of the ES.
I make some more tests based on your responses.
I use the moon as body, a time of the last lunar node (2021/01/24 21h47 GMT) and plot several position on earth. I plot mas errors for apparent and astrometric in a notebook : https://gist.github.com/zaltanar/5de40b7df43675f3fe881714015f3422 For apparent it goes up to 600mas errors and 400mas erros for astrometric.
But, a problem i didn't realize when i post my first resolution is that when you substract ICRF childs class you get back an ICRF object, that doesn't fit my use. So i guess i have to do myself the substraction of two ICRF childs. And i can confirm with sub function in ICRF https://github.com/skyfielders/python-skyfield/blob/2c05c63f0f968ac6917d582c0156e119a85e1dcd/skyfield/positionlib.py#L169-L177
Yes. In order to do this properly, you need to take the difference in the ICRS vectors including the difference in light time and then transform through GCRS to add the proper aberration and deflection of light due to the gravitational field of the Earth to apparent. Therefore, the initial geocentric calculations are redundant and a waste of time.
Of course, if you don't care about the difference in light time, then the initial geocentric calculations will save ephemeris lookup time. But if you are using one of the JPL ephemerides, those lookups are quite fast.. One possibility for rigorous speed up would be to do the lookup of the Earth once and then apply different observer locations to calculate the different light time delays to the target body. Once it has the proper ephemeris record in memory, this is just an additional Chebyshev polynomial evaluation
You could also just do the target body lookup once and then use the target body velocity to account for the different light time delays. So there are several possibilities here, but they are all at a fairly low level.
But, a problem i didn't realize when i post my first resolution is that when you substract ICRF childs class you get back an ICRF object, that doesn't fit my use.
Thanks for pointing that out! It should probably call build_position()
instead to allow the class to be chosen based on the center. And, the center: it needs to preserve the center and target! It looks like it was written in 2013 to satisfy a quick short-term need (the commit message is “Add rudimentary subtraction ability to ICRS”, so I apparently recognized it was rudimentary) so it’s now obviously time for an update.
As shown just above, I've committed a fix for vector subtraction that will use more specific vector classes like Geocentric
if subtraction indeed results in a vector whose origin is the geocenter. To try the new feature out:
pip install -U https://github.com/skyfielders/python-skyfield/archive/master.zip
As for your original question, is this an accurate summary of the discussion so far?
You are too reactive for me.
I had my response since the third post, the discussion after it's just bonuses and some curiosity.
I get everything i need now, thanks a lot, i learn everything :
I close the issue, i as i have my response. I will share tests results later here. But as it's a side project it may take some days. Thanks again.
Hi,
First thanks for your work, your library is really amazing.
But for a specific application, i try to generate astrometric table and graph in alt/az for earth observers. I know the dates in advance, but not the locations. To gain some time and I/O reads from the Kernel file i try to find a way to pre-compute Geocentric position and use them on demand to transform from Geocentric to a Apparent with the observer coordinate.
I try adding/substrating different positions object with no success. I think i have to Positions class directly, but it's not clear in my head, and the documentation is not talking about this approach.
How can we use an existing Geocentric Position (Apparent or not) and transform it into multiple Earth locations ? I guess it's just a Vector transformation, but don't know how to handle it.
Sorry i don't have a lot of code to show.