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  package org.orekit.frames;
18  
19  import org.hipparchus.util.Binary64;
20  import org.hipparchus.util.Binary64Field;
21  import org.junit.jupiter.api.Assertions;
22  import org.junit.jupiter.api.BeforeEach;
23  import org.junit.jupiter.api.Test;
24  import org.orekit.Utils;
25  import org.orekit.errors.OrekitException;
26  import org.orekit.errors.OrekitMessages;
27  import org.orekit.time.AbsoluteDate;
28  import org.orekit.time.FieldAbsoluteDate;
29  import org.orekit.time.TimeScalesFactory;
30  import org.orekit.utils.Constants;
31  import org.orekit.utils.IERSConventions;
32  
33  import java.io.IOException;
34  
35  public class EOPHistoryTest {
36  
37      @Test
38      public void testRegular() {
39          AbsoluteDate date = new AbsoluteDate(2004, 1, 4, TimeScalesFactory.getUTC());
40          EOPHistory eopHistory = FramesFactory.getEOPHistory(IERSConventions.IERS_2010, true);
41          double dt = eopHistory.getUT1MinusUTC(date);
42          Assertions.assertTrue(EopDataType.UNKNOWN.equals(eopHistory.getEopDataType(date)));
43          Assertions.assertEquals(-0.3906070, dt, 1.0e-10);
44      }
45  
46      @Test
47      public void testOutOfRange() {
48          EOPHistory history = FramesFactory.getEOPHistory(IERSConventions.IERS_2010, true);
49          AbsoluteDate endDate = new AbsoluteDate(2006, 3, 5, TimeScalesFactory.getUTC());
50          for (double t = -1000; t < 1000 ; t += 3) {
51              AbsoluteDate date = endDate.shiftedBy(t);
52              double dt = history.getUT1MinusUTC(date);
53              if (t <= 0) {
54                  Assertions.assertTrue(EopDataType.UNKNOWN.equals(history.getEopDataType(date)));
55                  Assertions.assertTrue(dt < 0.29236);
56                  Assertions.assertTrue(dt > 0.29233);
57              } else {
58                  // no more data after end date
59                  Assertions.assertTrue(EopDataType.UNKNOWN.equals(history.getEopDataType(date)));
60                  Assertions.assertEquals(0.0, dt, 1.0e-10);
61              }
62          }
63      }
64  
65      @Test
66      public void testFieldOutOfRange() {
67          EOPHistory history = FramesFactory.getEOPHistory(IERSConventions.IERS_2010, true);
68          FieldAbsoluteDate<Binary64> endDate = new FieldAbsoluteDate<>(Binary64Field.getInstance(),
69                                                                         2006, 3, 5, TimeScalesFactory.getUTC());
70          for (double t = -1000; t < 1000 ; t += 3) {
71              FieldAbsoluteDate<Binary64> date = endDate.shiftedBy(t);
72              Binary64 dt = history.getUT1MinusUTC(date);
73              if (t <= 0) {
74                  Assertions.assertTrue(dt.getReal() < 0.29236);
75                  Assertions.assertTrue(dt.getReal() > 0.29233);
76              } else {
77                  // no more data after end date
78                  Assertions.assertEquals(0.0, dt.getReal(), 1.0e-10);
79              }
80          }
81      }
82  
83      @Test
84      public void testContinuityThreshold() {
85          try {
86              FramesFactory.setEOPContinuityThreshold(0.5 * Constants.JULIAN_DAY);
87              AbsoluteDate date = new AbsoluteDate(2004, 1, 4, TimeScalesFactory.getUTC());
88              FramesFactory.getEOPHistory(IERSConventions.IERS_2010, true).getUT1MinusUTC(date);
89              Assertions.fail("an exception should have been thrown");
90          } catch (OrekitException oe) {
91              Assertions.assertEquals(OrekitMessages.MISSING_EARTH_ORIENTATION_PARAMETERS_BETWEEN_DATES_GAP,
92                                  oe.getSpecifier());
93          }
94      }
95  
96      @Test
97      public void testUTCLeap() {
98          EOPHistory history = FramesFactory.getEOPHistory(IERSConventions.IERS_2010, true);
99          AbsoluteDate endLeap = new AbsoluteDate(2006, 1, 1, TimeScalesFactory.getUTC());
100         for (double dt = -200; dt < 200; dt += 3) {
101             final AbsoluteDate date = endLeap.shiftedBy(dt);
102             double dtu1 = history.getUT1MinusUTC(date);
103             if (dt <= 0) {
104                 Assertions.assertEquals(-0.6612, dtu1, 3.0e-5);
105             } else {
106                 Assertions.assertEquals(0.3388, dtu1, 3.0e-5);
107             }
108         }
109     }
110 
111     @Test
112     public void testFieldUTCLeap() {
113         EOPHistory history = FramesFactory.getEOPHistory(IERSConventions.IERS_2010, true);
114         FieldAbsoluteDate<Binary64> endLeap = new FieldAbsoluteDate<>(Binary64Field.getInstance(),
115                                                                        2006, 1, 1, TimeScalesFactory.getUTC());
116         for (double dt = -200; dt < 200; dt += 3) {
117             final FieldAbsoluteDate<Binary64> date = endLeap.shiftedBy(dt);
118             Binary64 dtu1 = history.getUT1MinusUTC(date);
119             if (dt <= 0) {
120                 Assertions.assertEquals(-0.6612, dtu1.getReal(), 3.0e-5);
121             } else {
122                 Assertions.assertEquals(0.3388, dtu1.getReal(), 3.0e-5);
123             }
124         }
125     }
126 
127     @Test
128     public void testTidalInterpolationEffects() throws IOException, OrekitException {
129 
130         final EOPHistory h1 = FramesFactory.getEOPHistory(IERSConventions.IERS_2010, false);
131         final EOPHistory h2 = h1.getEOPHistoryWithoutCachedTidalCorrection();
132         final AbsoluteDate date0 = new AbsoluteDate(2004, 8, 16, 20, 0, 0, TimeScalesFactory.getUTC());
133 
134         for (double dt = 0; dt < Constants.JULIAN_DAY; dt += 10) {
135             final AbsoluteDate date = date0.shiftedBy(dt);
136             final double interpolationErrorUT1 = h1.getUT1MinusUTC(date) - h2.getUT1MinusUTC(date);
137             final double interpolationErrorLOD = h1.getLOD(date)         - h2.getLOD(date);
138             final PoleCorrection p1 = h1.getPoleCorrection(date);
139             final PoleCorrection p2 = h2.getPoleCorrection(date);
140             final double interpolationErrorXp  = (p1.getXp() - p2.getXp()) / Constants.ARC_SECONDS_TO_RADIANS;
141             final double interpolationErrorYp  = (p1.getYp() - p2.getYp()) / Constants.ARC_SECONDS_TO_RADIANS;
142             Assertions.assertEquals(0.0, interpolationErrorUT1, 1.2e-10); // seconds
143             Assertions.assertEquals(0.0, interpolationErrorLOD, 1.5e-9);  // seconds
144             Assertions.assertEquals(0.0, interpolationErrorXp,  2.3e-9);  // arcseconds
145             Assertions.assertEquals(0.0, interpolationErrorYp,  1.5e-9);  // arcseconds
146         }
147 
148     }
149 
150     @BeforeEach
151     public void setUp() {
152         Utils.setDataRoot("regular-data");
153     }
154 
155 }