From b3c4bc2c325d968ad39d33009736a355a8c60bff Mon Sep 17 00:00:00 2001
From: sesteves <sroesteves@gmail.com>
Date: Tue, 30 Aug 2016 19:19:55 +0100
Subject: [PATCH] -atmospheric refraction integrated in rugged -code style
 corrected and javadocs

---
 .../java/org/orekit/rugged/api/Rugged.java    | 56 +++++++++++++------
 .../org/orekit/rugged/api/RuggedBuilder.java  | 32 ++++++++++-
 .../java/org/orekit/rugged/errors/Dump.java   |  8 ++-
 .../org/orekit/rugged/errors/DumpManager.java |  7 ++-
 .../AtmosphericRefraction.java                | 16 +++++-
 .../ConstantRefractionLayer.java              | 41 ++++++++++++--
 .../MultiLayerModel.java                      | 24 +++++---
 .../MultiLayerModelTest.java                  |  2 +-
 8 files changed, 143 insertions(+), 43 deletions(-)
 rename src/main/java/org/orekit/rugged/{atmosphericrefraction => refraction}/AtmosphericRefraction.java (62%)
 rename src/main/java/org/orekit/rugged/{atmosphericrefraction => refraction}/ConstantRefractionLayer.java (52%)
 rename src/main/java/org/orekit/rugged/{atmosphericrefraction => refraction}/MultiLayerModel.java (90%)
 rename src/test/java/org/orekit/rugged/{atmosphericrefraction => refraction}/MultiLayerModelTest.java (99%)

diff --git a/src/main/java/org/orekit/rugged/api/Rugged.java b/src/main/java/org/orekit/rugged/api/Rugged.java
index 31c30b2f..9cae53f2 100644
--- a/src/main/java/org/orekit/rugged/api/Rugged.java
+++ b/src/main/java/org/orekit/rugged/api/Rugged.java
@@ -26,8 +26,6 @@ import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
 import org.apache.commons.math3.util.FastMath;
 import org.orekit.bodies.GeodeticPoint;
 import org.orekit.frames.Transform;
-import org.orekit.rugged.atmosphericrefraction.AtmosphericRefraction;
-import org.orekit.rugged.atmosphericrefraction.MultiLayerModel;
 import org.orekit.rugged.errors.DumpManager;
 import org.orekit.rugged.errors.RuggedException;
 import org.orekit.rugged.errors.RuggedMessages;
@@ -36,6 +34,7 @@ import org.orekit.rugged.linesensor.LineSensor;
 import org.orekit.rugged.linesensor.SensorMeanPlaneCrossing;
 import org.orekit.rugged.linesensor.SensorPixel;
 import org.orekit.rugged.linesensor.SensorPixelCrossing;
+import org.orekit.rugged.refraction.AtmosphericRefraction;
 import org.orekit.rugged.utils.ExtendedEllipsoid;
 import org.orekit.rugged.utils.NormalizedGeodeticPoint;
 import org.orekit.rugged.utils.SpacecraftToObservedBody;
