I've got familiar with the SGP4 model. The problem which I faced is that, the results are in TEME frame.

How to convert the TEME to J2000?

Would be glad also, if you suggest a method in python or julia.


4 Answers 4


The problem is solved using the Skyfield and Astropy packages in python.

import skyfield.sgp4lib as sgp4lib
from astropy import coordinates as coord, units as u
from astropy.time import Time 

  # time- J2000 date
  # p,v- vectors, result of SGP4 in TEME frame
  date= datetime.datetime(2000, 1, 1, 12, 0) + datetime.timedelta(days=time - 2451545)

  # Conversion from TEME to ITRS    
  p,v= sgp4lib.TEME_to_ITRF(time,np.asarray(p),np.asarray(v)*86400)

  # Conversion from ITRS to J2000    
  now = Time(date)
  itrs = coord.ITRS(p[0]*u.km, p[1]*u.km, p[2]*u.km, v[0]*u.km/u.s, v[1]*u.km/u.s, v[2]*u.km/u.s, obstime=now)
  gcrs = itrs.transform_to(coord.GCRS(obstime=now))
  • $\begingroup$ can you please explain the days=time - 2451545 part? I don't really understand what's happening here. Is time the datetime at which you want to convert from TEME to J2000? Is it supposed to be expressed in days? $\endgroup$
    – Raksha
    Jul 16, 2019 at 15:38
  • $\begingroup$ Hi the python code that is shown above using skyfield and astropy does not work because I guess it has been written in a previous version of python. Since I am totally greenhorn on python I need some help. How must this code be modified in order to be able to use it correctly with python 3.9.2. I posted the code again here bellow, because I tried already to get it run, and I think there where some bugs present in the original code (time must be Time and import datetime was missing) Thank you very much! PS: I am still not able to write comments, so I put my questions into answers, unfortunately $\endgroup$ Apr 18, 2021 at 16:31
  • $\begingroup$ ...... Sacha Here's the code: pastebin.com/4e87Qj94 $\endgroup$ Apr 18, 2021 at 16:31
  • $\begingroup$ @Raksha 2451545 is the Julian date of noon UTC 1 Jan 2000. That is close to the J2000 epoch, which is noon TT 1 Jan 2000. $\endgroup$ Jun 19, 2022 at 12:36
  • 2
    $\begingroup$ @SachaTholl The code as posted is worthless. I do not understand why this is the accepted and somewhat highly upvoted answer. The variable time is used but never never defined. The imports are wrong. This wouldn't have worked in python 2.7, let alone python 3. $\endgroup$ Jun 19, 2022 at 12:40

I have published a julia package called SatelliteToolbox.jl that has all the conversions related to IAU-76/FK5 model (ITRF, MOD, TOD, GCRF, PEF, etc.) and now I also added the support for TEME. However, you need to use the master branch because it is not released yet.

To install the package from master, you can do this:


If you have a vector represented in TEME r_teme, you can convert it to J2000 using:

r_j2000 = D_J2000_TEME*r_teme

where JD_TT is the Julian Day in Terrestrial Time. If you only have the Julian Day in UTC, you can use JD_TT = JD_UTCtoTT(JD_UTC).

This package also have a native implementation of SGP4 (without SDP4 bits yet). The computed vectors from the orbit propagator (position and velocity) are represented in TEME and can be converted to J2000 using the procedure above.

Notice that the definition of TEME in this package is the same as the one used by Vallado, since we do not have an "official" TEME definition. Moreover, all those transformations functions were heavily tested against the examples in the Vallado's book (as you can see in ./test/) folder.


With the newest commit, it is even easier:

using SatelliteToolbox

# Julian day at 2018-Feb-12 15:35:22 UTC
JD_UTC = DatetoJD(2018,2,12,15,35,22)

# DCM that rotates the TEME frame of Date `JD_UTC` into J2000.
D_J2000_TEME = rECItoECI(TEME(), J2000(), JD_UTC)

# Quaternion that rotates the TEME frame of Date `JD_UTC` into J2000.
q_J2000_TEME = rECItoECI(Quaternion, TEME(), J2000(), JD_UTC)
  • $\begingroup$ I do not think so, this was posted this year: asked 2 months ago $\endgroup$ May 26, 2018 at 23:20
  • 1
    $\begingroup$ quite right @RonanArraesJardimChagas. American date format is confusing $\endgroup$
    – user20636
    May 27, 2018 at 6:59

Tarlan is spot on with his answer but I wanted to tag along for those not using python or using some other software not being discussed here.

The general consensus is that converting directly between inertial frames gets messy and non-trivial. As a result it would be best to get TEME into a fixed/pseudo-fixed frame before converting it to your inertial frame of choice.

This works not only for J2000, but for any frame. TEME to ECF coordinate transforms are fairly common, especially with telecom companies who want to know what sort of coverage their satellites will be providing. From there going to ECF to whatever inertial frame you are working in will be trivial if you understand the relationship between your fixed and inertial coordinate systems.

  • $\begingroup$ A very late comment, but isn't the transformation from EC(E)F to another ECI frame non-trivial if factors like precession, nutation and polar motion are taken into account? $\endgroup$
    – jos
    Apr 14, 2020 at 5:28
  • $\begingroup$ @jos only if you're trying to do things over time (in a way, generating ephemerides) - if you're just doing it for a single instant, it's easier. $\endgroup$ Dec 15, 2023 at 0:09

How to convert the TEME to J2000? [using Python]

See: "astropysics/astropysics/coords/coordsys.py", which is from the Astrophysics package.

See also:

"Tracking satellite footprints on Earth’s surface" or

"Revisiting Spacetrack Report #3: Rev 2", Appendix C - TEME Coordinate System.

Source code (C++, FORTRAN, Java, MATLAB, Pascal. Total: 1,229,282 bytes, .ZIP File).

  • $\begingroup$ I can't find anything relating to the TEME frame there, do you have a line number? Or, if there isn't anything, maybe explain how one would use the different pieces here to accomplish the TEME <-> J2000 transformation? $\endgroup$
    – Chris
    Mar 20, 2018 at 14:28
  • $\begingroup$ @Chris As I know, astropy can convert from ITRS to J2000. For TEME->ITRS I used Skyfield. Added the code as answer. $\endgroup$ Mar 20, 2018 at 15:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.