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.errors;
18  
19  import org.hipparchus.geometry.euclidean.threed.Vector3D;
20  import java.io.File;
21  import java.io.IOException;
22  import java.io.PrintWriter;
23  
24  import org.orekit.bodies.GeodeticPoint;
25  import org.orekit.frames.Transform;
26  import org.orekit.rugged.api.AlgorithmId;
27  import org.orekit.rugged.linesensor.LineSensor;
28  import org.orekit.rugged.linesensor.SensorMeanPlaneCrossing;
29  import org.orekit.rugged.linesensor.SensorPixel;
30  import org.orekit.rugged.raster.Tile;
31  import org.orekit.rugged.utils.ExtendedEllipsoid;
32  import org.orekit.rugged.utils.SpacecraftToObservedBody;
33  import org.orekit.time.AbsoluteDate;
34  
35  /**
36   * Class managing debug dumps.
37   * <p>
38   * <em>WARNING</em>: this class is public only for technical reasons,
39   * it is not considered to belong to the public API of the library and should
40   * not be called by user code. It is only intended to be called internally by
41   * the Rugged library itself. This class may be changed or even removed at any
42   * time, so user code should not rely on it.
43   * </p>
44   * @author Luc Maisonobe
45   * @author Guylaine Prat
46   */
47  public class DumpManager {
48  
49      /** Dump file (default initial value is null, i.e. nothing is dumped). */
50      private static final ThreadLocal<Dump> DUMP = new ThreadLocal<Dump>();
51  
52      /** Boolean to check if the dump is suspended. */
53      private static boolean isSuspended = false;
54  
55      /** Private constructor for utility class.
56       */
57      private DumpManager() {
58          // by default, nothing is dumped
59      }
60  
61      /** Activate debug dump.
62       * @param file dump file
63       */
64      public static void activate(final File file) {
65          if (isActive()) {
66              throw new RuggedException(RuggedMessages.DEBUG_DUMP_ALREADY_ACTIVE);
67          } else {
68              try {
69                  DUMP.set(new Dump(new PrintWriter(file, "UTF-8")));
70              } catch (IOException ioe) {
71                  throw new RuggedException(ioe, RuggedMessages.DEBUG_DUMP_ACTIVATION_ERROR,
72                                            file.getAbsolutePath(), ioe.getLocalizedMessage());
73              }
74          }
75      }
76  
77      /** Deactivate debug dump.
78       */
79      public static void deactivate() {
80          if (isActive()) {
81              DUMP.get().deactivate();
82              DUMP.set(null);
83          } else {
84              throw new RuggedException(RuggedMessages.DEBUG_DUMP_NOT_ACTIVE);
85          }
86      }
87  
88      /** Suspend the dump.
89       * In case the dump is already suspended, keep the previous status in order to
90       * correctly deal the resume stage.
91       * @return a flag to tell if the dump is already suspended (true; false otherwise)
92       */
93      public static Boolean suspend() {
94          // Check if the dump is already suspended
95          if (isSuspended) {
96              return isSuspended;
97          } else {
98              isSuspended = true;
99              return false;
100         }
101     }
102 
103     /** Resume the dump, only if it was not already suspended.
104      * @param wasSuspended flag to tell if the dump was already suspended (true; false otherwise)
105      */
106     public static void resume(final Boolean wasSuspended) {
107         if (!wasSuspended) {
108             isSuspended = false;
109         }
110     }
111 
112     /** In case dump is suspended and an exception is thrown,
113      * allows the dump to end nicely.
114      */
115     public static void endNicely() {
116         isSuspended = false;
117         if (isActive()) deactivate();
118 
119     }
120 
121     /** Check if dump is active for this thread.
122      * @return true if dump is active for this thread
123      */
124     public static boolean isActive() {
125         return DUMP.get() != null && !isSuspended;
126     }
127 
128     /** Dump DEM cell data.
129      * @param tile tile to which the cell belongs
130      * @param latitudeIndex latitude index of the cell
131      * @param longitudeIndex longitude index of the cell
132      * @param elevation elevation of the cell
133      */
134     public static void dumpTileCell(final Tile tile,
135                                     final int latitudeIndex, final int longitudeIndex,
136                                     final double elevation) {
137         if (isActive()) {
138             DUMP.get().dumpTileCell(tile, latitudeIndex, longitudeIndex, elevation);
139         }
140     }
141 
142     /** Dump algorithm data.
143      * @param algorithmId algorithm ID
144      */
145     public static void dumpAlgorithm(final AlgorithmId algorithmId) {
146         if (isActive()) {
147             DUMP.get().dumpAlgorithm(algorithmId);
148         }
149     }
150 
151     /** Dump algorithm data.
152      * @param algorithmId algorithm ID
153      * @param specific algorithm specific extra data
154      */
155     public static void dumpAlgorithm(final AlgorithmId algorithmId, final double specific) {
156         if (isActive()) {
157             DUMP.get().dumpAlgorithm(algorithmId, specific);
158         }
159     }
160 
161     /** Dump ellipsoid data.
162      * @param ellipsoid ellipsoid to dump
163      */
164     public static void dumpEllipsoid(final ExtendedEllipsoid ellipsoid) {
165         if (isActive()) {
166             DUMP.get().dumpEllipsoid(ellipsoid);
167         }
168     }
169 
170     /** Dump a direct location computation.
171      * @param date date of the location
172      * @param sensorPosition sensor position in spacecraft frame
173      * @param los normalized line-of-sight in spacecraft frame
174      * @param lightTimeCorrection flag for light time correction
175      * @param aberrationOfLightCorrection flag for aberration of light correction
176      * @param refractionCorrection flag for refraction correction
177      */
178     public static void dumpDirectLocation(final AbsoluteDate date, final Vector3D sensorPosition, final Vector3D los,
179                                           final boolean lightTimeCorrection, final boolean aberrationOfLightCorrection,
180                                           final boolean refractionCorrection) {
181         if (isActive()) {
182             DUMP.get().dumpDirectLocation(date, sensorPosition, los, lightTimeCorrection, aberrationOfLightCorrection,
183                                           refractionCorrection);
184         }
185     }
186 
187     /** Dump a direct location result.
188      * @param gp resulting geodetic point
189      */
190     public static void dumpDirectLocationResult(final GeodeticPoint gp) {
191         if (isActive()) {
192             DUMP.get().dumpDirectLocationResult(gp);
193         }
194     }
195 
196     /** Dump an inverse location computation.
197      * @param sensor sensor
198      * @param point point to localize
199      * @param ellipsoid the used ellipsoid
200      * @param minLine minimum line number
201      * @param maxLine maximum line number
202      * @param lightTimeCorrection flag for light time correction
203      * @param aberrationOfLightCorrection flag for aberration of light correction
204      * @param refractionCorrection flag for refraction correction
205      */
206     public static void dumpInverseLocation(final LineSensor sensor, final GeodeticPoint point,
207                                            final ExtendedEllipsoid ellipsoid,
208                                            final int minLine, final int maxLine,
209                                            final boolean lightTimeCorrection, final boolean aberrationOfLightCorrection,
210                                            final boolean refractionCorrection) {
211         if (isActive()) {
212             DUMP.get().dumpInverseLocation(sensor, point, minLine, maxLine,
213                                            lightTimeCorrection, aberrationOfLightCorrection, refractionCorrection);
214             DUMP.get().dumpEllipsoid(ellipsoid);
215         }
216     }
217 
218     /** Dump an inverse location result.
219      * @param pixel resulting sensor pixel
220      */
221     public static void dumpInverseLocationResult(final SensorPixel pixel) {
222         if (isActive()) {
223             DUMP.get().dumpInverseLocationResult(pixel);
224         }
225     }
226 
227     /** Dump an observation transform transform.
228      * @param scToBody provider for observation
229      * @param index index of the transform
230      * @param bodyToInertial transform from body frame to inertial frame
231      * @param scToInertial transfrom from spacecraft frame to inertial frame
232      */
233     public static void dumpTransform(final SpacecraftToObservedBody scToBody, final int index,
234                                      final Transform bodyToInertial, final Transform scToInertial) {
235         if (isActive()) {
236             DUMP.get().dumpTransform(scToBody, index, bodyToInertial, scToInertial);
237         }
238     }
239 
240     /** Dump a sensor mean plane.
241      * @param meanPlane mean plane associated with sensor
242      */
243     public static void dumpSensorMeanPlane(final SensorMeanPlaneCrossing meanPlane) {
244         if (isActive()) {
245             DUMP.get().dumpSensorMeanPlane(meanPlane);
246         }
247     }
248 
249     /** Dump a sensor LOS.
250      * @param sensor sensor
251      * @param date date
252      * @param i pixel index
253      * @param los pixel normalized line-of-sight
254      */
255     public static void dumpSensorLOS(final LineSensor sensor, final AbsoluteDate date, final int i, final Vector3D los) {
256         if (isActive()) {
257             DUMP.get().dumpSensorLOS(sensor, date, i, los);
258         }
259     }
260 
261     /** Dump a sensor datation.
262      * @param sensor sensor
263      * @param lineNumber line number
264      * @param date date
265      */
266     public static void dumpSensorDatation(final LineSensor sensor, final double lineNumber, final AbsoluteDate date) {
267         if (isActive()) {
268             DUMP.get().dumpSensorDatation(sensor, lineNumber, date);
269         }
270     }
271 
272     /** Dump a sensor rate.
273      * @param sensor sensor
274      * @param lineNumber line number
275      * @param rate lines rate
276      */
277     public static void dumpSensorRate(final LineSensor sensor, final double lineNumber, final double rate) {
278         if (isActive()) {
279             DUMP.get().dumpSensorRate(sensor, lineNumber, rate);
280         }
281     }
282 
283 }