Why can n2yo somehow interpret this TLE but Skyfield can't? Why does it return nans and zeros for position?

@Rafa pointed out that there is at least one officially released TLE for the JWST mission after it left Earth orbit, and here's the latest one at n2yo.com:

1 50463U 21130A   21362.00000000  .00000000  00000-0  00000-0 0  9999
2 50463   4.6198  89.0659 9884983 192.3200  17.4027  0.01958082    27


The epoch 21362.00000000 is the 362nd day of 2021, which seems to be 2021-12-28 00:00 UTC.

JWST launched on 25 December 2021 at 12:20 UT so this is about two and a half days after launch; and therefore it would be in deep space already and not orbiting the Earth.

And yet, there was still a TLE issued!

Let's see what that suggests:

With a mean motion of 0.01958082 Earth orbits per day this TLE is trying to say that it's at least in a very high orbit. In reality it was no longer bound to Earth or in Earth orbit at this time, so it's not right.

$$T = 2 \pi \sqrt{\frac{a^3}{GM}}$$

gives

$$a = \left( \frac{GM T^2}{4 \pi^2} \right)^{1/3}$$

and with GM = 3.986E+14 m^3/s^2 and a 51.07 day orbit that puts the semimajor axis at about 580,000 kilometers.

But with an eccentricity of 0.9884983 the predicted distance from Earth at epoch or another given moment could be almost twice $$a$$ or 1 percent of $$a$$. So we'd have to propagate it with SGP4 to find out what it's saying and how well it matches the real trajectory.

Let's see if it works in Skyfield:

From JLP's Horizons:

 date & time UTC        distance (km)   rate (km/s)
-----------------     ----------------  -----------
2021-Dec-26 00:00     1.3369842393E+05   2.2108515
2021-Dec-26 06:00     1.7778266287E+05   1.9034419
2021-Dec-26 12:00     2.1651707751E+05   1.6961163
2021-Dec-26 18:00     2.5157752082E+05   1.5470824
2021-Dec-27 00:00     2.8371359651E+05   1.4329090
2021-Dec-27 06:00     3.1363829802E+05   1.3408820
2021-Dec-27 12:00     3.4175065486E+05   1.2642573
2021-Dec-27 18:00     3.6833557041E+05   1.1988998
2021-Dec-28 00:00     3.9360502697E+05   1.1421383
2021-Dec-28 06:00     4.1777927226E+05   1.0948360
2021-Dec-28 12:00     4.4093726644E+05   1.0502208
2021-Dec-28 18:00     4.6318106793E+05   1.0100482
2021-Dec-29 00:00     4.8459829675E+05   0.9735797
2021-Dec-29 06:00     5.0526046491E+05   0.9402252
2021-Dec-29 12:00     5.2523381459E+05   0.9095617
2021-Dec-29 18:00     5.4457084676E+05   0.8812288
2021-Dec-30 00:00     5.6331803317E+05   0.8549237


From Skyfield: uhoh!

Right now it looks like this TLE is so unphysical that it's outside of Skyfield version 1.41's ability to interpret. Stay tuned, since n2yo can do it, some newer version of Skyfield might be able to as well.

Question: Why can n2yo somehow interpret this TLE but Skyfield can't? Why does it return nans and zeros for position?

array([nan, nan, nan, nan, nan, nan, nan,  0.,  0.,  0.,  0.,  0.,  0.,
0.,  0.,  0.,  0.])


https://www.n2yo.com/satellite/?s=50463 at the time of this post

import numpy as np
import matplotlib.pyplot as plt
import datetime

ts = loaddata.timescale() # include builtin=True if you want to use older files (you may miss some leap-seconds)
eph = loaddata('de421.bsp') # a small one, fine for this

L1, L2 = """1 50463U 21130A   21362.00000000  .00000000  00000-0  00000-0 0  9999
2 50463   4.6198  89.0659 9884983 192.3200  17.4027  0.01958082    27""".splitlines()

sat = EarthSatellite(L1, L2)

days = np.arange(17)/4. - 2.  # +/- 2 days in 6 hour increments

times = ts.tt_jd(sat.epoch.tt + days)

epoch_string = datetime.datetime(*sat.epoch.utc[:5]).isoformat().replace('T', ' ') + 'UTC'

print('+/- 2 days around epoch of: ', epoch_string)

g = sat.at(times) # geocentric position object

p = g.position.km  # geocentric positions (km)

