1   /* Copyright 2002-2024 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  
18  package org.orekit.files.sinex;
19  
20  import java.util.HashMap;
21  import java.util.HashSet;
22  
23  import org.hipparchus.util.Pair;
24  import org.orekit.gnss.ObservationType;
25  import org.orekit.time.AbsoluteDate;
26  import org.orekit.utils.TimeSpanMap;
27  
28  /**
29   * Class to store DCB Solution data parsed in the SinexLoader.
30   * <p>
31   * This class is made to handle both station and satellite DCB data.
32   * Bias values are stored in TimeSpanMaps associated with a given pair
33   * of observation codes. Those TimeSpanMaps are stored in a Map, which
34   * associate a pair of observation code (as a HashSet of ObservationType)
35   * to a TimeSpanMap,  encapsulated in a DCBCode object.
36   * </p>
37   * @author Louis Aucouturier
38   * @since 12.0
39   */
40  public class Dcb {
41  
42      /** Ensemble of observation code pairs available for the satellite. */
43      private HashSet<Pair<ObservationType, ObservationType>> observationSets;
44  
45      /**
46       * Ensemble of DCBCode object, identifiable by observation code pairs,
47       * each containing the corresponding TimeSpanMap of biases (DCB).
48       */
49      private HashMap<Pair<ObservationType, ObservationType>, DcbCode> dcbCodeMap;
50  
51      /** Simple constructor. */
52      public Dcb() {
53          this.observationSets = new HashSet<>();
54          this.dcbCodeMap      = new HashMap<>();
55      }
56  
57      // Class to store the TimeSpanMap per DCB Observation Code set
58      private static class DcbCode {
59  
60          /** TimeSpanMap containing the DCB bias values. */
61          private TimeSpanMap<Double> dcbMap;
62  
63          /**
64           * Simple constructor.
65           */
66          DcbCode() {
67              this.dcbMap = new TimeSpanMap<>(null);
68          }
69  
70          /**
71           * Getter for the TimeSpanMap of DCB values.
72           *
73           * @return a time span map containing DCB values, for the observation code pair
74           * corresponding to this DCBCode object
75           */
76          public TimeSpanMap<Double> getDcbTimeMap() {
77              return dcbMap;
78          }
79  
80      }
81  
82      /**
83       * Add the content of a DCB line to the DCBSatellite object.
84       * <p>
85       * The method check the presence of a Code pair in a map, and add
86       * values to the corresponding TimeSpanMap.
87       * </p>
88       * @param obs1 String corresponding to the first code used for the DCB computation
89       * @param obs2 String corresponding to the second code used for the DCB computation
90       * @param spanBegin Absolute Date corresponding to the beginning of the validity span for this bias value
91       * @param spanEnd Absolute Date corresponding to the end of the validity span for this bias value
92       * @param biasValue DCB bias value expressed in S.I. units
93       */
94      public void addDcbLine(final String obs1, final String obs2,
95                             final AbsoluteDate spanBegin, final AbsoluteDate spanEnd,
96                             final double biasValue) {
97  
98          // Setting a pair of observation type.
99          final Pair<ObservationType, ObservationType> observationPair = new Pair<>(ObservationType.valueOf(obs1), ObservationType.valueOf(obs2));
100 
101         // If not present add a new DCBCode to the map, identified by the Observation Pair.
102         // Then add the bias value and validity period.
103         if (observationSets.add(observationPair)) {
104             dcbCodeMap.put(observationPair, new DcbCode());
105         }
106 
107         dcbCodeMap.get(observationPair).getDcbTimeMap().addValidBetween(biasValue, spanBegin, spanEnd);
108     }
109 
110     /**
111      * Get the value of the Differential Code Bias for a given observation pair
112      * and a at a given date.
113      *
114      * @param obs1 string corresponding to the first code used for the DCB computation
115      * @param obs2 string corresponding to the second code used for the DCB computation
116      * @param date date at which to obtain the DCB
117      * @return the value of the DCB in S.I. units
118      */
119     public double getDcb(final String obs1, final String obs2, final AbsoluteDate date) {
120         return getDcb(ObservationType.valueOf(obs1), ObservationType.valueOf(obs2), date);
121     }
122 
123     /**
124      * Get the value of the Differential Code Bias for a given observation pair
125      * and a at a given date.
126      *
127      * @param obs1 first observation type
128      * @param obs2 second observation type
129      * @param date date at which to obtain the DCB
130      * @return the value of the DCB in S.I. units
131      */
132     public double getDcb(final ObservationType obs1, final ObservationType obs2, final AbsoluteDate date) {
133         return getTimeSpanMap(obs1, obs2).get(date);
134     }
135 
136     /**
137      * Get all available observation code pairs for the satellite.
138      *
139      * @return HashSet(HashSet(ObservationType)) Observation code pairs obtained.
140      */
141     public HashSet<Pair<ObservationType, ObservationType>> getAvailableObservationPairs() {
142         return observationSets;
143     }
144 
145     /**
146      * Get the minimum valid date for a given observation pair.
147      *
148      * @param obs1 sString corresponding to the first code used for the DCB computation
149      * @param obs2 string corresponding to the second code used for the DCB computation
150      * @return minimum valid date for the observation pair
151      */
152     public AbsoluteDate getMinimumValidDateForObservationPair(final String obs1, final String obs2) {
153         return getMinimumValidDateForObservationPair(ObservationType.valueOf(obs1), ObservationType.valueOf(obs2));
154     }
155 
156     /**
157      * Get the minimum valid date for a given observation pair.
158      *
159      * @param obs1 first observation type
160      * @param obs2 second observation type
161      * @return minimum valid date for the observation pair
162      */
163     public AbsoluteDate getMinimumValidDateForObservationPair(final ObservationType obs1, final ObservationType obs2) {
164         return getTimeSpanMap(obs1, obs2).getFirstTransition().getDate();
165     }
166 
167     /**
168      * Get the maximum valid date for a given observation pair.
169      *
170      * @param obs1 string corresponding to the first code used for the DCB computation
171      * @param obs2 string corresponding to the second code used for the DCB computation
172      * @return maximum valid date for the observation pair
173      */
174     public AbsoluteDate getMaximumValidDateForObservationPair(final String obs1, final String obs2) {
175         return getMaximumValidDateForObservationPair(ObservationType.valueOf(obs1), ObservationType.valueOf(obs2));
176     }
177 
178     /**
179      * Get the maximum valid date for a given observation pair.
180      *
181      * @param obs1 first observation type
182      * @param obs2 second observation type
183      * @return maximum valid date for the observation pair
184      */
185     public AbsoluteDate getMaximumValidDateForObservationPair(final ObservationType obs1, final ObservationType obs2) {
186         return getTimeSpanMap(obs1, obs2).getLastTransition().getDate();
187     }
188 
189     /**
190      * Return the TimeSpanMap object for a given observation code pair,
191      * for further operation on the object directly.
192      *
193      * @param obs1 first observation type
194      * @param obs2 second observation type
195      * @return the time span map for a given observation code pair
196      */
197     private TimeSpanMap<Double> getTimeSpanMap(final ObservationType obs1, final ObservationType obs2) {
198         return dcbCodeMap.get(new Pair<>(obs1, obs2)).getDcbTimeMap();
199     }
200 
201 }
202