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.utils;
18  
19  import org.junit.jupiter.api.Assertions;
20  import org.junit.jupiter.api.Test;
21  
22  import java.util.concurrent.atomic.AtomicBoolean;
23  
24  import org.orekit.time.AbsoluteDate;
25  
26  public class ParameterDriversListTest {
27  
28      @Test
29      public void testDownwardAndUpwardSettings() {
30  
31          // this test used to generate an infinite recursion ending with StackOverFlowError
32          ParameterDriver p1A = new ParameterDriver("p1", 0.0, 1.0, -1.0, +1.0);
33          ParameterDriver p1B = new ParameterDriver("p1", 0.0, 1.0, -1.0, +1.0);
34          ParameterDriver p2A = new ParameterDriver("p2", 0.0, 1.0, -1.0, +1.0);
35          ParameterDriver p2B = new ParameterDriver("p2", 0.0, 1.0, -1.0, +1.0);
36  
37          ParameterDriversList list1 = new ParameterDriversList();
38          list1.add(p1A);
39          list1.add(p1B);
40          list1.add(p2A);
41          list1.add(p2B);
42          ParameterDriversList list2 = new ParameterDriversList();
43          list2.add(p1A);
44          list2.add(p1B);
45          list2.add(p2A);
46          list2.add(p2B);
47  
48          ParameterDriversList.DelegatingDriver delegating11 = list1.findByName("p1");
49          ParameterDriversList.DelegatingDriver delegating21 = list1.findByName("p2");
50          ParameterDriversList.DelegatingDriver delegating12 = list2.findByName("p1");
51          ParameterDriversList.DelegatingDriver delegating22 = list2.findByName("p2");
52  
53          // Value: downward settings, from top delegating driver to raw drivers and back to other list top
54          delegating11.setValue(0.5);
55          Assertions.assertEquals(0.5, p1A.getValue(),          1.0e-15);
56          Assertions.assertEquals(0.5, p1B.getValue(),          1.0e-15);
57          Assertions.assertEquals(0.5, delegating12.getValue(), 1.0e-15);
58  
59          // Value: upward settings, starting from raw drivers
60          p2A.setValue(-0.5);
61          Assertions.assertEquals(-0.5, p2B.getValue(),          1.0e-15);
62          Assertions.assertEquals(-0.5, delegating21.getValue(), 1.0e-15);
63          Assertions.assertEquals(-0.5, delegating22.getValue(), 1.0e-15);
64  
65          // Name: downward settings, from top delegating driver to raw drivers and back to other list top
66          delegating11.setName("q1");
67          Assertions.assertEquals("q1", p1A.getName());
68          Assertions.assertEquals("q1", p1B.getName());
69          Assertions.assertEquals("q1", delegating12.getName());
70  
71          // Name: upward settings, starting from raw drivers
72          p2A.setName("q2");
73          Assertions.assertEquals("q2", p2B.getName());
74          Assertions.assertEquals("q2", delegating21.getName());
75          Assertions.assertEquals("q2", delegating22.getName());
76  
77          // Reference value: downward settings, from top delegating driver to raw drivers and back to other list top
78          delegating11.setReferenceValue(0.5);
79          Assertions.assertEquals(0.5, p1A.getReferenceValue(),          1.0e-15);
80          Assertions.assertEquals(0.5, p1B.getReferenceValue(),          1.0e-15);
81          Assertions.assertEquals(0.5, delegating12.getReferenceValue(), 1.0e-15);
82  
83          // Reference value: upward settings, starting from raw drivers
84          p2A.setReferenceValue(-0.5);
85          Assertions.assertEquals(-0.5, p2B.getReferenceValue(),          1.0e-15);
86          Assertions.assertEquals(-0.5, delegating21.getReferenceValue(), 1.0e-15);
87          Assertions.assertEquals(-0.5, delegating22.getReferenceValue(), 1.0e-15);
88  
89          // Scale: downward settings, from top delegating driver to raw drivers and back to other list top
90          delegating11.setScale(2.);
91          Assertions.assertEquals(2., p1A.getScale(),          1.0e-15);
92          Assertions.assertEquals(2., p1B.getScale(),          1.0e-15);
93          Assertions.assertEquals(2., delegating12.getScale(), 1.0e-15);
94  
95          // Scale: upward settings, starting from raw drivers
96          p2A.setScale(3.);
97          Assertions.assertEquals(3., p2B.getScale(),          1.0e-15);
98          Assertions.assertEquals(3., delegating21.getScale(), 1.0e-15);
99          Assertions.assertEquals(3., delegating22.getScale(), 1.0e-15);
100 
101         // Min value: downward settings, from top delegating driver to raw drivers and back to other list top
102         delegating11.setMinValue(-2.);
103         Assertions.assertEquals(-2., p1A.getMinValue(),          1.0e-15);
104         Assertions.assertEquals(-2., p1B.getMinValue(),          1.0e-15);
105         Assertions.assertEquals(-2., delegating12.getMinValue(), 1.0e-15);
106 
107         // Min value: upward settings, starting from raw drivers
108         p2A.setMinValue(-0.25);
109         Assertions.assertEquals(-0.25, p2B.getMinValue(),          1.0e-15);
110         Assertions.assertEquals(-0.25, delegating21.getMinValue(), 1.0e-15);
111         Assertions.assertEquals(-0.25, delegating22.getMinValue(), 1.0e-15);
112         // Check that value is set to min as it was out of boundaries
113         Assertions.assertEquals(-0.25, p2B.getValue(),          1.0e-15);
114         Assertions.assertEquals(-0.25, delegating21.getValue(), 1.0e-15);
115         Assertions.assertEquals(-0.25, delegating22.getValue(), 1.0e-15);
116 
117         // Max value: downward settings, from top delegating driver to raw drivers and back to other list top
118         delegating11.setMaxValue(0.25);
119         Assertions.assertEquals(0.25, p1A.getMaxValue(),          1.0e-15);
120         Assertions.assertEquals(0.25, p1B.getMaxValue(),          1.0e-15);
121         Assertions.assertEquals(0.25, delegating12.getMaxValue(), 1.0e-15);
122         // Check that value is set to max as it was out of boundaries
123         Assertions.assertEquals(0.25, p1A.getValue(),          1.0e-15);
124         Assertions.assertEquals(0.25, p1B.getValue(),          1.0e-15);
125         Assertions.assertEquals(0.25, delegating12.getValue(), 1.0e-15);
126 
127         // Max value: upward settings, starting from raw drivers
128         p2A.setMaxValue(2.);
129         Assertions.assertEquals(2., p2B.getMaxValue(),          1.0e-15);
130         Assertions.assertEquals(2., delegating21.getMaxValue(), 1.0e-15);
131         Assertions.assertEquals(2., delegating22.getMaxValue(), 1.0e-15);
132     }
133 
134     @Test
135     public void testEmbeddedList() {
136         ParameterDriver pA1 = new ParameterDriver("p", 0.0, 1.0, -1.0, +1.0);
137         ParameterDriver pA2 = new ParameterDriver("p", 0.0, 1.0, -1.0, +1.0);
138         ParameterDriver pA3 = new ParameterDriver("p", 0.0, 1.0, -1.0, +1.0);
139         ParameterDriver pB1 = new ParameterDriver("p", 0.0, 1.0, -1.0, +1.0);
140         ParameterDriver pB2 = new ParameterDriver("p", 0.0, 1.0, -1.0, +1.0);
141         ParameterDriversList listA = new ParameterDriversList();
142         listA.add(pA1);
143         pA1.setSelected(true);
144         listA.add(pA2);
145         listA.add(pA3);
146         ParameterDriversList listB = new ParameterDriversList();
147         listB.add(pB1);
148         listB.add(pB2);
149 
150         listA.add(listB.getDrivers().get(0));
151 
152         pA1.setValue(0.5);
153         for (ParameterDriver pd : new ParameterDriver[] { pA1, pA2, pA3, pB1, pB2 }) {
154             Assertions.assertEquals(0.5, pd.getValue(), 1.0e-15);
155             Assertions.assertTrue(pd.isSelected());
156         }
157 
158         pB2.setValue(-0.5);
159         for (ParameterDriver pd : new ParameterDriver[] { pA1, pA2, pA3, pB1, pB2 }) {
160             Assertions.assertEquals(-0.5, pd.getValue(), 1.0e-15);
161         }
162 
163         for (final ParameterDriversList list : new ParameterDriversList[] { listA, listB }) {
164             Assertions.assertEquals(1, list.getNbParams());
165             Assertions.assertEquals(5, list.getDrivers().get(0).getRawDrivers().size());
166             Assertions.assertSame(pA1, list.getDrivers().get(0).getRawDrivers().get(0));
167             Assertions.assertSame(pA2, list.getDrivers().get(0).getRawDrivers().get(1));
168             Assertions.assertSame(pA3, list.getDrivers().get(0).getRawDrivers().get(2));
169             Assertions.assertSame(pB1, list.getDrivers().get(0).getRawDrivers().get(3));
170             Assertions.assertSame(pB2, list.getDrivers().get(0).getRawDrivers().get(4));
171         }
172 
173         // this should be a no-op
174         listB.add(listA.getDrivers().get(0));
175 
176         for (final ParameterDriversList list : new ParameterDriversList[] { listA, listB }) {
177             Assertions.assertEquals(1, list.getNbParams());
178             Assertions.assertEquals(5, list.getDrivers().get(0).getRawDrivers().size());
179             Assertions.assertSame(pA1, list.getDrivers().get(0).getRawDrivers().get(0));
180             Assertions.assertSame(pA2, list.getDrivers().get(0).getRawDrivers().get(1));
181             Assertions.assertSame(pA3, list.getDrivers().get(0).getRawDrivers().get(2));
182             Assertions.assertSame(pB1, list.getDrivers().get(0).getRawDrivers().get(3));
183             Assertions.assertSame(pB2, list.getDrivers().get(0).getRawDrivers().get(4));
184         }
185 
186         listB.findByName("p").setValue(0.0);
187         for (ParameterDriver pd : new ParameterDriver[] { pA1, pA2, pA3, pB1, pB2 }) {
188             Assertions.assertEquals(0.0, pd.getValue(), 1.0e-15);
189         }
190 
191     }
192 
193     @Test
194     public void testMerge() {
195         ParameterDriver pA1 = new ParameterDriver("p", 0.0, 1.0, -1.0, +1.0);
196         ParameterDriver pA2 = new ParameterDriver("p", 0.0, 1.0, -1.0, +1.0);
197         ParameterDriver pA3 = new ParameterDriver("p", 0.0, 1.0, -1.0, +1.0);
198         ParameterDriver pB1 = new ParameterDriver("p", 0.0, 1.0, -1.0, +1.0);
199         ParameterDriver pB2 = new ParameterDriver("p", 0.0, 1.0, -1.0, +1.0);
200         ParameterDriver pC1 = new ParameterDriver("p", 0.0, 1.0, -1.0, +1.0);
201         ParameterDriver qA1 = new ParameterDriver("q", 0.0, 1.0, -1.0, +1.0);
202         ParameterDriver qA2 = new ParameterDriver("q", 0.0, 1.0, -1.0, +1.0);
203         ParameterDriver qB1 = new ParameterDriver("q", 0.0, 1.0, -1.0, +1.0);
204         final AtomicBoolean called = new AtomicBoolean(false);
205         qB1.addObserver(new ParameterObserver() {
206             /** {@inheritDoc} */
207             @Override
208             public void valueChanged(final double previousValue, final ParameterDriver driver, final AbsoluteDate date) {
209                 called.set(true);
210             }
211 
212             @Override
213             public void valueSpanMapChanged(final TimeSpanMap<Double> previousValueSpanMap, final ParameterDriver driver) {
214                 called.set(true);
215             }
216         });
217         ParameterDriversList listA = new ParameterDriversList();
218         listA.add(pA1);
219         listA.add(pA2);
220         listA.add(pA3);
221         listA.add(qA1);
222         listA.add(qA2);
223         ParameterDriversList listB = new ParameterDriversList();
224         listB.add(pB1);
225         for (int i = 0; i < 3; ++i) {
226             pB2.setSelected(true);
227             listB.add(pB2);
228         }
229         listB.add(qB1);
230 
231         ParameterDriversList.DelegatingDriver oldDelegating = listB.getDrivers().get(0);
232         listA.add(oldDelegating);
233         listA.add(qB1);
234         new ParameterDriversList().add(pC1);
235         listB.add(pC1);
236         listA.sort();
237 
238         pA1.setValue(0.5);
239         for (ParameterDriver pd : new ParameterDriver[] { pA1, pA2, pA3, pB1, pB2, pC1 }) {
240             Assertions.assertEquals(0.5, pd.getValue(), 1.0e-15);
241             Assertions.assertTrue(pd.isSelected());
242         }
243         qA2.setValue(0.25);
244         for (ParameterDriver pd : new ParameterDriver[] { qA1, qA2, qB1 }) {
245             Assertions.assertEquals(0.25, pd.getValue(), 1.0e-15);
246             Assertions.assertFalse(pd.isSelected());
247         }
248         Assertions.assertTrue(called.get());
249 
250         listB.filter(false);
251         Assertions.assertEquals(2, listA.getNbParams());
252         Assertions.assertEquals(6, listA.getDrivers().get(0).getRawDrivers().size());
253         Assertions.assertSame(pA1, listA.getDrivers().get(0).getRawDrivers().get(0));
254         Assertions.assertSame(pA2, listA.getDrivers().get(0).getRawDrivers().get(1));
255         Assertions.assertSame(pA3, listA.getDrivers().get(0).getRawDrivers().get(2));
256         Assertions.assertSame(pB1, listA.getDrivers().get(0).getRawDrivers().get(3));
257         Assertions.assertSame(pB2, listA.getDrivers().get(0).getRawDrivers().get(4));
258         Assertions.assertSame(pC1, listA.getDrivers().get(0).getRawDrivers().get(5));
259         Assertions.assertEquals(3, listA.getDrivers().get(1).getRawDrivers().size());
260         Assertions.assertSame(qA1, listA.getDrivers().get(1).getRawDrivers().get(0));
261         Assertions.assertSame(qA2, listA.getDrivers().get(1).getRawDrivers().get(1));
262         Assertions.assertSame(qB1, listA.getDrivers().get(1).getRawDrivers().get(2));
263         Assertions.assertEquals(1, listB.getNbParams());
264         Assertions.assertEquals(3, listB.getDrivers().get(0).getRawDrivers().size());
265         Assertions.assertSame(qA1, listB.getDrivers().get(0).getRawDrivers().get(0));
266         Assertions.assertSame(qA2, listB.getDrivers().get(0).getRawDrivers().get(1));
267         Assertions.assertSame(qB1, listB.getDrivers().get(0).getRawDrivers().get(2));
268 
269         Assertions.assertNotSame(oldDelegating, listB.getDrivers().get(0));
270         Assertions.assertEquals(6, oldDelegating.getRawDrivers().size());
271         Assertions.assertSame(pA1, oldDelegating.getRawDrivers().get(0));
272         Assertions.assertSame(pA2, oldDelegating.getRawDrivers().get(1));
273         Assertions.assertSame(pA3, oldDelegating.getRawDrivers().get(2));
274         Assertions.assertSame(pB1, oldDelegating.getRawDrivers().get(3));
275         Assertions.assertSame(pB2, oldDelegating.getRawDrivers().get(4));
276         Assertions.assertSame(pC1, listA.getDrivers().get(0).getRawDrivers().get(5));
277 
278     }
279 
280     @Test
281     public void testAddSameDriver() {
282         ParameterDriver p = new ParameterDriver("p", 0.0, 1.0, -1.0, +1.0);
283         ParameterDriver q = new ParameterDriver("q", 0.0, 1.0, -1.0, +1.0);
284         ParameterDriver r = new ParameterDriver("r", 0.0, 1.0, -1.0, +1.0);
285         ParameterDriversList list = new ParameterDriversList();
286 
287         // first add the drivers once each
288         list.add(p);
289         list.add(q);
290         list.add(r);
291         Assertions.assertEquals(3, list.getDrivers().size());
292         Assertions.assertEquals(1, list.getDrivers().get(0).getRawDrivers().size());
293         Assertions.assertSame(p, list.getDrivers().get(0).getRawDrivers().get(0));
294         Assertions.assertEquals(1, list.getDrivers().get(1).getRawDrivers().size());
295         Assertions.assertSame(q, list.getDrivers().get(1).getRawDrivers().get(0));
296         Assertions.assertEquals(1, list.getDrivers().get(2).getRawDrivers().size());
297         Assertions.assertSame(r, list.getDrivers().get(2).getRawDrivers().get(0));
298 
299         // then add the same ones several times more, this should be a no-op
300         list.add(p);
301         list.add(q);
302         list.add(r);
303         list.add(r);
304         list.add(r);
305         list.add(p);
306         list.add(q);
307         list.add(p);
308         list.add(r);
309         Assertions.assertEquals(3, list.getDrivers().size());
310         Assertions.assertEquals(1, list.getDrivers().get(0).getRawDrivers().size());
311         Assertions.assertSame(p, list.getDrivers().get(0).getRawDrivers().get(0));
312         Assertions.assertEquals(1, list.getDrivers().get(1).getRawDrivers().size());
313         Assertions.assertSame(q, list.getDrivers().get(1).getRawDrivers().get(0));
314         Assertions.assertEquals(1, list.getDrivers().get(2).getRawDrivers().size());
315         Assertions.assertSame(r, list.getDrivers().get(2).getRawDrivers().get(0));
316 
317         // then add a new driver for the second parameter
318         ParameterDriver newQ = new ParameterDriver("q", 0.0, 1.0, -1.0, +1.0);
319         list.add(newQ);
320         Assertions.assertEquals(3, list.getDrivers().size());
321         Assertions.assertEquals(1, list.getDrivers().get(0).getRawDrivers().size());
322         Assertions.assertSame(p, list.getDrivers().get(0).getRawDrivers().get(0));
323         Assertions.assertEquals(2, list.getDrivers().get(1).getRawDrivers().size());
324         Assertions.assertSame(q, list.getDrivers().get(1).getRawDrivers().get(0));
325         Assertions.assertSame(newQ, list.getDrivers().get(1).getRawDrivers().get(1));
326         Assertions.assertEquals(1, list.getDrivers().get(2).getRawDrivers().size());
327         Assertions.assertSame(r, list.getDrivers().get(2).getRawDrivers().get(0));
328 
329     }
330 
331 }