d = g.distance().km

if True:
fig, ax = plt.subplots(1, 1)
ax.plot(days, d)
ax.plot(days, d, 'ok')
ax.set_xlim(days.min() - 0.1, days.max()+0.1)
ax.set_xlabel('days relative to TLE epoch')
ax.set_ylabel('distance to geocenter (km)')
ax.set_xlabel('days relative to TLE epoch')
plt.suptitle('JWST TLE epoch: ' + epoch_string)
plt.show()

• Given that its a wacky TLE I think the better question is why CAN n2yo interpret it? Jan 18 at 1:13
• @GrapefruitIsAwesome check the title: "Why can n2yo somehow interpret this TLE..." I've asked both.
– uhoh
Jan 18 at 1:28
• Doh! I think I need more sleep. Jan 18 at 1:34

The n2yo web site might be calling the SGP4 routine and, instead of checking its error code output and disregarding the coordinates that it returned, it might use the coordinates as though they are valid.

Here's the raw output of the Python SGP4 library that Skyfield uses:

from sgp4.api import SGP4_ERRORS, Satrec

a = '1 50463U 21130A   21362.00000000  .00000000  00000-0  00000-0 0  9999'
b = '2 50463   4.6198  89.0659 9884983 192.3200  17.4027  0.01958082    27'
sat = Satrec.twoline2rv(a, b)

jd, fr = sat.jdsatepoch, sat.jdsatepochF
e, r, v = sat.sgp4(jd, fr)

print(e)
print(SGP4_ERRORS[e])
print(r)

3
perturbed eccentricity is outside the range 0.0 to 1.0
(nan, nan, nan)


I think this indicates that the SGP4 routine exited early, and that the x,y,z coordinates are not valid.

You might want to check whether the map that n2yo is drawing in fact reflects exactly the location that has the space telescope overhead. They might not be properly checking the error return codes of their own copy of the SGP4 library?

• Note that both nans and real zeros were returned in this case. Anwyay, we can probably blame it all on Space Force :-) Has a TLE ever been issued for a spacecraft trajectory not bound to Earth orbit? Yes, it seems so!
– uhoh
Jan 18 at 2:26
• If you can come up with a sample script that produces zeros, that might be an entirely different case. I have not seen that locally. Jan 18 at 3:05
• My script above running on version 1.41 does exactly that. See the plot or just add print(g.distance().km) and print(g.position.km) Starting at 6 hours before epcoch they return zeros, before that, nans.
– uhoh
Jan 18 at 3:09
• I get [nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan] with no zeroes. What version of sgp4 do you have installed? Jan 18 at 23:30
• My python is from Anaconda, and my Skyfield is from pip install or update (can't remember) and now running version 1.41, so whatever sgp4 that brings with it. I tried import sgp4 which works but print(sgp4.__version__) fails because it has none. using help(spg4) I see that the most recent changelog entry is "2020-05-28 — 2.12 — Moved the decision of whether to set the locale during twoline2rv()" I'll be out the door in a bit, but if there's anything else I can check now let me know.
– uhoh
Jan 18 at 23:42

Attempting to use the Space Force SGP4 library directly, the TLE loads without errors, because it parses correctly. The error comes as soon as I do anything with it. They all look like "Sgp4Update: e**2 is too large, e**2 = 0.1037E+01." I can make the value of the reported squared eccentricity change slightly by varying the minutes since epoch of the first point I request, but so far every one I've tried has hit that error.

It looks a little strange, since the eccentricity written in the TLE itself is 0.9884983, which squares to 0.9771289 without difficulty, but this is exactly where the usual warnings kick in of "the numbers in TLEs are mean elements, which do not mean what you think they mean!"

• +1 yes the perturbed eccentricity used inside the SGP4 calculation is different from the mean eccentricity input. See the other answer. I think that "Why can perturbed eccentricity be larger than 1 when the mean isn't?" might be a good new question! Is the "Space Force SGP4 library" a publicly available thing or only for Gardians with clearance?
– uhoh
Jan 20 at 23:19
• publicly available. it's the one you can download from space-track.org documentation page. i've linked it before, let's see, first you need to register, log in, and then you can click space-track.org/documentation#/sgp4 , which is the same as clicking the "Help" dropdown menu and scrolling down to "SGP4". Jan 20 at 23:21
• Oh I see, got it.
– uhoh
Jan 20 at 23:22