1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.rugged.adjustment;
18
19 import java.lang.reflect.Field;
20 import java.util.ArrayList;
21 import java.util.Collection;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Map.Entry;
26 import java.util.Set;
27
28 import org.hipparchus.optim.nonlinear.vector.leastsquares.LeastSquaresOptimizer.Optimum;
29 import org.hipparchus.optim.nonlinear.vector.leastsquares.LeastSquaresProblem;
30 import org.junit.jupiter.api.AfterEach;
31 import org.junit.jupiter.api.Assertions;
32 import org.junit.jupiter.api.BeforeEach;
33 import org.junit.jupiter.api.Test;
34 import org.orekit.rugged.TestUtils;
35 import org.orekit.rugged.adjustment.measurements.Observables;
36 import org.orekit.rugged.adjustment.measurements.SensorToSensorMapping;
37 import org.orekit.rugged.adjustment.util.InitInterRefiningTest;
38 import org.orekit.rugged.api.Rugged;
39 import org.orekit.rugged.errors.RuggedException;
40 import org.orekit.rugged.errors.RuggedMessages;
41 import org.orekit.rugged.linesensor.LineSensor;
42 import org.orekit.rugged.linesensor.SensorPixel;
43
44 public class InterSensorOptimizationProblemBuilderTest {
45
46 @BeforeEach
47 public void setUp() {
48
49 try {
50 refiningTest = new InitInterRefiningTest();
51 refiningTest.initRefiningTest();
52
53 ruggedList = refiningTest.getRuggedList();
54
55 earthConstraintWeight = 0.1;
56
57 measurements = refiningTest.generateNoisyPoints(lineSampling, pixelSampling, earthConstraintWeight, false);
58 numberOfParameters = refiningTest.getParameterToAdjust();
59
60 } catch (RuggedException re) {
61 Assertions.fail(re.getLocalizedMessage());
62 }
63 }
64
65 @Test
66 public void testEstimateFreeParameters() throws SecurityException, IllegalArgumentException {
67
68 AdjustmentContext adjustmentContext = new AdjustmentContext(ruggedList, measurements);
69
70 List<String> ruggedNameList = new ArrayList<>();
71 for(Rugged rugged : ruggedList) {
72 ruggedNameList.add(rugged.getName());
73 }
74 final int maxIterations = 100;
75 final double convergenceThreshold = 1.e-7;
76
77 Optimum optimum = adjustmentContext.estimateFreeParameters(ruggedNameList, maxIterations, convergenceThreshold);
78
79 Assertions.assertTrue(optimum.getIterations() < maxIterations);
80
81
82
83 Assertions.assertTrue(optimum.getEvaluations() == optimum.getIterations());
84
85 final double expectedMaxValue = 1.924769e-03;
86 Assertions.assertEquals(expectedMaxValue, optimum.getResiduals().getMaxValue(), 1.0e-6);
87
88 final double expectedRMS = 0.069302;
89 Assertions.assertEquals(expectedRMS, optimum.getRMS(), 1.0e-6);
90
91 final double expectedCost = 3.596994;
92 Assertions.assertEquals(expectedCost, optimum.getCost(), 2.5e-6);
93
94 Assertions.assertTrue(numberOfParameters == optimum.getPoint().getDimension());
95
96 final int sensorToSensorMappingSize = 1347;
97 Collection<SensorToSensorMapping> ssm = measurements.getInterMappings();
98 Iterator<SensorToSensorMapping> it = ssm.iterator();
99 while (it.hasNext()) {
100 SensorToSensorMapping ssmit = it.next();
101 Assertions.assertTrue(sensorToSensorMappingSize == ssmit.getMapping().size());
102 }
103 Assertions.assertTrue(sensorToSensorMappingSize*2 == optimum.getResiduals().getDimension());
104
105 }
106
107 @Test
108 public void testEarthConstraintPostponed() {
109
110
111 Collection<SensorToSensorMapping> sensorToSensorMapping = measurements.getInterMappings();
112 int nbModels = measurements.getNbModels();
113
114
115 Observables measurementsPostponed = refiningTest.generateNoisyPoints(lineSampling, pixelSampling, earthConstraintWeight, true);
116 Collection<SensorToSensorMapping> sensorToSensorMappingPostponed = measurementsPostponed.getInterMappings();
117 int nbModelsPostponed = measurementsPostponed.getNbModels();
118
119
120 Assertions.assertEquals(nbModels, nbModelsPostponed);
121
122 Assertions.assertEquals(sensorToSensorMapping.size(), sensorToSensorMappingPostponed.size());
123
124
125 SensorToSensorMapping arraySensorToSensorMapping = (SensorToSensorMapping) sensorToSensorMapping.toArray()[0];
126 SensorToSensorMapping arraySensorToSensorMappingPostponed = (SensorToSensorMapping) sensorToSensorMappingPostponed.toArray()[0];
127
128 List<Double> listBody = arraySensorToSensorMapping.getBodyDistances();
129
130
131 double[] arrayBody = listBody.stream().mapToDouble(Double::doubleValue).toArray();
132
133
134
135
136
137
138 List<Double> listBodyPostponed = arraySensorToSensorMappingPostponed.getBodyDistances();
139 double[] arrayBodyPostponed = listBodyPostponed.stream().mapToDouble(Double::doubleValue).toArray();
140
141 Assertions.assertEquals(listBody.size(), listBodyPostponed.size());
142 Assertions.assertArrayEquals(arrayBody, arrayBodyPostponed, 3.e-3);
143
144 List<Double> listLos = arraySensorToSensorMapping.getLosDistances();
145 double[] arrayLos = listLos.stream().mapToDouble(Double::doubleValue).toArray();
146 List<Double> listLosPostponed = arraySensorToSensorMappingPostponed.getLosDistances();
147 double[] arrayLosPostponed = listLosPostponed.stream().mapToDouble(Double::doubleValue).toArray();
148
149 Assertions.assertEquals(listLos.size(), listLosPostponed.size());
150 Assertions.assertArrayEquals(arrayLos, arrayLosPostponed, 1.e-6);
151
152
153 Set<Entry<SensorPixel, SensorPixel>> mapping = arraySensorToSensorMapping.getMapping();
154 Set<Entry<SensorPixel, SensorPixel>> mappingPostponed = arraySensorToSensorMappingPostponed.getMapping();
155
156 Iterator<Entry<SensorPixel, SensorPixel>> itMapping = mapping.iterator();
157 while(itMapping.hasNext()) {
158 Entry<SensorPixel, SensorPixel> current = itMapping.next();
159 SensorPixel key = current.getKey();
160 SensorPixel value = current.getValue();
161
162
163 Boolean found = false;
164 Iterator<Entry<SensorPixel, SensorPixel>> itMappingPost = mappingPostponed.iterator();
165 while(itMappingPost.hasNext()) {
166 Entry<SensorPixel, SensorPixel> currentPost = itMappingPost.next();
167 SensorPixel keyPost = currentPost.getKey();
168 SensorPixel valuePost = currentPost.getValue();
169
170
171 if (TestUtils.sameSensorPixels(key, keyPost, 3.e-3) &&
172 TestUtils.sameSensorPixels(value, valuePost, 3.e-3)) {
173
174 found = true;
175 }
176 }
177
178 if (!found) {
179 Assertions.assertTrue(found);
180 }
181 }
182
183 Assertions.assertEquals(arraySensorToSensorMapping.getRuggedNameA(),arraySensorToSensorMappingPostponed.getRuggedNameA());
184 Assertions.assertEquals(arraySensorToSensorMapping.getRuggedNameB(),arraySensorToSensorMappingPostponed.getRuggedNameB());
185 Assertions.assertEquals(arraySensorToSensorMapping.getSensorNameA(),arraySensorToSensorMappingPostponed.getSensorNameA());
186 Assertions.assertEquals(arraySensorToSensorMapping.getSensorNameB(),arraySensorToSensorMappingPostponed.getSensorNameB());
187 }
188
189 @Test
190 public void testDefaultRuggedNames() {
191
192
193
194
195 Observables measurementsWithWeight = refiningTest.generateSimpleInterMapping(lineSampling, pixelSampling, earthConstraintWeight, false);
196 Collection<SensorToSensorMapping> sensorToSensorMappingWithWeight = measurementsWithWeight.getInterMappings();
197 int nbModelsWithWeight = measurementsWithWeight.getNbModels();
198
199
200 Observables measurementsWithoutWeight = refiningTest.generateSimpleInterMapping(lineSampling, pixelSampling, earthConstraintWeight, true);
201 Collection<SensorToSensorMapping> sensorToSensorMappingPostponed = measurementsWithoutWeight.getInterMappings();
202 int nbModelsPostponed = measurementsWithoutWeight.getNbModels();
203
204
205 Assertions.assertEquals(nbModelsWithWeight, nbModelsPostponed);
206
207 Assertions.assertEquals(sensorToSensorMappingWithWeight.size(), sensorToSensorMappingPostponed.size());
208
209
210 SensorToSensorMapping arraySensorToSensorMappingWithWeight = (SensorToSensorMapping) sensorToSensorMappingWithWeight.toArray()[0];
211 SensorToSensorMapping arraySensorToSensorMappingPostponed = (SensorToSensorMapping) sensorToSensorMappingPostponed.toArray()[0];
212
213
214 List<Double> listLosWithWeight = arraySensorToSensorMappingWithWeight.getLosDistances();
215 double[] arrayLosWithWeight = listLosWithWeight.stream().mapToDouble(Double::doubleValue).toArray();
216 List<Double> listLosPostponed = arraySensorToSensorMappingPostponed.getLosDistances();
217 double[] arrayLosPostponed = listLosPostponed.stream().mapToDouble(Double::doubleValue).toArray();
218
219 Assertions.assertEquals(listLosWithWeight.size(), listLosPostponed.size());
220 Assertions.assertArrayEquals(arrayLosWithWeight, arrayLosPostponed, 1.e-6);
221
222
223 Set<Entry<SensorPixel, SensorPixel>> mappingWithWeight = arraySensorToSensorMappingWithWeight.getMapping();
224 Set<Entry<SensorPixel, SensorPixel>> mappingPostponed = arraySensorToSensorMappingPostponed.getMapping();
225
226 Iterator<Entry<SensorPixel, SensorPixel>> itMapping = mappingWithWeight.iterator();
227 while(itMapping.hasNext()) {
228 Entry<SensorPixel, SensorPixel> current = itMapping.next();
229 SensorPixel key = current.getKey();
230 SensorPixel value = current.getValue();
231
232
233 boolean found = false;
234 Iterator<Entry<SensorPixel, SensorPixel>> itMappingPost = mappingPostponed.iterator();
235 while(itMappingPost.hasNext()) {
236 Entry<SensorPixel, SensorPixel> currentPost = itMappingPost.next();
237 SensorPixel keyPost = currentPost.getKey();
238 SensorPixel valuePost = currentPost.getValue();
239
240
241 if (TestUtils.sameSensorPixels(key, keyPost, 1.e-3) &&
242 TestUtils.sameSensorPixels(value, valuePost, 1.e-3)) {
243
244 found = true;
245 }
246 }
247
248 if (!found) {
249 Assertions.assertTrue(found);
250 }
251 }
252
253 Assertions.assertEquals(arraySensorToSensorMappingWithWeight.getRuggedNameA(),arraySensorToSensorMappingPostponed.getRuggedNameA());
254 Assertions.assertEquals(arraySensorToSensorMappingWithWeight.getRuggedNameB(),arraySensorToSensorMappingPostponed.getRuggedNameB());
255 Assertions.assertEquals(arraySensorToSensorMappingWithWeight.getSensorNameA(),arraySensorToSensorMappingPostponed.getSensorNameA());
256 Assertions.assertEquals(arraySensorToSensorMappingWithWeight.getSensorNameB(),arraySensorToSensorMappingPostponed.getSensorNameB());
257 }
258
259 @Test
260 public void testNoReferenceMapping() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
261
262 try {
263 final int maxIterations = 120;
264 final double convergenceThreshold = 1.e-7;
265
266 final List<LineSensor> selectedSensors = new ArrayList<>();
267 for (Rugged rugged : ruggedList) {
268 selectedSensors.addAll(rugged.getLineSensors());
269 }
270 final InterSensorsOptimizationProblemBuilder interSensorsOptimizationProblem =
271 new InterSensorsOptimizationProblemBuilder(selectedSensors, measurements, ruggedList);
272
273 Field sensorToSensorMapping = interSensorsOptimizationProblem.getClass().getDeclaredField("sensorToSensorMappings");
274 sensorToSensorMapping.setAccessible(true);
275 sensorToSensorMapping.set(interSensorsOptimizationProblem,new ArrayList<SensorToSensorMapping>());
276
277 interSensorsOptimizationProblem.build(maxIterations, convergenceThreshold);
278 Assertions.fail("An exception should have been thrown");
279
280 } catch (RuggedException re) {
281 Assertions.assertEquals(RuggedMessages.NO_REFERENCE_MAPPINGS,re.getSpecifier());
282 }
283 }
284
285 @Test
286 public void testInvalidRuggedNames() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
287
288 final int maxIterations = 120;
289 final double convergenceThreshold = 1.e-7;
290
291 final List<LineSensor> selectedSensors = new ArrayList<>();
292 for (Rugged rugged : ruggedList) {
293 selectedSensors.addAll(rugged.getLineSensors());
294 }
295 final InterSensorsOptimizationProblemBuilder interSensorsOptimizationProblem =
296 new InterSensorsOptimizationProblemBuilder(selectedSensors, measurements, ruggedList);
297
298 Field ruggedMapField = interSensorsOptimizationProblem.getClass().getDeclaredField("ruggedMap");
299 ruggedMapField.setAccessible(true);
300 @SuppressWarnings("unchecked")
301 Map<String,Rugged> ruggedMap = (Map<String,Rugged>) ruggedMapField.get(interSensorsOptimizationProblem);
302
303
304 try {
305 ruggedMap.put("RuggedB",null);
306
307 ruggedMapField.set(interSensorsOptimizationProblem,ruggedMap);
308
309 final LeastSquareAdjuster adjuster = new LeastSquareAdjuster(OptimizerId.GAUSS_NEWTON_QR);
310 LeastSquaresProblem theProblem = interSensorsOptimizationProblem.build(maxIterations, convergenceThreshold);
311 adjuster.optimize(theProblem);
312 Assertions.fail("An exception should have been thrown");
313
314 } catch (RuggedException re) {
315 Assertions.assertEquals(RuggedMessages.INVALID_RUGGED_NAME,re.getSpecifier());
316 }
317
318
319 try {
320 ruggedMap.put("RuggedA",null);
321
322 ruggedMapField.set(interSensorsOptimizationProblem,ruggedMap);
323
324 final LeastSquareAdjuster adjuster = new LeastSquareAdjuster(OptimizerId.GAUSS_NEWTON_QR);
325 LeastSquaresProblem theProblem = interSensorsOptimizationProblem.build(maxIterations, convergenceThreshold);
326 adjuster.optimize(theProblem);
327 Assertions.fail("An exception should have been thrown");
328
329 } catch (RuggedException re) {
330 Assertions.assertEquals(RuggedMessages.INVALID_RUGGED_NAME,re.getSpecifier());
331 }
332 }
333
334
335 @AfterEach
336 public void tearDown() {
337 measurements = null;
338 ruggedList = null;
339 }
340
341 private InitInterRefiningTest refiningTest;
342 private Observables measurements;
343 private List<Rugged> ruggedList;
344 private int numberOfParameters;
345 private double earthConstraintWeight;
346
347 private final int lineSampling = 1000;
348 private final int pixelSampling = 1000;
349 }