diff --git a/src/main/java/org/orekit/rugged/adjustment/measurements/Observables.java b/src/main/java/org/orekit/rugged/adjustment/measurements/Observables.java index 845a1c2dd87b53454080f5dcfd1863d67d59e6d5..5eca225657ac2c9d44d49540d32981767826ac03 100644 --- a/src/main/java/org/orekit/rugged/adjustment/measurements/Observables.java +++ b/src/main/java/org/orekit/rugged/adjustment/measurements/Observables.java @@ -35,10 +35,10 @@ public class Observables { /** Separator between sensors. */ private static final String SENSORS_SEPARATOR = "__"; - /** Sensor to ground mapping structure (example: for GCP points).*/ + /** Sensor to ground mapping structure (example: for Ground Control Points GCP points).*/ private final Map<String, SensorToGroundMapping> groundMappings; - /** Sensor to sensor mappings structure (liaison points). */ + /** Sensor to sensor mappings structure (Tie points). */ private final Map<String, SensorToSensorMapping> interMappings; /** Number of viewing models to map.*/ diff --git a/src/test/java/org/orekit/rugged/adjustment/AdjustmentContextTest.java b/src/test/java/org/orekit/rugged/adjustment/AdjustmentContextTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3d45d74577081676fae919421df232f931f7888d --- /dev/null +++ b/src/test/java/org/orekit/rugged/adjustment/AdjustmentContextTest.java @@ -0,0 +1,147 @@ +/* Copyright 2013-2018 CS Systèmes d'Information + * Licensed to CS Systèmes d'Information (CS) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * CS licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.orekit.rugged.adjustment; + +import static org.junit.Assert.assertTrue; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +import org.hipparchus.optim.nonlinear.vector.leastsquares.LeastSquaresOptimizer.Optimum; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.orekit.rugged.adjustment.measurements.Observables; +import org.orekit.rugged.api.Rugged; +import org.orekit.rugged.errors.RuggedException; +import org.orekit.rugged.utils.RefiningTest; + +public class AdjustmentContextTest { + + @Before + public void setUp() { + + try { + RefiningTest refiningTest = new RefiningTest(); + refiningTest.initRefiningTest(); + + ruggedList = refiningTest.getRuggedList(); + + int lineSampling = 1000; + int pixelSampling = 1000; + + measurements = refiningTest.generateNoisyPoints(lineSampling, pixelSampling); + numberOfParameters = refiningTest.getParameterToAdjust(); + + } catch (RuggedException re) { + Assert.fail(re.getLocalizedMessage()); + } + } + + @Test + public void testAdjustmentContext() throws RuggedException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { + + AdjustmentContext adjustmentContext = new AdjustmentContext(ruggedList, measurements); + + // Check if the default OptimizerId is the expected one + Field optimizerId = adjustmentContext.getClass().getDeclaredField("optimizerID"); + optimizerId.setAccessible(true); + OptimizerId defaultOptimizerId = (OptimizerId) optimizerId.get(adjustmentContext); + + System.out.println(defaultOptimizerId); + assertTrue((defaultOptimizerId == OptimizerId.GAUSS_NEWTON_QR)); + +// // Check if the change of the default OptimizerId is correct +// adjustmentContext.setOptimizer(OptimizerId.GAUSS_NEWTON_LU); +// OptimizerId modifiedOptimizerId = (OptimizerId) optimizerId.get(adjustmentContext); +// System.out.println(modifiedOptimizerId); +// assertTrue((modifiedOptimizerId == OptimizerId.GAUSS_NEWTON_LU)); + +// // Check if the change of the default OptimizerId is correct +// adjustmentContext.setOptimizer(OptimizerId.GAUSS_NEWTON_LU); +// OptimizerId modifiedOptimizerId = (OptimizerId) optimizerId.get(adjustmentContext); +// System.out.println(modifiedOptimizerId); +// assertTrue((modifiedOptimizerId == OptimizerId.GAUSS_NEWTON_LU)); + + +// OptimizerId.valueOf(OptimizerId.LEVENBERG_MARQUADT.toString()); + } + + + + @Test + public void testEstimateFreeParameters() throws RuggedException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { + + AdjustmentContext adjustmentContext = new AdjustmentContext(ruggedList, measurements); + + List<String> ruggedNameList = new ArrayList<String>(); + for(Rugged rugged : ruggedList) { + ruggedNameList.add(rugged.getName()); + } + final int maxIterations = 120; + final double convergenceThreshold = 1.e-7; + + Optimum optimum = adjustmentContext.estimateFreeParameters(ruggedNameList, maxIterations, convergenceThreshold); + + Assert.assertTrue(optimum.getIterations() < 20); + Field optimizerId = adjustmentContext.getClass().getDeclaredField("optimizerID"); + optimizerId.setAccessible(true); + OptimizerId usedOptimizerId = (OptimizerId) optimizerId.get(adjustmentContext); + if (usedOptimizerId == OptimizerId.GAUSS_NEWTON_QR || usedOptimizerId == OptimizerId.GAUSS_NEWTON_LU) { + // For Gauss Newton, the number of evaluations is equal to the number of iterations + Assert.assertTrue(optimum.getEvaluations() == optimum.getIterations()); + } else if (usedOptimizerId == OptimizerId.LEVENBERG_MARQUADT) { + // For Levenberg Marquadt, the number of evaluations is slightly greater than the number of iterations + Assert.assertTrue(optimum.getEvaluations() >= optimum.getIterations()); + } + + final double expectedMaxValue = 3.324585e-03; + Assert.assertEquals(expectedMaxValue, optimum.getResiduals().getMaxValue(), 1.0e-6); + + final double expectedRMS = 0.069669; + Assert.assertEquals(expectedRMS, optimum.getRMS(), 1.0e-6); + + System.out.format("Chi sqaure %3.8e %n", optimum.getChiSquare()); + + assertTrue(numberOfParameters == optimum.getPoint().getDimension()); + + System.out.format("residuals %d \n", optimum.getResiduals().getDimension()); +// int measureCount = 0; +// while (measurements.getInterMappings().iterator().hasNext()) { +// measureCount++; +// System.out.println("measure " + measureCount); +// } +// System.out.format(" measurements %d \n", measureCount); + System.out.format("cost %3.8e \n", optimum.getCost()); + + + + } + + @After + public void tearDown() { + measurements = null; + ruggedList = null; + } + + private Observables measurements; + private List<Rugged> ruggedList; + private int numberOfParameters; + +} diff --git a/src/test/java/org/orekit/rugged/utils/RefiningTest.java b/src/test/java/org/orekit/rugged/utils/RefiningTest.java index bf0ff2dad01bef03746e078add0b94f6a8ef8b00..01269840918f7bf72ab8565ba9c56984aaf6e110 100644 --- a/src/test/java/org/orekit/rugged/utils/RefiningTest.java +++ b/src/test/java/org/orekit/rugged/utils/RefiningTest.java @@ -83,35 +83,32 @@ import org.orekit.rugged.los.TimeDependentLOS; public class RefiningTest { /** Pleiades viewing model A */ - PleiadesViewingModel pleiadesViewingModelA; + private PleiadesViewingModel pleiadesViewingModelA; /** Pleiades viewing model B */ - PleiadesViewingModel pleiadesViewingModelB; + private PleiadesViewingModel pleiadesViewingModelB; /** Line sensor A */ - LineSensor lineSensorA; + private LineSensor lineSensorA; /** Line sensor B */ - LineSensor lineSensorB; + private LineSensor lineSensorB; /** RuggedA's instance */ - Rugged ruggedA; + private Rugged ruggedA; /** RuggedB's instance */ - Rugged ruggedB; + private Rugged ruggedB; + /** Number of parameters to adjust */ + private int parameterToAdjust; - /** - * Part of the name of parameter drivers - */ + // Part of the name of parameter drivers static final String rollSuffix = "_roll"; static final String pitchSuffix = "_pitch"; static final String factorName = "factor"; - - /** - * Default values for disruption to apply to roll (deg), pitch (deg) and factor - */ + // Default values for disruption to apply to roll (deg), pitch (deg) and factor static final double defaultRollDisruptionA = 0.004; static final double defaultPitchDisruptionA = 0.0008; static final double defaultFactorDisruptionA = 1.000000001; @@ -242,6 +239,8 @@ public class RefiningTest { setSelectedRoll(ruggedB, sensorNameB); setSelectedPitch(ruggedB, sensorNameB); + + this.parameterToAdjust = 4; // Initialize disruptions: // ----------------------- @@ -461,11 +460,7 @@ public class RefiningTest { // Observables which contains sensor to sensor mapping Observables observables = new Observables(2); - - System.out.format("\n**** Generate noisy measurements (sensor to sensor mapping) **** %n"); - // Generation noisy measurements - // distribution: gaussian(0), vector dimension: 2 final double meanA[] = { 5.0, 5.0 }; final double stdA[] = { 0.1, 0.1 }; @@ -541,9 +536,6 @@ public class RefiningTest { } // end loop on line of sensorA observables.addInterMapping(interMapping); - - System.out.format("Number of tie points generated: %d %n", measurementCount); - return observables; } @@ -565,6 +557,13 @@ public class RefiningTest { @After public void tearDown() { } + + /** Get the number of parameters to adjust + * @return number of parameters to adjust + */ + public int getParameterToAdjust() { + return parameterToAdjust; + } } diff --git a/src/test/java/org/orekit/rugged/utils/RefiningTiePointsMetrics.java b/src/test/java/org/orekit/rugged/utils/RefiningTiePointsMetrics.java index 4e655361f62416b0179112fb9571a00e7dd3deb2..5e3f3038f5da30437d0190e83400a3cd0c568579 100644 --- a/src/test/java/org/orekit/rugged/utils/RefiningTiePointsMetrics.java +++ b/src/test/java/org/orekit/rugged/utils/RefiningTiePointsMetrics.java @@ -1,9 +1,9 @@ package org.orekit.rugged.utils; /** - * Contains results from liaison metrics computation + * Contains results from tie metrics computation */ -public class RefiningLiaisonMetrics { +public class RefiningTiePointsMetrics { /** Maximum residual distance. */ private double resMax; @@ -18,7 +18,7 @@ public class RefiningLiaisonMetrics { /** Earth distance mean.*/ private double earthDistanceMean; - public RefiningLiaisonMetrics() { + public RefiningTiePointsMetrics() { this.resMax = 0.0; this.resMean = 0.0;