1   /* Copyright 2002-2022 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.estimation.measurements.gnss;
18  
19  import java.io.File;
20  import java.io.FileInputStream;
21  import java.io.IOException;
22  import java.net.URISyntaxException;
23  import java.util.Arrays;
24  import java.util.List;
25  
26  import org.junit.Assert;
27  import org.junit.Before;
28  import org.junit.Test;
29  import org.orekit.Utils;
30  import org.orekit.data.DataFilter;
31  import org.orekit.data.GzipFilter;
32  import org.orekit.data.DataSource;
33  import org.orekit.data.UnixCompressFilter;
34  import org.orekit.gnss.Frequency;
35  import org.orekit.gnss.HatanakaCompressFilter;
36  import org.orekit.gnss.ObservationDataSet;
37  import org.orekit.gnss.RinexObservationLoader;
38  import org.orekit.time.AbsoluteDate;
39  import org.orekit.time.TimeScalesFactory;
40  
41  public class GeometryFreeCycleSlipDetectorTest {
42      
43      @Before
44      public void setUp() {
45          Utils.setDataRoot("regular-data");
46      }
47      
48      @Test
49      public void testTheBasicData() throws URISyntaxException, IOException {
50          
51          final String inputPath = GeometryFreeCycleSlipDetectorTest.class.getClassLoader().getResource("gnss/cycleSlip/shld0440.16d.Z").toURI().getPath();
52          final File input  = new File(inputPath);
53          String fileName = "shld0440.16d.Z";
54          DataSource nd = new DataSource(fileName,
55                                       () -> new FileInputStream(new File(input.getParentFile(), fileName)));
56          for (final DataFilter filter : Arrays.asList(new GzipFilter(),
57                                                       new UnixCompressFilter(),
58                                                       new HatanakaCompressFilter())) {
59              nd = filter.filter(nd);
60          }
61          final RinexObservationLoader loader = new RinexObservationLoader(nd);
62          //RinexLoader  loader = loadCompressed("cycleSlip/shld0440.16d.Z");
63          final List<ObservationDataSet> obserDataSets = loader.getObservationDataSets();
64          GeometryFreeCycleSlipDetector slipDetectors =
65              new GeometryFreeCycleSlipDetector(31, 31.0, 10);
66          final List<CycleSlipDetectorResults> results = slipDetectors.detect(obserDataSets);
67          for(CycleSlipDetectorResults d: results) {
68              switch(getPrn(d)) {
69      
70                  case 1: 
71                      Assert.assertEquals(19.0, d.getEndDate(Frequency.G01).durationFrom(new AbsoluteDate(2016,  2, 13,  5,  0,  0.0000000, TimeScalesFactory.getTAI())),1e-9);
72                      Assert.assertEquals(19.0, d.getBeginDate(Frequency.G01).durationFrom(new AbsoluteDate(2016,2, 13  ,2  ,8 ,30.0000000, TimeScalesFactory.getTAI())),1e-9);
73                      break;
74                  case 5: 
75                      Assert.assertEquals(19.0, d.getEndDate(Frequency.G01).durationFrom(new AbsoluteDate(2016,  2, 13,  2, 48, 30.0000000, TimeScalesFactory.getTAI())),1e-9);
76                      Assert.assertEquals(19.0, d.getBeginDate(Frequency.G01).durationFrom(new AbsoluteDate(2016,2, 13  ,2  ,8 ,30.0000000, TimeScalesFactory.getTAI())),1e-9);
77                      break;
78                          
79                  case 6: 
80                      Assert.assertEquals(19.0, d.getEndDate(Frequency.G01).durationFrom(new AbsoluteDate(2016, 2, 13,  5,  0,  0.0000000, TimeScalesFactory.getTAI())),1e-9);
81                      Assert.assertEquals(19.0, d.getBeginDate(Frequency.G01).durationFrom(new AbsoluteDate(2016,  2, 13,  4, 15,  0.0000000, TimeScalesFactory.getTAI())),1e-9); 
82                      break;
83                 
84                  case 7: 
85                      Assert.assertEquals(19.0, d.getEndDate(Frequency.G01).durationFrom(new AbsoluteDate(2016,  2, 13,  4, 27,  30.0000000, TimeScalesFactory.getTAI())),1e-9);
86                      Assert.assertEquals(19.0, d.getBeginDate(Frequency.G01).durationFrom(new AbsoluteDate(2016,2, 13  ,2  ,8 ,30.0000000, TimeScalesFactory.getTAI())),1e-9);
87                      break;
88                          
89                  case 9: 
90                      Assert.assertEquals(19.0, d.getEndDate(Frequency.G01).durationFrom(new AbsoluteDate(2016, 2, 13,  2, 45,  30.0000000, TimeScalesFactory.getTAI())),1e-9);
91                      Assert.assertEquals(19.0, d.getBeginDate(Frequency.G01).durationFrom(new AbsoluteDate(2016,2, 13  ,2  ,8 ,30.0000000, TimeScalesFactory.getTAI())),1e-9);
92                      break;
93                              
94                  case 11:
95                      Assert.assertEquals(19.0, d.getEndDate(Frequency.G01).durationFrom(new AbsoluteDate(2016,  2, 13,  5,  0,  0.0000000, TimeScalesFactory.getTAI())),1e-9);
96                      Assert.assertEquals(19.0, d.getBeginDate(Frequency.G01).durationFrom(new AbsoluteDate(2016,2, 13  ,2  ,8 ,30.0000000, TimeScalesFactory.getTAI())),1e-9);
97                      break; 
98  
99                  default:   break;
100             }   
101         }
102     }
103     
104     @Test
105     public void testTimeCycleSlip() throws URISyntaxException, IOException {
106         final String inputPath = GeometryFreeCycleSlipDetectorTest.class.getClassLoader().getResource("gnss/cycleSlip/WithCycleSlip.16o").toURI().getPath();
107         final File input  = new File(inputPath);
108         String fileName = "WithCycleSlip.16o";
109         DataSource nd = new DataSource(fileName,
110                                      () -> new FileInputStream(new File(input.getParentFile(), fileName)));
111         for (final DataFilter filter : Arrays.asList(new GzipFilter(),
112                                                      new UnixCompressFilter(),
113                                                      new HatanakaCompressFilter())) {
114             nd = filter.filter(nd);
115         }
116         final RinexObservationLoader loader = new RinexObservationLoader(nd);
117         final List<ObservationDataSet>  obserDataSets = loader.getObservationDataSets();
118         //With dt = 31 s, cycle slip should not exist, a very huge threshold is used to not detect cycle-slip
119         GeometryFreeCycleSlipDetector slipDetectors =
120             new GeometryFreeCycleSlipDetector(31, 31.0, 10);    
121         final List<CycleSlipDetectorResults> results = slipDetectors.detect(obserDataSets);
122         for(CycleSlipDetectorResults d: results) {
123             Assert.assertFalse(d.getCycleSlipMap().get(Frequency.G01).isEmpty());
124         }
125         //With dt = 29 s, a cycle-slip should occur at each new measurement (97 times)
126         GeometryFreeCycleSlipDetector slipDetectors2 =
127                         new GeometryFreeCycleSlipDetector(29, 29.0, 10);
128         final List<CycleSlipDetectorResults> results2 = slipDetectors2.detect(obserDataSets);
129         for(CycleSlipDetectorResults d: results2) {
130             Assert.assertTrue(d.getCycleSlipMap().get(Frequency.G01).size() == 97);
131         }
132     }
133     
134     @Test
135     public void testCycleSlip() throws URISyntaxException, IOException {
136         final String inputPath = GeometryFreeCycleSlipDetectorTest.class.getClassLoader().getResource("gnss/cycleSlip/WithCycleSlip.16o").toURI().getPath();
137         final File input  = new File(inputPath);
138         String fileName = "WithCycleSlip.16o";
139         DataSource nd = new DataSource(fileName,
140                                      () -> new FileInputStream(new File(input.getParentFile(), fileName)));
141         for (final DataFilter filter : Arrays.asList(new GzipFilter(),
142                                                      new UnixCompressFilter(),
143                                                      new HatanakaCompressFilter())) {
144             nd = filter.filter(nd);
145         }
146         final RinexObservationLoader loader = new RinexObservationLoader(nd);
147         final List<ObservationDataSet> obserDataSets = loader.getObservationDataSets();
148         //With dt = 31 s, cycle slip for time gap cannot be detected (see previous test).
149         //We use T0 = 60s for threshold time constant as advice from Navipedia page.
150         GeometryFreeCycleSlipDetector slipDetectors =
151             new GeometryFreeCycleSlipDetector(31, 31.0, 9);
152         final List<CycleSlipDetectorResults> results = slipDetectors.detect(obserDataSets);
153         //According to excel graph, cycle-slip occur at 1 h 59m 43s
154         AbsoluteDate trueDate = new AbsoluteDate(2016, 02, 13, 1, 59, 43, TimeScalesFactory.getUTC());
155         final int size = results.get(0).getCycleSlipMap().get(Frequency.G01).size();
156         Assert.assertEquals(1, size);
157         final AbsoluteDate computedDate = results.get(0).getCycleSlipMap().get(Frequency.G01).get(0);
158         Assert.assertEquals(0.0, trueDate.durationFrom(computedDate),  1e-9);
159    }
160     
161     private int getPrn(final CycleSlipDetectorResults d) {
162         
163         if(d.getSatelliteName().substring(6).compareTo("1")==0) {return 1;};
164         if(d.getSatelliteName().substring(6).compareTo("2")==0) {return 2;};
165         if(d.getSatelliteName().substring(6).compareTo("3")==0) {return 3;};
166         if(d.getSatelliteName().substring(6).compareTo("4")==0) {return 4;};
167         if(d.getSatelliteName().substring(6).compareTo("5")==0) {return 5;};
168         if(d.getSatelliteName().substring(6).compareTo("6")==0) {return 6;};
169         if(d.getSatelliteName().substring(6).compareTo("7")==0) {return 7;};
170         if(d.getSatelliteName().substring(6).compareTo("8")==0) {return 8;};
171         if(d.getSatelliteName().substring(6).compareTo("9")==0) {return 9;};
172         if(d.getSatelliteName().substring(6).compareTo("10")==0) {return 10;};
173         if(d.getSatelliteName().substring(6).compareTo("11")==0) {return 11;};
174         if(d.getSatelliteName().substring(6).compareTo("12")==0) {return 12;};
175         if(d.getSatelliteName().substring(6).compareTo("13")==0) {return 13;};
176         if(d.getSatelliteName().substring(6).compareTo("14")==0) {return 14;};
177         if(d.getSatelliteName().substring(6).compareTo("15")==0) {return 15;};
178         if(d.getSatelliteName().substring(6).compareTo("16")==0) {return 16;};
179         if(d.getSatelliteName().substring(6).compareTo("17")==0) {return 17;};
180         if(d.getSatelliteName().substring(6).compareTo("18")==0) {return 18;};
181         if(d.getSatelliteName().substring(6).compareTo("19")==0) {return 19;};
182         if(d.getSatelliteName().substring(6).compareTo("20")==0) {return 20;};
183         if(d.getSatelliteName().substring(6).compareTo("21")==0) {return 21;};
184         if(d.getSatelliteName().substring(6).compareTo("22")==0) {return 22;};
185         if(d.getSatelliteName().substring(6).compareTo("23")==0) {return 23;};
186         if(d.getSatelliteName().substring(6).compareTo("24")==0) {return 24;};
187         if(d.getSatelliteName().substring(6).compareTo("25")==0) {return 25;};
188         if(d.getSatelliteName().substring(6).compareTo("26")==0) {return 26;};
189         if(d.getSatelliteName().substring(6).compareTo("27")==0) {return 27;};
190         if(d.getSatelliteName().substring(6).compareTo("28")==0) {return 28;};
191         if(d.getSatelliteName().substring(6).compareTo("29")==0) {return 29;};
192         if(d.getSatelliteName().substring(6).compareTo("30")==0) {return 30;};
193         if(d.getSatelliteName().substring(6).compareTo("31")==0) {return 31;} else {return 32;}
194               
195     }
196 
197 }