1   /* Copyright 2002-2018 CS Systèmes d'Information
2    * Licensed to CS Systèmes d'Information (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  
20  import java.io.ByteArrayInputStream;
21  import java.io.ByteArrayOutputStream;
22  import java.io.IOException;
23  import java.io.ObjectInputStream;
24  import java.io.ObjectOutputStream;
25  import java.util.ArrayList;
26  
27  import org.hipparchus.util.FastMath;
28  import org.junit.Assert;
29  import org.junit.Before;
30  import org.junit.Test;
31  import org.orekit.Utils;
32  import org.orekit.errors.OrekitException;
33  import org.orekit.time.AbsoluteDate;
34  import org.orekit.time.TimeScalesFactory;
35  import org.orekit.utils.AngularDerivativesFilter;
36  import org.orekit.utils.CartesianDerivativesFilter;
37  import org.orekit.utils.Constants;
38  import org.orekit.utils.IERSConventions;
39  import org.orekit.utils.OrekitConfiguration;
40  
41  public class CIRFProviderTest {
42  
43      @Test
44      public void testRotationRate() throws OrekitException {
45          EOPHistory eopHistory = FramesFactory.getEOPHistory(IERSConventions.IERS_2010, true);
46          TransformProvider provider =
47                  new InterpolatingTransformProvider(new CIRFProvider(eopHistory),
48                                                     CartesianDerivativesFilter.USE_PVA,
49                                                     AngularDerivativesFilter.USE_R,
50                                                     3, 1.0, 5, Constants.JULIAN_DAY, 100.0);
51          AbsoluteDate tMin = new AbsoluteDate(2009, 4, 7, 2, 56, 33.816, TimeScalesFactory.getUTC());
52          double minRate = provider.getTransform(tMin).getRotationRate().getNorm();
53          Assert.assertEquals(1.1e-15, minRate, 1.0e-16);
54          AbsoluteDate tMax = new AbsoluteDate(2043, 12, 16, 10, 47, 20, TimeScalesFactory.getUTC());
55          double maxRate = provider.getTransform(tMax).getRotationRate().getNorm();
56          Assert.assertEquals(8.6e-12, maxRate, 1.0e-13);
57      }
58  
59      @Test
60      public void testShiftingAccuracyWithEOP() throws OrekitException {
61  
62          // max shift error observed on a 2 months period with 60 seconds step
63          // the shifting step after the interpolation step induces that mainly the
64          // step size has an influence on the error. The number of points used in
65          // the lower level interpolation does affect the results but less than
66          // step size. Plotting the error curves show almost superposition of all
67          // curves with the same time step. The error curves exhibit smooth periodic
68          // pattern with a main period corresponding to the Moon period plus peaks
69          // corresponding to Runge phenomenon when EOP data changes at midnight.
70          //
71          // number of sample points    time between sample points    max error
72          //         6                         86400s / 12 = 2h00    9.56e-12 rad
73          //         6                         86400s / 18 = 1h20    6.20e-12 rad
74          //         6                         86400s / 24 = 1h00    4.60e-12 rad
75          //         6                         86400s / 48 = 0h30    2.25e-12 rad
76          //         8                         86400s / 12 = 2h00    8.21e-12 rad
77          //         8                         86400s / 18 = 1h20    5.32e-12 rad
78          //         8                         86400s / 24 = 1h00    3.94e-12 rad
79          //         8                         86400s / 48 = 0h30    1.93e-12 rad
80          //        12                         86400s / 12 = 2h00    7.09e-12 rad
81          //        12                         86400s / 18 = 1h20    4.61e-12 rad
82          //        12                         86400s / 24 = 1h00    3.42e-12 rad
83          //        12                         86400s / 48 = 0h30    1.68e-12 rad
84          EOPHistory eopHistory = FramesFactory.getEOPHistory(IERSConventions.IERS_2010, false);
85          TransformProvider nonShitfing = new CIRFProvider(eopHistory);
86          final TransformProvider shifting =
87                  new ShiftingTransformProvider(nonShitfing,
88                                                CartesianDerivativesFilter.USE_PVA,
89                                                AngularDerivativesFilter.USE_R,
90                                                6, Constants.JULIAN_DAY / 24,
91                                                OrekitConfiguration.getCacheSlotsNumber(),
92                                                Constants.JULIAN_YEAR, 30 * Constants.JULIAN_DAY);
93  
94          // the following time range is located around the maximal observed error
95          AbsoluteDate start = new AbsoluteDate(2002, 9, 12, TimeScalesFactory.getTAI());
96          AbsoluteDate end   = new AbsoluteDate(2002, 9, 14, TimeScalesFactory.getTAI());
97          double maxError = 0.0;
98          for (AbsoluteDate date = start; date.compareTo(end) < 0; date = date.shiftedBy(60)) {
99              final Transform transform =
100                     new Transform(date,
101                                   shifting.getTransform(date),
102                                   nonShitfing.getTransform(date).getInverse());
103             final double error = transform.getRotation().getAngle();
104             maxError = FastMath.max(maxError, error);
105         }
106         Assert.assertTrue(maxError < 4.6e-12);
107 
108     }
109 
110     @Test
111     public void testShiftingAccuracyWithoutEOP() throws OrekitException {
112 
113         // max shift error observed on a 2 months period with 60 seconds step
114         // the shifting step after the interpolation step induces that only the
115         // step size has an influence on the error. The number of points used in
116         // the lower level interpolation does not affect the results. Plotting
117         // the error curves show exact superposition of all curves with the same
118         // time step. The error curves exhibit smooth periodic pattern with a
119         // main period corresponding to the Moon period
120         //
121         // number of sample points    time between sample points    max error
122         //         6                         86400s / 12 = 2h00    9.99e-13 rad
123         //         6                         86400s / 18 = 1h20    2.96e-13 rad
124         //         6                         86400s / 24 = 1h00    1.25e-13 rad
125         //         6                         86400s / 48 = 0h30    1.56e-14 rad
126         //         8                         86400s / 12 = 2h00    9.99e-13 rad
127         //         8                         86400s / 18 = 1h20    2.96e-13 rad
128         //         8                         86400s / 24 = 1h00    1.25e-13 rad
129         //         8                         86400s / 48 = 0h30    1.56e-14 rad
130         //        12                         86400s / 12 = 2h00    9.99e-13 rad
131         //        12                         86400s / 18 = 1h20    2.96e-13 rad
132         //        12                         86400s / 24 = 1h00    1.25e-13 rad
133         //        12                         86400s / 48 = 0h30    1.56e-14 rad
134         EOPHistory eopHistory = new EOPHistory(IERSConventions.IERS_2010, new ArrayList<EOPEntry>(), true);
135         TransformProvider nonShifting = new CIRFProvider(eopHistory);
136         final TransformProvider shifting =
137                 new ShiftingTransformProvider(nonShifting,
138                                               CartesianDerivativesFilter.USE_PVA,
139                                               AngularDerivativesFilter.USE_R,
140                                               6, Constants.JULIAN_DAY / 24,
141                                               OrekitConfiguration.getCacheSlotsNumber(),
142                                               Constants.JULIAN_YEAR, 30 * Constants.JULIAN_DAY);
143 
144         // the following time range is located around the maximal observed error
145         AbsoluteDate start = new AbsoluteDate(2002, 9, 7, TimeScalesFactory.getTAI());
146         AbsoluteDate end   = new AbsoluteDate(2002, 9, 8, TimeScalesFactory.getTAI());
147         double maxError = 0.0;
148         for (AbsoluteDate date = start; date.compareTo(end) < 0; date = date.shiftedBy(60)) {
149             final Transform transform =
150                     new Transform(date,
151                                   shifting.getTransform(date),
152                                   nonShifting.getTransform(date).getInverse());
153             final double error = transform.getRotation().getAngle();
154             maxError = FastMath.max(maxError, error);
155         }
156         Assert.assertTrue(maxError < 1.3e-13);
157 
158     }
159 
160     @Test
161     public void testSerialization() throws OrekitException, IOException, ClassNotFoundException {
162         CIRFProvider provider = new CIRFProvider(FramesFactory.getEOPHistory(IERSConventions.IERS_2010, true));
163 
164         ByteArrayOutputStream bos = new ByteArrayOutputStream();
165         ObjectOutputStream    oos = new ObjectOutputStream(bos);
166         oos.writeObject(provider);
167 
168         Assert.assertTrue(bos.size() > 295000);
169         Assert.assertTrue(bos.size() < 300000);
170 
171         ByteArrayInputStream  bis = new ByteArrayInputStream(bos.toByteArray());
172         ObjectInputStream     ois = new ObjectInputStream(bis);
173         CIRFProvider deserialized  = (CIRFProvider) ois.readObject();
174         for (int i = 0; i < FastMath.min(100, provider.getEOPHistory().getEntries().size()); ++i) {
175             AbsoluteDate date = provider.getEOPHistory().getEntries().get(i).getDate();
176             Transform expectedIdentity = new Transform(date,
177                                                        provider.getTransform(date).getInverse(),
178                                                        deserialized.getTransform(date));
179             Assert.assertEquals(0.0, expectedIdentity.getTranslation().getNorm(), 1.0e-15);
180             Assert.assertEquals(0.0, expectedIdentity.getRotation().getAngle(),   1.0e-15);
181         }
182 
183     }
184 
185     @Before
186     public void setUp() {
187         Utils.setDataRoot("compressed-data");
188     }
189 
190 }