AtmosphericRefraction.java

  1. /* Copyright 2013-2022 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.rugged.refraction;

  18. import org.hipparchus.analysis.interpolation.BilinearInterpolatingFunction;
  19. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  20. import org.orekit.rugged.errors.RuggedException;
  21. import org.orekit.rugged.errors.RuggedMessages;
  22. import org.orekit.rugged.intersection.IntersectionAlgorithm;
  23. import org.orekit.rugged.linesensor.LineSensor;
  24. import org.orekit.rugged.linesensor.SensorPixel;
  25. import org.orekit.rugged.utils.NormalizedGeodeticPoint;

  26. /**
  27.  * Base class for atmospheric refraction model.
  28.  * @author Sergio Esteves
  29.  * @author Guylaine Prat
  30.  * @since 2.0
  31.  */
  32. public abstract class AtmosphericRefraction {

  33.     /** Flag to tell if we must compute the correction.
  34.      * By default: computation is set up.
  35.      * @since 2.1
  36.      */
  37.     private boolean mustBeComputed;

  38.     /** The current atmospheric parameters.
  39.      * @since 2.1
  40.      */
  41.     private AtmosphericComputationParameters atmosphericParams;

  42.     /** Bilinear interpolating function for pixel (used by inverse location).
  43.      * @since 2.1
  44.     */
  45.     private BilinearInterpolatingFunction bifPixel;

  46.     /** Bilinear interpolating function of line (used by inverse location).
  47.      * @since 2.1
  48.     */
  49.     private BilinearInterpolatingFunction bifLine;

  50.     /**
  51.      * Default constructor.
  52.      */
  53.     protected AtmosphericRefraction() {
  54.         // Set up the atmospheric parameters ... with lazy evaluation of the grid (done only if necessary)
  55.         this.atmosphericParams = new AtmosphericComputationParameters();
  56.         this.mustBeComputed    = true;
  57.         this.bifPixel          = null;
  58.         this.bifLine           = null;
  59.     }

  60.     /** Apply correction to the intersected point with an atmospheric refraction model.
  61.      * @param satPos satellite position, in <em>body frame</em>
  62.      * @param satLos satellite line of sight, in <em>body frame</em>
  63.      * @param rawIntersection intersection point before refraction correction
  64.      * @param algorithm intersection algorithm
  65.      * @return corrected point with the effect of atmospheric refraction
  66.      * {@link org.orekit.rugged.utils.ExtendedEllipsoid#pointAtAltitude(Vector3D, Vector3D, double)} or see
  67.      * {@link org.orekit.rugged.intersection.IntersectionAlgorithm#refineIntersection(org.orekit.rugged.utils.ExtendedEllipsoid, Vector3D, Vector3D, NormalizedGeodeticPoint)}
  68.      */
  69.     public abstract NormalizedGeodeticPoint applyCorrection(Vector3D satPos, Vector3D satLos, NormalizedGeodeticPoint rawIntersection,
  70.                                             IntersectionAlgorithm algorithm);

  71.     /** Deactivate computation (needed for the inverse location computation).
  72.      * @since 2.1
  73.      */
  74.     public void deactivateComputation() {
  75.         this.mustBeComputed = false;
  76.     }

  77.     /** Reactivate computation (needed for the inverse location computation).
  78.      * @since 2.1
  79.      */
  80.     public void reactivateComputation() {
  81.         this.mustBeComputed = true;
  82.     }

  83.     /** Tell if the computation must be performed.
  84.      * @return true if computation must be performed; false otherwise
  85.      * @since 2.1
  86.      */
  87.     public boolean mustBeComputed() {
  88.         return mustBeComputed;
  89.     }

  90.     /** Configuration of the interpolation grid. This grid is associated to the given sensor,
  91.      * with the given min and max lines.
  92.      * @param sensor line sensor
  93.      * @param minLine min line defined for the inverse location
  94.      * @param maxLine max line defined for the inverse location
  95.      * @since 2.1
  96.      */
  97.     public void configureCorrectionGrid(final LineSensor sensor, final int minLine, final int maxLine) {

  98.         atmosphericParams.configureCorrectionGrid(sensor, minLine, maxLine);
  99.     }

  100.    /** Check if the current atmospheric parameters are the same as the asked ones.
  101.     * @param sensorName the asked sensor name
  102.     * @param minLine the asked min line
  103.     * @param maxLine the asked max line
  104.     * @return true if same context; false otherwise
  105.     * @since 2.1
  106.     */
  107.     public Boolean isSameContext(final String sensorName, final int minLine, final int maxLine) {

  108.         return Double.compare(atmosphericParams.getMinLineSensor(), minLine) == 0 &&
  109.                Double.compare(atmosphericParams.getMaxLineSensor(), maxLine) == 0 &&
  110.                atmosphericParams.getSensorName().compareTo(sensorName) == 0;
  111.     }

  112.     /** Get the computation parameters.
  113.      * @return the AtmosphericComputationParameters
  114.      * @since 2.1
  115.      */
  116.     public AtmosphericComputationParameters getComputationParameters() {
  117.         return atmosphericParams;
  118.     }

  119.     /** Set the grid steps in pixel and line (used to compute inverse location).
  120.      * Overwrite the default values, for time optimization for instance.
  121.      * @param pixelStep pixel step for the inverse location computation
  122.      * @param lineStep line step for the inverse location computation
  123.      * @since 2.1
  124.      */
  125.     public void setGridSteps(final int pixelStep, final int lineStep) {
  126.         atmosphericParams.setGridSteps(pixelStep, lineStep);
  127.     }

  128.     /**
  129.      * Set the margin for computation of inverse location with atmospheric refraction correction.
  130.      * Overwrite the default value DEFAULT_INVLOC_MARGIN.
  131.      * No check is done about this margin. A recommended value is around 1.
  132.      * @param inverseLocMargin margin in pixel size to compute inverse location with atmospheric refraction correction.
  133.      * @since 3.0
  134.      */
  135.     public void setInverseLocMargin(final double inverseLocMargin) {
  136.         atmosphericParams.setInverseLocMargin(inverseLocMargin);
  137.     }

  138.     /** Compute the correction functions for pixel and lines.
  139.      * The corrections are computed for pixels and lines, on a regular grid at sensor level.
  140.      * The corrections are based on the difference on grid nodes (where direct loc is known with atmosphere refraction)
  141.      * and the sensor pixel found by inverse loc without atmosphere refraction.
  142.      * The bilinear interpolating functions are then computed for pixel and for line.
  143.      * Need to be computed only once for a given sensor with the same minLine and maxLine.
  144.      * @param sensorPixelGridInverseWithout inverse location grid WITHOUT atmospheric refraction
  145.      * @since 2.1
  146.      */
  147.     public void computeGridCorrectionFunctions(final SensorPixel[][] sensorPixelGridInverseWithout) {

  148.         final int nbPixelGrid = atmosphericParams.getNbPixelGrid();
  149.         final int nbLineGrid = atmosphericParams.getNbLineGrid();
  150.         final double[] pixelGrid = atmosphericParams.getUgrid();
  151.         final double[] lineGrid = atmosphericParams.getVgrid();

  152.         // Initialize the needed diff functions
  153.         final double[][] gridDiffPixel = new double[nbPixelGrid][nbLineGrid];
  154.         final double[][] gridDiffLine = new double[nbPixelGrid][nbLineGrid];

  155.         // Compute the difference between grids nodes WITH - without atmosphere
  156.         for (int lineIndex = 0; lineIndex < nbLineGrid; lineIndex++) {
  157.             for (int pixelIndex = 0; pixelIndex < nbPixelGrid; pixelIndex++) {

  158.                 if (sensorPixelGridInverseWithout[pixelIndex][lineIndex] != null) {
  159.                     final double diffLine = lineGrid[lineIndex] - sensorPixelGridInverseWithout[pixelIndex][lineIndex].getLineNumber();
  160.                     final double diffPixel = pixelGrid[pixelIndex] - sensorPixelGridInverseWithout[pixelIndex][lineIndex].getPixelNumber();
  161.                     gridDiffPixel[pixelIndex][lineIndex] = diffPixel;
  162.                     gridDiffLine[pixelIndex][lineIndex] = diffLine;

  163.                 } else {
  164.                     // Impossible to find the sensor pixel in the given range lines
  165.                     throw new RuggedException(RuggedMessages.SENSOR_PIXEL_NOT_FOUND_IN_RANGE_LINES,
  166.                                               atmosphericParams.getMinLineSensor(), atmosphericParams.getMaxLineSensor());
  167.                 }
  168.             }
  169.         }
  170.         // Definition of the interpolating function for pixel and for line
  171.         this.bifPixel = new BilinearInterpolatingFunction(pixelGrid, lineGrid, gridDiffPixel);
  172.         this.bifLine = new BilinearInterpolatingFunction(pixelGrid, lineGrid, gridDiffLine);
  173.     }

  174.     /**
  175.      * @return the bilinear interpolating function for pixel correction
  176.      */
  177.     public BilinearInterpolatingFunction getBifPixel() {
  178.         return bifPixel;
  179.     }

  180.     /**
  181.      * @return the bilinear interpolating function for line correction
  182.      */
  183.     public BilinearInterpolatingFunction getBifLine() {
  184.         return bifLine;
  185.     }
  186. }