-
Notifications
You must be signed in to change notification settings - Fork 10
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
TDB TT conversion accuracy versus CPU time #26
Comments
Thanks for your input, Bernard! I agree and this is something I wanted to tackle eventually. Orekit uses the following formula:
|
I don't think the term "convention" should be used here. function orekitlike_TTminusTDB(tdb1,tdb2)
T = (tdb1 - 2451545) + tdb2
g = 357.53 + 0.9856003 * T
- 0.001658 * sind(g) - 0.000014 * sind(2g)
end
difference2(tdb) = orekitlike_TTminusTDB(tdb,0.0)-calceph_TTminusTDB(tdb,0.0)
plot(tdb,difference2.(tdb))
b4 = @benchmark test1(orekitlike_TTminusTDB,$tdb)
display(b4)
println() Results
In summary:
Not bad for only using two periodic terms (amplitudes 1.6 ms and 14 us) due to Earth motion.
while the error is within 40-50 us. Plotting the FFT of the residuals: tdb = 2414105.5:1.0:2488984.5
diff_fft = norm.(fft(difference2.(tdb)))
N = size(diff_fft)[1]
T = (tdb[end]-tdb[1])/(365.25) # in years
Δf = 1/T
fmax = Δf*N/2
fgrid = 0.0:Δf:fmax
diff_fft = diff_fft[1:size(fgrid)[1]]
indices = 0.9.<fgrid.<0.975
plot(fgrid[indices],diff_fft[indices])
indices = 0.0.<fgrid.<0.3
plot(fgrid[indices],diff_fft[indices])
we see a clear peak at frequency ~0.92 year^-1 (corresponding to synodic period of Jupiter) A fit of an additional sine function starting initially with the approximate frequency of Jupiter synodic period improves the error by a factor 2 for the 200 years range covered by the used INPOP ephemeris. function model(tdb,x)
T = (tdb - 2451545)
g = 357.53 + 0.9856003 * T
- 0.001658 * sind(g) - 0.000014 * sind(2g) + x[1]*sin(x[2]*T+x[3])
end
xdata = tdb
ydata = calceph_TTminusTDB.(tdb,0.0)
x0 = [30e-6, 2*π/365.25 * 0.915 ,0.0]
using LsqFit
fit = curve_fit(model, xdata, ydata, x0)
display(fit) |
Great analysis @bgodard! Could you open a PR that implements this difference function? I would then integrate it with the transformation tree and possibly implement a new time scale, e.g. |
I could not find a reference in the Orekit source code but I think I found the source I will implement the same as Orekit. Accuracy about 30 us while the maximum difference for two fixed observers on the Earth surface is about 4.3us (two observers on opposite sides of the equator aligned with Earth barycentric velocity with Earth at pericentre).
I am not sure about defining multiple version of TDB, then you would need TCBObserver. But you could also make it such that there is only one TDB and a TTObserver... I think that for accurate observation modeling, the user should not in general rely on automatic timescales conversion because he needs to specify additional information about the observer. He should only be given the tools to perform the transformation. |
Good point, having an explicit constructor would be the cleanest solution and convenient enough for advanced users: function TDBEpoch(ep::TTEpoch, ut, elong, u, v)
...
end |
I guess the inverse function is needed too: TTEpoch(ep::TDBEpoch, ut, elong, u, v) When modelling 2-way range for a deep space probe, you need the quantity TDB-TT at the ground station at the transmission and reception events. dtdb(jd1, jd2, ut, elong, u, v) Then if the methods: TDBEpoch(ep::TTEpoch, ut, elong, u, v)
TTEpoch(ep::TDBEpoch, ut, elong, u, v) are exported then dtdb(jd1, jd2, ut, elong, u, v) should be too. And similar methods which would be even more useful are: TDBEpoch(ep::TTEpoch, ΔT)
TTEpoch(ep::TDBEpoch, ΔT) where ΔT is TDB-TT/TT-TDB computed by the user because there are many different ways to compute a TDB-TT difference (eg time ephemeris interpolation, function of planetary ephemeris state vectors, time series...) both for the geocenter and for the observer correction. |
@prakharcode See above. This is something we should consider when we start refactoring the conversion functions. |
@bgodard Using a custom TDB/TT offset should work now, e.g. by manually calling the TDB constructor like this: tt = TTEpoch(now())
tdb_tt = ???
tdb = TDBEpoch(tt, tdb_tt) |
The conversion between TDB and TT in AstroTime.jl taken from ERFA/SOFA is time consuming because it is computing a large series.
The accuracy is probably of the order of a few nanoseconds but for what purpose: the difference between TDB and TT is a quantity which is different for each observers and dependent on their trajectory (their position and velocities in GCRS). The quantity can vary by a few microseconds from one ground station at the surface of the Earth to another.
In the routine dtdb(jd1, jd2, ut, elong, u, v), arguments ut, elong, u and v are only used to compute the observer position correction (observer position is actually defined by elong, u and v but the correction needs additionally the value of ut) neglecting radial velocity correction (which is only important for observer not on the surface such as an Earth satellite), but they are set to zeros (correction disabled) in the rest of the code because there is no observer trajectory information. Thus the quantity computed is the TT minus TDB for an observer at the geocenter.
While it is good to have the routine dtdb available for high accuracy computation, for most use cases where the observer location is unspecified a faster and lower accuracy routine would probably be better.
Additionally the difference between TDB and TT can be computed faster and more accurately using state of the art numerically integrated geocenter time ephemeris. Example:
Result:
The computed values differ by only a few nanoseconds but the runtime is much better.
If AstroTime could target microsecond TDB-TT conversion accuracy (better accuracy doesn't make sense without a location specification) while being much faster than interpolating the time ephemeris that would be very useful.
EDIT: I mixed up nanoseconds and picoseconds. This is fixed now!
The text was updated successfully, but these errors were encountered: