1 /* Copyright 2013-2019 CS Systèmes d'Information
2 * Licensed to CS Systèmes d'Information (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
19 import org.hipparchus.analysis.interpolation.BilinearInterpolatingFunction;
20 import org.hipparchus.geometry.euclidean.threed.Vector3D;
21 import org.orekit.rugged.errors.RuggedException;
22 import org.orekit.rugged.errors.RuggedMessages;
23 import org.orekit.rugged.intersection.IntersectionAlgorithm;
24 import org.orekit.rugged.linesensor.LineSensor;
25 import org.orekit.rugged.linesensor.SensorPixel;
26 import org.orekit.rugged.utils.NormalizedGeodeticPoint;
27
28 /**
29 * Base class for atmospheric refraction model.
30 * @author Sergio Esteves
31 * @author Guylaine Prat
32 * @since 2.0
33 */
34 public abstract class AtmosphericRefraction {
35
36 /** Flag to tell if we must compute the correction.
37 * By default: computation is set up.
38 * @since 2.1
39 */
40 private boolean mustBeComputed;
41
42 /** The current atmospheric parameters.
43 * @since 2.1
44 */
45 private AtmosphericComputationParameters atmosphericParams;
46
47 /** Bilinear interpolating function for pixel (used by inverse location).
48 * @since 2.1
49 */
50 private BilinearInterpolatingFunction bifPixel;
51
52 /** Bilinear interpolating function of line (used by inverse location).
53 * @since 2.1
54 */
55 private BilinearInterpolatingFunction bifLine;
56
57 /**
58 * Default constructor.
59 */
60 protected AtmosphericRefraction() {
61 // Set up the atmospheric parameters ... with lazy evaluation of the grid (done only if necessary)
62 this.atmosphericParams = new AtmosphericComputationParameters();
63 this.mustBeComputed = true;
64 this.bifPixel = null;
65 this.bifLine = null;
66 }
67
68 /** Apply correction to the intersected point with an atmospheric refraction model.
69 * @param satPos satellite position, in <em>body frame</em>
70 * @param satLos satellite line of sight, in <em>body frame</em>
71 * @param rawIntersection intersection point before refraction correction
72 * @param algorithm intersection algorithm
73 * @return corrected point with the effect of atmospheric refraction
74 * {@link org.orekit.rugged.utils.ExtendedEllipsoid#pointAtAltitude(Vector3D, Vector3D, double)} or see
75 * {@link org.orekit.rugged.intersection.IntersectionAlgorithm#refineIntersection(org.orekit.rugged.utils.ExtendedEllipsoid, Vector3D, Vector3D, NormalizedGeodeticPoint)}
76 */
77 public abstract NormalizedGeodeticPointnt.html#NormalizedGeodeticPoint">NormalizedGeodeticPoint applyCorrection(Vector3D satPos, Vector3D satLos, NormalizedGeodeticPoint rawIntersection,
78 IntersectionAlgorithm algorithm);
79
80 /** Deactivate computation (needed for the inverse location computation).
81 * @since 2.1
82 */
83 public void deactivateComputation() {
84 this.mustBeComputed = false;
85 }
86
87 /** Reactivate computation (needed for the inverse location computation).
88 * @since 2.1
89 */
90 public void reactivateComputation() {
91 this.mustBeComputed = true;
92 }
93
94 /** Tell if the computation must be performed.
95 * @return true if computation must be performed; false otherwise
96 * @since 2.1
97 */
98 public boolean mustBeComputed() {
99 return mustBeComputed;
100 }
101
102 /** Configuration of the interpolation grid. This grid is associated to the given sensor,
103 * with the given min and max lines.
104 * @param sensor line sensor
105 * @param minLine min line defined for the inverse location
106 * @param maxLine max line defined for the inverse location
107 * @since 2.1
108 */
109 public void configureCorrectionGrid(final LineSensor sensor, final int minLine, final int maxLine) {
110
111 atmosphericParams.configureCorrectionGrid(sensor, minLine, maxLine);
112 }
113
114 /** Check if the current atmospheric parameters are the same as the asked ones.
115 * @param sensorName the asked sensor name
116 * @param minLine the asked min line
117 * @param maxLine the asked max line
118 * @return true if same context; false otherwise
119 * @since 2.1
120 */
121 public Boolean isSameContext(final String sensorName, final int minLine, final int maxLine) {
122
123 return (Double.compare(atmosphericParams.getMinLineSensor(), minLine) == 0) &&
124 (Double.compare(atmosphericParams.getMaxLineSensor(), maxLine) == 0) &&
125 (atmosphericParams.getSensorName().compareTo(sensorName) == 0);
126 }
127
128 /** Get the computation parameters.
129 * @return the AtmosphericComputationParameters
130 * @since 2.1
131 */
132 public AtmosphericComputationParameters getComputationParameters() {
133 return atmosphericParams;
134 }
135
136 /** Set the grid steps in pixel and line (used to compute inverse location).
137 * Overwrite the default values, for time optimization for instance.
138 * @param pixelStep pixel step for the inverse location computation
139 * @param lineStep line step for the inverse location computation
140 * @since 2.1
141 */
142 public void setGridSteps(final int pixelStep, final int lineStep) {
143 atmosphericParams.setGridSteps(pixelStep, lineStep);
144 }
145
146 /** Compute the correction functions for pixel and lines.
147 * The corrections are computed for pixels and lines, on a regular grid at sensor level.
148 * The corrections are based on the difference on grid nodes (where direct loc is known with atmosphere refraction)
149 * and the sensor pixel found by inverse loc without atmosphere refraction.
150 * The bilinear interpolating functions are then computed for pixel and for line.
151 * Need to be computed only once for a given sensor with the same minLine and maxLine.
152 * @param sensorPixelGridInverseWithout inverse location grid WITHOUT atmospheric refraction
153 * @since 2.1
154 */
155 public void computeGridCorrectionFunctions(final SensorPixel[][] sensorPixelGridInverseWithout) {
156
157 final int nbPixelGrid = atmosphericParams.getNbPixelGrid();
158 final int nbLineGrid = atmosphericParams.getNbLineGrid();
159 final double[] pixelGrid = atmosphericParams.getUgrid();
160 final double[] lineGrid = atmosphericParams.getVgrid();
161
162 // Initialize the needed diff functions
163 final double[][] gridDiffPixel = new double[nbPixelGrid][nbLineGrid];
164 final double[][] gridDiffLine = new double[nbPixelGrid][nbLineGrid];
165
166 // Compute the difference between grids nodes WITH - without atmosphere
167 for (int lineIndex = 0; lineIndex < nbLineGrid; lineIndex++) {
168 for (int pixelIndex = 0; pixelIndex < nbPixelGrid; pixelIndex++) {
169
170 if (sensorPixelGridInverseWithout[pixelIndex][lineIndex] != null) {
171 final double diffLine = lineGrid[lineIndex] - sensorPixelGridInverseWithout[pixelIndex][lineIndex].getLineNumber();
172 final double diffPixel = pixelGrid[pixelIndex] - sensorPixelGridInverseWithout[pixelIndex][lineIndex].getPixelNumber();
173 gridDiffPixel[pixelIndex][lineIndex] = diffPixel;
174 gridDiffLine[pixelIndex][lineIndex] = diffLine;
175
176 } else {
177 // Impossible to find the point in the given min line and max line
178 throw new RuggedException(RuggedMessages.INVALID_RANGE_FOR_LINES,
179 atmosphericParams.getMinLineSensor(), atmosphericParams.getMaxLineSensor(), "");
180 }
181 }
182 }
183 // Definition of the interpolating function for pixel and for line
184 this.bifPixel = new BilinearInterpolatingFunction(pixelGrid, lineGrid, gridDiffPixel);
185 this.bifLine = new BilinearInterpolatingFunction(pixelGrid, lineGrid, gridDiffLine);
186 }
187
188 /**
189 * @return the bilinear interpolating function for pixel correction
190 */
191 public BilinearInterpolatingFunction getBifPixel() {
192 return bifPixel;
193 }
194
195 /**
196 * @return the bilinear interpolating function for line correction
197 */
198 public BilinearInterpolatingFunction getBifLine() {
199 return bifLine;
200 }
201 }