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.TimeScalesFactory;
27  import org.orekit.utils.Constants;
28  import org.orekit.utils.IERSConventions;
29  
30  import java.util.SortedSet;
31  import java.util.TreeSet;
32  
33  
34  public class BulletinBFilesLoaderTest extends AbstractFilesLoaderTest {
35  
36      @Test
37      public void testMissingMonths() {
38          setRoot("missing-months");
39          IERSConventions.NutationCorrectionConverter converter =
40                  IERSConventions.IERS_2010.getNutationCorrectionConverter();
41           SortedSet<EOPEntry> history = new TreeSet<EOPEntry>(new ChronologicalComparator());
42          new BulletinBFilesLoader(FramesFactory.BULLETINB_2000_FILENAME, manager, () -> utc).fillHistory(converter, history);
43          Assertions.assertTrue(getMaxGap(history) > 5);
44      }
45  
46      @Test
47      public void testStartDate() {
48          setRoot("regular-data");
49          IERSConventions.NutationCorrectionConverter converter =
50                  IERSConventions.IERS_2010.getNutationCorrectionConverter();
51          SortedSet<EOPEntry> history = new TreeSet<EOPEntry>(new ChronologicalComparator());
52          new BulletinBFilesLoader(FramesFactory.BULLETINB_2000_FILENAME, manager, () -> utc).fillHistory(converter, history);
53          Assertions.assertEquals(new AbsoluteDate(2005, 12, 5, TimeScalesFactory.getUTC()),
54                              new EOPHistory(IERSConventions.IERS_2010, EOPHistory.DEFAULT_INTERPOLATION_DEGREE,
55                                             history, true).getStartDate());
56      }
57  
58      @Test
59      public void testEndDate() {
60          setRoot("regular-data");
61          IERSConventions.NutationCorrectionConverter converter =
62                  IERSConventions.IERS_2010.getNutationCorrectionConverter();
63          SortedSet<EOPEntry> history = new TreeSet<EOPEntry>(new ChronologicalComparator());
64          new BulletinBFilesLoader(FramesFactory.BULLETINB_2000_FILENAME, manager, () -> utc).fillHistory(converter, history);
65          Assertions.assertTrue(getMaxGap(history) < 5);
66          Assertions.assertEquals(new AbsoluteDate(2006, 3, 5, TimeScalesFactory.getUTC()),
67                              new EOPHistory(IERSConventions.IERS_2010, EOPHistory.DEFAULT_INTERPOLATION_DEGREE,
68                                             history, false).getEndDate());
69      }
70  
71      @Test
72      public void testNewFormatNominal() {
73          setRoot("new-bulletinB");
74          IERSConventions.NutationCorrectionConverter converter =
75                  IERSConventions.IERS_2010.getNutationCorrectionConverter();
76          SortedSet<EOPEntry> data = new TreeSet<EOPEntry>(new ChronologicalComparator());
77          new BulletinBFilesLoader("^bulletinb\\.270$", manager, () -> utc).fillHistory(converter, data);
78          EOPHistory history = new EOPHistory(IERSConventions.IERS_2010, EOPHistory.DEFAULT_INTERPOLATION_DEGREE,
79                                              data, true);
80          Assertions.assertEquals(new AbsoluteDate(2010, 6, 2, TimeScalesFactory.getUTC()),
81                              history.getStartDate());
82          Assertions.assertEquals(new AbsoluteDate(2010, 7, 1, TimeScalesFactory.getUTC()),
83                              history.getEndDate());
84      }
85  
86      @Test
87      public void testOldFormatContent() {
88          setRoot("regular-data");
89          IERSConventions.NutationCorrectionConverter converter =
90                  IERSConventions.IERS_2010.getNutationCorrectionConverter();
91          SortedSet<EOPEntry> data = new TreeSet<EOPEntry>(new ChronologicalComparator());
92          new BulletinBFilesLoader(FramesFactory.BULLETINB_2000_FILENAME, manager, () -> utc).fillHistory(converter, data);
93          EOPHistory history = new EOPHistory(IERSConventions.IERS_2010, EOPHistory.DEFAULT_INTERPOLATION_DEGREE,
94                                              data, true);
95          AbsoluteDate date = new AbsoluteDate(2006, 1, 11, 12, 0, 0, TimeScalesFactory.getUTC());
96          Assertions.assertEquals(msToS(  (-3 * 0.073    + 27 * -0.130   + 27 * -0.244   - 3 * -0.264)   / 48), history.getLOD(date), 1.0e-10);
97          Assertions.assertEquals(        (-3 * 0.333275 + 27 * 0.333310 + 27 * 0.333506 - 3 * 0.333768) / 48,  history.getUT1MinusUTC(date), 1.0e-10);
98          Assertions.assertEquals(asToRad((-3 * 0.04958  + 27 * 0.04927  + 27 * 0.04876  - 3 * 0.04854)  / 48), history.getPoleCorrection(date).getXp(), 1.0e-10);
99          Assertions.assertEquals(asToRad((-3 * 0.38117  + 27 * 0.38105  + 27 * 0.38071  - 3 * 0.38036)  / 48), history.getPoleCorrection(date).getYp(), 1.0e-10);
100     }
101 
102     @Test
103     public void testOldFormat1980() {
104         setRoot("old-bulletinB");
105         IERSConventions.NutationCorrectionConverter converter =
106                 IERSConventions.IERS_1996.getNutationCorrectionConverter();
107         SortedSet<EOPEntry> data = new TreeSet<EOPEntry>(new ChronologicalComparator());
108         new BulletinBFilesLoader("^bulletinb_IAU1980-220\\.txt$", manager, () -> utc).fillHistory(converter, data);
109         EOPHistory history = new EOPHistory(IERSConventions.IERS_1996, EOPHistory.DEFAULT_INTERPOLATION_DEGREE,
110                                             data, true);
111         Assertions.assertEquals(new AbsoluteDate(2006,  4,  4, TimeScalesFactory.getUTC()),
112                             history.getStartDate());
113         Assertions.assertEquals(new AbsoluteDate(2006,  5,  4, TimeScalesFactory.getUTC()),
114                             history.getEndDate());
115     }
116 
117     @Test
118     public void testOldFormat1980RemovedFirstDates() {
119         setRoot("old-bulletinB");
120         IERSConventions.NutationCorrectionConverter converter =
121                 IERSConventions.IERS_1996.getNutationCorrectionConverter();
122         SortedSet<EOPEntry> data = new TreeSet<EOPEntry>(new ChronologicalComparator());
123         new BulletinBFilesLoader("^bulletinb_IAU1980-220-edited\\.txt$", manager, () -> utc).fillHistory(converter, data);
124         EOPHistory history = new EOPHistory(IERSConventions.IERS_1996, EOPHistory.DEFAULT_INTERPOLATION_DEGREE,
125                                             data, true);
126         Assertions.assertEquals(new AbsoluteDate(2006,  4, 14, TimeScalesFactory.getUTC()),
127                             history.getStartDate());
128         Assertions.assertEquals(new AbsoluteDate(2006,  5,  4, TimeScalesFactory.getUTC()),
129                             history.getEndDate());
130     }
131 
132     @Test
133     public void testOldFormatTruncated() {
134         setRoot("old-bulletinB");
135         IERSConventions.NutationCorrectionConverter converter =
136                 IERSConventions.IERS_2010.getNutationCorrectionConverter();
137         SortedSet<EOPEntry> data = new TreeSet<EOPEntry>(new ChronologicalComparator());
138         try {
139             new BulletinBFilesLoader("^bulletinb_IAU2000-216-truncated\\.txt$", manager, () -> utc).fillHistory(converter, data);
140         } catch (OrekitException oe) {
141             Assertions.assertEquals(OrekitMessages.UNEXPECTED_END_OF_FILE_AFTER_LINE, oe.getSpecifier());
142             Assertions.assertEquals(54, ((Integer) oe.getParts()[1]).intValue());
143         }
144     }
145 
146     @Test
147     public void testNewFormatContent() {
148         setRoot("new-bulletinB");
149         IERSConventions.NutationCorrectionConverter converter =
150                 IERSConventions.IERS_2010.getNutationCorrectionConverter();
151         SortedSet<EOPEntry> data = new TreeSet<EOPEntry>(new ChronologicalComparator());
152         new BulletinBFilesLoader("^bulletinb\\.270$", manager, () -> utc).fillHistory(converter, data);
153         EOPHistory history = new EOPHistory(IERSConventions.IERS_2010, EOPHistory.DEFAULT_INTERPOLATION_DEGREE,
154                                             data, true);
155         AbsoluteDate date = new AbsoluteDate(2010, 6, 12, 12, 0, 0, TimeScalesFactory.getUTC());
156         Assertions.assertEquals(msToS((   -3 *   0.1202 + 27 *   0.0294 + 27 *   0.0682 - 3 *   0.1531) / 48), history.getLOD(date), 1.0e-10);
157         Assertions.assertEquals(msToS((   -3 * -57.1711 + 27 * -57.2523 + 27 * -57.3103 - 3 * -57.4101) / 48), history.getUT1MinusUTC(date), 1.0e-10);
158         Assertions.assertEquals(masToRad((-3 *  -1.216  + 27 *   1.658  + 27 *   4.926  - 3 *   7.789)  / 48), history.getPoleCorrection(date).getXp(), 1.0e-10);
159         Assertions.assertEquals(masToRad((-3 * 467.780  + 27 * 469.330  + 27 * 470.931  - 3 * 472.388)  / 48), history.getPoleCorrection(date).getYp(), 1.0e-10);
160         Assertions.assertEquals(masToRad((-3 *   0.097  + 27 *   0.089  + 27 *   0.050  - 3 *  -0.007)  / 48), history.getNonRotatinOriginNutationCorrection(date)[0],  1.0e-10);
161         Assertions.assertEquals(masToRad((-3 *   0.071  + 27 *   0.066  + 27 *   0.090  - 3 *   0.111)  / 48), history.getNonRotatinOriginNutationCorrection(date)[1],  1.0e-10);
162     }
163 
164     @Test
165     public void testNewFormatRemovedFirstDates() {
166         setRoot("new-bulletinB");
167         IERSConventions.NutationCorrectionConverter converter =
168                 IERSConventions.IERS_2010.getNutationCorrectionConverter();
169         SortedSet<EOPEntry> data = new TreeSet<EOPEntry>(new ChronologicalComparator());
170         new BulletinBFilesLoader("^bulletinb-edited\\.270$", manager, () -> utc).fillHistory(converter, data);
171         EOPHistory history = new EOPHistory(IERSConventions.IERS_2010, EOPHistory.DEFAULT_INTERPOLATION_DEGREE,
172                                             data, true);
173         Assertions.assertEquals(new AbsoluteDate(2010,  6, 11, TimeScalesFactory.getUTC()),
174                             history.getStartDate());
175     }
176 
177     private double msToS(double ms) {
178         return ms / 1000.0;
179     }
180 
181     private double asToRad(double mas) {
182         return mas * Constants.ARC_SECONDS_TO_RADIANS;
183     }
184 
185     private double masToRad(double mas) {
186         return mas * Constants.ARC_SECONDS_TO_RADIANS / 1000.0;
187     }
188 
189     @Test
190     public void testNewFormatTruncated() {
191         Assertions.assertThrows(OrekitException.class, () -> {
192             setRoot("new-bulletinB");
193             IERSConventions.NutationCorrectionConverter converter =
194                     IERSConventions.IERS_2010.getNutationCorrectionConverter();
195             SortedSet<EOPEntry> history = new TreeSet<EOPEntry>(new ChronologicalComparator());
196             new BulletinBFilesLoader("^bulletinb-truncated\\.270$", manager, () -> utc).fillHistory(converter, history);
197         });
198      }
199 
200     @Test
201     public void testNewFormatTruncatedEarly() {
202         Assertions.assertThrows(OrekitException.class, () -> {
203             setRoot("new-bulletinB");
204             IERSConventions.NutationCorrectionConverter converter =
205                     IERSConventions.IERS_2010.getNutationCorrectionConverter();
206             SortedSet<EOPEntry> history = new TreeSet<EOPEntry>(new ChronologicalComparator());
207             new BulletinBFilesLoader("^bulletinb-truncated-early\\.270$", manager, () -> utc).fillHistory(converter, history);
208         });
209    }
210 
211     @Test
212     public void testNewFormatInconsistent() {
213         Assertions.assertThrows(OrekitException.class, () -> {
214             setRoot("new-bulletinB");
215             IERSConventions.NutationCorrectionConverter converter =
216                     IERSConventions.IERS_2010.getNutationCorrectionConverter();
217             SortedSet<EOPEntry> history = new TreeSet<EOPEntry>(new ChronologicalComparator());
218             new BulletinBFilesLoader("^bulletinb-inconsistent\\.270$", manager, () -> utc).fillHistory(converter, history);
219         });
220     }
221 
222     @Test
223     public void testNewFormatInconsistentDate() {
224         setRoot("new-bulletinB");
225         IERSConventions.NutationCorrectionConverter converter =
226                 IERSConventions.IERS_2010.getNutationCorrectionConverter();
227        SortedSet<EOPEntry> history = new TreeSet<EOPEntry>(new ChronologicalComparator());
228        try {
229            new BulletinBFilesLoader("bulletinb-inconsistent-date.270", manager, () -> utc).fillHistory(converter, history);
230            Assertions.fail("an exception should have been thrown");
231        } catch (OrekitException oe) {
232            Assertions.assertEquals(OrekitMessages.INCONSISTENT_DATES_IN_IERS_FILE, oe.getSpecifier());
233        }
234     }
235 
236 }