1   /* Copyright 2013-2025 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  
19  import org.orekit.rugged.errors.RuggedException;
20  import org.orekit.rugged.errors.RuggedMessages;
21  import org.orekit.rugged.linesensor.LineSensor;
22  import org.orekit.rugged.utils.GridCreation;
23  
24  /**
25   * Atmospheric refraction computation parameters.
26   * Defines for inverse location a set of parameters in order to be able to perform the computation.
27   * @author Guylaine Prat
28   * @since 2.1
29   */
30  
31  public class AtmosphericComputationParameters {
32  
33      /** Margin for definition of the interpolation grid.
34       * To be inside the min line and max line range to avoid problem with inverse location grid computation. */
35      private static final int MARGIN_LINE = 10;
36  
37      /** Default value for pixel step. */
38      private static final int DEFAULT_STEP_PIXEL = 100;
39      /** Default value for line step. */
40      private static final int DEFAULT_STEP_LINE = 100;
41  
42      /** Default margin for computation of inverse location with atmospheric refraction correction.
43      * @since 3.0
44      */
45      private static final double DEFAULT_INVLOC_MARGIN = 0.8;
46  
47      /** Actual values for pixel step in case default are overwritten. */
48      private int pixelStep;
49      /** Actual values for line step in case default are overwritten. */
50      private int lineStep;
51  
52      /** Actual values for inverse location margin with atmospheric refraction  in case default are overwritten.
53      * @since 3.0
54      */
55      private double invlocMargin;
56  
57      // Definition of grids for sensor (u = along pixel; v = along line)
58      /** Linear grid in pixel. */
59      private double[] uGrid;
60      /** Linear grid in line. */
61      private double[] vGrid;
62      /** Size of uGrid = nbPixelGrid. */
63      private int nbPixelGrid;
64      /** Size of vGrid = nbLineGrid. */
65      private int nbLineGrid;
66  
67      // Definition of the associated sensor
68      /** Current min line. */
69      private double minLineSensor = Double.NaN;
70      /** Current max line. */
71      private double maxLineSensor = Double.NaN;
72      /** Current sensor name. */
73      private String sensorName = null;
74  
75      /**
76       * Default constructor.
77       */
78      public AtmosphericComputationParameters() {
79          this.pixelStep = DEFAULT_STEP_PIXEL;
80          this.lineStep = DEFAULT_STEP_LINE;
81          this.invlocMargin = DEFAULT_INVLOC_MARGIN;
82      }
83  
84      /** Configuration of the interpolation grid. This grid is associated to the given sensor,
85       * with the given min and max lines.
86       * @param sensor line sensor
87       * @param minLine min line defined for the inverse location
88       * @param maxLine max line defined for the inverse location
89       */
90      public void configureCorrectionGrid(final LineSensor sensor, final int minLine, final int maxLine) {
91  
92          // Keep information about the sensor and the required search lines.
93          // Needed to test if the grid is initialized with this context.
94          this.minLineSensor = minLine;
95          this.maxLineSensor = maxLine;
96          this.sensorName = sensor.getName();
97  
98          // Compute the number of pixels and lines for the grid (round value is sufficient)
99          final int sensorNbPxs = sensor.getNbPixels();
100         this.nbPixelGrid = sensorNbPxs / this.pixelStep;
101 
102         // check the validity of the min and max lines
103         if ((maxLine - minLine + 1 - 2 * MARGIN_LINE) < 2 * this.lineStep) {
104             final String info = ": (maxLine - minLine + 1 - 2*" + MARGIN_LINE + ") < 2*" + this.lineStep;
105             throw new RuggedException(RuggedMessages.INVALID_RANGE_FOR_LINES, minLine, maxLine, info);
106         }
107         this.nbLineGrid = (maxLine - minLine + 1 - 2 * MARGIN_LINE) / this.lineStep;
108 
109         // Compute the linear grids in pixel (u index) and line (v index)
110         this.uGrid = GridCreation.createLinearGrid(0, sensorNbPxs - 1, this.nbPixelGrid);
111         this.vGrid = GridCreation.createLinearGrid(minLine + MARGIN_LINE, maxLine - MARGIN_LINE, this.nbLineGrid);
112 
113     }
114 
115     /**
116      * Set the grid steps in pixel and line (used to compute inverse location).
117      * Overwrite the default values, for time optimization if necessary.
118      * @param gridPixelStep grid pixel step for the inverse location computation
119      * @param gridLineStep grid line step for the inverse location computation
120      */
121     public void setGridSteps(final int gridPixelStep, final int gridLineStep) {
122 
123         if (gridPixelStep <= 0) {
124             final String reason = " pixelStep <= 0";
125             throw new RuggedException(RuggedMessages.INVALID_STEP, gridPixelStep, reason);
126         }
127         if (gridLineStep <= 0) {
128             final String reason = " lineStep <= 0";
129             throw new RuggedException(RuggedMessages.INVALID_STEP, gridLineStep, reason);
130         }
131         this.pixelStep = gridPixelStep;
132         this.lineStep = gridLineStep;
133     }
134 
135     /**
136      * Set the margin for computation of inverse location with atmospheric refraction correction.
137      * Overwrite the default value DEFAULT_INVLOC_MARGIN.
138      * No check is done about this margin. A recommended value is around 1.
139      * @param inverseLocMargin margin in pixel size to compute inverse location with atmospheric refraction correction.
140      * @since 3.0
141      */
142     public void setInverseLocMargin(final double inverseLocMargin) {
143         this.invlocMargin = inverseLocMargin;
144     }
145 
146     /**
147      * @return the inverse location margin for computation of inverse location with atmospheric refraction correction.
148     * @since 3.0
149     */
150     public double getInverseLocMargin () {
151         return this.invlocMargin;
152     }
153 
154     /**
155     * @return the default inverse location margin for computation of inverse location with atmospheric refraction correction.
156     * @since 3.0
157     */
158     public double getDefaultInverseLocMargin () {
159         return DEFAULT_INVLOC_MARGIN;
160     }
161 
162     /**
163      * @return the size of pixel grid
164      */
165     public int getNbPixelGrid() {
166         return nbPixelGrid;
167     }
168 
169     /**
170      * @return the size of line grid
171      */
172     public int getNbLineGrid() {
173         return nbLineGrid;
174     }
175 
176     /**
177      * @return the pixel grid
178      */
179     public double[] getUgrid() {
180         return uGrid.clone();
181     }
182 
183     /**
184      * @return the line grid
185      */
186     public double[] getVgrid() {
187         return vGrid.clone();
188     }
189 
190     /**
191      * @return the min line used to compute the current grids
192      */
193     public double getMinLineSensor() {
194         return minLineSensor;
195     }
196 
197     /**
198      * @return the max line used to compute the current grids
199      */
200     public double getMaxLineSensor() {
201         return maxLineSensor;
202     }
203 
204     /**
205      * @return the sensor name used to compute the current grids
206      */
207     public String getSensorName() {
208         return sensorName;
209     }
210 }