ObservationType.java
- /* Copyright 2002-2024 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.tdm;
- import java.util.regex.Pattern;
- import org.orekit.errors.OrekitException;
- import org.orekit.errors.OrekitMessages;
- import org.orekit.files.ccsds.definitions.Units;
- import org.orekit.files.ccsds.utils.ContextBinding;
- import org.orekit.files.ccsds.utils.lexical.ParseToken;
- import org.orekit.files.ccsds.utils.lexical.TokenType;
- import org.orekit.time.AbsoluteDate;
- import org.orekit.utils.Constants;
- import org.orekit.utils.units.Unit;
- /** Keys for {@link Observation TDM observations} entries.
- * @author Maxime Journot
- * @since 11.0
- */
- public enum ObservationType {
- // 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(Unit.ONE),
- /** Data: Doppler counts [n/a].<p>
- * Count of signal cycles.
- */
- DOPPLER_COUNT(Unit.ONE),
- /** Data: Doppler instantaneous [km/s].<p>
- * Instantaneous range rate of the spacecraft.
- */
- DOPPLER_INSTANTANEOUS(Units.KM_PER_S),
- /** Data: Doppler integrated [km/s].<p>
- * Mean range rate of the spacecraft over the INTEGRATION_INTERVAL specified in the meta-data section.
- */
- DOPPLER_INTEGRATED(Units.KM_PER_S),
- /** Data: Carrier power to noise spectral density ratio (Pc/No) [dBHz]. */
- PC_N0(Unit.ONE),
- /** Data: Ranging power to noise spectral density ratio (Pr/No) [dBHz]. */
- PR_N0(Unit.ONE),
- /** Data: phase cycle count at receiver. */
- RECEIVE_PHASE_CT_1(Unit.ONE),
- /** Data: phase cycle count at receiver. */
- RECEIVE_PHASE_CT_2(Unit.ONE),
- /** Data: phase cycle count at receiver. */
- RECEIVE_PHASE_CT_3(Unit.ONE),
- /** Data: phase cycle count at receiver. */
- RECEIVE_PHASE_CT_4(Unit.ONE),
- /** Data: phase cycle count at receiver. */
- RECEIVE_PHASE_CT_5(Unit.ONE),
- /** Data: phase cycle count at transmitter. */
- TRANSMIT_PHASE_CT_1(Unit.ONE),
- /** Data: phase cycle count at transmitter. */
- TRANSMIT_PHASE_CT_2(Unit.ONE),
- /** Data: phase cycle count at transmitter. */
- TRANSMIT_PHASE_CT_3(Unit.ONE),
- /** Data: phase cycle count at transmitter. */
- TRANSMIT_PHASE_CT_4(Unit.ONE),
- /** Data: phase cycle count at transmitter. */
- TRANSMIT_PHASE_CT_5(Unit.ONE),
- /** Data: Range value [km, s or RU].
- * @see RangeUnits
- */
- RANGE(Unit.KILOMETRE) {
- /** {@inheritDoc}*/
- @Override
- public double rawToSI(final RangeUnitsConverter ruConverter, final TdmMetadata metadata,
- final AbsoluteDate date, final double rawValue) {
- if (metadata.getRangeUnits() == RangeUnits.km) {
- return Unit.KILOMETRE.toSI(rawValue);
- } else if (metadata.getRangeUnits() == RangeUnits.s) {
- return rawValue * Constants.SPEED_OF_LIGHT;
- } else {
- if (ruConverter == null) {
- throw new OrekitException(OrekitMessages.CCSDS_TDM_MISSING_RANGE_UNITS_CONVERTER);
- }
- return ruConverter.ruToMeters(metadata, date, rawValue);
- }
- }
- /** {@inheritDoc}*/
- @Override
- public double siToRaw(final RangeUnitsConverter ruConverter, final TdmMetadata metadata,
- final AbsoluteDate date, final double siValue) {
- if (metadata.getRangeUnits() == RangeUnits.km) {
- return Unit.KILOMETRE.fromSI(siValue);
- } else if (metadata.getRangeUnits() == RangeUnits.s) {
- return siValue / Constants.SPEED_OF_LIGHT;
- } else {
- if (ruConverter == null) {
- throw new OrekitException(OrekitMessages.CCSDS_TDM_MISSING_RANGE_UNITS_CONVERTER);
- }
- return ruConverter.metersToRu(metadata, date, siValue);
- }
- }
- },
- /** 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(Unit.HERTZ),
- /** Received frequency 2. */
- RECEIVE_FREQ_2(Unit.HERTZ),
- /** Received frequency 3. */
- RECEIVE_FREQ_3(Unit.HERTZ),
- /** Received frequency 4. */
- RECEIVE_FREQ_4(Unit.HERTZ),
- /** Received frequency 5. */
- RECEIVE_FREQ_5(Unit.HERTZ),
- /** Data: Received frequency [Hz].<p>
- * Case without an index; where the frequency cannot be associated with a particular participant.
- */
- RECEIVE_FREQ(Unit.HERTZ),
- /** 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(Unit.HERTZ),
- /** Transmitted frequency 2. */
- TRANSMIT_FREQ_2(Unit.HERTZ),
- /** Transmitted frequency 3. */
- TRANSMIT_FREQ_3(Unit.HERTZ),
- /** Transmitted frequency 4. */
- TRANSMIT_FREQ_4(Unit.HERTZ),
- /** Transmitted frequency 5. */
- TRANSMIT_FREQ_5(Unit.HERTZ),
- /** 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(Units.HZ_PER_S),
- /** Transmitted frequency rate 2. */
- TRANSMIT_FREQ_RATE_2(Units.HZ_PER_S),
- /** Transmitted frequency rate 3. */
- TRANSMIT_FREQ_RATE_3(Units.HZ_PER_S),
- /** Transmitted frequency rate 4. */
- TRANSMIT_FREQ_RATE_4(Units.HZ_PER_S),
- /** Transmitted frequency rate 5. */
- TRANSMIT_FREQ_RATE_5(Units.HZ_PER_S),
- // 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(Unit.SECOND),
- /** 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(Unit.SECOND),
- // 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 ≤ ANGLE_1 < 360.0<p>
- * Units shall be degrees.<p>
- * See meta-data keyword ANGLE_TYPE for the definition of the angles.
- */
- ANGLE_1(Unit.DEGREE),
- /** 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 ≤ ANGLE_2 < 360.0.<p>
- * Units shall be degrees.<p>
- * See meta-data keyword ANGLE_TYPE for the definition of the angles.
- */
- ANGLE_2(Unit.DEGREE),
- // Optical/Radar Related keywords
- /** Data: visual magnitude. */
- MAG(Unit.ONE),
- /** Data: Radar Cross section [m²]. */
- RCS(Units.M2),
- // 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(Unit.SECOND),
- /** 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(Unit.ONE),
- // 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(Unit.TOTAL_ELECTRON_CONTENT_UNIT),
- /** Data: TROPO DRY [m].<p>
- * Dry zenith delay through the troposphere measured at the timetag.
- */
- TROPO_DRY(Unit.METRE),
- /** Data: TROPO WET [m].<p>
- * Wet zenith delay through the troposphere measured at the timetag.
- */
- TROPO_WET(Unit.METRE),
- // Meteorological Related Keywords
- /** Data: Pressure [hPa].<p>
- * Atmospheric pressure observable as measured at the tracking participant.
- */
- PRESSURE(Units.HECTO_PASCAL),
- /** Data: Relative humidity [%].<p>
- * Relative humidity observable as measured at the tracking participant.
- */
- RHUMIDITY(Unit.PERCENT),
- /** Data: Temperature [K].<p>
- * Temperature observable as measured at the tracking participant.
- */
- TEMPERATURE(Unit.ONE);
- /** Pattern for delimiting regular expressions. */
- private static final Pattern SEPARATOR = Pattern.compile("\\s+");
- /** Unit. */
- private final Unit unit;
- /** Simple constructor.
- * @param unit observation unit
- */
- ObservationType(final Unit unit) {
- this.unit = unit;
- }
- /** Process an observation line.
- * @param token parse token
- * @param context context binding
- * @param ruConverter converter for {@link RangeUnits#RU Range Units} (may be null)
- * @param metadata metadata for current block
- * @param observationsBlock observation block to fill
- * @return true if token was accepted
- */
- public boolean process(final ParseToken token, final ContextBinding context,
- final RangeUnitsConverter ruConverter, final TdmMetadata metadata,
- final ObservationsBlock observationsBlock) {
- if (token.getType() == TokenType.ENTRY) {
- // in an XML file, an observation element contains only the value, the epoch has been parsed before
- // in a KVN file, an observation line should contains both epoch and value
- if (observationsBlock.getCurrentObservationEpoch() != null) {
- // we are parsing an XML file with epoch already parsed
- // parse the measurement
- final AbsoluteDate epoch = observationsBlock.getCurrentObservationEpoch();
- final double rawValue = token.getContentAsDouble();
- observationsBlock.addObservationValue(this, rawToSI(ruConverter, metadata, epoch, rawValue));
- } else {
- // we are parsing a KVN file and need to parse both epoch and measurement
- final String[] fields = SEPARATOR.split(token.getContentAsNormalizedString());
- if (fields.length != 2) {
- throw token.generateException(null);
- }
- // parse the epoch
- final AbsoluteDate epoch = context.getTimeSystem().getConverter(context).parse(fields[0]);
- observationsBlock.addObservationEpoch(epoch);
- // parse the measurement
- try {
- final double rawValue = Double.parseDouble(fields[1]);
- observationsBlock.addObservationValue(this, rawToSI(ruConverter, metadata, epoch, rawValue));
- } catch (NumberFormatException nfe) {
- throw token.generateException(nfe);
- }
- }
- }
- return true;
- }
- /** Convert a measurement to SI units.
- * @param ruConverter converter for {@link RangeUnits#RU Range Units} (may be null)
- * @param metadata metadata corresponding to the observation
- * @param date observation date
- * @param rawValue measurement raw value
- * @return measurement in SI units
- */
- public double rawToSI(final RangeUnitsConverter ruConverter, final TdmMetadata metadata,
- final AbsoluteDate date, final double rawValue) {
- return unit.toSI(rawValue);
- }
- /** Convert a measurement from SI units.
- * @param ruConverter converter for {@link RangeUnits#RU Range Units} (may be null)
- * @param metadata metadata corresponding to the observation
- * @param date observation date
- * @param siValue measurement value in SI units
- * @return measurement raw value
- */
- public double siToRaw(final RangeUnitsConverter ruConverter, final TdmMetadata metadata,
- final AbsoluteDate date, final double siValue) {
- return unit.fromSI(siValue);
- }
- }