1   /* Copyright 2022-2025 Luc Maisonobe
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 org.orekit.gnss.MeasurementType;
20  import org.orekit.gnss.ObservationType;
21  import org.orekit.gnss.SatInSystem;
22  import org.orekit.time.AbsoluteDate;
23  import org.orekit.utils.Constants;
24  
25  import java.util.function.Predicate;
26  
27  /** Predicates for bias solution blocks.
28   * @author Luc Maisonobe
29   * @since 13.0
30   */
31  enum BiasSolutionPredicate implements Predicate<SinexBiasParseInfo> {
32  
33      /** Predicate for DSB line. */
34      DSB {
35          /** {@inheritDoc} */
36          @Override
37          protected void store(final SinexBiasParseInfo parseInfo,
38                               final String svn, final SatInSystem satId, final String siteCode,
39                               final ObservationType obs1, final ObservationType obs2,
40                               final AbsoluteDate start, final AbsoluteDate end,
41                               final double bias) {
42              if (siteCode.isEmpty()) {
43                  // this is a satellite bias
44                  final SatelliteDifferentialSignalBias dsb = parseInfo.getSatelliteDsb(satId);
45                  dsb.getDsb().addBias(obs1, obs2, start, end, bias);
46              } else {
47                  // this is a station bias
48                  final StationDifferentialSignalBias dsb = parseInfo.getStationDsb(siteCode);
49                  dsb.getDsb(satId.getSystem()).addBias(obs1, obs2, start, end, bias);
50              }
51          }
52      },
53  
54      /** Predicate for OSB line. */
55      OSB {
56          /** {@inheritDoc} */
57          @Override
58          protected void store(final SinexBiasParseInfo parseInfo,
59                               final String svn, final SatInSystem satId, final String siteCode,
60                               final ObservationType obs1, final ObservationType obs2,
61                               final AbsoluteDate start, final AbsoluteDate end,
62                               final double bias) {
63              if (siteCode.isEmpty()) {
64                  // this is a satellite bias
65                  final SatelliteObservableSpecificSignalBias osb = parseInfo.getSatelliteOsb(satId);
66                  osb.getOsb().addBias(obs1, start, end, bias);
67              } else {
68                  // this is a station bias
69                  final StationObservableSpecificSignalBias osb = parseInfo.getStationOsb(siteCode);
70                  osb.getOsb(satId.getSystem()).addBias(obs1, start, end, bias);
71              }
72          }
73      };
74  
75      /** {@inheritDoc} */
76      @Override
77      public boolean test(final SinexBiasParseInfo parseInfo) {
78          if (name().equals(parseInfo.parseString(1, 3))) {
79              // this is the data type we are concerned with
80              final String          svn      = parseInfo.parseString(6, 4);
81              final SatInSystem     satId    = new SatInSystem(parseInfo.parseString(11, 3));
82              final String          siteCode = parseInfo.parseString(15, 9);
83              final ObservationType obs1     = parseInfo.parseObservationType(satId.getSystem(), 25, 4);
84              final ObservationType obs2     = parseInfo.parseObservationType(satId.getSystem(), 30, 4);
85              final AbsoluteDate    start    = parseInfo.stringEpochToAbsoluteDate(parseInfo.parseString(35, 14), true);
86              final AbsoluteDate    end      = parseInfo.stringEpochToAbsoluteDate(parseInfo.parseString(50, 14), false);
87  
88              // code biases are in time units (ns converted to seconds by parseDoubleWithUnit),
89              // they must be converted to meters
90              // phase biases are in cycles, no conversion is needed for them
91              final double          factor   =
92                  obs1.getMeasurementType() == MeasurementType.PSEUDO_RANGE ? Constants.SPEED_OF_LIGHT :  1;
93              final double          bias     = factor * parseInfo.parseDoubleWithUnit(65, 4, 70, 21);
94  
95              store(parseInfo, svn, satId, siteCode, obs1, obs2, start, end, bias);
96              return true;
97          } else {
98              // it is a data type for another predicate
99              return false;
100         }
101     }
102 
103     /** Store parsed fields.
104      * @param parseInfo container for parse info
105      * @param svn satellite SVN
106      * @param satId satellite identifier
107      * @param siteCode station site code
108      * @param obs1 code of first observable
109      * @param obs2 code of second observable
110      * @param start validity start date
111      * @param end validity end date
112      * @param bias estimated bias
113      */
114     protected abstract void store(SinexBiasParseInfo parseInfo,
115                                   String svn, SatInSystem satId, String siteCode,
116                                   ObservationType obs1, ObservationType obs2,
117                                   AbsoluteDate start, AbsoluteDate end,
118                                   double bias);
119 
120 }