1   /* Copyright 2002-2025 CS GROUP
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.orekit.files.sinex;
19  
20  import org.junit.jupiter.api.Assertions;
21  import org.junit.jupiter.api.BeforeEach;
22  import org.junit.jupiter.api.Test;
23  import org.orekit.Utils;
24  import org.orekit.data.DataContext;
25  import org.orekit.data.DataSource;
26  import org.orekit.frames.EOPEntry;
27  import org.orekit.frames.EOPHistory;
28  import org.orekit.frames.ITRFVersion;
29  import org.orekit.frames.LazyLoadedFrames;
30  import org.orekit.time.AbsoluteDate;
31  import org.orekit.time.ChronologicalComparator;
32  import org.orekit.time.DateComponents;
33  import org.orekit.time.TimeScale;
34  import org.orekit.time.TimeScalesFactory;
35  import org.orekit.utils.Constants;
36  import org.orekit.utils.IERSConventions;
37  import org.orekit.utils.units.Unit;
38  import org.orekit.utils.units.UnitsConverter;
39  
40  import java.util.Arrays;
41  import java.util.List;
42  import java.util.SortedSet;
43  import java.util.TreeSet;
44  
45  public class SinexParserEopTest {
46  
47      private TimeScale utc;
48  
49      @BeforeEach
50      public void setUp() {
51          // Sets the root of data to read
52          Utils.setDataRoot("gnss");
53          // Setup utc for defining dates
54          utc = TimeScalesFactory.getUTC();
55      }
56  
57      @Test
58      // Check the behaviour for a simple Sinex file containing EOP data
59      public void testSmallIGSSinexEopFile() {
60  
61          // Setting up the Sinex Loader
62          Sinex sinex = load("/sinex/cod20842-small.snx");
63  
64          // Extracting the data parsed in the Sinex loader to fill the history set
65          IERSConventions.NutationCorrectionConverter converter =
66                  IERSConventions.IERS_2010.getNutationCorrectionConverter();
67          SortedSet<EOPEntry> history = new TreeSet<>(new ChronologicalComparator());
68          sinex.getEopLoader(ITRFVersion.ITRF_2014).fillHistory(converter, history);
69  
70          final UnitsConverter unitConvRad = new UnitsConverter(Unit.parse("mas"), Unit.RADIAN);
71          AbsoluteDate date1 = new AbsoluteDate(new DateComponents(2019, 1, 1), utc).shiftedBy(Constants.JULIAN_DAY * (350));
72          AbsoluteDate date2 = new AbsoluteDate(new DateComponents(2019, 1, 1), utc).shiftedBy(Constants.JULIAN_DAY * (352));
73  
74          // Check size of set
75          Assertions.assertEquals(4, history.size());
76  
77          // Test if the values are correctly extracted
78          EOPEntry firstEntry = history.first();
79          Assertions.assertEquals(unitConvRad.convert(0.101379061387836E+03), firstEntry.getX(), 1e-15);
80          Assertions.assertEquals(unitConvRad.convert(0.274820464392703E+03), firstEntry.getY(), 1e-15);
81          Assertions.assertEquals(-0.172036907064256E+03, firstEntry.getUT1MinusUTC() * 1000, 1e-15);
82  
83          // Test if a valid EOPHistory object can be built
84          EOPHistory eopHistory = new EOPHistory(IERSConventions.IERS_2010, EOPHistory.DEFAULT_INTERPOLATION_DEGREE,
85                                                 history, true, DataContext.getDefault().getTimeScales());
86          Assertions.assertEquals(-0.172046001405041, eopHistory.getUT1MinusUTC(date1), 1e-15);
87          Assertions.assertEquals(unitConvRad.convert(0.994323310003336E+02), eopHistory.getPoleCorrection(date1).getXp(), 1e-15);
88          Assertions.assertEquals(unitConvRad.convert(0.275001985187467E+03), eopHistory.getPoleCorrection(date1).getYp(), 1e-15);
89          Assertions.assertEquals(0, eopHistory.getEquinoxNutationCorrection(date1)[0], 1e-15);
90          Assertions.assertEquals(0, eopHistory.getEquinoxNutationCorrection(date1)[1], 1e-15);
91          Assertions.assertEquals(0, eopHistory.getNonRotatinOriginNutationCorrection(date1)[0], 1e-15);
92          Assertions.assertEquals(0, eopHistory.getNonRotatinOriginNutationCorrection(date1)[1], 1e-15);
93  
94          Assertions.assertEquals(-.172731650844468, eopHistory.getUT1MinusUTC(date2), 1e-15);
95          Assertions.assertEquals(unitConvRad.convert(0.958035125590580E+02), eopHistory.getPoleCorrection(date2).getXp(), 1e-15);
96          Assertions.assertEquals(unitConvRad.convert(0.275653571617736E+03), eopHistory.getPoleCorrection(date2).getYp(), 1e-15);
97          Assertions.assertEquals(0, eopHistory.getEquinoxNutationCorrection(date2)[0], 1e-15);
98          Assertions.assertEquals(0, eopHistory.getEquinoxNutationCorrection(date2)[1], 1e-15);
99          Assertions.assertEquals(0, eopHistory.getNonRotatinOriginNutationCorrection(date2)[0], 1e-15);
100         Assertions.assertEquals(0, eopHistory.getNonRotatinOriginNutationCorrection(date2)[1], 1e-15);
101 
102         // Checking start and end dates
103         // 19:350:00000
104         AbsoluteDate firstDate = new AbsoluteDate(new DateComponents(2019, 1, 1), utc).shiftedBy(Constants.JULIAN_DAY * (349));
105         Assertions.assertEquals(firstDate, eopHistory.getStartDate());
106         // 19:353:00000
107         AbsoluteDate endDate = new AbsoluteDate(new DateComponents(2019, 1, 1), utc).shiftedBy(Constants.JULIAN_DAY * (352));
108         Assertions.assertEquals(endDate, eopHistory.getEndDate());
109 
110     }
111 
112 
113     @Test
114     // Tests to go through the different branches of the IF-ELSE used to differentiate cases on the presence of
115     // nutation data. (NUT_X, NUT_Y, NUT_LN, NUT_OB)
116     // Case NUT_X, NUT_Y != null, NUT_LN, NUT_OB == null
117     public void testSmallSinexEopSynth1File() {
118 
119         // Setting up the Sinex loader
120         Sinex sinex = load("/sinex/cod20842-small-synthEOP.snx");
121 
122         // Extracting the data parsed in the Sinex loader to fill the history set
123         IERSConventions.NutationCorrectionConverter converter =
124                 IERSConventions.IERS_2010.getNutationCorrectionConverter();
125         SortedSet<EOPEntry> history = new TreeSet<>(new ChronologicalComparator());
126         sinex.getEopLoader(ITRFVersion.ITRF_2014).fillHistory(converter, history);
127 
128         final UnitsConverter unitConvRad = new UnitsConverter(Unit.parse("mas"), Unit.RADIAN);
129 
130         // Setting up the date, and generating elements not present at first for check
131         AbsoluteDate date = new AbsoluteDate(new DateComponents(2019, 1, 1), utc).shiftedBy(Constants.JULIAN_DAY * 350 + 43185.0);
132 
133         // Test if the values are correctly extracted
134         EOPEntry firstEntry = history.first();
135         double xPo = unitConvRad.convert(7.68783442726072E+01);
136         double yPo = unitConvRad.convert(3.47286203337827E+02);
137         double nutX = unitConvRad.convert(-1.10122731910265E+03);
138         double nutY = unitConvRad.convert(-4.00387630903350E+03);
139         double[] equinox = converter.toEquinox(date, nutX, nutY);
140         Assertions.assertEquals(xPo, firstEntry.getX(), 1e-15);
141         Assertions.assertEquals(yPo, firstEntry.getY(), 1e-15);
142         Assertions.assertEquals(-3.17284190690589E+04, firstEntry.getUT1MinusUTC() * 1000, 1e-15);
143         Assertions.assertEquals(1.32354538674901E+00, firstEntry.getLOD() * 1000, 1e-15);
144         Assertions.assertEquals(nutX, firstEntry.getDx(), 1e-15);
145         Assertions.assertEquals(nutY, firstEntry.getDy(), 1e-15);
146         Assertions.assertEquals(equinox[0], firstEntry.getDdPsi(), 4.5e-11);
147         Assertions.assertEquals(equinox[1], firstEntry.getDdEps(), 4.8e-12);
148 
149         // Test if a valid EOPHistory object can be built
150         EOPHistory eopHistory = new EOPHistory(IERSConventions.IERS_2010, EOPHistory.DEFAULT_INTERPOLATION_DEGREE,
151                                                history, true, DataContext.getDefault().getTimeScales());
152 
153         Assertions.assertEquals(unitConvRad.convert(7.68783442726072E+01), eopHistory.getPoleCorrection(date.shiftedBy(0)).getXp(), 1e-15);
154         Assertions.assertEquals(unitConvRad.convert(3.47286203337827E+02), eopHistory.getPoleCorrection(date.shiftedBy(-1)).getYp(), 1e-15);
155         Assertions.assertEquals(-3.17284190690589E+04, eopHistory.getUT1MinusUTC(date.shiftedBy(10)) * 1000, 1e-15);
156         Assertions.assertEquals( 1.32354538674901E+00, eopHistory.getLOD(date.shiftedBy(10))* 1000, 1e-15);
157         Assertions.assertEquals(unitConvRad.convert(-1.10122731910265E+03), eopHistory.getNonRotatinOriginNutationCorrection(date.shiftedBy(10))[0], 1e-15);
158         Assertions.assertEquals(unitConvRad.convert(-4.00387630903350E+03), eopHistory.getNonRotatinOriginNutationCorrection(date.shiftedBy(10))[1], 1e-15);
159         Assertions.assertEquals(equinox[0], eopHistory.getEquinoxNutationCorrection(date.shiftedBy(10))[0], 4.5e-11);
160         Assertions.assertEquals(equinox[1], eopHistory.getEquinoxNutationCorrection(date.shiftedBy(10))[1], 4.8e-12);
161     }
162 
163     @Test
164     // Case NUT_X, NUT_Y != null, NUT_LN, NUT_OB != null
165     public void testSmallSinexEopSynth2File() {
166         // Setting up the Sinex loader
167         Sinex sinex = load("/sinex/cod20842-small-synthEOP2.snx");
168 
169         // Extracting the data parsed in the Sinex loader to fill the history set
170         IERSConventions.NutationCorrectionConverter converter =
171                 IERSConventions.IERS_2010.getNutationCorrectionConverter();
172         SortedSet<EOPEntry> history = new TreeSet<>(new ChronologicalComparator());
173         sinex.getEopLoader(ITRFVersion.ITRF_2014).fillHistory(converter, history);
174 
175         // Setting up the date
176         AbsoluteDate date = new AbsoluteDate(new DateComponents(2019, 1, 1), utc).shiftedBy(Constants.JULIAN_DAY * (351 - 1)).shiftedBy(43185);
177         final UnitsConverter unitConvRad = new UnitsConverter(Unit.parse("mas"), Unit.RADIAN);
178         EOPEntry firstEntry = history.first();
179 
180         Assertions.assertEquals(unitConvRad.convert(7.68783442726072E+01), firstEntry.getX(), 1e-15);
181         Assertions.assertEquals(unitConvRad.convert(3.47286203337827E+02), firstEntry.getY(), 1e-15);
182         Assertions.assertEquals(-3.17284190690589E+04, firstEntry.getUT1MinusUTC() * 1000, 1e-15);
183         Assertions.assertEquals(1.32354538674901E+00, firstEntry.getLOD() * 1000, 1e-15);
184         Assertions.assertEquals(unitConvRad.convert(-1.10122731910265E+03), firstEntry.getDx(), 1e-15);
185         Assertions.assertEquals(unitConvRad.convert(-4.00387630903350E+03), firstEntry.getDy(), 1e-15);
186         Assertions.assertEquals(unitConvRad.convert(-1.10122731910265E+03), firstEntry.getDdPsi(), 1e-15);
187         Assertions.assertEquals(unitConvRad.convert(-4.00387630903350E+03), firstEntry.getDdEps(), 1e-15);
188 
189         DataContext.getDefault().getFrames().addEOPHistoryLoader(IERSConventions.IERS_2010,
190                                                                  sinex.getEopLoader(ITRFVersion.ITRF_2014));
191         EOPHistory eopHistory =DataContext.getDefault().getFrames().getEOPHistory(IERSConventions.IERS_2010, true);
192 
193         Assertions.assertEquals(unitConvRad.convert(7.68783442726072E+01), eopHistory.getPoleCorrection(date.shiftedBy(10)).getXp(), 1e-15);
194         Assertions.assertEquals(unitConvRad.convert(3.47286203337827E+02), eopHistory.getPoleCorrection(date.shiftedBy(10)).getYp(), 1e-15);
195         Assertions.assertEquals(-3.17284190690589E+04, eopHistory.getUT1MinusUTC(date.shiftedBy(10)) * 1000, 1e-15);
196         Assertions.assertEquals( 1.32354538674901E+00, eopHistory.getLOD(date.shiftedBy(10))* 1000, 1e-15);
197         Assertions.assertEquals(unitConvRad.convert(-1.10122731910265E+03), eopHistory.getNonRotatinOriginNutationCorrection(date.shiftedBy(10))[0], 1e-15);
198         Assertions.assertEquals(unitConvRad.convert(-4.00387630903350E+03), eopHistory.getNonRotatinOriginNutationCorrection(date.shiftedBy(10))[1], 1e-15);
199         Assertions.assertEquals(unitConvRad.convert(-1.10122731910265E+03), eopHistory.getEquinoxNutationCorrection(date.shiftedBy(10))[0], 1e-15);
200         Assertions.assertEquals(unitConvRad.convert(-4.00387630903350E+03), eopHistory.getEquinoxNutationCorrection(date.shiftedBy(10))[1], 1e-15);
201     }
202 
203     @Test
204     // Case NUT_X, NUT_OB != null, NUT_LN, NUT_Y == null
205     public void testSmallSinexEopSynth3File() {
206 
207         // Setting up the Sinex loader
208         Sinex sinex = load("/sinex/cod20842-small-synthEOP3.snx");
209 
210         IERSConventions.NutationCorrectionConverter converter =
211                 IERSConventions.IERS_2010.getNutationCorrectionConverter();
212         SortedSet<EOPEntry> history = new TreeSet<>(new ChronologicalComparator());
213         sinex.getEopLoader(ITRFVersion.ITRF_2014).fillHistory(converter, history);
214         final UnitsConverter unitConvRad = new UnitsConverter(Unit.parse("mas"), Unit.RADIAN);
215 
216         AbsoluteDate date = new AbsoluteDate(new DateComponents(2019, 1, 1), utc).shiftedBy(Constants.JULIAN_DAY * (351 - 1)).shiftedBy(43185);
217         double[] nro = converter.toNonRotating(date, unitConvRad.convert(-1.10122731910265E+03), unitConvRad.convert(-4.00387630903350E+03));
218 
219         EOPEntry firstEntry = history.first();
220 
221         Assertions.assertEquals(unitConvRad.convert(7.68783442726072E+01), firstEntry.getX(), 1e-15);
222         Assertions.assertEquals(unitConvRad.convert(3.47286203337827E+02), firstEntry.getY(), 1e-15);
223         Assertions.assertEquals(-3.17284190690589E+04, firstEntry.getUT1MinusUTC() * 1000, 1e-15);
224         Assertions.assertEquals(1.32354538674901E+00, firstEntry.getLOD() * 1000, 1e-15);
225         Assertions.assertEquals(unitConvRad.convert(-1.10122731910265E+03), firstEntry.getDdPsi(), 1e-15);
226         Assertions.assertEquals(unitConvRad.convert(-4.00387630903350E+03), firstEntry.getDdEps(), 1e-15);
227         Assertions.assertEquals(nro[0], firstEntry.getDx(), 1.8e-11);
228         Assertions.assertEquals(nro[1], firstEntry.getDy(), 2.0e-12);
229 
230     }
231 
232     @Test
233     // Test the number of EOP entries and epochs
234     public void testEpochsInFile() {
235         // Setting up the Sinex loader
236         Sinex sinex = load("/sinex/cod_ifCloseEnd.snx");
237 
238         IERSConventions.NutationCorrectionConverter converter =
239                 IERSConventions.IERS_2010.getNutationCorrectionConverter();
240         SortedSet<EOPEntry> history = new TreeSet<>(new ChronologicalComparator());
241         sinex.getEopLoader(ITRFVersion.ITRF_2014).fillHistory(converter, history);
242 
243         AbsoluteDate dateStart = new AbsoluteDate(new DateComponents(2019, 1, 1), utc).shiftedBy(Constants.JULIAN_DAY * 350);
244         AbsoluteDate dateStartPlusOne = dateStart.shiftedBy(+1.0);
245         AbsoluteDate dateInFile = new AbsoluteDate(new DateComponents(2019, 1, 1), utc).shiftedBy(Constants.JULIAN_DAY * 350 + 45000.0);
246         AbsoluteDate dateEnd = new AbsoluteDate(new DateComponents(2019, 1, 1), utc).shiftedBy(Constants.JULIAN_DAY * 351);
247         AbsoluteDate dateEndMinusOne = dateEnd.shiftedBy(-1.0);
248 
249         List<AbsoluteDate> listDates = Arrays.asList(dateStart, dateStartPlusOne, dateInFile, dateEndMinusOne, dateEnd);
250 
251         int cpt = 0;
252         for (EOPEntry entry : history) {
253             Assertions.assertEquals(listDates.get(cpt), entry.getDate());
254             cpt = cpt+1;
255         }
256 
257     }
258 
259     @Test
260     // Check the behaviour of the SinexParser when given several sources, with consistent dates for EOP entries.
261     public void testSmallSinexEopSynthMultiFile() {
262 
263         Sinex sinex = load("/sinex/cod_test_1.snx", "/sinex/cod_test_2.snx", "/sinex/cod_test_3.snx");
264 
265         IERSConventions.NutationCorrectionConverter converter =
266                 IERSConventions.IERS_2010.getNutationCorrectionConverter();
267         SortedSet<EOPEntry> history = new TreeSet<>(new ChronologicalComparator());
268         sinex.getEopLoader(ITRFVersion.ITRF_2014).fillHistory(converter, history);
269 
270         final UnitsConverter unitConvRad = new UnitsConverter(Unit.parse("mas"), Unit.RADIAN);
271 
272         EOPEntry firstEntry = history.first();
273 
274         Assertions.assertEquals(unitConvRad.convert(7.68783442726072E+01), firstEntry.getX(), 1e-15);
275         Assertions.assertEquals(unitConvRad.convert(3.47286203337827E+02), firstEntry.getY(), 1e-15);
276         Assertions.assertEquals(-3.17284190690589E+04, firstEntry.getUT1MinusUTC() * 1000, 1e-15);
277         Assertions.assertEquals(1.32354538674901E+00, firstEntry.getLOD() * 1000, 1e-15);
278         Assertions.assertEquals(unitConvRad.convert(-1.10122731910265E+03), firstEntry.getDx(), 1e-15);
279         Assertions.assertEquals(unitConvRad.convert(-4.00387630903350E+03), firstEntry.getDy(), 1e-15);
280     }
281 
282 
283     @Test
284     // Check the behaviour of the LazyLoadedEop class used in the Default DataContext case, with multiple Sinex files.
285     // We suppose the dates are not overlapping, and are consistent with the header of each file.
286     public void testSmallSinexEopSynthMultiLoader() {
287 
288         Sinex sinex1 = load("/sinex/cod_test_1.snx");
289         Sinex sinex2 = load("/sinex/cod_test_2.snx");
290         Sinex sinex3 = load("/sinex/cod_test_3.snx");
291 
292         // Setting the DataContext to extract the EOP data from the 3 SinexParser objects
293         final LazyLoadedFrames frames = DataContext.getDefault().getFrames();
294         frames.addEOPHistoryLoader(IERSConventions.IERS_2010, sinex1.getEopLoader(ITRFVersion.ITRF_2014));
295         frames.addEOPHistoryLoader(IERSConventions.IERS_2010, sinex2.getEopLoader(ITRFVersion.ITRF_2014));
296         frames.addEOPHistoryLoader(IERSConventions.IERS_2010, sinex3.getEopLoader(ITRFVersion.ITRF_2014));
297 
298         // Generate the EOPHistory
299         EOPHistory eopHistory  = DataContext.getDefault().getFrames().getEOPHistory(IERSConventions.IERS_2010, true);
300 
301         // Setting up dates for further checks
302         AbsoluteDate startDate = new AbsoluteDate(new DateComponents(2019, 1, 1), utc).shiftedBy(Constants.JULIAN_DAY * (350));
303         AbsoluteDate startDatePlusOne = startDate.shiftedBy(+1.0);
304         AbsoluteDate endDate = new AbsoluteDate(new DateComponents(2019, 1, 1), utc).shiftedBy(Constants.JULIAN_DAY * (353));
305         AbsoluteDate endDateMinusOne = endDate.shiftedBy(-1.0);
306 
307         AbsoluteDate date  = new AbsoluteDate(new DateComponents(2019, 1, 1), utc).shiftedBy(Constants.JULIAN_DAY * 350 + 43185.0);
308         AbsoluteDate date2 = new AbsoluteDate(new DateComponents(2019, 1, 1), utc).shiftedBy(Constants.JULIAN_DAY * 351 + 43185.0);
309         AbsoluteDate date3 = new AbsoluteDate(new DateComponents(2019, 1, 1), utc).shiftedBy(Constants.JULIAN_DAY * 352 + 43185.0);
310 
311         // Intermediate shared date between two files
312         AbsoluteDate dateI12 = new AbsoluteDate(new DateComponents(2019, 1, 1), utc).shiftedBy(Constants.JULIAN_DAY * (352 - 1)).shiftedBy(0);
313         AbsoluteDate dateI12MinusOne = dateI12.shiftedBy(-1.0);
314         AbsoluteDate dateI12PlusOne = dateI12.shiftedBy(+1.0);
315         AbsoluteDate dateI23 = new AbsoluteDate(new DateComponents(2019, 1, 1), utc).shiftedBy(Constants.JULIAN_DAY * (353 - 1)).shiftedBy(0);
316         AbsoluteDate dateI23MinusOne = dateI23.shiftedBy(-1.0);
317         AbsoluteDate dateI23PlusOne = dateI23.shiftedBy(+1.0);
318 
319         List<AbsoluteDate> listDates = Arrays.asList(startDate, startDatePlusOne, date,
320                                                      dateI12MinusOne, dateI12, dateI12PlusOne, date2,
321                                                      dateI23MinusOne, dateI23, dateI23PlusOne, date3,
322                                                      endDateMinusOne, endDate);
323         // Simplify checks to stay in the units of Orekit
324         final UnitsConverter unitConvRad = new UnitsConverter(Unit.parse("mas"), Unit.RADIAN);
325 
326         // Check dates
327         int cpt = 0;
328         for (EOPEntry entry : eopHistory.getEntries()) {
329             Assertions.assertEquals(listDates.get(cpt), entry.getDate());
330             cpt = cpt+1;
331         }
332 
333         // First Entry
334         double shift  = 0;
335         Assertions.assertEquals(unitConvRad.convert(7.68783442726072E+01), eopHistory.getPoleCorrection(startDate).getXp(), 1e-15);
336         Assertions.assertEquals(unitConvRad.convert(3.47286203337827E+02), eopHistory.getPoleCorrection(startDate).getYp(), 1e-15);
337         Assertions.assertEquals(-3.17284190690589E+04, eopHistory.getUT1MinusUTC(startDate) * 1000, 1e-15);
338         Assertions.assertEquals( 1.32354538674901E+00, eopHistory.getLOD(startDate)* 1000, 1e-15);
339         Assertions.assertEquals(unitConvRad.convert(-1.10122731910265E+03), eopHistory.getNonRotatinOriginNutationCorrection(startDate)[0], 1e-15);
340         Assertions.assertEquals(unitConvRad.convert(-4.00387630903350E+03), eopHistory.getNonRotatinOriginNutationCorrection(startDate)[1], 1e-15);
341 
342         Assertions.assertEquals(unitConvRad.convert(7.68783442726072E+01), eopHistory.getPoleCorrection(date.shiftedBy(shift)).getXp(), 1e-15);
343         Assertions.assertEquals(unitConvRad.convert(3.47286203337827E+02), eopHistory.getPoleCorrection(date.shiftedBy(shift)).getYp(), 1e-15);
344         Assertions.assertEquals(-3.17284190690589E+04, eopHistory.getUT1MinusUTC(date.shiftedBy(shift)) * 1000, 1e-15);
345         Assertions.assertEquals( 1.32354538674901E+00, eopHistory.getLOD(date.shiftedBy(shift))* 1000, 1e-15);
346         Assertions.assertEquals(unitConvRad.convert(-1.10122731910265E+03), eopHistory.getNonRotatinOriginNutationCorrection(date.shiftedBy(shift))[0], 1e-15);
347         Assertions.assertEquals(unitConvRad.convert(-4.00387630903350E+03), eopHistory.getNonRotatinOriginNutationCorrection(date.shiftedBy(shift))[1], 1e-15);
348 
349         // Last entry for 1st file
350         Assertions.assertEquals(unitConvRad.convert(7.68783442726072E+01), eopHistory.getPoleCorrection(dateI12).getXp(), 1e-15);
351         Assertions.assertEquals(unitConvRad.convert(3.47286203337827E+02), eopHistory.getPoleCorrection(dateI12).getYp(), 1e-15);
352         Assertions.assertEquals(-3.17284190690589E+04, eopHistory.getUT1MinusUTC(dateI12) * 1000, 1e-15);
353         Assertions.assertEquals( 1.32354538674901E+00, eopHistory.getLOD(dateI12)* 1000, 1e-15);
354         Assertions.assertEquals(unitConvRad.convert(-1.10122731910265E+03), eopHistory.getNonRotatinOriginNutationCorrection(dateI12)[0], 1e-15);
355         Assertions.assertEquals(unitConvRad.convert(-4.00387630903350E+03), eopHistory.getNonRotatinOriginNutationCorrection(dateI12)[1], 1e-15);
356 
357         // Second Entry
358         Assertions.assertEquals(unitConvRad.convert(6.68783442726072E+01), eopHistory.getPoleCorrection(date2).getXp(), 1e-15);
359         Assertions.assertEquals(unitConvRad.convert(2.47286203337827E+02), eopHistory.getPoleCorrection(date2).getYp(), 1e-15);
360         Assertions.assertEquals(-4.17284190690589E+04, eopHistory.getUT1MinusUTC(date2) * 1000, 1e-15);
361         Assertions.assertEquals( 2.32354538674901E+00, eopHistory.getLOD(date2)* 1000, 1e-15);
362         Assertions.assertEquals(unitConvRad.convert(-2.10122731910265E+03), eopHistory.getNonRotatinOriginNutationCorrection(date2)[0], 1e-15);
363         Assertions.assertEquals(unitConvRad.convert(-5.00387630903350E+03), eopHistory.getNonRotatinOriginNutationCorrection(date2)[1], 1e-15);
364 
365         // Between second and third file
366         Assertions.assertEquals(unitConvRad.convert(6.68783442726072E+01), eopHistory.getPoleCorrection(dateI23).getXp(), 1e-15);
367         Assertions.assertEquals(unitConvRad.convert(2.47286203337827E+02), eopHistory.getPoleCorrection(dateI23).getYp(), 1e-15);
368         Assertions.assertEquals(-4.17284190690589E+04, eopHistory.getUT1MinusUTC(dateI23) * 1000, 1e-15);
369         Assertions.assertEquals( 2.32354538674901E+00, eopHistory.getLOD(dateI23)* 1000, 1e-15);
370         Assertions.assertEquals(unitConvRad.convert(-2.10122731910265E+03), eopHistory.getNonRotatinOriginNutationCorrection(dateI23)[0], 1e-15);
371         Assertions.assertEquals(unitConvRad.convert(-5.00387630903350E+03), eopHistory.getNonRotatinOriginNutationCorrection(dateI23)[1], 1e-15);
372 
373         // Third file main entry
374         Assertions.assertEquals(unitConvRad.convert(5.68783442726072E+01), eopHistory.getPoleCorrection(date3).getXp(), 1e-15);
375         Assertions.assertEquals(unitConvRad.convert(1.47286203337827E+02), eopHistory.getPoleCorrection(date3).getYp(), 1e-15);
376         Assertions.assertEquals(-5.17284190690589E+04, eopHistory.getUT1MinusUTC(date3) * 1000, 1e-15);
377         Assertions.assertEquals( 3.32354538674901E+00, eopHistory.getLOD(date3)* 1000, 1e-15);
378         Assertions.assertEquals(unitConvRad.convert(-3.10122731910265E+03), eopHistory.getNonRotatinOriginNutationCorrection(date3)[0], 1e-15);
379         Assertions.assertEquals(unitConvRad.convert(-6.00387630903350E+03), eopHistory.getNonRotatinOriginNutationCorrection(date3)[1], 1e-15);
380 
381         // Last entry
382         Assertions.assertEquals(unitConvRad.convert(5.68783442726072E+01), eopHistory.getPoleCorrection(endDate).getXp(), 1e-15);
383         Assertions.assertEquals(unitConvRad.convert(1.47286203337827E+02), eopHistory.getPoleCorrection(endDate).getYp(), 1e-15);
384         Assertions.assertEquals(-5.17284190690589E+01, eopHistory.getUT1MinusUTC(endDate), 1e-14);
385         Assertions.assertEquals( 3.32354538674901E+00, eopHistory.getLOD(endDate)* 1000, 1e-15);
386         Assertions.assertEquals(unitConvRad.convert(-3.10122731910265E+03), eopHistory.getNonRotatinOriginNutationCorrection(endDate)[0], 1e-15);
387         Assertions.assertEquals(unitConvRad.convert(-6.00387630903350E+03), eopHistory.getNonRotatinOriginNutationCorrection(endDate)[1], 1e-15);
388 
389     }
390 
391     private Sinex load(final String... names) {
392         final DataSource[] sources = new DataSource[names.length];
393         for (int i = 0 ; i < names.length ; i++) {
394             final String name = names[i];
395             sources[i] = new DataSource(name, () -> SinexParserEopTest.class.getResourceAsStream(name));
396         }
397         return new SinexParser(TimeScalesFactory.getTimeScales()).parse(sources);
398     }
399 
400 }