1   /* Copyright 2002-2025 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 org.hipparchus.geometry.euclidean.threed.Vector3D;
20  import org.orekit.frames.EopHistoryLoader;
21  import org.orekit.frames.ITRFVersion;
22  import org.orekit.gnss.GnssSignal;
23  import org.orekit.gnss.SatInSystem;
24  import org.orekit.time.AbsoluteDate;
25  import org.orekit.time.ChronologicalComparator;
26  import org.orekit.time.TimeScales;
27  
28  import java.util.Collections;
29  import java.util.Map;
30  import java.util.SortedSet;
31  import java.util.TreeSet;
32  
33  /**
34   * Container for Solution INdependent EXchange (SINEX) files.
35   * @author Bryan Cazabonne
36   * @author Luc Maisonobe
37   * @since 13.0
38   */
39  public class Sinex extends AbstractSinex {
40  
41      /** Satellites phase centers. */
42      private final Map<SatInSystem, Map<GnssSignal, Vector3D>> satellitesPhaseCenters;
43  
44      /** Station data. */
45      private final Map<String, Station> stations;
46  
47      /** Earth Orientation Parameters data. */
48      private final Map<AbsoluteDate, SinexEopEntry> eop;
49  
50      /** Simple constructor.
51       * @param timeScales time scales
52       * @param creationDate SINEX file creation date
53       * @param startDate start time of the data used in the Sinex solution
54       * @param endDate end time of the data used in the Sinex solution
55       * @param satellitesPhaseCenters satellites phase centers
56       * @param stations station data
57       * @param eop Earth Orientation Parameters data
58       */
59      public Sinex(final TimeScales timeScales,
60                   final AbsoluteDate creationDate, final AbsoluteDate startDate, final AbsoluteDate endDate,
61                   final Map<SatInSystem, Map<GnssSignal, Vector3D>> satellitesPhaseCenters,
62                   final Map<String, Station> stations, final Map<AbsoluteDate, SinexEopEntry> eop) {
63          super(timeScales, creationDate, startDate, endDate);
64          this.satellitesPhaseCenters = satellitesPhaseCenters;
65          this.stations               = stations;
66          this.eop                    = eop;
67      }
68  
69      /** Get the parsed satellites phase centers.
70       * @return unmodifiable view of parsed satellites phase centers
71       */
72      public Map<SatInSystem, Map<GnssSignal, Vector3D>> getSatellitesPhaseCenters() {
73          return Collections.unmodifiableMap(satellitesPhaseCenters);
74      }
75  
76      /** Get the parsed station data.
77       * @return unmodifiable view of parsed station data
78       */
79      public Map<String, Station> getStations() {
80          return Collections.unmodifiableMap(stations);
81      }
82  
83      /** Get the parsed EOP data.
84       * @param itrfVersion ITRF version corresponding to the entries
85       * @return loader for EOP data
86       */
87      public EopHistoryLoader getEopLoader(final ITRFVersion itrfVersion) {
88          return (converter, history) -> {
89  
90              // first set up all entries explicitly present in the parsed files
91              final SortedSet<SinexEopEntry> sorted = new TreeSet<>(new ChronologicalComparator());
92              sorted.addAll(eop.values());
93  
94              // copy first and last entries according to files validity
95              sorted.add(sorted.first().toNewEpoch(getFileEpochStartTime()));
96              sorted.add(sorted.last().toNewEpoch(getFileEpochEndTime()));
97  
98              if (sorted.size() < 4) {
99                  // insert extra entries after first and before last to allow interpolation
100                 sorted.add(sorted.first().toNewEpoch(getFileEpochStartTime().shiftedBy(1.0)));
101                 sorted.add(sorted.last().toNewEpoch(getFileEpochEndTime().shiftedBy(-1.0)));
102             }
103 
104             // convert to regular EOP history
105             sorted.forEach(e -> history.add(e.toEopEntry(converter, itrfVersion, getTimeScales().getUTC())));
106 
107         };
108     }
109 
110 }