1   /* Copyright 2002-2026 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 org.orekit.time.AbsoluteDate;
21  import org.orekit.utils.TimeSpanMap;
22  
23  import java.util.HashMap;
24  import java.util.HashSet;
25  
26  /** Container for observation-specific signal bias for a single link endpoint
27   * (either emitter or receiver).
28   * <p>
29   * This class is made to handle both station and satellite OSB data.
30   * Bias values are stored in TimeSpanMaps associated with a given
31   * observation type. Those TimeSpanMaps are stored in a Map, which
32   * associate an observation code to a TimeSpanMap of double values.
33   * </p>
34   * @author Louis Aucouturier
35   * @author Luc Maisonobe
36   * @since 13.0
37   */
38  public class ObservableSpecificSignalBias {
39  
40      /** Set of observation types available for the satellite. */
41      private final HashSet<String> observationSets;
42  
43      /** Set of biases, identifiable by observation types,
44       * each containing the corresponding TimeSpanMap of biases.
45       */
46      private final HashMap<String, TimeSpanMap<Double>> biases;
47  
48      /** Simple constructor.
49       */
50      public ObservableSpecificSignalBias() {
51          this.observationSets = new HashSet<>();
52          this.biases          = new HashMap<>();
53      }
54  
55      /** Add a bias.
56       * @param obs observation used for the OSB computation
57       * @param spanBegin beginning of the validity span for this bias value
58       * @param spanEnd end of the validity span for this bias value
59       * @param biasValue Observable-specific Signal Bias value (meters for code and cycle for phase)
60       */
61      public void addBias(final String obs,
62                          final AbsoluteDate spanBegin, final AbsoluteDate spanEnd,
63                          final double biasValue) {
64  
65          // If not present add a new bias to the map, identified by the Observation type.
66          // Then add the bias value and validity period.
67          if (observationSets.add(obs)) {
68              biases.put(obs, new TimeSpanMap<>(null));
69          }
70  
71          biases.get(obs).addValidBetween(biasValue, spanBegin, spanEnd);
72      }
73  
74      /** Get the value of the Observable-specific Signal Bias for a given observation type at a given date.
75       * @param obs observation type
76       * @param date date at which to obtain the Observable-specific Signal Bias
77       * @return the value of the Observable-specific Signal Bias (meters for code and cycle for phase)
78       */
79      public double getBias(final String obs, final AbsoluteDate date) {
80          return getTimeSpanMap(obs).get(date);
81      }
82  
83      /** Get all available observation types for the satellite.
84       * @return Observation types obtained.
85       */
86      public HashSet<String> getAvailableObservations() {
87          return observationSets;
88      }
89  
90      /** Get the minimum valid date for a given observation type.
91       * @param obs observation type
92       * @return minimum valid date for the observation pair
93       */
94      public AbsoluteDate getMinimumValidDateForObservation(final String obs) {
95          final TimeSpanMap.Transition<Double> transition = getTimeSpanMap(obs).getFirstTransition();
96          return transition == null ? AbsoluteDate.PAST_INFINITY : transition.getDate();
97      }
98  
99      /** Get the maximum valid date for a given observation type.
100      * @param obs observation type
101      * @return maximum valid date for the observation pair
102      */
103     public AbsoluteDate getMaximumValidDateForObservation(final String obs) {
104         final TimeSpanMap.Transition<Double> transition = getTimeSpanMap(obs).getLastTransition();
105         return transition == null ? AbsoluteDate.FUTURE_INFINITY : transition.getDate();
106     }
107 
108     /** Get the TimeSpanMap object for a given observation type,
109      * for further operation on the object directly.
110      *
111      * @param obs observation type
112      * @return the time span map for a given observation code pair
113      */
114     public TimeSpanMap<Double> getTimeSpanMap(final String obs) {
115         return biases.get(obs);
116     }
117 
118 }