RinexClock.java

  1. /* Copyright 2002-2023 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.rinex.clock;

  18. import java.util.ArrayList;
  19. import java.util.Collections;
  20. import java.util.HashMap;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.function.Function;

  24. import org.orekit.errors.OrekitIllegalArgumentException;
  25. import org.orekit.errors.OrekitMessages;
  26. import org.orekit.files.rinex.AppliedDCBS;
  27. import org.orekit.files.rinex.AppliedPCVS;
  28. import org.orekit.frames.Frame;
  29. import org.orekit.gnss.ObservationType;
  30. import org.orekit.gnss.SatelliteSystem;
  31. import org.orekit.gnss.TimeSystem;
  32. import org.orekit.time.AbsoluteDate;
  33. import org.orekit.time.DateComponents;
  34. import org.orekit.time.TimeComponents;
  35. import org.orekit.time.TimeScale;
  36. import org.orekit.utils.TimeSpanMap;

  37. /** Represents a parsed clock file from the IGS.
  38.  * <p> A time system should be specified in the file. However, if it is not, default time system will be chosen
  39.  * regarding the satellite system. If it is mixed or not specified, default time system will be UTC. </p>
  40.  * <p> Some fields might be null after parsing. It is expected because of the numerous kind of data that can be stored in clock data file. </p>
  41.  * <p> Caution, files with missing information in header can lead to wrong data dates and station positions.
  42.  * It is adviced to check the correctness and format compliance of the clock file to be parsed.
  43.  * Some values such as file time scale still can be set by user. </p>
  44.  * @see <a href="ftp://igs.org/pub/data/format/rinex_clock300.txt"> 3.00 clock file format</a>
  45.  * @see <a href="ftp://igs.org/pub/data/format/rinex_clock302.txt"> 3.02 clock file format</a>
  46.  * @see <a href="ftp://igs.org/pub/data/format/rinex_clock304.txt"> 3.04 clock file format</a>
  47.  *
  48.  * @author Thomas Paulet
  49.  * @since 11.0
  50.  */
  51. public class RinexClock {

  52.     /** Format version. */
  53.     private double formatVersion;

  54.     /** Satellite system. */
  55.     private SatelliteSystem satelliteSystem;

  56.     /** Name of the program creating current file. */
  57.     private String programName;

  58.     /** Name of the agency creating the current file. */
  59.     private String agencyName;

  60.     /** Date of the file creation as a string. */
  61.     private String creationDateString;

  62.     /** Time of the file creation as a string. */
  63.     private String creationTimeString;

  64.     /** Time zone of the file creation as a string. */
  65.     private String creationTimeZoneString;

  66.     /** Creation date as absolute date. */
  67.     private AbsoluteDate creationDate;

  68.     /** Comments. */
  69.     private String comments;

  70.     /** Satellite system code. */
  71.     private Map<SatelliteSystem, List<ObservationType>> systemObservationTypes;

  72.     /** Time system. */
  73.     private TimeSystem timeSystem;

  74.     /** Data time scale related to time system. */
  75.     private TimeScale timeScale;

  76.     /** Number of leap seconds separating UTC and TAI (UTC = TAI - numberOfLeapSeconds). */
  77.     private int numberOfLeapSeconds;

  78.     /** Number of leap seconds separating UTC and GNSS time systems. */
  79.     private int numberOfLeapSecondsGNSS;

  80.     /** List of applied differential code bias corrections. */
  81.     private List<AppliedDCBS> listAppliedDCBS;

  82.     /** List of antenna center variation corrections. */
  83.     private List<AppliedPCVS> listAppliedPCVS;

  84.     /** List of the data types in the file. */
  85.     private List<ClockDataType> clockDataTypes;

  86.     /** Station name for calibration and discontinuity data. */
  87.     private String stationName;

  88.     /** Station identifier for calibration and discontinuity data. */
  89.     private String stationIdentifier;

  90.     /** External reference clock identifier for calibration. */
  91.     private String externalClockReference;

  92.     /** Analysis center ID. */
  93.     private String analysisCenterID;

  94.     /** Full analysis center name. */
  95.     private String analysisCenterName;

  96.     /** Reference clocks. */
  97.     private TimeSpanMap<List<ReferenceClock>> referenceClocks;

  98.     /** Earth centered frame name as a string. */
  99.     private String frameName;

  100.     /** Maps {@link #coordinateSystem} to a {@link Frame}. */
  101.     private final Function<? super String, ? extends Frame> frameBuilder;

  102.     /** List of the receivers in the file. */
  103.     private List<Receiver> receivers;

  104.     /** List of the satellites in the file. */
  105.     private List<String> satellites;

  106.     /** A map containing receiver/satellite information. */
  107.     private Map<String, List<ClockDataLine>> clockData;

  108.     /** Constructor.
  109.      * @param frameBuilder for constructing a reference frame from the identifier
  110.      */
  111.     public RinexClock(final Function<? super String, ? extends Frame> frameBuilder) {
  112.         // Initialize fields with default data
  113.         this.systemObservationTypes  = new HashMap<SatelliteSystem, List<ObservationType>>();
  114.         this.listAppliedDCBS         = new ArrayList<AppliedDCBS>();
  115.         this.listAppliedPCVS         = new ArrayList<AppliedPCVS>();
  116.         this.clockDataTypes          = new ArrayList<ClockDataType>();
  117.         this.receivers               = new ArrayList<Receiver>();
  118.         this.satellites              = new ArrayList<String>();
  119.         this.clockData               = new HashMap<String, List<ClockDataLine>>();
  120.         this.agencyName              = "";
  121.         this.analysisCenterID        = "";
  122.         this.analysisCenterName      = "";
  123.         this.comments                = "";
  124.         this.creationDate            = null;
  125.         this.creationDateString      = "";
  126.         this.creationTimeString      = "";
  127.         this.creationTimeZoneString  = "";
  128.         this.externalClockReference  = "";
  129.         this.formatVersion           = 0.0;
  130.         this.frameBuilder            = frameBuilder;
  131.         this.frameName               = "";
  132.         this.numberOfLeapSeconds     = 0;
  133.         this.numberOfLeapSecondsGNSS = 0;
  134.         this.programName             = "";
  135.         this.referenceClocks         = null;
  136.         this.satelliteSystem         = null;
  137.         this.stationIdentifier       = "";
  138.         this.stationName             = "";
  139.         this.timeScale               = null;
  140.         this.timeSystem              = null;
  141.     }

  142.     /** Add a new satellite with a given identifier to the list of stored satellites.
  143.      * @param satId the satellite identifier
  144.      */
  145.     public void addSatellite(final String satId) {
  146.         // only add satellites which have not been added before
  147.         if (!satellites.contains(satId)) {
  148.             satellites.add(satId);
  149.         }
  150.     }

  151.     /** Add a new receiver to the list of stored receivers.
  152.      * @param receiver the receiver
  153.      */
  154.     public void addReceiver(final Receiver receiver) {

  155.         boolean notInList = true;
  156.         for (Receiver rec : receivers) {
  157.             if (rec.designator.equals(receiver.designator)) {
  158.                 notInList = false;
  159.             }
  160.         }
  161.         // only add satellites which have not been added before
  162.         if (notInList) {
  163.             receivers.add(receiver);
  164.         }
  165.     }

  166.     /** Get the number of different clock data types in the file.
  167.      * @return the number of different clock data types
  168.      */
  169.     public int getNumberOfClockDataTypes() {
  170.         return clockDataTypes.size();
  171.     }

  172.     /** Get the total number of complete data lines in the file.
  173.      * @return the total number of complete data lines in the file
  174.      */
  175.     public int getTotalNumberOfDataLines() {
  176.         int result = 0;
  177.         final Map<String, List<ClockDataLine>> data = getClockData();
  178.         for (final Map.Entry<String, List<ClockDataLine>> entry : data.entrySet()) {
  179.             result += entry.getValue().size();
  180.         }
  181.         return result;
  182.     }

  183.     /** Get the number of observation types for a given system.
  184.      * @param system the satellite system to consider
  185.      * @return the number of observation types for a given system
  186.      */
  187.     public int numberOfObsTypes(final SatelliteSystem system) {
  188.         if (systemObservationTypes.containsKey(system)) {
  189.             return systemObservationTypes.get(system).size();
  190.         } else {
  191.             return 0;
  192.         }
  193.     }

  194.     /** Get the number of receivers that are considered in the file.
  195.      * @return the number of receivers that are considered in the file
  196.      */
  197.     public int getNumberOfReceivers() {
  198.         return receivers.size();
  199.     }

  200.     /** Get the number of satellites that are considered in the file.
  201.      * @return the number of satellites that are considered in the file
  202.      */
  203.     public int getNumberOfSatellites() {
  204.         return satellites.size();
  205.     }

  206.     /** Getter for the format version.
  207.      * @return the format version
  208.      */
  209.     public double getFormatVersion() {
  210.         return formatVersion;
  211.     }

  212.     /** Setter for the format version.
  213.      * @param formatVersion the format version to set
  214.      */
  215.     public void setFormatVersion(final double formatVersion) {
  216.         this.formatVersion = formatVersion;
  217.     }

  218.     /** Getter for the satellite system.
  219.      * @return the satellite system
  220.      */
  221.     public SatelliteSystem getSatelliteSystem() {
  222.         return satelliteSystem;
  223.     }

  224.     /** Setter for the satellite system.
  225.      * @param satelliteSystem the satellite system to set
  226.      */
  227.     public void setSatelliteSystem(final SatelliteSystem satelliteSystem) {
  228.         this.satelliteSystem = satelliteSystem;
  229.     }

  230.     /** Getter for the program name.
  231.      * @return the program name
  232.      */
  233.     public String getProgramName() {
  234.         return programName;
  235.     }

  236.     /** Setter for the program name.
  237.      * @param programName the program name to set
  238.      */
  239.     public void setProgramName(final String programName) {
  240.         this.programName = programName;
  241.     }

  242.     /** Getter for the agency name.
  243.      * @return the agencyName
  244.      */
  245.     public String getAgencyName() {
  246.         return agencyName;
  247.     }

  248.     /** Setter for the agency name.
  249.      * @param agencyName the agency name to set
  250.      */
  251.     public void setAgencyName(final String agencyName) {
  252.         this.agencyName = agencyName;
  253.     }

  254.     /** Getter for the creation date of the file as a string.
  255.      * @return the creation date as a string
  256.      */
  257.     public String getCreationDateString() {
  258.         return creationDateString;
  259.     }

  260.     /** Setter for the creation date as a string.
  261.      * @param creationDateString the creation date as a string to set
  262.      */
  263.     public void setCreationDateString(final String creationDateString) {
  264.         this.creationDateString = creationDateString;
  265.     }

  266.     /** Getter for the creation time of the file as a string.
  267.      * @return the creation time as a string
  268.      */
  269.     public String getCreationTimeString() {
  270.         return creationTimeString;
  271.     }

  272.     /** Setter for the creation time as a string.
  273.      * @param creationTimeString the creation time as a string to set
  274.      */
  275.     public void setCreationTimeString(final String creationTimeString) {
  276.         this.creationTimeString = creationTimeString;
  277.     }

  278.     /** Getter for the creation time zone of the file as a string.
  279.      * @return the creation time zone as a string
  280.      */
  281.     public String getCreationTimeZoneString() {
  282.         return creationTimeZoneString;
  283.     }

  284.     /** Setter for the creation time zone.
  285.      * @param creationTimeZoneString the creation time zone as a string to set
  286.      */
  287.     public void setCreationTimeZoneString(final String creationTimeZoneString) {
  288.         this.creationTimeZoneString = creationTimeZoneString;
  289.     }

  290.     /** Getter for the creation date.
  291.      * @return the creation date
  292.      */
  293.     public AbsoluteDate getCreationDate() {
  294.         return creationDate;
  295.     }

  296.     /** Setter for the creation date.
  297.      * @param creationDate the creation date to set
  298.      */
  299.     public void setCreationDate(final AbsoluteDate creationDate) {
  300.         this.creationDate = creationDate;
  301.     }

  302.     /** Getter for the comments.
  303.      * @return the comments
  304.      */
  305.     public String getComments() {
  306.         return comments;
  307.     }

  308.     /** Add a comment line.
  309.      * @param comment the comment line to add
  310.      */
  311.     public void addComment(final String comment) {
  312.         this.comments = comments.concat(comment + "\n");
  313.     }

  314.     /** Getter for the different observation type for each satellite system.
  315.      * @return the map of the different observation type per satellite system
  316.      */
  317.     public Map<SatelliteSystem, List<ObservationType>> getSystemObservationTypes() {
  318.         return Collections.unmodifiableMap(systemObservationTypes);
  319.     }

  320.     /** Add an observation type for a specified satellite system.
  321.      * @param satSystem the satellite system to add observation type
  322.      * @param observationType the system observation type to set
  323.      */
  324.     public void addSystemObservationType(final SatelliteSystem satSystem,
  325.                                          final ObservationType observationType) {
  326.         systemObservationTypes.putIfAbsent(satSystem, new ArrayList<ObservationType>());
  327.         systemObservationTypes.get(satSystem).add(observationType);
  328.     }

  329.     /** Getter for the file time system.
  330.      * @return the file time system
  331.      */
  332.     public TimeSystem getTimeSystem() {
  333.         return timeSystem;
  334.     }

  335.     /** Setter for the file time system.
  336.      * @param timeSystem the file time system to set
  337.      */
  338.     public void setTimeSystem(final TimeSystem timeSystem) {
  339.         this.timeSystem = timeSystem;
  340.     }

  341.     /** Getter for the data time scale.
  342.      * @return the data time scale
  343.      */
  344.     public TimeScale getTimeScale() {
  345.         return timeScale;
  346.     }

  347.     /** Setter for the data time scale.
  348.      * @param timeScale the data time scale to set
  349.      */
  350.     public void setTimeScale(final TimeScale timeScale) {
  351.         this.timeScale = timeScale;
  352.     }

  353.     /** Getter for the number of leap seconds.
  354.      * @return the number of leap seconds
  355.      */
  356.     public int getNumberOfLeapSeconds() {
  357.         return numberOfLeapSeconds;
  358.     }

  359.     /** Setter for the number of leap seconds.
  360.      * @param numberOfLeapSeconds the number of leap seconds to set
  361.      */
  362.     public void setNumberOfLeapSeconds(final int numberOfLeapSeconds) {
  363.         this.numberOfLeapSeconds = numberOfLeapSeconds;
  364.     }

  365.     /** Getter for the number of leap second for GNSS time scales.
  366.      * @return the number of leap seconds for GNSS time scales
  367.      */
  368.     public int getNumberOfLeapSecondsGNSS() {
  369.         return numberOfLeapSecondsGNSS;
  370.     }

  371.     /** Setter for the number of leap seconds for GNSS time scales.
  372.      * @param numberOfLeapSecondsGNSS the number of leap seconds for GNSS time scales to set
  373.      */
  374.     public void setNumberOfLeapSecondsGNSS(final int numberOfLeapSecondsGNSS) {
  375.         this.numberOfLeapSecondsGNSS = numberOfLeapSecondsGNSS;
  376.     }

  377.     /** Getter for the applied differential code bias corrections.
  378.      * @return the list of applied differential code bias corrections
  379.      */
  380.     public List<AppliedDCBS> getListAppliedDCBS() {
  381.         return Collections.unmodifiableList(listAppliedDCBS);
  382.     }

  383.     /** Add an applied differencial code bias corrections.
  384.      * @param appliedDCBS the applied differencial code bias corrections to add
  385.      */
  386.     public void addAppliedDCBS(final AppliedDCBS appliedDCBS) {
  387.         listAppliedDCBS.add(appliedDCBS);
  388.     }

  389.     /** Getter for the applied phase center variations.
  390.      * @return the list of the applied phase center variations
  391.      */
  392.     public List<AppliedPCVS> getListAppliedPCVS() {
  393.         return Collections.unmodifiableList(listAppliedPCVS);
  394.     }

  395.     /** Add an applied phase center variations.
  396.      * @param appliedPCVS the phase center variations to add
  397.      */
  398.     public void addAppliedPCVS(final AppliedPCVS appliedPCVS) {
  399.         listAppliedPCVS.add(appliedPCVS);
  400.     }

  401.     /** Getter for the different clock data types.
  402.      * @return the list of the different clock data types
  403.      */
  404.     public List<ClockDataType> getClockDataTypes() {
  405.         return Collections.unmodifiableList(clockDataTypes);
  406.     }

  407.     /** Add a clock data types.
  408.      * @param clockDataType the clock data types to add
  409.      */
  410.     public void addClockDataType(final ClockDataType clockDataType) {
  411.         clockDataTypes.add(clockDataType);
  412.     }

  413.     /** Getter for the station name.
  414.      * @return the station name
  415.      */
  416.     public String getStationName() {
  417.         return stationName;
  418.     }

  419.     /** Setter for the station name.
  420.      * @param stationName the station name to set
  421.      */
  422.     public void setStationName(final String stationName) {
  423.         this.stationName = stationName;
  424.     }

  425.     /** Getter for the station identifier.
  426.      * @return the station identifier
  427.      */
  428.     public String getStationIdentifier() {
  429.         return stationIdentifier;
  430.     }

  431.     /** Setter for the station identifier.
  432.      * @param stationIdentifier the station identifier to set
  433.      */
  434.     public void setStationIdentifier(final String stationIdentifier) {
  435.         this.stationIdentifier = stationIdentifier;
  436.     }

  437.     /** Getter for the external clock reference.
  438.      * @return the external clock reference
  439.      */
  440.     public String getExternalClockReference() {
  441.         return externalClockReference;
  442.     }

  443.     /** Setter for the external clock reference.
  444.      * @param externalClockReference the external clock reference to set
  445.      */
  446.     public void setExternalClockReference(final String externalClockReference) {
  447.         this.externalClockReference = externalClockReference;
  448.     }

  449.     /** Getter for the analysis center ID.
  450.      * @return the analysis center ID
  451.      */
  452.     public String getAnalysisCenterID() {
  453.         return analysisCenterID;
  454.     }

  455.     /** Setter for the analysis center ID.
  456.      * @param analysisCenterID the analysis center ID to set
  457.      */
  458.     public void setAnalysisCenterID(final String analysisCenterID) {
  459.         this.analysisCenterID = analysisCenterID;
  460.     }

  461.     /** Getter for the analysis center name.
  462.      * @return the analysis center name
  463.      */
  464.     public String getAnalysisCenterName() {
  465.         return analysisCenterName;
  466.     }

  467.     /** Setter for the analysis center name.
  468.      * @param analysisCenterName the analysis center name to set
  469.      */
  470.     public void setAnalysisCenterName(final String analysisCenterName) {
  471.         this.analysisCenterName = analysisCenterName;
  472.     }

  473.     /** Getter for the reference clocks.
  474.      * @return the time span map of the different refence clocks
  475.      */
  476.     public TimeSpanMap<List<ReferenceClock>> getReferenceClocks() {
  477.         return referenceClocks;
  478.     }

  479.     /** Add a list of reference clocks wich will be used after a specified date.
  480.      * If the reference map has not been already created, it will be.
  481.      * @param referenceClockList the reference clock list
  482.      * @param startDate the date the list will be valid after.
  483.      */
  484.     public void addReferenceClockList(final List<ReferenceClock> referenceClockList,
  485.                                       final AbsoluteDate startDate) {
  486.         if (referenceClocks == null) {
  487.             referenceClocks = new TimeSpanMap<>(null);
  488.         }
  489.         referenceClocks.addValidAfter(referenceClockList, startDate, false);
  490.     }

  491.     /** Getter for the frame name.
  492.      * @return the frame name
  493.      */
  494.     public String getFrameName() {
  495.         return frameName;
  496.     }


  497.     /** Setter for the frame name.
  498.      * @param frameName the frame name to set
  499.      */
  500.     public void setFrameName(final String frameName) {
  501.         this.frameName = frameName;
  502.     }


  503.     /** Getter for the receivers.
  504.      * @return the list of the receivers
  505.      */
  506.     public List<Receiver> getReceivers() {
  507.         return Collections.unmodifiableList(receivers);
  508.     }

  509.     /** Getter for the satellites.
  510.      * @return the list of the satellites
  511.      */
  512.     public List<String> getSatellites() {
  513.         return Collections.unmodifiableList(satellites);
  514.     }

  515.     /** Get the reference frame for the station positions.
  516.      * @return the reference frame for station positions
  517.      */
  518.     public Frame getFrame() {
  519.         return frameBuilder.apply(frameName);
  520.     }


  521.     /** Getter for an unmodifiable map of clock data.
  522.      * @return the clock data
  523.      */
  524.     public Map<String, List<ClockDataLine>> getClockData() {
  525.         return Collections.unmodifiableMap(clockData);
  526.     }


  527.     /** Add a clock data line to a specified receiver/satellite.
  528.      * @param id the satellite system to add observation type
  529.      * @param clockDataLine the clock data line to add
  530.      */
  531.     public void addClockData(final String id,
  532.                              final ClockDataLine clockDataLine) {
  533.         clockData.putIfAbsent(id, new ArrayList<ClockDataLine>());
  534.         clockData.get(id).add(clockDataLine);
  535.     }

  536.     /** Clock data for a single station.
  537.      * <p> Data epoch is not linked to any time system in order to pars files with missing lines.
  538.      * Though, the default version of the getEpoch() method links the data time components with the clock file object time scale.
  539.      * The latter can be set with a default value (UTC). Caution is recommanded.
  540.      */
  541.     public class ClockDataLine {

  542.         /** Clock data type. */
  543.         private ClockDataType dataType;

  544.         /** Receiver/Satellite name. */
  545.         private String name;

  546.         /** Epoch date components. */
  547.         private DateComponents dateComponents;

  548.         /** Epoch time components. */
  549.         private TimeComponents timeComponents;

  550.         /** Number of data values to follow.
  551.          * This number might not represent the non zero values in the line.
  552.          */
  553.         private int numberOfValues;

  554.         /** Clock bias (seconds). */
  555.         private double clockBias;

  556.         /** Clock bias sigma (seconds). */
  557.         private double clockBiasSigma;

  558.         /** Clock rate (dimensionless). */
  559.         private double clockRate;

  560.         /** Clock rate sigma (dimensionless). */
  561.         private double clockRateSigma;

  562.         /** Clock acceleration (seconds^-1). */
  563.         private double clockAcceleration;

  564.         /** Clock acceleration sigma (seconds^-1). */
  565.         private double clockAccelrerationSigma;

  566.         /** Constructor.
  567.          * @param type the clock data type
  568.          * @param name the receiver/satellite name
  569.          * @param dateComponents the epoch date components
  570.          * @param timeComponents the epoch time components
  571.          * @param numberOfValues the number of values to follow
  572.          * @param clockBias the clock bias in seconds
  573.          * @param clockBiasSigma the clock bias sigma in seconds
  574.          * @param clockRate the clock rate
  575.          * @param clockRateSigma the clock rate sigma
  576.          * @param clockAcceleration the clock acceleration in seconds^-1
  577.          * @param clockAccelerationSigma the clock acceleration in seconds^-1
  578.          */
  579.         public ClockDataLine (final ClockDataType type, final String name,
  580.                               final DateComponents dateComponents,
  581.                               final TimeComponents timeComponents,
  582.                               final int numberOfValues,
  583.                               final double clockBias, final double clockBiasSigma,
  584.                               final double clockRate, final double clockRateSigma,
  585.                               final double clockAcceleration, final double clockAccelerationSigma) {

  586.             this.dataType                = type;
  587.             this.name                    = name;
  588.             this.dateComponents          = dateComponents;
  589.             this.timeComponents          = timeComponents;
  590.             this.numberOfValues          = numberOfValues;
  591.             this.clockBias               = clockBias;
  592.             this.clockBiasSigma          = clockBiasSigma;
  593.             this.clockRate               = clockRate;
  594.             this.clockRateSigma          = clockRateSigma;
  595.             this.clockAcceleration       = clockAcceleration;
  596.             this.clockAccelrerationSigma = clockAccelerationSigma;
  597.         }

  598.         /** Getter for the clock data type.
  599.          * @return the clock data type
  600.          */
  601.         public ClockDataType getDataType() {
  602.             return dataType;
  603.         }

  604.         /** Getter for the receiver/satellite name.
  605.          * @return the receiver/satellite name
  606.          */
  607.         public String getName() {
  608.             return name;
  609.         }

  610.         /** Getter for the number of values to follow.
  611.          * @return the number of values to follow
  612.          */
  613.         public int getNumberOfValues() {
  614.             return numberOfValues;
  615.         }

  616.         /** Get data line epoch.
  617.          * This method should be used if Time System ID line is present in the clock file.
  618.          * If it is missing, UTC time scale will be applied.
  619.          * To specify tim scale, use {@link #getEpoch(TimeScale) getEpoch(TimeScale)} method.
  620.          * @return the data line epoch
  621.          */
  622.         public AbsoluteDate getEpoch() {
  623.             return new AbsoluteDate(dateComponents, timeComponents, timeScale);
  624.         }

  625.         /** Get data line epoch.
  626.          * This method should be used in case Time System ID line is missing.
  627.          * Otherwise, it is adviced to rather use {@link #getEpoch() getEpoch()} method.
  628.          * @param epochTimeScale the time scale in which the epoch is defined
  629.          * @return the data line epoch set in the specified time scale
  630.          */
  631.         public AbsoluteDate getEpoch(final TimeScale epochTimeScale) {
  632.             return new AbsoluteDate(dateComponents, timeComponents, epochTimeScale);
  633.         }

  634.         /** Getter for the clock bias.
  635.          * @return the clock bias in seconds
  636.          */
  637.         public double getClockBias() {
  638.             return clockBias;
  639.         }

  640.         /** Getter for the clock bias sigma.
  641.          * @return the clock bias sigma in seconds
  642.          */
  643.         public double getClockBiasSigma() {
  644.             return clockBiasSigma;
  645.         }

  646.         /** Getter for the clock rate.
  647.          * @return the clock rate
  648.          */
  649.         public double getClockRate() {
  650.             return clockRate;
  651.         }

  652.         /** Getter for the clock rate sigma.
  653.          * @return the clock rate sigma
  654.          */
  655.         public double getClockRateSigma() {
  656.             return clockRateSigma;
  657.         }

  658.         /** Getter for the clock acceleration.
  659.          * @return the clock acceleration in seconds^-1
  660.          */
  661.         public double getClockAcceleration() {
  662.             return clockAcceleration;
  663.         }

  664.         /** Getter for the clock acceleration sigma.
  665.          * @return the clock acceleration sigma in seconds^-1
  666.          */
  667.         public double getClockAccelerationSigma() {
  668.             return clockAccelrerationSigma;
  669.         }

  670.     }

  671.     /** Represents a reference clock with its validity time span. */
  672.     public static class ReferenceClock {

  673.         /** Receiver/satellite embedding the reference clock name. */
  674.         private String referenceName;

  675.         /** Clock ID. */
  676.         private String clockID;

  677.         /** A priori clock constraint (in seconds). */
  678.         private double clockConstraint;

  679.         /** Start date of the validity period. */
  680.         private AbsoluteDate startDate;

  681.         /** End date of the validity period. */
  682.         private AbsoluteDate endDate;

  683.         /** Constructor.
  684.          * @param referenceName the name of the receiver/satellite embedding the reference clock
  685.          * @param clockID the clock ID
  686.          * @param clockConstraint the a priori clock constraint
  687.          * @param startDate the validity period start date
  688.          * @param endDate the validity period end date
  689.          */
  690.         public ReferenceClock (final String referenceName, final String clockID, final double clockConstraint,
  691.                                final AbsoluteDate startDate, final AbsoluteDate endDate) {
  692.             this.referenceName   = referenceName;
  693.             this.clockID         = clockID;
  694.             this.clockConstraint = clockConstraint;
  695.             this.startDate       = startDate;
  696.             this.endDate         = endDate;
  697.         }

  698.         /** Getter for the name of the receiver/satellite embedding the reference clock.
  699.          * @return the name of the receiver/satellite embedding the reference clock
  700.          */
  701.         public String getReferenceName() {
  702.             return referenceName;
  703.         }

  704.         /** Getter for the clock ID.
  705.          * @return the clock ID
  706.          */
  707.         public String getClockID() {
  708.             return clockID;
  709.         }

  710.         /** Getter for the clock constraint.
  711.          * @return the clock constraint
  712.          */
  713.         public double getClockConstraint() {
  714.             return clockConstraint;
  715.         }

  716.         /** Getter for the validity period start date.
  717.          * @return the validity period start date
  718.          */
  719.         public AbsoluteDate getStartDate() {
  720.             return startDate;
  721.         }

  722.         /** Getter for the validity period end date.
  723.          * @return the validity period end date
  724.          */
  725.         public AbsoluteDate getEndDate() {
  726.             return endDate;
  727.         }

  728.     }

  729.     /** Represents a receiver or a satellite with its position in the considered frame. */
  730.     public static class Receiver {

  731.         /** Designator. */
  732.         private String designator;

  733.         /** Receiver identifier. */
  734.         private String receiverIdentifier;

  735.         /** X coordinates in file considered Earth centered frame (in meters). */
  736.         private double x;

  737.         /** Y coordinates in file considered Earth centered frame (in meters). */
  738.         private double y;

  739.         /** Z coordinates in file considered Earth centered frame (in meters). */
  740.         private double z;

  741.         /** Constructor.
  742.          * @param designator the designator
  743.          * @param receiverIdentifier the receiver identifier
  744.          * @param x the X coordinate in meters in considered Earth centered frame
  745.          * @param y the Y coordinate in meters in considered Earth centered frame
  746.          * @param z the Z coordinate in meters in considered Earth centered frame
  747.          */
  748.         public Receiver(final String designator, final String receiverIdentifier,
  749.                         final double x, final double y, final double z) {
  750.             this.designator         = designator;
  751.             this.receiverIdentifier = receiverIdentifier;
  752.             this.x                  = x;
  753.             this.y                  = y;
  754.             this.z                  = z;
  755.         }

  756.         /** Getter for the designator.
  757.          * @return the designator
  758.          */
  759.         public String getDesignator() {
  760.             return designator;
  761.         }

  762.         /** Getter for the receiver identifier.
  763.          * @return the receiver identifier
  764.          */
  765.         public String getReceiverIdentifier() {
  766.             return receiverIdentifier;
  767.         }

  768.         /** Getter for the X coordinate in meters in considered Earth centered frame.
  769.          * @return  the X coordinate in meters in considered Earth centered frame
  770.          */
  771.         public double getX() {
  772.             return x;
  773.         }

  774.         /** Getter for the Y coordinate in meters in considered Earth centered frame.
  775.          * @return  the Y coordinate in meters in considered Earth centered frame
  776.          */
  777.         public double getY() {
  778.             return y;
  779.         }

  780.         /** Getter for the Z coordinate in meters in considered Earth centered frame.
  781.          * @return  the Z coordinate in meters in considered Earth centered frame
  782.          */
  783.         public double getZ() {
  784.             return z;
  785.         }
  786.     }

  787.     /** Clock data type.
  788.      * In case of a DR type, clock data are in the sense of clock value after discontinuity minus prior.
  789.      * In other cases, clock data are in the sense of reported station/satellite clock minus reference clock value. */
  790.     public enum ClockDataType {

  791.         /** Data analysis for receiver clocks. Clock Data are*/
  792.         AR("AR"),

  793.         /** Data analysis for satellite clocks. */
  794.         AS("AS"),

  795.         /** Calibration measurement for a single GPS receiver. */
  796.         CR("CR"),

  797.         /** Discontinuity measurements for a single GPS receiver. */
  798.         DR("DR"),

  799.         /** Monitor measurements for the broadcast satellite clocks. */
  800.         MS("MS");

  801.         /** Parsing map. */
  802.         private static final Map<String, ClockDataType> KEYS_MAP = new HashMap<>();
  803.         static {
  804.             for (final ClockDataType timeSystem : values()) {
  805.                 KEYS_MAP.put(timeSystem.getKey(), timeSystem);
  806.             }
  807.         }

  808.         /** Key for the system. */
  809.         private final String key;

  810.         /** Simple constructor.
  811.          * @param key key letter
  812.          */
  813.         ClockDataType(final String key) {
  814.             this.key = key;
  815.         }

  816.         /** Get the key for the system.
  817.          * @return key for the system
  818.          */
  819.         public String getKey() {
  820.             return key;
  821.         }

  822.         /** Parse a string to get the time system.
  823.          * <p>
  824.          * The string must be the time system.
  825.          * </p>
  826.          * @param s string to parse
  827.          * @return the time system
  828.          * @exception OrekitIllegalArgumentException if the string does not correspond to a time system key
  829.          */
  830.         public static ClockDataType parseClockDataType(final String s)
  831.             throws OrekitIllegalArgumentException {
  832.             final ClockDataType clockDataType = KEYS_MAP.get(s);
  833.             if (clockDataType == null) {
  834.                 throw new OrekitIllegalArgumentException(OrekitMessages.UNKNOWN_CLOCK_DATA_TYPE, s);
  835.             }
  836.             return clockDataType;
  837.         }
  838.     }
  839. }