Dear Orekit Team,
I would like to ask you few questions related to the caching/interpolation feature used internally in Orekit during a frame transformation. In particular I am referring to the chain that is triggered when querying a transform at a given date connecting the GCRF to the ITRF based on the IERS conventions.
Here you can find a small example to support the explanation:
public class TestTransformBehaviour {
public static void main(String[] args) throws OrekitException {
String orekitDataPath = args[0];
File orekitData = new File(orekitDataPath);
DataProvidersManager manager = DataProvidersManager.getInstance();
manager.addProvider(new DirectoryCrawler(orekitData));
AbsoluteDate date1 = new AbsoluteDate(2015, 01, 01, 00, 00, 00, TimeScalesFactory.getTAI());
AbsoluteDate date2 = new AbsoluteDate(2015, 01, 01, 00, 01, 00, TimeScalesFactory.getTAI());
Frame gcrf = FramesFactory.getGCRF();
Frame itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, false);
KeplerianOrbit myOrbit = new KeplerianOrbit(54354, 0, 0, 0, 0, 0, PositionAngle.TRUE, gcrf, date1, CelestialBodyFactory.getEarth().getGM());
System.out.println("Z component at date1: " + myOrbit.getPVCoordinates(date1, itrf).getPosition().getZ());
System.out.println("Z component at date2: " + myOrbit.getPVCoordinates(date2, itrf).getPosition().getZ());
}
}
The Orekit version used is the v10.0 together with the latest orekit-data that I could find on your website.
What has been done was to output in two different runs the Z position vector component [m] in ITRF by following 2 queries order:
- First Date1 and then Date2 in the first run
- First Date2 and then Date1 in the second run
So basically by exchanging the order of the sysouts in the 2 runs.
The result is the following:
Run 1: z at date1: 79.64028519559314;— z at date2: 75.72821368799973
Run 2: z at date1: 79.6402851954891; ---- z at date2: 75.72821368794723
As you can see they are slightly different. By inspecting the code we have seen that the Transforms that are provided in the 2 runs are not the same, they have a different orientation.
We inspected the cache of the ShiftingTransformProvider after the 2 runs; you can find the content in the attached file. ShiftingTransformProviderCaches.xlsx (11.1 KB)
We understood that the reason for this difference is that the algorithm sets as reference date of the ShiftingTransformProvider cache the one that is queried as first when creating the first slot. Afterwards depending on the next queried dates the slot may be extended or not or a new one is created.
This means that order matters. So by querying first a date in the future or first a date in the past you obtain different results.
I am really interested in this topic since for the application that we are developing we execute multiple processes in parallel that may have queries at different times not always sorted in a chronological order. So depending on the load of the machine one process may be run before or after another one resulting in different results due to the cache being populated differently.
Coming to the questions:
-
Is this the supposed correct behavior of the algorithm? So that depending on the population of the cache you can obtain different results?
-
Could it be that due to the caching Orekit is intended to be used sequentially rather than in parallel to avoid a different population of the cache between 2 runs?
-
Maybe this has been already thought and accounted via the maximum errors that you check in the unit tests of the ShiftingTransformProvider and InterpolatingProvider? If that is the case can we consider those as the maximum errors due to the caching/interpolation feature? If not how can we compute it?
-
Does Orekit have an internal way to avoid the caching? Or this would require a forking?
-
I have understood that the caching is of course in place to optimize performances, is it possible to find some benchmarks about it? I have seen that here you mention an increase in efficiency but only for the tidal effects, is this valid also for the others cached entries? And on which scale is it? Seconds or minutes?
Hopefully I was clear enough and I am not asking something that has already been discussed.
Thank you really much for your support and your time
Kind Regards,
Leonardo
–
PS: While debugging the Orekit code I have noticed that in the method of the GenericTimeStampedCache:
private int entryIndex(final AbsoluteDate date, final long dateQuantum)
the date is given as an input but then is never used locally, could it be a left over from a refactoring?