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.junit.jupiter.api.Assertions;
20  import org.junit.jupiter.api.Test;
21  import org.orekit.data.AbstractFilesLoaderTest;
22  import org.orekit.errors.OrekitException;
23  import org.orekit.errors.OrekitMessages;
24  import org.orekit.time.AbsoluteDate;
25  import org.orekit.time.ChronologicalComparator;
26  import org.orekit.time.DateComponents;
27  import org.orekit.time.TimeScalesFactory;
28  import org.orekit.utils.Constants;
29  import org.orekit.utils.IERSConventions;
30  
31  import java.util.SortedSet;
32  import java.util.TreeSet;
33  
34  
35  public class BulletinAFilesLoaderTest extends AbstractFilesLoaderTest {
36  
37      @Test
38      public void testStartDate() {
39          setRoot("bulletinA");
40          SortedSet<EOPEntry> history = new TreeSet<EOPEntry>(new ChronologicalComparator());
41          new BulletinAFilesLoader("bulletina-xxvi-\\d\\d\\d\\.txt", manager, () -> utc).fillHistory(null, history);
42          Assertions.assertEquals(new AbsoluteDate(new DateComponents(DateComponents.MODIFIED_JULIAN_EPOCH, 56475),
43                                               TimeScalesFactory.getUTC()),
44                              new EOPHistory(IERSConventions.IERS_2010, EOPHistory.DEFAULT_INTERPOLATION_DEGREE,
45                                             history, true).getStartDate());
46      }
47  
48      @Test
49      public void testEndDate() {
50          setRoot("bulletinA");
51          SortedSet<EOPEntry> history = new TreeSet<EOPEntry>(new ChronologicalComparator());
52          new BulletinAFilesLoader("bulletina-xxvi-\\d\\d\\d\\.txt", manager, () -> utc).fillHistory(null, history);
53          Assertions.assertTrue(getMaxGap(history) < 2);
54          Assertions.assertEquals(new AbsoluteDate(new DateComponents(DateComponents.MODIFIED_JULIAN_EPOCH, 56968),
55                                               TimeScalesFactory.getUTC()),
56                              new EOPHistory(IERSConventions.IERS_2010, EOPHistory.DEFAULT_INTERPOLATION_DEGREE,
57                                             history, false).getEndDate());
58      }
59  
60      @Test
61      public void testSingleFile() {
62          setRoot("bulletinA");
63          SortedSet<EOPEntry> data = new TreeSet<EOPEntry>(new ChronologicalComparator());
64          new BulletinAFilesLoader("bulletina-xxvi-039.txt", manager, () -> utc).fillHistory(null, data);
65          EOPHistory history = new EOPHistory(IERSConventions.IERS_2010, EOPHistory.DEFAULT_INTERPOLATION_DEGREE,
66                                              data, true);
67  
68          // earliest date is for pole position, provided days 56546, 56547, 56548
69          Assertions.assertEquals(new AbsoluteDate(new DateComponents(DateComponents.MODIFIED_JULIAN_EPOCH, 56546),
70                                               TimeScalesFactory.getUTC()),
71                              history.getStartDate());
72  
73          // with this single file, there is a hole between last pole (56548) and first rapid data (56555)
74          Assertions.assertEquals(56555 - 56548, getMaxGap(data));
75  
76          // latest date is for EOP prediction, corresponding to 56926
77          Assertions.assertEquals(new AbsoluteDate(new DateComponents(DateComponents.MODIFIED_JULIAN_EPOCH, 56926),
78                                               TimeScalesFactory.getUTC()),
79                              history.getEndDate());
80      }
81  
82      @Test
83      public void testRapidDataContent() {
84          setRoot("bulletinA");
85          SortedSet<EOPEntry> data = new TreeSet<EOPEntry>(new ChronologicalComparator());
86          new BulletinAFilesLoader(FramesFactory.BULLETINA_FILENAME, manager, () -> utc).fillHistory(null, data);
87          EOPHistory history = new EOPHistory(IERSConventions.IERS_2010, EOPHistory.DEFAULT_INTERPOLATION_DEGREE,
88                                              data, true);
89          AbsoluteDate date = new AbsoluteDate(2013, 10, 14, 12, 0, 0, TimeScalesFactory.getUTC());
90          // the following values are from bulletina-xxvi-042.txt, rapid service section, lines 53-56
91          Assertions.assertEquals(        (-3 * -0.001957 + 27 * -0.003274 + 27 * -0.004706 - 3 * -0.006211) / 48,  history.getUT1MinusUTC(date), 1.0e-10);
92          Assertions.assertEquals(asToRad((-3 *  0.11518  + 27 *  0.11389  + 27 *  0.11285  - 3 *  0.11171)  / 48), history.getPoleCorrection(date).getXp(), 1.0e-10);
93          Assertions.assertEquals(asToRad((-3 *  0.28484  + 27 *  0.28449  + 27 *  0.28408  - 3 *  0.28379)  / 48), history.getPoleCorrection(date).getYp(), 1.0e-10);
94      }
95  
96      @Test
97      public void testFinalValuesContent() {
98          setRoot("bulletinA");
99          SortedSet<EOPEntry> data = new TreeSet<EOPEntry>(new ChronologicalComparator());
100         new BulletinAFilesLoader(FramesFactory.BULLETINA_FILENAME, manager, () -> utc).fillHistory(null, data);
101         EOPHistory history = new EOPHistory(IERSConventions.IERS_2010, EOPHistory.DEFAULT_INTERPOLATION_DEGREE,
102                                             data, true);
103         AbsoluteDate date = new AbsoluteDate(2013, 8, 26, 12, 0, 0, TimeScalesFactory.getUTC());
104         // the following values are from bulletina-xxvi-040.txt, final values section, lines 79-82
105         Assertions.assertEquals(        (-3 * 0.04058 + 27 * 0.04000 + 27 * 0.03953 - 3 * 0.03917) / 48,  history.getUT1MinusUTC(date), 1.0e-10);
106         Assertions.assertEquals(asToRad((-3 * 0.1692  + 27 * 0.1689  + 27 * 0.1685  - 3 * 0.1684)  / 48), history.getPoleCorrection(date).getXp(), 1.0e-10);
107         Assertions.assertEquals(asToRad((-3 * 0.3336  + 27 * 0.3322  + 27 * 0.3307  - 3 * 0.3294)  / 48), history.getPoleCorrection(date).getYp(), 1.0e-10);
108     }
109 
110     private double asToRad(double mas) {
111         return mas * Constants.ARC_SECONDS_TO_RADIANS;
112     }
113 
114     @Test
115     public void testMissingSections() {
116         setRoot("bulletinA");
117         checkTruncated("bulletina-missing-eop-rapid-service.txt",    OrekitMessages.NOT_A_SUPPORTED_IERS_DATA_FILE);
118         checkTruncated("bulletina-missing-eop-prediction.txt",       OrekitMessages.NOT_A_SUPPORTED_IERS_DATA_FILE);
119         checkTruncated("bulletina-with-1980-without-2000-rapid.txt", OrekitMessages.NOT_A_SUPPORTED_IERS_DATA_FILE);
120         checkTruncated("bulletina-without-1980-with-2000-rapid.txt", OrekitMessages.NOT_A_SUPPORTED_IERS_DATA_FILE);
121         checkTruncated("bulletina-with-1980-without-2000-final.txt", OrekitMessages.NOT_A_SUPPORTED_IERS_DATA_FILE);
122         checkTruncated("bulletina-without-1980-with-2000-final.txt", OrekitMessages.NOT_A_SUPPORTED_IERS_DATA_FILE);
123     }
124 
125     @Test
126     public void testMissingData() {
127         setRoot("bulletinA");
128         checkTruncated("bulletina-truncated-in-eop-data.txt",  OrekitMessages.UNEXPECTED_END_OF_FILE_AFTER_LINE);
129         checkTruncated("bulletina-truncated-in-pole-data.txt", OrekitMessages.UNEXPECTED_END_OF_FILE_AFTER_LINE);
130     }
131 
132     private void checkTruncated(String name, OrekitMessages expected) {
133         SortedSet<EOPEntry> history = new TreeSet<EOPEntry>(new ChronologicalComparator());
134         try {
135             new BulletinAFilesLoader(name, manager, () -> utc).fillHistory(null, history);
136             Assertions.fail("an exception should have been thrown");
137         } catch (OrekitException oe) {
138             Assertions.assertEquals(expected, oe.getSpecifier());
139             Assertions.assertTrue(((String) oe.getParts()[0]).endsWith(name));
140         }
141     }
142 
143     @Test
144     public void testInconsistentDate() {
145         setRoot("bulletinA");
146         checkInconsistent("bulletina-inconsistent-year.txt");
147         checkInconsistent("bulletina-inconsistent-month.txt");
148         checkInconsistent("bulletina-inconsistent-day.txt");
149     }
150 
151     private void checkInconsistent(String name) {
152         SortedSet<EOPEntry> history = new TreeSet<EOPEntry>(new ChronologicalComparator());
153         try {
154             new BulletinAFilesLoader(name, manager, () -> utc).fillHistory(null, history);
155             Assertions.fail("an exception should have been thrown");
156         } catch (OrekitException oe) {
157             Assertions.assertEquals(OrekitMessages.INCONSISTENT_DATES_IN_IERS_FILE, oe.getSpecifier());
158             Assertions.assertTrue(((String) oe.getParts()[0]).endsWith(name));
159         }
160     }
161 
162 }