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.time;
18  
19  import org.hipparchus.random.RandomGenerator;
20  import org.hipparchus.random.Well19937a;
21  import org.hipparchus.util.Binary64;
22  import org.junit.jupiter.api.Assertions;
23  import org.junit.jupiter.api.BeforeEach;
24  import org.junit.jupiter.api.Test;
25  import org.orekit.Utils;
26  
27  
28  public class SatelliteClockScaleTest {
29  
30      private TimeScale          utc;
31      private DateTimeComponents dtc;
32      private AbsoluteDate       epoch;
33  
34      @Test
35      public void testZeroAtEpoch() {
36          final double    offset = 0.0;
37          final double    drift  = 0.001;
38          final TimeScale sclk   = new SatelliteClockScale("SCLK", epoch, utc, offset, drift);
39          Assertions.assertEquals("SCLK", sclk.toString());
40          Assertions.assertEquals(-25.0, sclk.offsetFromTAI(epoch).toDouble(), 1.0e-12);
41          Assertions.assertEquals(-24.0, sclk.offsetFromTAI(epoch.shiftedBy(1000)).toDouble(), 1.0e-12);
42      }
43  
44      @Test
45      public void testNonZeroAtEpoch() {
46          final double    offset = 325.0;
47          final double    drift  = 0.002;
48          final TimeScale sclk   = new SatelliteClockScale("SCLK", epoch, utc, offset, drift);
49          Assertions.assertEquals("SCLK", sclk.toString());
50          Assertions.assertEquals(300.0, sclk.offsetFromTAI(epoch).toDouble(), 1.0e-12);
51          Assertions.assertEquals(302.0, sclk.offsetFromTAI(epoch.shiftedBy(1000)).toDouble(), 1.0e-12);
52      }
53  
54      @Test
55      public void testField() {
56          final double    offset = 0.0;
57          final double    drift  = 0.001;
58          final TimeScale sclk   = new SatelliteClockScale("SCLK",epoch, utc,  offset, drift);
59          FieldAbsoluteDate<Binary64> date = new FieldAbsoluteDate<>(epoch, new Binary64(1000.0));
60          Assertions.assertEquals(-24.0, sclk.offsetFromTAI(date).getReal(), 1.0e-12);
61      }
62  
63      @Test
64      public void testParseEpoch() {
65          final double       offset = 325.0;
66          final double       drift  = 10.002;
67          final TimeScale    sclk   = new SatelliteClockScale("SCLK", epoch, utc, offset, drift);
68          final AbsoluteDate date   = new AbsoluteDate(dtc.getDate(),
69                                                 new TimeComponents(dtc.getTime().getSecondsInUTCDay() +
70                                                                    offset),
71                                                 sclk);
72          Assertions.assertEquals(0.0, date.durationFrom(epoch), 2.0e-12);
73      }
74  
75      @Test
76      public void testParse() {
77          final double       offset = 325.0;
78          final double       drift  = 10.002;
79          final TimeScale    sclk   = new SatelliteClockScale("SCLK", epoch, utc, offset, drift);
80          final double       shift  = 2343.426;
81          final AbsoluteDate date   = new AbsoluteDate(dtc.getDate(),
82                                                 new TimeComponents(dtc.getTime().getSecondsInUTCDay() +
83                                                                    offset + shift),
84                                                 sclk);
85          Assertions.assertEquals(shift / (1 + drift), date.durationFrom(epoch), 2.0e-12);
86      }
87  
88      @Test
89      public void testSymmetryDrift() {
90          final double       offset = 325.0;
91          final double       drift  = 10.002;
92          final TimeScale    sclk   = new SatelliteClockScale("SCLK", epoch, utc, offset, drift);
93          for (double dt = -1000; dt < 1000; dt += 0.01) {
94              AbsoluteDate ref     = epoch.shiftedBy(dt);
95              AbsoluteDate rebuilt = new AbsoluteDate(ref.getComponents(sclk), sclk);
96              Assertions.assertEquals(0.0, rebuilt.durationFrom(ref), 6.0e-12);
97          }
98      }
99  
100     @Test
101     public void testCountSymmetry() {
102         final double              offset = 325.0;
103         final double              drift  = 10.002;
104         final SatelliteClockScale sclk   = new SatelliteClockScale("SCLK", epoch, utc, offset, drift);
105         for (double count = -1000; count < 1000; count += 0.01) {
106             double rebuilt = sclk.countAtDate(sclk.dateAtCount(count));
107             Assertions.assertEquals(count, rebuilt, 2.0e-13);
108         }
109     }
110 
111     @Test
112     public void testCount() {
113         final double              offset = 325.0;
114         final double              drift  = 10.002;
115         final SatelliteClockScale sclk   = new SatelliteClockScale("SCLK", epoch, utc, offset, drift);
116         Assertions.assertEquals(0.0,    sclk.dateAtCount(offset).durationFrom(epoch), 1.0e-15);
117         Assertions.assertEquals(offset, sclk.countAtDate(epoch),                      1.0e-15);
118         RandomGenerator random = new Well19937a(0xc7607abceb6835bdL);
119         AbsoluteDate previous = epoch;
120         for (int i = 0; i < 100; ++i) {
121             AbsoluteDate current = epoch.shiftedBy((random.nextDouble() * 10000) - 5000);
122             double deltaT     = current.durationFrom(previous);
123             double deltaCount = sclk.countAtDate(current) - sclk.countAtDate(previous);
124             Assertions.assertEquals(drift, deltaCount / deltaT - 1.0, 2.0e-12);
125             previous = current;
126         }
127     }
128 
129     @BeforeEach
130     public void setUp() {
131         Utils.setDataRoot("regular-data");
132         utc   = TimeScalesFactory.getUTC();
133         dtc   = new DateTimeComponents(1990, 6, 23, 11, 30, 45.756);
134         epoch = new AbsoluteDate(dtc, utc);
135     }
136 
137 }