Commit 5616a746 authored by Luc Maisonobe's avatar Luc Maisonobe

Use the new infrastructure for parsing TDM files.

parent 8ca7ae90
Pipeline #869 passed with stage
in 30 minutes and 10 seconds
......@@ -74,6 +74,7 @@ public enum OrekitMessages implements Localizable {
NOT_A_SUPPORTED_IERS_DATA_FILE("file {0} is not a supported IERS data file"),
INCONSISTENT_DATES_IN_IERS_FILE("inconsistent dates in IERS file {0}: {1}-{2}-{3} and MJD {4}"),
UNEXPECTED_DATA_AFTER_LINE_IN_FILE("unexpected data after line {0} in file {1}: {2}"),
UNEXPECTED_DATA_AT_LINE_IN_FILE("unexpected data at line {0} in file {1}"),
NON_CHRONOLOGICAL_DATES_IN_FILE("non-chronological dates in file {0}, line {1}"),
NO_IERS_UTC_TAI_HISTORY_DATA_LOADED("no IERS UTC-TAI history data loaded"),
NO_ENTRIES_IN_IERS_UTC_TAI_HISTORY_FILE("no entries found in IERS UTC-TAI history file {0}"),
......@@ -168,14 +169,8 @@ public enum OrekitMessages implements Localizable {
"use of time system {0} in CCSDS files requires an additional ICD and is not implemented in Orekit"),
CCSDS_NO_CORRESPONDING_TIME_SCALE("the CCSDS time system {0} has no corresponding Orekit TimeScale."),
CCSDS_TDM_INCONSISTENT_TIME_SYSTEMS("Inconsistent time systems in the observations blocks: {0} ≠ {1}"),
CCSDS_TDM_INCONSISTENT_DATA_LINE("Inconsistent data line in TDM file at line {0} of file {1}.\n" +
"A TDM data line should be as follows \"keyword = epoch value\".\n" + "Whereas read data line is: {2}"),
CCSDS_TDM_XML_INCONSISTENT_DATA_BLOCK("Inconsistent XML observation block at line {0} of TDM file {1}.\n" +
"A TDM observation block should be as follows\n\t<observation>\n\t\t<EPOCH>epoch</EPOCH>\n" +
"\t\t<KEYWORD>value</KEYWORD>\n\t</observation>"),
CCSDS_TDM_KEYWORD_NOT_FOUND("No CCSDS TDM keyword was found at line {0} of file {1}:\n{2}"),
CCSDS_TIME_SYSTEM_NOT_READ_YET("Time system should have already been set before line {0} of file {1}:\n{2}"),
CCSDS_TDM_UNKNOWN_FORMAT("TDM file {0} format is unknown. Please specify a file format: KEYVALUE or XML"),
CCSDS_TIME_SYSTEM_NOT_READ_YET("Time system should have already been set before line {0} of file {1}"),
CCSDS_AEM_INCONSISTENT_TIME_SYSTEMS("inconsistent time systems in the attitude blocks: {0} ≠ {1}"),
CCSDS_AEM_NULL_ATTITUDE_TYPE("invalid attitude type {0}"),
CCSDS_AEM_ATTITUDE_TYPE_NOT_IMPLEMENTED("attitude type {0} in CCSDS AEM files is not implemented in Orekit"),
......@@ -239,7 +234,8 @@ public enum OrekitMessages implements Localizable {
UNKNOWN_RINEX_FREQUENCY("unknown RINEX frequency {0} in file {1}, line {2}"),
MISMATCHED_FREQUENCIES("mismatched frequencies in file {0}, line {1} (expected {2}, got {3})"),
WRONG_COLUMNS_NUMBER("wrong number of columns in file {0}, line {1} (expected {2} columns, got {3} columns)"),
UNSUPPORTED_FILE_FORMAT("unsupported format for file {0}"), INCOMPLETE_HEADER("incomplete header in file {0}"),
UNSUPPORTED_FILE_FORMAT("unsupported format for file {0}"),
INCOMPLETE_HEADER("incomplete header in file {0}"),
INCONSISTENT_NUMBER_OF_SATS(
"inconsistent number of satellites in line {0}, file {1}: observation with {2} satellites and number of max satellites is {3}"),
INCONSISTENT_SATELLITE_SYSTEM(
......
......@@ -620,366 +620,10 @@ public enum Keyword {
/** Recommended interpolation method for attitude ephemeris data. */
INTERPOLATION_METHOD,
// ----------------------------------------------
// Tracking Data Messages (TDM) specific keywords
// ----------------------------------------------
// TDM Header section
// ------------------
/** Header: TDM format version in the form of ‘x.y’, where ‘y’ shall be incremented for
* corrections and minor changes, and ‘x’ shall be incremented for major changes.
* <p>Obligatory: YES
*/
CCSDS_TDM_VERS,
// TDM meta-data section
// ---------------------
/** Meta-data: PARTICIPANT_n, n = {1, 2, 3, 4, 5}.<p>
* Participants in a tracking data sessions (spacecraft(s), ground station(s)...)
* <p>Obligatory: YES (at least 1)
*/
PARTICIPANT_1,
/** Participant 2. */
PARTICIPANT_2,
/** Participant 3. */
PARTICIPANT_3,
/** Participant 4. */
PARTICIPANT_4,
/** Participant 5. */
PARTICIPANT_5,
/** Meta-data: Tracking mode associated with data section of the segment.<p>
* - SEQUENTIAL: Applies only for range, Doppler, angles, and LOS ionosphere calibrations.
* The name implies a sequential signal path between tracking participants;<p>
* - SINGLE_DIFF: Applies for differenced data;<p>
* - In other cases, such as troposphere, weather, clocks, etc., use of the MODE keyword does not apply.
* <p>Obligatory: NO
*/
MODE,
/** Meta-data: The PATH keywords shall reflect the signal path by listing the index of each PARTICIPANT
* in order, separated by commas, with no inserted white space.<p>
* The first entry in the PATH shall be the transmit participant.<p>
* The non-indexed ‘PATH’ keyword shall be used if the MODE is SEQUENTIAL.<p>
* The indexed ‘PATH_1’ and ‘PATH_2’ keywords shall be used where the MODE is SINGLE_DIFF.<p>
* Examples:<p>
* - 1,2 = one-way;<p>
* - 2,1,2 = two-way;<p>
* - 3,2,1 = three-way;<p>
* - 1,2,3,4 = four-way;<p>
* - 1,2,3,2,1 = turn-around range with 1=primary station, 2=satellite, 3=secondary station.
* <p>Obligatory: NO
*/
PATH,
/** Path 1. */
PATH_1,
/** Path 2. */
PATH_2,
/** Frequency band for transmitted frequencies.
* <p>Obligatory: NO
*/
TRANSMIT_BAND,
/** Meta-data: Frequency band for received frequencies.
* <p>Obligatory: NO
*/
RECEIVE_BAND,
/** Meta-data: Turn-around ratio numerator. <p>
* Numerator of the turn-around ratio that is necessary to calculate the coherent downlink from the uplink frequency.
* <p>Obligatory: NO
*/
TURNAROUND_NUMERATOR,
/** Meta-data: Turn-around ratio denominator.
* <p>Obligatory: NO
*/
TURNAROUND_DENOMINATOR,
/** Meta-data: Timetag reference.<p>
* Provides a reference for time tags in the tracking data.<p>
* It indicates whether the timetag associated with the data is the transmit time or the receive time.
* <p>Obligatory: NO
*/
TIMETAG_REF,
/** Meta-data: Integration interval.<p>
* Provides the Doppler count time in seconds for Doppler data or for the creation
* of normal points.
* <p>Obligatory: NO
*/
INTEGRATION_INTERVAL,
/** Meta-data: Integration reference.<p>
* Used in conjunction with timetag reference and integration interval.<p>
* Indicates whether the timetag represents the start, middle or end of the integration interval.
* <p>Obligatory: NO
*/
INTEGRATION_REF,
/** Meta-data: Frequency offset.<p>
* A frequency in Hz that must be added to every RECEIVE_FREQ to reconstruct it.
* <p>Obligatory: NO
*/
FREQ_OFFSET,
/** Meta-data: Range mode.<p>
* COHERENT, CONSTANT or ONE_WAY.
* <p>Obligatory: NO
*/
RANGE_MODE,
/** Meta-data: Range modulus.<p>
* Modulus of the range observable in the units as specified by the RANGE_UNITS keyword.
* <p>Obligatory: NO
*/
RANGE_MODULUS,
/** Meta-data: The RANGE_UNITS keyword specifies the units for the range observable.<p>
* ‘km’ shall be used if the range is measured in kilometers.<p>
* ‘s’ shall be used if the range is measured in seconds.<p>
* 'RU' for "range units'
* <p>Obligatory: NO
*/
RANGE_UNITS,
/** Meta-data: The ANGLE_TYPE keyword shall indicate the type of antenna geometry represented in the angle data (ANGLE_1 and ANGLE_2 keywords).<p>
* The value shall be one of the following:<p>
* - AZEL for azimuth, elevation (local horizontal);<p>
* - RADEC for right ascension, declination or hour angle, declination (needs to be referenced to an inertial frame);<p>
* - XEYN for x-east, y-north;<p>
* - XSYE for x-south, y-east.
* <p>Obligatory: NO
*/
ANGLE_TYPE,
/** Reference frame in which data are given: used in combination with ANGLE_TYPE=RADEC.
* <p>Obligatory: NO
*/
REFERENCE_FRAME,
/** Meta-data: Transmit delays list (up to 5).<p>
* Specifies a fixed interval of time, in seconds, for the signal to travel from the transmitting
* electronics to the transmit point. Each item in the list corresponds to the each participants.
* <p>Obligatory: NO
*/
TRANSMIT_DELAY_1,
/** Second. */
TRANSMIT_DELAY_2,
/** Second. */
TRANSMIT_DELAY_3,
/** Second. */
TRANSMIT_DELAY_4,
/** Second. */
TRANSMIT_DELAY_5,
/** Meta-data: Receive delays list.<p>
* Specifies a fixed interval of time, in seconds, for the signal to travel from the tracking
* point to the receiving electronics. Each item in the list corresponds to the each participants.
* <p>Obligatory: NO
*/
RECEIVE_DELAY_1,
/** Second. */
RECEIVE_DELAY_2,
/** Second. */
RECEIVE_DELAY_3,
/** Second. */
RECEIVE_DELAY_4,
/** Second. */
RECEIVE_DELAY_5,
/** Meta-data: Data quality.<p>
* Estimate of the quality of the data: RAW, DEGRADED or VALIDATED.
* <p>Obligatory: NO
*/
DATA_QUALITY,
/** Meta-data: Correction angle 1.<p>
* Angle correction that has been added or should be added to the ANGLE_1 data.
* <p>Obligatory: NO
*/
CORRECTION_ANGLE_1,
/** Meta-data: Correction angle 2.<p>
* Angle correction that has been added or should be added to the ANGLE_2 data.
* <p>Obligatory: NO
*/
CORRECTION_ANGLE_2,
/** Meta-data: Correction Doppler.<p>
* Doppler correction that has been added or should be added to the DOPPLER data.
* <p>Obligatory: NO
*/
CORRECTION_DOPPLER,
/** Meta-data: Correction Range.<p>
* Range correction that has been added or should be added to the RANGE data.
* <p>Obligatory: NO
*/
CORRECTION_RANGE,
/** Meta-data: Correction receive.<p>
* Receive correction that has been added or should be added to the RECEIVE data.
* <p>Obligatory: NO
*/
CORRECTION_RECEIVE,
/** Meta-data: Correction transmit.<p>
* Transmit correction that has been added or should be added to the TRANSMIT data.
* <p>Obligatory: NO
*/
CORRECTION_TRANSMIT,
/** Meta-data: Correction applied ? YES/NO<p>
* Indicate whethers or not the values associated with the CORRECTION_* keywords have been
* applied to the tracking data.
* <p>Obligatory: NO
*/
CORRECTIONS_APPLIED,
// TDM Data section
// ----------------
// Signal related keywords.
/** Data: Carrier power [dBW].<p>
* Strength of the radio signal transmitted by the spacecraft as received at the ground station or at another spacecraft.
*/
CARRIER_POWER,
/** Data: Doppler instantaneous [km/s].<p>
* Instantaneous range rate of the spacecraft.
*/
DOPPLER_INSTANTANEOUS,
/** Data: Doppler integrated [km/s].<p>
* Mean range rate of the spacecraft over the INTEGRATION_INTERVAL specified in the meta-data section.
*/
DOPPLER_INTEGRATED,
/** Data: Carrier power to noise spectral density ratio (Pc/No) [dBHz]. */
PC_N0,
/** Data: Ranging power to noise spectral density ratio (Pr/No) [dBHz]. */
PR_N0,
/** Data: Range value [km, s or RU].
* @see #RANGE_UNITS
*/
RANGE,
/** Data: Received frequencies [Hz].<p>
* The RECEIVE_FREQ keyword shall be used to indicate that the values represent measurements of the received frequency.<p>
* The keyword is indexed to accommodate a scenario in which multiple downlinks are used.<p>
* RECEIVE_FREQ_n (n = 1, 2, 3, 4, 5)
*/
RECEIVE_FREQ_1,
/** Received frequency 2. */
RECEIVE_FREQ_2,
/** Received frequency 3. */
RECEIVE_FREQ_3,
/** Received frequency 4. */
RECEIVE_FREQ_4,
/** Received frequency 5. */
RECEIVE_FREQ_5,
/** Data: Received frequency [Hz].<p>
* Case without an index; where the frequency cannot be associated with a particular participant.
*/
RECEIVE_FREQ,
/** Data: Transmitted frequencies [Hz].<p>
* The TRANSMIT_FREQ keyword shall be used to indicate that the values represent measurements of a transmitted frequency, e.g., from an uplink operation.<p>
* The TRANSMIT_FREQ keyword is indexed to accommodate scenarios in which multiple transmitters are used.<p>
* TRANSMIT_FREQ_n (n = 1, 2, 3, 4, 5)
*/
TRANSMIT_FREQ_1,
/** Transmitted frequency 2. */
TRANSMIT_FREQ_2,
/** Transmitted frequency 3. */
TRANSMIT_FREQ_3,
/** Transmitted frequency 4. */
TRANSMIT_FREQ_4,
/** Transmitted frequency 5. */
TRANSMIT_FREQ_5,
/** Data: Transmitted frequencies rates [Hz/s].<p>
* The value associated with the TRANSMIT_FREQ_RATE_n keyword is the linear rate of
* change of the frequency TRANSMIT_FREQ_n starting at the timetag and continuing
* until the next TRANSMIT_FREQ_RATE_n timetag (or until the end of the data).<p>
* TRANSMIT_FREQ_RATE_n (n = 1, 2, 3, 4, 5)
*/
TRANSMIT_FREQ_RATE_1,
/** Transmitted frequency rate 2. */
TRANSMIT_FREQ_RATE_2,
/** Transmitted frequency rate 3. */
TRANSMIT_FREQ_RATE_3,
/** Transmitted frequency rate 4. */
TRANSMIT_FREQ_RATE_4,
/** Transmitted frequency rate 5. */
TRANSMIT_FREQ_RATE_5,
// VLBI/Delta-DOR Related Keywords
/** Data: DOR [s].<p>
* the DOR keyword represents the range measured via PATH_2 minus the range measured via PATH_1.
*/
DOR,
/** Data: VLBI delay [s].<p>
* The observable associated with the VLBI_DELAY keyword represents the time of signal
* arrival via PATH_2 minus the time of signal arrival via PATH_1.
*/
VLBI_DELAY,
// Angle Related Keywords
/** Data: ANGLE_1 in degrees and in [-180, +360[ [deg].<p>
* The value assigned to the ANGLE_1 keyword represents the azimuth, right ascension, or ‘X’
* angle of the measurement, depending on the value of the ANGLE_TYPE keyword.<p>
* The angle measurement shall be a double precision value as follows: -180.0 &le; ANGLE_1 &lt; 360.0<p>
* Units shall be degrees.<p>
* See meta-data keyword ANGLE_TYPE for the definition of the angles.
*/
ANGLE_1,
/** Data: ANGLE_2 in degrees and in [-180, +360[ [deg].<p>
* The value assigned to the ANGLE_2 keyword represents the elevation, declination, or ‘Y’
* angle of the measurement, depending on the value of the ANGLE_TYPE keyword.<p>
* The angle measurement shall be a double precision value as follows: -180.0 &le; ANGLE_2 &lt; 360.0.<p>
* Units shall be degrees.<p>
* See meta-data keyword ANGLE_TYPE for the definition of the angles.
*/
ANGLE_2,
// Time Related Keywords
/** Data: Clock bias [s].<p>
* The CLOCK_BIAS keyword can be used by the message recipient to adjust timetag
* measurements by a specified amount with respect to a common reference.
*/
CLOCK_BIAS,
/** Data: Clock drift [s/s].<p>
* The CLOCK_DRIFT keyword should be used to adjust timetag measurements by an amount that is a function of time with
* respect to a common reference, normally UTC (as opposed to the CLOCK_BIAS, which is meant to be a constant adjustment).
*/
CLOCK_DRIFT,
// Media Related Keywords
/** Data: STEC - Slant Total Electron Count [TECU].
* The STEC keyword shall be used to convey the line of sight,
* one way charged particle delay or total electron count (TEC) at the timetag associated with a
* tracking measurement, which is calculated by integrating the electron density along the
* propagation path (electrons/m2).
*/
STEC,
/** Data: TROPO DRY [m].<p>
* Dry zenith delay through the troposphere measured at the timetag.
*/
TROPO_DRY,
/** Data: TROPO WET [m].<p>
* Wet zenith delay through the troposphere measured at the timetag.
*/
TROPO_WET,
// Meteorological Related Keywords
/** Data: Pressure [hPa].<p>
* Atmospheric pressure observable as measured at the tracking participant.
*/
PRESSURE,
/** Data: Relative humidity [%].<p>
* Relative humidity observable as measured at the tracking participant.
*/
RHUMIDITY,
/** Data: Temperature [K].<p>
* Temperature observable as measured at the tracking participant.
*/
TEMPERATURE,
// Miscellaneous KEYVALUE keywords
/** Keyword used to delineate the start of a Data block in Keyvalue files. */
DATA_START,
/** Keyword used to delineate the end of a Data block in Keyvalue files.. */
DATA_STOP,
DATA_STOP;
// XML TDM start/end keywords
/** TDM first keyword. */
tdm,
/** Header keyword. */
header,
/** Body keyword. */
body,
/** Segment keyword. */
segment,
/** Meta-data keyword. */
metadata,
/** Data keyword. */
data,
/** Observation keyword. */
observation;
}
/* Copyright 2002-2021 CS GROUP
* Licensed to CS GROUP (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.files.ccsds.ndm;
import java.util.Deque;
import org.orekit.files.ccsds.utils.CcsdsTimeScale;
import org.orekit.files.ccsds.utils.lexical.ParseEvent;
import org.orekit.files.ccsds.utils.lexical.ParsingState;
import org.orekit.time.AbsoluteDate;
import org.orekit.utils.IERSConventions;
/** {@link ParsingState} for {@link NDMHeader NDM header}.
* @author Luc Maisonobe
* @since 11.0
*/
public class NDMHeaderParsingState implements ParsingState {
/** IERS Conventions. */
private final IERSConventions conventions;
/** Reference date for Mission Elapsed Time or Mission Relative Time time systems. */
private final AbsoluteDate missionReferenceDate;
/** Key for format version. */
private final String formatVersionKey;
/** Header. */
private final NDMHeader header;
/** Next state to use. */
private final ParsingState nextState;
/** Simple constructor.
* @param conventions IERS Conventions
* @param missionReferenceDate reference date for Mission Elapsed Time or Mission Relative Time time systems
* @param formatVersionKey key for format version
* @param header header to fill
* @param nextState state to use when this state annot parse an event by itself
*/
public NDMHeaderParsingState(final IERSConventions conventions, final AbsoluteDate missionReferenceDate,
final String formatVersionKey, final NDMHeader header,
final ParsingState nextState) {
this.conventions = conventions;
this.missionReferenceDate = missionReferenceDate;
this.nextState = nextState;
this.formatVersionKey = formatVersionKey;
this.header = header;
}
/** {@inheritDoc} */
@Override
public ParsingState parseEvent(final ParseEvent event, final Deque<ParseEvent> next) {
if (formatVersionKey.equals(event.getName())) {
event.processAsDouble(header::setFormatVersion);
return this;
}
switch (event.getName()) {
case "COMMENT" :
event.processAsFreeTextString(header::addComment);
return this;
case "CREATION_DATE" :
event.processAsDate(header::setCreationDate, CcsdsTimeScale.UTC,
conventions, missionReferenceDate);
return this;
case "ORIGINATOR" :
event.processAsNormalizedString(header::setOriginator);
return this;
default :
// we were not able to parse the event, we push it back in the queue
next.offerLast(event);
return nextState;
}
}
}
......@@ -42,6 +42,9 @@ public class NDMMetadata {
/** IERS conventions to use. */
private final IERSConventions conventions;
/** Indicator for simple or accurate EOP interpolation. */
private final boolean simpleEOP;
/** Data context. */
private final DataContext dataContext;
......@@ -53,10 +56,12 @@ public class NDMMetadata {
/** Create a new meta-data.
* @param conventions IERS conventions to use
* @param simpleEOP if true, tidal effects are ignored when interpolating EOP
* @param dataContext data context to use
*/
public NDMMetadata(final IERSConventions conventions, final DataContext dataContext) {
public NDMMetadata(final IERSConventions conventions, final boolean simpleEOP, final DataContext dataContext) {
this.conventions = conventions;
this.simpleEOP = simpleEOP;
this.dataContext = dataContext;
this.comments = new ArrayList<>();
}
......@@ -68,6 +73,13 @@ public class NDMMetadata {
return conventions;
}
/** Get EOP interpolation method.
* @return true if tidal effects are ignored when interpolating EOP
*/
public boolean isSimpleEOP() {
return simpleEOP;
}
/** Get the data context.
* @return data context
*/
......
......@@ -27,6 +27,7 @@ import org.orekit.errors.OrekitIllegalArgumentException;
import org.orekit.errors.OrekitMessages;
import org.orekit.files.ccsds.utils.CCSDSFrame;
import org.orekit.files.ccsds.utils.CcsdsTimeScale;
import org.orekit.files.ccsds.utils.lexical.ParsingState;
import org.orekit.time.AbsoluteDate;
import org.orekit.utils.IERSConventions;
......@@ -60,17 +61,30 @@ public abstract class NDMParser<T extends NDMFile<?, ?>, P extends NDMParser<T,
/** Data context used for obtain frames and time scales. */
private final DataContext dataContext;
/** Initial parsing state.
* @since 11.0
*/
private final ParsingState initialState;
/** Current parsing state.
* @since 11.0
*/
private ParsingState state;
/** Complete constructor.
* @param conventions IERS Conventions
* @param simpleEOP if true, tidal effects are ignored when interpolating EOP
* @param dataContext used to retrieve frames and time scales.
* @param initialState initial parsing state
* @since 10.1
*/
protected NDMParser(final IERSConventions conventions, final boolean simpleEOP,
final DataContext dataContext) {
this.conventions = conventions;
this.simpleEOP = simpleEOP;
this.dataContext = dataContext;
final DataContext dataContext, final ParsingState initialState) {
this.conventions = conventions;
this.simpleEOP = simpleEOP;
this.dataContext = dataContext;
this.initialState = initialState;
this.state = null;
}
/** Set IERS conventions.
...