@@ -81,6 +80,9 @@ public class Rugged {
     /** Flag for aberration of light correction. */
     private boolean aberrationOfLightCorrection;
 
+    /** Atmospheric refraction for line of sight correction. */
+    private AtmosphericRefraction atmosphericRefraction;
+
     /** Build a configured instance.
      * <p>
      * By default, the instance performs both light time correction (which refers
@@ -94,13 +96,14 @@ public class Rugged {
      * @param ellipsoid f reference ellipsoid
      * @param lightTimeCorrection if true, the light travel time between ground
      * @param aberrationOfLightCorrection if true, the aberration of light
-     * is corrected for more accurate location
-     * and spacecraft is compensated for more accurate location
+* is corrected for more accurate location
+* and spacecraft is compensated for more accurate location
+     * @param atmosphericRefraction the atmospheric refraction model to be used for more accurate location
      * @param scToBody transforms interpolator
      * @param sensors sensors
      */
-    Rugged(final IntersectionAlgorithm algorithm, final ExtendedEllipsoid ellipsoid,
-           final boolean lightTimeCorrection, final boolean aberrationOfLightCorrection,
+    Rugged(final IntersectionAlgorithm algorithm, final ExtendedEllipsoid ellipsoid, final boolean lightTimeCorrection,
+           final boolean aberrationOfLightCorrection, final AtmosphericRefraction atmosphericRefraction,
            final SpacecraftToObservedBody scToBody, final Collection<LineSensor> sensors) {
 
         // space reference
@@ -120,7 +123,7 @@ public class Rugged {
 
         this.lightTimeCorrection         = lightTimeCorrection;
         this.aberrationOfLightCorrection = aberrationOfLightCorrection;
-
+        this.atmosphericRefraction       = atmosphericRefraction;
     }
 
     /** Get the DEM intersection algorithm.
@@ -146,6 +149,13 @@ public class Rugged {
         return aberrationOfLightCorrection;
     }
 
+    /** Get the atmospheric refraction model.
+     * @return atmospheric refraction model
+     */
+    public AtmosphericRefraction getRefractionCorrection() {
+        return atmosphericRefraction;
+    }
+
     /** Get the line sensors.
      * @return line sensors
      */
@@ -214,8 +224,8 @@ public class Rugged {
         final GeodeticPoint[] gp = new GeodeticPoint[sensor.getNbPixels()];
         for (int i = 0; i < sensor.getNbPixels(); ++i) {
 
-            DumpManager.dumpDirectLocation(date, sensor.getPosition(), sensor.getLos(date, i),
-                                           lightTimeCorrection, aberrationOfLightCorrection);
+            DumpManager.dumpDirectLocation(date, sensor.getPosition(), sensor.getLos(date, i), lightTimeCorrection,
+                    aberrationOfLightCorrection, atmosphericRefraction != null);
 
             final Vector3D obsLInert = scToInert.transformVector(sensor.getLos(date, i));
             final Vector3D lInert;
@@ -264,6 +274,12 @@ public class Rugged {
                                                      algorithm.intersection(ellipsoid, pBody, lBody));
             }
 
+            if (atmosphericRefraction != null) {
+                // apply atmospheric refraction correction
+                gp[i] = atmosphericRefraction.applyCorrection(sensor.getPosition(), sensor.getLos(date, i),
+                                                              (NormalizedGeodeticPoint) gp[i], algorithm);
+            }
+
             DumpManager.dumpDirectLocationResult(gp[i]);
 
         }
@@ -282,7 +298,8 @@ public class Rugged {
     public GeodeticPoint directLocation(final AbsoluteDate date, final Vector3D position, final Vector3D los)
         throws RuggedException {
 
-        DumpManager.dumpDirectLocation(date, position, los, lightTimeCorrection, aberrationOfLightCorrection);
+        DumpManager.dumpDirectLocation(date, position, los, lightTimeCorrection, aberrationOfLightCorrection,
+                                       atmosphericRefraction != null);
 
         // compute the approximate transform between spacecraft and observed body
         final Transform    scToInert   = scToBody.getScToInertial(date);
@@ -315,7 +332,7 @@ public class Rugged {
             lInert = obsLInert;
         }
 
-        final NormalizedGeodeticPoint result;
+        final NormalizedGeodeticPoint gp;
         if (lightTimeCorrection) {
             // compute DEM intersection with light time correction
             final Vector3D  sP       = approximate.transformPosition(position);
@@ -330,7 +347,7 @@ public class Rugged {
             final Vector3D  eP2      = ellipsoid.transform(gp1);
             final double    deltaT2  = eP2.distance(sP) / Constants.SPEED_OF_LIGHT;
             final Transform shifted2 = inertToBody.shiftedBy(-deltaT2);
-            result = algorithm.refineIntersection(ellipsoid,
+            gp = algorithm.refineIntersection(ellipsoid,
                                                   shifted2.transformPosition(pInert),
                                                   shifted2.transformVector(lInert),
                                                   gp1);
@@ -339,14 +356,17 @@ public class Rugged {
             // compute DEM intersection without light time correction
             final Vector3D pBody = inertToBody.transformPosition(pInert);
             final Vector3D lBody = inertToBody.transformVector(lInert);
-            result = algorithm.refineIntersection(ellipsoid, pBody, lBody,
+            gp = algorithm.refineIntersection(ellipsoid, pBody, lBody,
                                                   algorithm.intersection(ellipsoid, pBody, lBody));
+        }
 
-            // compute atmosphere deviation.
-            //AtmosphericRefraction atmosphericRefraction = new MultiLayerModel();
-            // result.getZenith()
-            //long deviation = atmosphericRefraction.getDeviation(pBody, lBody, result.getAltitude());
-
+        final NormalizedGeodeticPoint result;
+        if (atmosphericRefraction != null) {
+            // apply atmospheric refraction correction
+            result = atmosphericRefraction.applyCorrection(position, los, gp, algorithm);
+        } else {
+            // don't apply atmospheric refraction correction
+            result = gp;
         }
 
         DumpManager.dumpDirectLocationResult(result);
diff --git a/src/main/java/org/orekit/rugged/api/RuggedBuilder.java b/src/main/java/org/orekit/rugged/api/RuggedBuilder.java
index 679d909e..a6c5439a 100644
--- a/src/main/java/org/orekit/rugged/api/RuggedBuilder.java
+++ b/src/main/java/org/orekit/rugged/api/RuggedBuilder.java
@@ -45,6 +45,7 @@ import org.orekit.rugged.intersection.IntersectionAlgorithm;
 import org.orekit.rugged.intersection.duvenhage.DuvenhageAlgorithm;
 import org.orekit.rugged.linesensor.LineSensor;
 import org.orekit.rugged.raster.TileUpdater;
+import org.orekit.rugged.refraction.AtmosphericRefraction;
 import org.orekit.rugged.utils.ExtendedEllipsoid;
 import org.orekit.rugged.utils.SpacecraftToObservedBody;
 import org.orekit.time.AbsoluteDate;
@@ -155,6 +156,9 @@ public class RuggedBuilder {
     /** Flag for aberration of light correction. */
     private boolean aberrationOfLightCorrection;
 
+    /** Atmospheric refraction to use for line of sight correction. */
+    private AtmosphericRefraction atmosphericRefraction;
+
     /** Sensors. */
     private final List<LineSensor> sensors;
 
@@ -838,6 +842,32 @@ public class RuggedBuilder {
         return aberrationOfLightCorrection;
     }
 
+    /** Set atmospheric refraction for line of sight correction.
+     * <p>
+     * This method sets an atmospheric refraction model to be used between
+     * spacecraft and ground for the correction of intersected points on ground.
+     * Compensating for the effect of atmospheric refraction improves location
+     * accuracy.
+     * </p>
+     * @param atmosphericRefraction the atmospheric refraction model to be used for more accurate location
+     * @return the builder instance
+     * @see #getRefractionCorrection()
+     */
+    // CHECKSTYLE: stop HiddenField check
+    public RuggedBuilder setRefractionCorrection(final AtmosphericRefraction atmosphericRefraction) {
+        // CHECKSTYLE: resume HiddenField check
+        this.atmosphericRefraction = atmosphericRefraction;
+        return this;
+    }
+
+    /** Get the atmospheric refraction model.
+     * @return atmospheric refraction model
+     * @see #setRefractionCorrection(AtmosphericRefraction)
+     */
+    public AtmosphericRefraction getRefractionCorrection() {
+        return atmosphericRefraction;
+    }
+
     /** Set up line sensor model.
      * @param lineSensor line sensor model
      * @return the builder instance
@@ -996,7 +1026,7 @@ public class RuggedBuilder {
         }
         createInterpolatorIfNeeded();
         return new Rugged(createAlgorithm(algorithmID, tileUpdater, maxCachedTiles, constantElevation), ellipsoid,
-                          lightTimeCorrection, aberrationOfLightCorrection, scToBody, sensors);
+                          lightTimeCorrection, aberrationOfLightCorrection, atmosphericRefraction, scToBody, sensors);
     }
 
 }
diff --git a/src/main/java/org/orekit/rugged/errors/Dump.java b/src/main/java/org/orekit/rugged/errors/Dump.java
index e74fad66..26f2b254 100644
--- a/src/main/java/org/orekit/rugged/errors/Dump.java
+++ b/src/main/java/org/orekit/rugged/errors/Dump.java
@@ -150,17 +150,19 @@ class Dump {
      * @param los normalized line-of-sight in spacecraft frame
      * @param lightTimeCorrection flag for light time correction
      * @param aberrationOfLightCorrection flag for aberration of light correction
+     * @param refractionCorrection flag for refraction correction
      * @exception RuggedException if date cannot be converted to UTC
      */
     public void dumpDirectLocation(final AbsoluteDate date, final Vector3D position, final Vector3D los,
-                                   final boolean lightTimeCorrection, final boolean aberrationOfLightCorrection)
+                                   final boolean lightTimeCorrection, final boolean aberrationOfLightCorrection,
+                                   final boolean refractionCorrection)
         throws RuggedException {
         writer.format(Locale.US,
-                      "direct location: date %s position %22.15e %22.15e %22.15e los %22.15e %22.15e %22.15e lightTime %b aberration %b%n",
+                      "direct location: date %s position %22.15e %22.15e %22.15e los %22.15e %22.15e %22.15e lightTime %b aberration %b refraction %b %n",
                       convertDate(date),
                       position.getX(), position.getY(), position.getZ(),
                       los.getX(),      los.getY(),      los.getZ(),
-                      lightTimeCorrection, aberrationOfLightCorrection);
+                      lightTimeCorrection, aberrationOfLightCorrection, refractionCorrection);
     }
 
     /** Dump a direct location result.
diff --git a/src/main/java/org/orekit/rugged/errors/DumpManager.java b/src/main/java/org/orekit/rugged/errors/DumpManager.java
index 379bef03..f787f0f9 100644
--- a/src/main/java/org/orekit/rugged/errors/DumpManager.java
+++ b/src/main/java/org/orekit/rugged/errors/DumpManager.java
@@ -139,13 +139,16 @@ public class DumpManager {
      * @param los normalized line-of-sight in spacecraft frame
      * @param lightTimeCorrection flag for light time correction
      * @param aberrationOfLightCorrection flag for aberration of light correction
+     * @param refractionCorrection flag for refraction correction
      * @exception RuggedException if date cannot be converted to UTC
      */
     public static void dumpDirectLocation(final AbsoluteDate date, final Vector3D position, final Vector3D los,
-                                          final boolean lightTimeCorrection, final boolean aberrationOfLightCorrection)
+                                          final boolean lightTimeCorrection, final boolean aberrationOfLightCorrection,
+                                          final boolean refractionCorrection)
         throws RuggedException {
         if (isActive()) {
-            DUMP.get().dumpDirectLocation(date, position, los, lightTimeCorrection, aberrationOfLightCorrection);
+            DUMP.get().dumpDirectLocation(date, position, los, lightTimeCorrection, aberrationOfLightCorrection,
+                    refractionCorrection);
         }
     }
 
diff --git a/src/main/java/org/orekit/rugged/atmosphericrefraction/AtmosphericRefraction.java b/src/main/java/org/orekit/rugged/refraction/AtmosphericRefraction.java
similarity index 62%
rename from src/main/java/org/orekit/rugged/atmosphericrefraction/AtmosphericRefraction.java
rename to src/main/java/org/orekit/rugged/refraction/AtmosphericRefraction.java
index 21a545bf..3a234db4 100644
--- a/src/main/java/org/orekit/rugged/atmosphericrefraction/AtmosphericRefraction.java
+++ b/src/main/java/org/orekit/rugged/refraction/AtmosphericRefraction.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.orekit.rugged.atmosphericrefraction;
+package org.orekit.rugged.refraction;
 
 
 import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
@@ -23,13 +23,23 @@ import org.orekit.rugged.intersection.IntersectionAlgorithm;
 import org.orekit.rugged.utils.NormalizedGeodeticPoint;
 
 /**
- * Interface for atmospheric refraction.
+ * Interface for atmospheric refraction model.
  * @author Sergio Esteves
  */
 public interface AtmosphericRefraction {
 
+    /** Apply correction to the intersected point with an atmospheric refraction model.
+     * @param satPos satellite position
+     * @param satLos satellite line of sight
+     * @param rawIntersection intersection point before refraction correction
+     * @param algorithm intersection algorithm
+     * @return corrected point with the effect of atmospheric refraction
+     * @throws RuggedException if there is no refraction data at altitude of rawIntersection or see
+     * {@link org.orekit.rugged.utils.ExtendedEllipsoid#pointAtAltitude(Vector3D, Vector3D, double)} or see
+     * {@link IntersectionAlgorithm#refineIntersection(ExtendedEllipsoid, Vector3D, Vector3D, NormalizedGeodeticPoint)}
+     */
     NormalizedGeodeticPoint applyCorrection(Vector3D satPos, Vector3D satLos, NormalizedGeodeticPoint rawIntersection,
                                              IntersectionAlgorithm algorithm)
-            throws RuggedException;
+        throws RuggedException;
 
 }
diff --git a/src/main/java/org/orekit/rugged/atmosphericrefraction/ConstantRefractionLayer.java b/src/main/java/org/orekit/rugged/refraction/ConstantRefractionLayer.java
similarity index 52%
rename from src/main/java/org/orekit/rugged/atmosphericrefraction/ConstantRefractionLayer.java
rename to src/main/java/org/orekit/rugged/refraction/ConstantRefractionLayer.java
index 6e9dd6a0..3b0da0c8 100644
--- a/src/main/java/org/orekit/rugged/atmosphericrefraction/ConstantRefractionLayer.java
+++ b/src/main/java/org/orekit/rugged/refraction/ConstantRefractionLayer.java
@@ -14,18 +14,25 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.orekit.rugged.atmosphericrefraction;
+package org.orekit.rugged.refraction;
 
 /**
  * Class that represents a constant refraction layer to be used with {@link MultiLayerModel}.
- *
  * @author Sergio Esteves
  */
 public class ConstantRefractionLayer implements Comparable<ConstantRefractionLayer> {
-    private Double lowestAltitude;
-    private double refractiveIndex;
 
-    public ConstantRefractionLayer(double lowestAltitude, double refractiveIndex) {
+    /** lowest altitude of this layer. */
+    private final Double lowestAltitude;
+
+    /** refractive index of this layer. */
+    private final double refractiveIndex;
+
+    /** Simple constructor.
+     * @param lowestAltitude lowest altitude of the layer
+     * @param refractiveIndex refractive index of the layer
+     */
+    public ConstantRefractionLayer(final double lowestAltitude, final double refractiveIndex) {
         this.lowestAltitude = lowestAltitude;
         this.refractiveIndex = refractiveIndex;
     }
@@ -39,7 +46,29 @@ public class ConstantRefractionLayer implements Comparable<ConstantRefractionLay
     }
 
     @Override
-    public int compareTo(ConstantRefractionLayer o) {
+    public int compareTo(final ConstantRefractionLayer o) {
         return lowestAltitude.compareTo(o.lowestAltitude);
     }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        final ConstantRefractionLayer that = (ConstantRefractionLayer) o;
+
+        if (Double.compare(that.refractiveIndex, refractiveIndex) != 0) return false;
+        return lowestAltitude != null ? lowestAltitude.equals(that.lowestAltitude) : that.lowestAltitude == null;
+
+    }
+
+    @Override
+    public int hashCode() {
+        int result;
+        long temp;
+        result = lowestAltitude != null ? lowestAltitude.hashCode() : 0;
+        temp = Double.doubleToLongBits(refractiveIndex);
+        result = 31 * result + (int) (temp ^ (temp >>> 32));
+        return result;
+    }
 }
diff --git a/src/main/java/org/orekit/rugged/atmosphericrefraction/MultiLayerModel.java b/src/main/java/org/orekit/rugged/refraction/MultiLayerModel.java
similarity index 90%
rename from src/main/java/org/orekit/rugged/atmosphericrefraction/MultiLayerModel.java
rename to src/main/java/org/orekit/rugged/refraction/MultiLayerModel.java
index 1c44c275..d1652248 100644
--- a/src/main/java/org/orekit/rugged/atmosphericrefraction/MultiLayerModel.java
+++ b/src/main/java/org/orekit/rugged/refraction/MultiLayerModel.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.orekit.rugged.atmosphericrefraction;
+package org.orekit.rugged.refraction;
 
 import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
 import org.apache.commons.math3.util.FastMath;
@@ -39,14 +39,16 @@ public class MultiLayerModel implements AtmosphericRefraction {
     /** Observed body ellipsoid. */
     private final ExtendedEllipsoid ellipsoid;
 
-    /** Constant refraction layers */
+    /** Constant refraction layers. */
     private final List<ConstantRefractionLayer> refractionLayers;
 
-    /** Atmosphere lowest altitude */
+    /** Atmosphere lowest altitude. */
     private final double atmosphereLowestAltitude;
 
-    public MultiLayerModel(final ExtendedEllipsoid ellipsoid)
-            throws OrekitException {
+    /** Simple constructor.
+     * @param ellipsoid the ellipsoid to be used.
+     */
+    public MultiLayerModel(final ExtendedEllipsoid ellipsoid) {
         this.ellipsoid = ellipsoid;
 
         refractionLayers = new ArrayList<ConstantRefractionLayer>(15);
@@ -69,22 +71,26 @@ public class MultiLayerModel implements AtmosphericRefraction {
         atmosphereLowestAltitude = refractionLayers.get(refractionLayers.size() - 1).getLowestAltitude();
     }
 
-    public MultiLayerModel(final ExtendedEllipsoid ellipsoid, final List<ConstantRefractionLayer> refractionLayers)
-            throws OrekitException {
+    /** Simple constructor.
+     * @param ellipsoid the ellipsoid to be used.
+     * @param refractionLayers the refraction layers to be used with this model.
+     */
+    public MultiLayerModel(final ExtendedEllipsoid ellipsoid, final List<ConstantRefractionLayer> refractionLayers) {
         this.ellipsoid = ellipsoid;
         this.refractionLayers = refractionLayers;
         Collections.sort(this.refractionLayers, Collections.<ConstantRefractionLayer>reverseOrder());
         atmosphereLowestAltitude = refractionLayers.get(refractionLayers.size() - 1).getLowestAltitude();
     }
 
+    /** {@inheritDoc} */
     @Override
     public NormalizedGeodeticPoint applyCorrection(final Vector3D satPos, final Vector3D satLos,
                                                    final NormalizedGeodeticPoint rawIntersection,
                                                    final IntersectionAlgorithm algorithm)
-            throws RuggedException {
+        throws RuggedException {
 
         try {
-            if(rawIntersection.getAltitude() < atmosphereLowestAltitude) {
+            if (rawIntersection.getAltitude() < atmosphereLowestAltitude) {
                 throw new RuggedException(RuggedMessages.NO_LAYER_DATA, rawIntersection.getAltitude(),
                         atmosphereLowestAltitude);
             }
diff --git a/src/test/java/org/orekit/rugged/atmosphericrefraction/MultiLayerModelTest.java b/src/test/java/org/orekit/rugged/refraction/MultiLayerModelTest.java
similarity index 99%
rename from src/test/java/org/orekit/rugged/atmosphericrefraction/MultiLayerModelTest.java
rename to src/test/java/org/orekit/rugged/refraction/MultiLayerModelTest.java
index 4103307c..fa972508 100644
--- a/src/test/java/org/orekit/rugged/atmosphericrefraction/MultiLayerModelTest.java
+++ b/src/test/java/org/orekit/rugged/refraction/MultiLayerModelTest.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.orekit.rugged.atmosphericrefraction;
+package org.orekit.rugged.refraction;
 
 import org.apache.commons.math3.geometry.euclidean.threed.Rotation;
 import org.apache.commons.math3.geometry.euclidean.threed.RotationConvention;
-- 
GitLab