1   /* Copyright 2002-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.files.sinex;
18  
19  import java.util.HashMap;
20  import java.util.Map;
21  
22  import org.hipparchus.geometry.euclidean.threed.Vector3D;
23  import org.orekit.errors.OrekitException;
24  import org.orekit.errors.OrekitMessages;
25  import org.orekit.time.AbsoluteDate;
26  import org.orekit.utils.TimeSpanMap;
27  
28  /**
29   * Station model.
30   * <p>
31   * Since Orekit 11.1, this class handles multiple site antenna
32   * eccentricity. The {@link #getEccentricities()} method
33   * provides the last known eccentricity values.
34   * The {@link #getEccentricities(AbsoluteDate)} method can be
35   * used to access the site antenna eccentricity values for a
36   * given epoch.
37   * </p>
38   * @author Bryan Cazabonne
39   * @since 10.3
40   */
41  public class Station {
42  
43      /** Site code. */
44      private String siteCode;
45  
46      /** DOMES number. */
47      private String domes;
48  
49      /** Start of validity. */
50      private AbsoluteDate validFrom;
51  
52      /** End of validity. */
53      private AbsoluteDate validUntil;
54  
55      /** Eccentricity reference system. */
56      private ReferenceSystem eccRefSystem;
57  
58      /** Latest site antenna eccentricities (m). */
59      private Vector3D eccentricities;
60  
61      /** TimeSpanMap of site antenna eccentricities. */
62      private TimeSpanMap<Vector3D> eccentricitiesTimeSpanMap;
63  
64      /** Station position. */
65      private Vector3D position;
66  
67      /** Station velocity. */
68      private Vector3D velocity;
69  
70      /** Coordinates reference epoch. */
71      private AbsoluteDate epoch;
72  
73      /**
74       * Constructor.
75       */
76      public Station() {
77          this.eccentricities            = Vector3D.ZERO;
78          this.eccentricitiesTimeSpanMap = new TimeSpanMap<>(null);
79          this.position                  = Vector3D.ZERO;
80          this.velocity                  = Vector3D.ZERO;
81      }
82  
83      /**
84       * Get the site code (station identifier).
85       * @return the site code
86       */
87      public String getSiteCode() {
88          return siteCode;
89      }
90  
91      /**
92       * Set the site code (station identifier).
93       * @param siteCode the site code to set
94       */
95      public void setSiteCode(final String siteCode) {
96          this.siteCode = siteCode;
97      }
98  
99      /**
100      * Get the site DOMES number.
101      * @return the DOMES number
102      */
103     public String getDomes() {
104         return domes;
105     }
106 
107     /**
108      * Set the DOMES number.
109      * @param domes the DOMES number to set
110      */
111     public void setDomes(final String domes) {
112         this.domes = domes;
113     }
114 
115     /**
116      * Get start of validity.
117      * @return start of validity
118      */
119     public AbsoluteDate getValidFrom() {
120         if (validFrom == null) {
121             validFrom = eccentricitiesTimeSpanMap.getFirstTransition().getDate();
122         }
123         return validFrom;
124     }
125 
126     /**
127      * Set the start of validity.
128      * @param validFrom the start of validity to set
129      */
130     public void setValidFrom(final AbsoluteDate validFrom) {
131         this.validFrom = validFrom;
132     }
133 
134     /**
135      * Get end of validity.
136      * @return end of validity
137      */
138     public AbsoluteDate getValidUntil() {
139         if (validUntil == null) {
140             validUntil = eccentricitiesTimeSpanMap.getLastTransition().getDate();
141         }
142         return validUntil;
143     }
144 
145     /**
146      * Set the end of validity.
147      * @param validUntil the end of validity to set
148      */
149     public void setValidUntil(final AbsoluteDate validUntil) {
150         this.validUntil = validUntil;
151     }
152 
153     /**
154      * Get the reference system used to define the eccentricity vector (local or cartesian).
155      * @return the reference system used to define the eccentricity vector
156      */
157     public ReferenceSystem getEccRefSystem() {
158         return eccRefSystem;
159     }
160 
161     /**
162      * Set the reference system used to define the eccentricity vector (local or cartesian).
163      * @param eccRefSystem the reference system used to define the eccentricity vector
164      */
165     public void setEccRefSystem(final ReferenceSystem eccRefSystem) {
166         this.eccRefSystem = eccRefSystem;
167     }
168 
169     /**
170      * Get the last known station antenna eccentricities.
171      * <p>
172      * Vector convention: X-Y-Z or UP-NORTH-EAST.
173      * See {@link #getEccRefSystem()} method.
174      * </p>
175      * @return station antenna eccentricities (m)
176      */
177     public Vector3D getEccentricities() {
178         return eccentricities;
179     }
180 
181     /**
182      * Set the last known station antenna eccentricities.
183      * @param eccentricities the eccenticities to set (m)
184      */
185     public void setEccentricities(final Vector3D eccentricities) {
186         this.eccentricities = eccentricities;
187     }
188 
189     /**
190      * Get the station antenna eccentricities for the given epoch.
191      * <p>
192      * Vector convention: X-Y-Z or UP-NORTH-EAST.
193      * See {@link #getEccRefSystem()} method.
194      * <p>
195      * If there is no eccentricity values for the given epoch, an
196      * exception is thrown. It is possible to access the last known
197      * values using the {@link #getEccentricities()} method.
198      * @param date epoch
199      * @return station antenna eccentricities (m)
200      * @since 11.1
201      */
202     public Vector3D getEccentricities(final AbsoluteDate date) {
203         final Vector3D eccAtEpoch = eccentricitiesTimeSpanMap.get(date);
204         // If the entry is null, there is no valid eccentricity values for the input epoch
205         if (eccAtEpoch == null) {
206             // Throw an exception
207             throw new OrekitException(OrekitMessages.NO_STATION_ECCENTRICITY_FOR_EPOCH, date, getValidFrom(), getValidUntil());
208         }
209         return eccAtEpoch;
210     }
211 
212     /**
213      * Get the TimeSpanMap of site antenna eccentricities.
214      * @return the TimeSpanMap of site antenna eccentricities
215      * @since 11.1
216      */
217     public TimeSpanMap<Vector3D> getEccentricitiesTimeSpanMap() {
218         return eccentricitiesTimeSpanMap;
219     }
220 
221     /** Add a station eccentricity vector entry valid before a limit date.<br>
222      * Using <code>addStationEccentricitiesValidBefore(entry, t)</code> will make <code>entry</code>
223      * valid in ]-∞, t[ (note the open bracket).
224      * @param entry station eccentricity vector entry
225      * @param latestValidityDate date before which the entry is valid
226      * (must be different from <b>all</b> dates already used for transitions)
227      * @since 11.1
228      */
229     public void addStationEccentricitiesValidBefore(final Vector3D entry, final AbsoluteDate latestValidityDate) {
230         eccentricitiesTimeSpanMap.addValidBefore(entry, latestValidityDate, false);
231     }
232 
233     /** Add a station eccentricity vector entry valid after a limit date.<br>
234      * Using <code>addStationEccentricitiesValidAfter(entry, t)</code> will make <code>entry</code>
235      * valid in [t, +∞[ (note the closed bracket).
236      * @param entry station eccentricity vector entry
237      * @param earliestValidityDate date after which the entry is valid
238      * (must be different from <b>all</b> dates already used for transitions)
239      * @since 11.1
240      */
241     public void addStationEccentricitiesValidAfter(final Vector3D entry, final AbsoluteDate earliestValidityDate) {
242         eccentricitiesTimeSpanMap.addValidAfter(entry, earliestValidityDate, false);
243     }
244 
245     /**
246      * Get the station position.
247      * @return the station position (m)
248      */
249     public Vector3D getPosition() {
250         return position;
251     }
252 
253     /**
254      * Set the station position.
255      * @param position the position to set
256      */
257     public void setPosition(final Vector3D position) {
258         this.position = position;
259     }
260 
261     /**
262      * Get the station velocity.
263      * @return the station velocity (m/s)
264      */
265     public Vector3D getVelocity() {
266         return velocity;
267     }
268 
269     /**
270      * Set the station velocity.
271      * @param velocity the velocity to set
272      */
273     public void setVelocity(final Vector3D velocity) {
274         this.velocity = velocity;
275     }
276 
277     /**
278      * Get the coordinates reference epoch.
279      * @return the coordinates reference epoch
280      */
281     public AbsoluteDate getEpoch() {
282         return epoch;
283     }
284 
285     /**
286      * Set the coordinates reference epoch.
287      * @param epoch the epoch to set
288      */
289     public void setEpoch(final AbsoluteDate epoch) {
290         this.epoch = epoch;
291     }
292 
293     /** Eccentricity reference system. */
294     public enum ReferenceSystem {
295 
296         /** Local reference system Up, North, East. */
297         UNE("UNE"),
298 
299         /** Cartesian reference system X, Y, Z. */
300         XYZ("XYZ");
301 
302         /** Codes map. */
303         private static final Map<String, ReferenceSystem> CODES_MAP = new HashMap<>();
304         static {
305             for (final ReferenceSystem type : values()) {
306                 CODES_MAP.put(type.getName(), type);
307             }
308         }
309 
310         /** Name used to define the reference system in SINEX file. */
311         private final String name;
312 
313         /**
314          * Constructor.
315          * @param name name used to define the reference system in SINEX file
316          */
317         ReferenceSystem(final String name) {
318             this.name = name;
319         }
320 
321         /**
322          * Get the name used to define the reference system in SINEX file.
323          * @return the name
324          */
325         public String getName() {
326             return name;
327         }
328 
329         /**
330          * Get the eccentricity reference system corresponding to the given value.
331          * @param value given value
332          * @return the corresponding eccentricity reference system
333          */
334         public static ReferenceSystem getEccRefSystem(final String value) {
335             return CODES_MAP.get(value);
336         }
337 
338     }
339 
340 }
341