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.gnss.antenna;
18  
19  import java.net.URISyntaxException;
20  import java.net.URL;
21  
22  import org.hipparchus.geometry.euclidean.threed.Vector3D;
23  import org.hipparchus.util.FastMath;
24  import org.junit.jupiter.api.Assertions;
25  import org.junit.jupiter.api.BeforeEach;
26  import org.junit.jupiter.api.Test;
27  import org.orekit.Utils;
28  import org.orekit.data.DataSource;
29  import org.orekit.errors.OrekitException;
30  import org.orekit.errors.OrekitMessages;
31  import org.orekit.gnss.PredefinedGnssSignal;
32  import org.orekit.gnss.RadioWave;
33  import org.orekit.gnss.SatelliteSystem;
34  import org.orekit.time.AbsoluteDate;
35  import org.orekit.time.TimeScalesFactory;
36  import org.orekit.utils.TimeSpanMap;
37  
38  
39  public class AntexLoaderTest {
40  
41      @BeforeEach
42      public void setUp() {
43          // Sets the root of data to read
44          Utils.setDataRoot("gnss:antex");
45      }
46  
47      @Test
48      public void testSmallAntex14File() throws URISyntaxException {
49  
50          final URL url = AntexLoaderTest.class.getClassLoader().getResource("antex/igs14-small.atx");
51          AntexLoader  loader = new AntexLoader(new DataSource(url.toURI()),
52                                                TimeScalesFactory.getGPS());
53  
54          Assertions.assertEquals(16, loader.getSatellitesAntennas().size());
55  
56          checkSatellite(loader.getSatellitesAntennas().get( 0), 1992, 11, 22, 2008, 10, 16,
57                         SatelliteSystem.GPS,     "BLOCK IIA",   SatelliteType.BLOCK_IIA, 32, 1,
58                         "1992-079A", PredefinedGnssSignal.G01, 45.0, 7.0, 1.30);
59          checkSatellite(loader.getSatellitesAntennas().get( 0), 2008, 10, 23, 2009,  1,  6,
60                         SatelliteSystem.GPS,     "BLOCK IIA",   SatelliteType.BLOCK_IIA, 37, 1,
61                         "1993-032A", PredefinedGnssSignal.G02, 120.0, 4.0, -0.4);
62          checkSatellite(loader.getSatellitesAntennas().get( 0), 2009,  3, 24, 2011,  5,  6,
63                         SatelliteSystem.GPS,     "BLOCK IIR-M", SatelliteType.BLOCK_IIR_M, 49, 1,
64                         "2009-014A", PredefinedGnssSignal.G01, 57.0, 3.0, 4.60);
65          checkSatellite(loader.getSatellitesAntennas().get( 0), 2011,  6,  2, 2011,  7, 12,
66                         SatelliteSystem.GPS,     "BLOCK IIA",   SatelliteType.BLOCK_IIA, 35, 1,
67                         "1993-054A", PredefinedGnssSignal.G02, 25.0, 9.0, 1.20);
68          checkSatellite(loader.getSatellitesAntennas().get( 0), 2011,  7, 16, 9999, 12, 31,
69                         SatelliteSystem.GPS,     "BLOCK IIF",   SatelliteType.BLOCK_IIF, 63, 1,
70                         "2011-036A", PredefinedGnssSignal.G01, 17.0, 2.0, 2.80);
71  
72          checkSatellite(loader.getSatellitesAntennas().get( 1), 1989,  6, 10, 2004,  5,  12,
73                         SatelliteSystem.GPS,     "BLOCK II",    SatelliteType.BLOCK_II, 13, 2,
74                         "1989-044A", PredefinedGnssSignal.G02, 0.0, 0.0, -0.80);
75          checkSatellite(loader.getSatellitesAntennas().get( 1), 2004, 11,  6, 9999, 12, 31,
76                         SatelliteSystem.GPS,     "BLOCK IIR-B", SatelliteType.BLOCK_IIR_B, 61, 2,
77                         "2004-045A", PredefinedGnssSignal.G01, 270.0, 17.0, 40.60);
78  
79          checkSatellite(loader.getSatellitesAntennas().get( 2), 1985, 10,  9, 1994,  4,  17,
80                         SatelliteSystem.GPS,     "BLOCK I",     SatelliteType.BLOCK_I, 11, 3,
81                         "1985-093A", PredefinedGnssSignal.G02, 3.0, 3.0, -0.90);
82          checkSatellite(loader.getSatellitesAntennas().get( 2), 1996,  3, 28, 2014,  8,  18,
83                         SatelliteSystem.GPS,     "BLOCK IIA",   SatelliteType.BLOCK_IIA, 33, 3,
84                         "1996-019A", PredefinedGnssSignal.G01, 34.0, 6.0, 0.80);
85          checkSatellite(loader.getSatellitesAntennas().get( 2), 2014,  9,  5, 2014,  10, 20,
86                         SatelliteSystem.GPS,     "BLOCK IIA",   SatelliteType.BLOCK_IIA, 35, 3,
87                         "1993-054A", PredefinedGnssSignal.G02, 12.0, 10.0, 0.70);
88          checkSatellite(loader.getSatellitesAntennas().get( 2), 2014, 10, 29, 9999, 12, 31,
89                         SatelliteSystem.GPS,     "BLOCK IIF",   SatelliteType.BLOCK_IIF, 69, 3,
90                         "2014-068A", PredefinedGnssSignal.G01, 78.0, 0.5, 5.25);
91  
92          checkSatellite(loader.getSatellitesAntennas().get( 3), 1998, 12, 30, 2004, 12, 25,
93                         SatelliteSystem.GLONASS, "GLONASS",     SatelliteType.GLONASS, 779, 1,
94                         "1998-077A", PredefinedGnssSignal.R01, 33.0, 9.0, -1.60);
95          checkSatellite(loader.getSatellitesAntennas().get( 3), 2004, 12, 26, 2009, 12, 13,
96                         SatelliteSystem.GLONASS, "GLONASS",     SatelliteType.GLONASS, 796, 1,
97                         "2004-053A", PredefinedGnssSignal.R02, 114.0, 5.0, -0.20);
98          checkSatellite(loader.getSatellitesAntennas().get( 3), 2009, 12, 14, 9999, 12, 31,
99                         SatelliteSystem.GLONASS, "GLONASS-M",  SatelliteType.GLONASS_M, 730, 1,
100                        "2009-070A", PredefinedGnssSignal.R01, 46.0, 3.0, 0.8);
101 
102         checkSatellite(loader.getSatellitesAntennas().get( 4), 2003, 12, 10, 2008, 12, 24,
103                        SatelliteSystem.GLONASS, "GLONASS",     SatelliteType.GLONASS, 794, 2,
104                        "2003-056B", PredefinedGnssSignal.R02, 67.0, 7.0, -1.10);
105         checkSatellite(loader.getSatellitesAntennas().get( 4), 2008, 12, 25, 2013,  6, 30,
106                        SatelliteSystem.GLONASS, "GLONASS-M",   SatelliteType.GLONASS_M, 728, 2,
107                        "2008-067C", PredefinedGnssSignal.R01, 23.0, 6.0, -0.6);
108         checkSatellite(loader.getSatellitesAntennas().get( 4), 2013,  7,  1, 9999, 12, 31,
109                        SatelliteSystem.GLONASS, "GLONASS-M",   SatelliteType.GLONASS_M, 747, 2,
110                        "2013-019A", PredefinedGnssSignal.R02, 1.0, 14.0, 1.50);
111 
112         checkSatellite(loader.getSatellitesAntennas().get( 5), 1994, 11, 20, 2001, 11, 30,
113                        SatelliteSystem.GLONASS, "GLONASS",     SatelliteType.GLONASS, 763, 3,
114                        "1994-076A", PredefinedGnssSignal.R01, 6.0, 1.0, 1.50);
115         checkSatellite(loader.getSatellitesAntennas().get( 5), 2001, 12,  1, 2008, 12, 24,
116                        SatelliteSystem.GLONASS, "GLONASS",     SatelliteType.GLONASS, 789, 3,
117                        "2001-053B", PredefinedGnssSignal.R02, 54.0, 13.0, 0.0);
118         checkSatellite(loader.getSatellitesAntennas().get( 5), 2008, 12, 25, 2010,  9, 30,
119                        SatelliteSystem.GLONASS, "GLONASS-M",   SatelliteType.GLONASS_M, 727, 3,
120                        "2008-067A", PredefinedGnssSignal.R01, 98.0, 5.0, -0.20);
121         checkSatellite(loader.getSatellitesAntennas().get( 5), 2010, 10,  1, 2010, 12, 15,
122                        SatelliteSystem.GLONASS, "GLONASS-M",   SatelliteType.GLONASS_M, 722, 3,
123                        "2007-065B", PredefinedGnssSignal.R02, 112.0, 2.0, 1.10);
124         checkSatellite(loader.getSatellitesAntennas().get( 5), 2010, 12, 16, 2011,  3, 10,
125                        SatelliteSystem.GLONASS, "GLONASS-M",   SatelliteType.GLONASS_M, 727, 3,
126                        "2008-067A", PredefinedGnssSignal.R01, 134.0, 3.0, 0.8);
127         checkSatellite(loader.getSatellitesAntennas().get( 5), 2011,  3, 11, 2011, 10, 12,
128                        SatelliteSystem.GLONASS, "GLONASS-M",   SatelliteType.GLONASS_M, 715, 3,
129                        "2006-062C", PredefinedGnssSignal.R02, 12.0, 2.5, 0.95);
130         checkSatellite(loader.getSatellitesAntennas().get( 5), 2011, 10, 13, 2011, 11, 30,
131                        SatelliteSystem.GLONASS, "GLONASS-K1",  SatelliteType.GLONASS_K1, 801, 3,
132                        "2011-009A", PredefinedGnssSignal.R01, 345.0, 3.456, 0.0);
133         checkSatellite(loader.getSatellitesAntennas().get( 5), 2011, 12,  1, 9999, 12, 31,
134                        SatelliteSystem.GLONASS, "GLONASS-M",   SatelliteType.GLONASS_M, 744, 3,
135                        "2011-064A", PredefinedGnssSignal.R02, 360.0, 10.0 / 3.0, 0.60);
136 
137         checkSatellite(loader.getSatellitesAntennas().get( 6), 2016,  5, 24, 9999, 12, 31,
138                        SatelliteSystem.GALILEO, "GALILEO-2",   SatelliteType.GALILEO_2, 210, 1,
139                        "2016-030B", PredefinedGnssSignal.E01, 359.0, 4.2, 0.0);
140 
141         checkSatellite(loader.getSatellitesAntennas().get( 7), 2016,  5, 24, 9999, 12, 31,
142                        SatelliteSystem.GALILEO, "GALILEO-2",   SatelliteType.GALILEO_2, 211, 2,
143                        "2016-030A", PredefinedGnssSignal.E05, 23.0, 12.0, 0.0);
144 
145         checkSatellite(loader.getSatellitesAntennas().get( 8), 2011, 10, 21, 9999, 12, 31,
146                        SatelliteSystem.GALILEO, "GALILEO-1",   SatelliteType.GALILEO_1, 101, 11,
147                        "2011-060A", PredefinedGnssSignal.E06, 110.0, 22.0 / 3.0, 0.64);
148 
149         checkSatellite(loader.getSatellitesAntennas().get( 9), 2010,  1, 16, 9999, 12, 31,
150                        SatelliteSystem.BEIDOU, "BEIDOU-2G",    SatelliteType.BEIDOU_2G, 3, 1,
151                        "2010-001A", PredefinedGnssSignal.C01, 14.0, 7.0, 0.0);
152 
153         checkSatellite(loader.getSatellitesAntennas().get(10), 2010,  7, 31, 9999, 12, 31,
154                        SatelliteSystem.BEIDOU, "BEIDOU-2I",    SatelliteType.BEIDOU_2I, 5, 6,
155                        "2010-036A", PredefinedGnssSignal.C02, 245.0, 8.0, 0.0);
156 
157         checkSatellite(loader.getSatellitesAntennas().get(11), 2012,  4, 29, 9999, 12, 31,
158                        SatelliteSystem.BEIDOU, "BEIDOU-2M",    SatelliteType.BEIDOU_2M, 12, 11,
159                        "2012-018A", PredefinedGnssSignal.C06, 146.0, 3.2, 0.0);
160 
161         checkSatellite(loader.getSatellitesAntennas().get(12), 2010,  9, 11, 9999, 12, 31,
162                        SatelliteSystem.QZSS,    "QZSS",        SatelliteType.QZSS, 1, 193,
163                        "2010-045A", PredefinedGnssSignal.J01, 113.0, 6.0, 0.0);
164 
165         checkSatellite(loader.getSatellitesAntennas().get(13), 2013, 7, 1, 9999, 12, 31,
166                        SatelliteSystem.NAVIC, "IRNSS-1IGSO", SatelliteType.NAVIC_1IGSO, 1, 1,
167                        "2013-034A", PredefinedGnssSignal.I05, 34.0, 9.0, 0.0);
168 
169         checkSatellite(loader.getSatellitesAntennas().get(14), 2014, 10, 15, 9999, 12, 31,
170                        SatelliteSystem.NAVIC, "IRNSS-1GEO", SatelliteType.NAVIC_1GEO, 3, 3,
171                        "2014-061A", PredefinedGnssSignal.I09, 23.0, 10.0, 0.0);
172 
173         checkSatellite(loader.getSatellitesAntennas().get(15), 2015, 3, 28, 9999, 12, 31,
174                        SatelliteSystem.NAVIC, "IRNSS-1IGSO", SatelliteType.NAVIC_1IGSO, 4, 4,
175                        "2015-018A", PredefinedGnssSignal.I05, 321.0, 13.0, 0.0);
176 
177         Assertions.assertEquals( 3, loader.getReceiversAntennas().size());
178         Assertions.assertEquals("3S-02-TSADM     NONE",  loader.getReceiversAntennas().get(0).getType());
179         Assertions.assertEquals("",                      loader.getReceiversAntennas().get(0).getSerialNumber());
180         Assertions.assertEquals("3S-02-TSATE     NONE",  loader.getReceiversAntennas().get(1).getType());
181         Assertions.assertEquals("",                      loader.getReceiversAntennas().get(1).getSerialNumber());
182         Assertions.assertEquals("AERAT1675_120   SPKE",  loader.getReceiversAntennas().get(2).getType());
183         Assertions.assertEquals("",                      loader.getReceiversAntennas().get(2).getSerialNumber());
184         Assertions.assertEquals("IGS14_1972",            loader.getReceiversAntennas().get(2).getSinexCode());
185         Assertions.assertEquals(1, loader.getReceiversAntennas().get(2).getRadioWaves().size());
186         Assertions.assertTrue(loader.getReceiversAntennas().get(2).getRadioWaves().get(0).closeTo(PredefinedGnssSignal.G01));
187         try {
188             loader.getReceiversAntennas().get(2).getEccentricities(PredefinedGnssSignal.E06);
189             Assertions.fail("an exception should have been thrown");
190         } catch (OrekitException oe) {
191             Assertions.assertEquals(OrekitMessages.UNSUPPORTED_FREQUENCY_FOR_ANTENNA, oe.getSpecifier());
192             Assertions.assertSame(PredefinedGnssSignal.E06, oe.getParts()[0]);
193             Assertions.assertEquals("AERAT1675_120   SPKE", oe.getParts()[1]);
194         }
195         Assertions.assertEquals(-0.00001, loader.getReceiversAntennas().get(2).getEccentricities(PredefinedGnssSignal.G01).getX(), 1.0e-15);
196         Assertions.assertEquals(+0.00057, loader.getReceiversAntennas().get(2).getEccentricities(PredefinedGnssSignal.G01).getY(), 1.0e-15);
197         Assertions.assertEquals(+0.08051, loader.getReceiversAntennas().get(2).getEccentricities(PredefinedGnssSignal.G01).getZ(), 1.0e-15);
198         Assertions.assertEquals(-0.00249,
199                             loader.getReceiversAntennas().get(2).getPhaseCenterVariation(PredefinedGnssSignal.G01,
200                                                                                          new Vector3D(FastMath.toRadians(90.0 - 60.0),
201                                                                                                       FastMath.toRadians(55.0))),
202                             1.0e-15);
203 
204     }
205 
206     @Test
207     public void testSmallAntex20File() throws URISyntaxException {
208 
209         final URL url = AntexLoaderTest.class.getClassLoader().getResource("antex/igs20-small.atx");
210         AntexLoader  loader = new AntexLoader(new DataSource(url.toURI()),
211                                               TimeScalesFactory.getGPS());
212         Assertions.assertEquals(12, loader.getSatellitesAntennas().size());
213         Assertions.assertEquals(3,  loader.getReceiversAntennas().size());
214     }
215 
216     @Test
217     public void testWrongColumns() {
218         try {
219             new AntexLoader("^igs14-wrong-columns\\.atx$");
220             Assertions.fail("an exception should have been thrown");
221         } catch (OrekitException oe) {
222             Assertions.assertEquals(OrekitMessages.WRONG_COLUMNS_NUMBER, oe.getSpecifier());
223             Assertions.assertEquals(25, ((Integer) oe.getParts()[1]).intValue());
224             Assertions.assertEquals(17, ((Integer) oe.getParts()[2]).intValue());
225             Assertions.assertEquals(10, ((Integer) oe.getParts()[3]).intValue());
226         }
227     }
228 
229     @Test
230     public void testUnknownFrequency() {
231         try {
232             new AntexLoader("^igs14-unknown-rinex-frequency\\.atx$");
233             Assertions.fail("an exception should have been thrown");
234         } catch (OrekitException oe) {
235             Assertions.assertEquals(OrekitMessages.UNKNOWN_RINEX_FREQUENCY, oe.getSpecifier());
236             Assertions.assertEquals("U99", (String) oe.getParts()[0]);
237             Assertions.assertEquals(23, ((Integer) oe.getParts()[2]).intValue());
238         }
239     }
240 
241     @Test
242     public void testMismatchedFrequencies() {
243         try {
244             new AntexLoader("^igs14-mismatched-frequencies\\.atx$");
245             Assertions.fail("an exception should have been thrown");
246         } catch (OrekitException oe) {
247             Assertions.assertEquals(OrekitMessages.MISMATCHED_FREQUENCIES, oe.getSpecifier());
248             Assertions.assertEquals(88, ((Integer) oe.getParts()[1]).intValue());
249             Assertions.assertEquals("E01", "" + oe.getParts()[2]);
250             Assertions.assertEquals("E06", "" + oe.getParts()[3]);
251         }
252     }
253 
254     @Test
255     public void testWrongLabel() {
256         try {
257             new AntexLoader("^igs14-unknown-label\\.atx$");
258             Assertions.fail("an exception should have been thrown");
259         } catch (OrekitException oe) {
260             Assertions.assertEquals(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE, oe.getSpecifier());
261             Assertions.assertEquals(17, ((Integer) oe.getParts()[0]).intValue());
262             Assertions.assertEquals("THIS IS NOT AN ANTEX LABEL", ((String) oe.getParts()[2]).substring(60).trim());
263         }
264     }
265 
266     @Test
267     /**
268      * This test is related to issue-622.
269      */
270     public void testUnknownNumberFrequencies() {
271         try {
272             new AntexLoader("^igs14-unknown-nb-frequencies\\.atx$");
273             Assertions.fail("an exception should have been thrown");
274         } catch (OrekitException oe) {
275             Assertions.assertEquals(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE, oe.getSpecifier());
276             Assertions.assertEquals(21, ((Integer) oe.getParts()[0]).intValue());
277             Assertions.assertEquals("END OF FREQUENCY", ((String) oe.getParts()[2]).substring(60).trim());
278         }
279     }
280 
281     @Test
282     public void testCorruptedFile() {
283         try {
284             new AntexLoader("^igs14-corrupted\\.atx$");
285             Assertions.fail("an exception should have been thrown");
286         } catch (OrekitException oe) {
287             Assertions.assertEquals(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE, oe.getSpecifier());
288             Assertions.assertEquals(21, ((Integer) oe.getParts()[0]).intValue());
289         }
290     }
291 
292     private void checkSatellite(final TimeSpanMap<SatelliteAntenna> tsm,
293                                 final int startYear, final int startMonth, final int startDay,
294                                 final int endYear, final int endMonth, final int endDay,
295                                 final SatelliteSystem system, final String type,
296                                 final SatelliteType satType, final int satCode, final int prnNumber,
297                                 final String cosparId, final RadioWave radioWave,
298                                 final double antexAz, final double pol,
299                                 final double phaseCenterVariation) {
300         final double oneMilliSecond = 0.001;
301         final AbsoluteDate startDate = new AbsoluteDate(startYear, startMonth, startDay,
302                                                         TimeScalesFactory.getGPS());
303         final AbsoluteDate endDate   = endYear > 9000 ?
304                                        AbsoluteDate.FUTURE_INFINITY :
305                                        new AbsoluteDate(endYear, endMonth, endDay,
306                                                         23, 59, 59.9999999,
307                                                         TimeScalesFactory.getGPS());
308         final SatelliteAntenna antenna = tsm.get(startDate.shiftedBy(oneMilliSecond));
309         Assertions.assertEquals(system,         antenna.getSatInSystem().getSystem());
310         Assertions.assertEquals(type,           antenna.getType());
311         Assertions.assertEquals(satType,        antenna.getSatelliteType());
312         Assertions.assertEquals(satCode,        antenna.getSatelliteCode());
313         Assertions.assertEquals(prnNumber,      antenna.getSatInSystem().getPRN());
314         Assertions.assertEquals(cosparId,       antenna.getCosparID());
315         Assertions.assertEquals(0.0,            startDate.durationFrom(antenna.getValidFrom()), 1.0e-10);
316         if (endDate == AbsoluteDate.FUTURE_INFINITY) {
317             Assertions.assertSame(endDate, antenna.getValidUntil());
318         } else {
319             Assertions.assertEquals(0.0,            endDate.durationFrom(antenna.getValidUntil()), 1.0e-10);
320         }
321         Assertions.assertEquals(phaseCenterVariation * 0.001,
322                             antenna.getPhaseCenterVariation(radioWave,
323                                                             new Vector3D(FastMath.toRadians(90 - antexAz),
324                                                                          FastMath.toRadians(90 - pol))),
325                             1.0e-10);
326     }
327 
328 }