1   /* Contributed in the public domain.
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.utils;
18  
19  import org.hipparchus.Field;
20  import org.hipparchus.util.Binary64;
21  import org.hipparchus.util.Binary64Field;
22  import org.junit.jupiter.api.Assertions;
23  import org.junit.jupiter.api.BeforeAll;
24  import org.junit.jupiter.api.BeforeEach;
25  import org.junit.jupiter.api.Test;
26  import org.orekit.Utils;
27  import org.orekit.errors.OrekitException;
28  import org.orekit.errors.OrekitMessages;
29  import org.orekit.errors.TimeStampedCacheException;
30  import org.orekit.time.FieldAbsoluteDate;
31  
32  import java.util.Arrays;
33  import java.util.Collections;
34  import java.util.List;
35  
36  /**
37   * Unit tests for {@link FieldSortedListTrimmer}.
38   *
39   * @author Evan Ward
40   */
41  public class FieldSortedListTrimmerTest {
42  
43      /**
44       * Binary64 field.
45       */
46      private static final Field<Binary64> field = Binary64Field.getInstance();
47  
48      /**
49       * arbitrary date
50       */
51      private static final FieldAbsoluteDate<Binary64> date = FieldAbsoluteDate.getCCSDSEpoch(field);
52  
53      /**
54       * data provided to {@link #trimmer}
55       */
56      private List<FieldAbsoluteDate<Binary64>> data;
57  
58      /**
59       * subject under test
60       */
61      private FieldSortedListTrimmer trimmer;
62  
63      /**
64       * set Orekit data for useful debugging messages from dates.
65       */
66      @BeforeAll
67      public static void setUpBefore() {
68          Utils.setDataRoot("regular-data");
69      }
70  
71      /**
72       * create {@link #trimmer} and {@link #data} with neighborsSize = 3
73       */
74      @BeforeEach
75      public void setUp() {
76          data  = Arrays.asList(date, date.shiftedBy(1), date.shiftedBy(2),
77                                date.shiftedBy(3), date.shiftedBy(4),
78                                date.shiftedBy(5));
79          trimmer = new FieldSortedListTrimmer(3);
80      }
81  
82      /**
83       * check {@link FieldSortedListTrimmer#getNeighborsSubList(FieldAbsoluteDate, List)}
84       */
85      @Test
86      public void testGetNeighborsSubList() {
87          // exception for neighborsSize > data.size()
88          try {
89              new FieldSortedListTrimmer(data.size() + 1).getNeighborsSubList(date, data);
90              Assertions.fail("Expected Exception");
91          } catch (OrekitException e) {
92              Assertions.assertEquals(OrekitMessages.NOT_ENOUGH_DATA, e.getSpecifier());
93          }
94  
95          // exception for non-positive neighborsSize
96          try {
97              new FieldSortedListTrimmer(0);
98              Assertions.fail("Expected Exception");
99          } catch (IllegalArgumentException e) {
100             // expected
101         }
102 
103         // exception for null data
104         try {
105             new FieldSortedListTrimmer(1).getNeighborsSubList(date, null);
106             Assertions.fail("Expected Exception");
107         } catch (NullPointerException e) {
108             // expected
109         }
110 
111         // exception for zero data
112         try {
113             new FieldSortedListTrimmer(1).getNeighborsSubList(date, Collections.emptyList());
114             Assertions.fail("Expected Exception");
115         } catch (OrekitException e) {
116             Assertions.assertEquals(OrekitMessages.NOT_ENOUGH_DATA, e.getSpecifier());
117         }
118     }
119 
120     /**
121      * check {@link FieldSortedListTrimmer#getNeighborsSubList(FieldAbsoluteDate, List)}
122      * at a series of different dates designed to test all logic paths.
123      */
124     @Test
125     public void testgetNeighborsSubList() {
126         // setup
127         int size = data.size();
128 
129         // actions + verify
130 
131         // before fist data
132         try {
133             trimmer.getNeighborsSubList(data.get(0).shiftedBy(-1), data);
134             Assertions.fail("Expected Exception");
135         }
136         catch (TimeStampedCacheException e) {
137             // expected
138             Assertions.assertEquals(OrekitMessages.UNABLE_TO_GENERATE_NEW_DATA_BEFORE, e.getSpecifier());
139         }
140 
141         // on fist date
142         Assertions.assertArrayEquals(trimmer.getNeighborsSubList(data.get(0), data).toArray(),
143                                      data.subList(0, 3).toArray());
144         // between fist and second date
145         Assertions.assertArrayEquals(trimmer.getNeighborsSubList(data.get(0).shiftedBy(0.5), data).toArray(),
146                                      data.subList(0, 3).toArray());
147         // in the middle on a date
148         Assertions.assertArrayEquals(trimmer.getNeighborsSubList(data.get(2), data).toArray(),
149                                      data.subList(1, 4).toArray());
150         // in the middle between dates
151         Assertions.assertArrayEquals(trimmer.getNeighborsSubList(data.get(2).shiftedBy(0.5), data).toArray(),
152                                      data.subList(1, 4).toArray());
153         // just before last date
154         Assertions.assertArrayEquals(trimmer.getNeighborsSubList(data.get(size - 1).shiftedBy(-0.5), data).toArray(),
155                                      data.subList(size - 3, size).toArray());
156         // on last date
157         Assertions.assertArrayEquals(trimmer.getNeighborsSubList(data.get(size - 1), data).toArray(),
158                                      data.subList(size - 3, size).toArray());
159 
160         // after last date
161         FieldAbsoluteDate<Binary64> central = data.get(size - 1).shiftedBy(1);
162         try {
163             trimmer.getNeighborsSubList(central, data);
164             Assertions.fail("Expected Exception");
165         }
166         catch (TimeStampedCacheException e) {
167             // expected
168             Assertions.assertEquals(OrekitMessages.UNABLE_TO_GENERATE_NEW_DATA_AFTER, e.getSpecifier());
169         }
170     }
171 
172     /**
173      * check {@link FieldSortedListTrimmer#getNeighborsSize()}
174      */
175     @Test
176     public void testGetNeighborsSize() {
177         Assertions.assertEquals(trimmer.getNeighborsSize(), 3);
178     }
179 
180     @Test
181     public void testNonLinear() {
182         final List<FieldAbsoluteDate<Binary64>> nonLinearCache = Arrays.asList(date.shiftedBy(10),
183                                                                                date.shiftedBy(14),
184                                                                                date.shiftedBy(18),
185                                                                                date.shiftedBy(23),
186                                                                                date.shiftedBy(30),
187                                                                                date.shiftedBy(36),
188                                                                                date.shiftedBy(45),
189                                                                                date.shiftedBy(55),
190                                                                                date.shiftedBy(67),
191                                                                                date.shiftedBy(90),
192                                                                                date.shiftedBy(118));
193         for (double dt = 10; dt < 118; dt += 0.01) {
194             checkNeighbors(new FieldSortedListTrimmer(2), nonLinearCache, dt);
195         }
196     }
197 
198     private void checkNeighbors(final FieldSortedListTrimmer nonLinearTrimmer,
199                                 final List<FieldAbsoluteDate<Binary64>> nonLinearCache,
200                                 final double offset) {
201         List<FieldAbsoluteDate<Binary64>> s = nonLinearTrimmer.getNeighborsSubList(date.shiftedBy(offset), nonLinearCache);
202         Assertions.assertEquals(2, s.size());
203         Assertions.assertTrue(s.get(0).durationFrom(date).getReal() <= offset);
204         Assertions.assertTrue(s.get(1).durationFrom(date).getReal() >  offset);
205     }
206     
207 }