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.ccsds.ndm.tdm;
18  
19  import org.orekit.files.ccsds.definitions.Units;
20  import org.orekit.files.ccsds.utils.ContextBinding;
21  import org.orekit.files.ccsds.utils.lexical.ParseToken;
22  import org.orekit.utils.units.Unit;
23  
24  
25  /** Keys for {@link TdmMetadata TDM container} entries.
26   * @author Maxime Journot
27   * @since 11.0
28   */
29  public enum TdmMetadataKey {
30  
31      /** Identifier for the tracking data. */
32      TRACK_ID((token, context, container) -> token.processAsNormalizedString(container::setTrackId)),
33  
34      /** Lit of data types in the data section. */
35      DATA_TYPES((token, context, container) -> token.processAsEnumsList(ObservationType.class, container::setDataTypes)),
36  
37      /** Start time entry. */
38      START_TIME((token, context, container) -> token.processAsDate(container::setStartTime, context)),
39  
40      /** Stop time entry. */
41      STOP_TIME((token, context, container) -> token.processAsDate(container::setStopTime, context)),
42  
43      /** First participant entry. */
44      PARTICIPANT_1((token, context, container) -> token.processAsIndexedNormalizedString(1, container::addParticipant)),
45  
46      /** Second participant entry. */
47      PARTICIPANT_2((token, context, container) -> token.processAsIndexedNormalizedString(2, container::addParticipant)),
48  
49      /** Third participant entry. */
50      PARTICIPANT_3((token, context, container) -> token.processAsIndexedNormalizedString(3, container::addParticipant)),
51  
52      /** Fourth participant entry. */
53      PARTICIPANT_4((token, context, container) -> token.processAsIndexedNormalizedString(4, container::addParticipant)),
54  
55      /** Fifth participant entry. */
56      PARTICIPANT_5((token, context, container) -> token.processAsIndexedNormalizedString(5, container::addParticipant)),
57  
58      /** Mode entry. */
59      MODE((token, context, container) -> token.processAsEnum(TrackingMode.class, container::setMode)),
60  
61      /** Path entry. */
62      PATH((token, context, container) -> token.processAsIntegerArrayNoSpace(container::setPath)),
63  
64      /** Path 1 entry. */
65      PATH_1((token, context, container) -> token.processAsIntegerArrayNoSpace(container::setPath1)),
66  
67      /** Path 2 entry. */
68      PATH_2((token, context, container) -> token.processAsIntegerArrayNoSpace(container::setPath2)),
69  
70      /** External ephemeris file for the participant 1. */
71      EPHEMERIS_NAME_1((token, context, container) -> token.processAsIndexedNormalizedString(1, container::addEphemerisName)),
72  
73      /** External ephemeris file for the participant 2. */
74      EPHEMERIS_NAME_2((token, context, container) -> token.processAsIndexedNormalizedString(2, container::addEphemerisName)),
75  
76      /** External ephemeris file for the participant 3. */
77      EPHEMERIS_NAME_3((token, context, container) -> token.processAsIndexedNormalizedString(3, container::addEphemerisName)),
78  
79      /** External ephemeris file for the participant 4. */
80      EPHEMERIS_NAME_4((token, context, container) -> token.processAsIndexedNormalizedString(4, container::addEphemerisName)),
81  
82      /** External ephemeris file for the participant 5. */
83      EPHEMERIS_NAME_5((token, context, container) -> token.processAsIndexedNormalizedString(5, container::addEphemerisName)),
84  
85      /** Transmit band entry. */
86      TRANSMIT_BAND((token, context, container) -> token.processAsUppercaseString(container::setTransmitBand)),
87  
88      /** Receive band entry. */
89      RECEIVE_BAND((token, context, container) -> token.processAsUppercaseString(container::setReceiveBand)),
90  
91      /** Turnaround numerator entry. */
92      TURNAROUND_NUMERATOR((token, context, container) -> token.processAsInteger(container::setTurnaroundNumerator)),
93  
94      /** turnaround denominator entry. */
95      TURNAROUND_DENOMINATOR((token, context, container) -> token.processAsInteger(container::setTurnaroundDenominator)),
96  
97      /** Timetag reference entry. */
98      TIMETAG_REF((token, context, container) -> token.processAsEnum(TimetagReference.class, container::setTimetagRef)),
99  
100     /** Integration interval entry. */
101     INTEGRATION_INTERVAL((token, context, container) -> token.processAsDouble(Unit.SECOND, context.getParsedUnitsBehavior(),
102                                                                               container::setIntegrationInterval)),
103 
104     /** Integration reference entry. */
105     INTEGRATION_REF((token, context, container) -> token.processAsEnum(IntegrationReference.class, container::setIntegrationRef)),
106 
107     /** Frequency offset entry. */
108     FREQ_OFFSET((token, context, container) -> token.processAsDouble(Unit.HERTZ, context.getParsedUnitsBehavior(),
109                                                                      container::setFreqOffset)),
110 
111     /** Range mode entry. */
112     RANGE_MODE((token, context, container) -> token.processAsEnum(RangeMode.class, container::setRangeMode)),
113 
114     /** Range modulus entry (beware the unit is Range Units here). */
115     RANGE_MODULUS((token, context, container) -> token.processAsDouble(Unit.ONE, context.getParsedUnitsBehavior(),
116                                                                        container::setRawRangeModulus)),
117 
118     /** Range units entry. */
119     RANGE_UNITS((token, context, container) -> token.processAsEnum(RangeUnits.class, container::setRangeUnits)),
120 
121     /** Angle type entry. */
122     ANGLE_TYPE((token, context, container) -> token.processAsEnum(AngleType.class, container::setAngleType)),
123 
124     /** reference frame entry. */
125     REFERENCE_FRAME((token, context, container) -> token.processAsFrame(container::setReferenceFrame, context, true, false, false)),
126 
127     /** Interpolation method for transmit phase count. */
128     INTERPOLATION((token, context, container) -> token.processAsUppercaseString(container::setInterpolationMethod)),
129 
130     /** Interpolation degree for transmit phase count. */
131     INTERPOLATION_DEGREE((token, context, container) -> token.processAsInteger(container::setInterpolationDegree)),
132 
133     /** Bias that was added to Doppler count in the data section. */
134     DOPPLER_COUNT_BIAS((token, context, container) -> token.processAsDouble(Unit.HERTZ, context.getParsedUnitsBehavior(),
135                                                                             container::setDopplerCountBias)),
136 
137     /** Scaled by which Doppler count was multiplied in the data section. */
138     DOPPLER_COUNT_SCALE((token, context, container) -> token.processAsDouble(Unit.ONE, context.getParsedUnitsBehavior(),
139                                                                             container::setDopplerCountScale)),
140 
141     /** Indicator for occurred rollover in Doppler count. */
142     DOPPLER_COUNT_ROLLOVER((token, context, container) -> token.processAsBoolean(container::setDopplerCountRollover)),
143 
144     /** First transmit delay entry. */
145     TRANSMIT_DELAY_1((token, context, container) -> token.processAsIndexedDouble(1, Unit.SECOND, context.getParsedUnitsBehavior(),
146                                                                                  container::addTransmitDelay)),
147 
148     /** Second transmit delay entry. */
149     TRANSMIT_DELAY_2((token, context, container) -> token.processAsIndexedDouble(2, Unit.SECOND, context.getParsedUnitsBehavior(),
150                                                                                  container::addTransmitDelay)),
151 
152     /** Third transmit delay entry. */
153     TRANSMIT_DELAY_3((token, context, container) -> token.processAsIndexedDouble(3, Unit.SECOND, context.getParsedUnitsBehavior(),
154                                                                                  container::addTransmitDelay)),
155 
156     /** Fourth transmit delay entry. */
157     TRANSMIT_DELAY_4((token, context, container) -> token.processAsIndexedDouble(4, Unit.SECOND, context.getParsedUnitsBehavior(),
158                                                                                  container::addTransmitDelay)),
159 
160     /** Fifth transmit delay entry. */
161     TRANSMIT_DELAY_5((token, context, container) -> token.processAsIndexedDouble(5, Unit.SECOND, context.getParsedUnitsBehavior(),
162                                                                                  container::addTransmitDelay)),
163 
164     /** First receive delay entry. */
165     RECEIVE_DELAY_1((token, context, container) -> token.processAsIndexedDouble(1, Unit.SECOND, context.getParsedUnitsBehavior(),
166                                                                                 container::addReceiveDelay)),
167 
168     /** Second receive delay entry. */
169     RECEIVE_DELAY_2((token, context, container) -> token.processAsIndexedDouble(2, Unit.SECOND, context.getParsedUnitsBehavior(),
170                                                                                 container::addReceiveDelay)),
171 
172     /** Third receive delay entry. */
173     RECEIVE_DELAY_3((token, context, container) -> token.processAsIndexedDouble(3, Unit.SECOND, context.getParsedUnitsBehavior(),
174                                                                                 container::addReceiveDelay)),
175 
176     /** Fourth receive delay entry. */
177     RECEIVE_DELAY_4((token, context, container) -> token.processAsIndexedDouble(4, Unit.SECOND, context.getParsedUnitsBehavior(),
178                                                                                 container::addReceiveDelay)),
179 
180     /** Fifth receive delay entry. */
181     RECEIVE_DELAY_5((token, context, container) -> token.processAsIndexedDouble(5, Unit.SECOND, context.getParsedUnitsBehavior(),
182                                                                                 container::addReceiveDelay)),
183 
184     /** data quality entry. */
185     DATA_QUALITY((token, context, container) -> token.processAsEnum(DataQuality.class, container::setDataQuality)),
186 
187     /** Angle 1 correction entry. */
188     CORRECTION_ANGLE_1((token, context, container) -> token.processAsDouble(Unit.DEGREE, context.getParsedUnitsBehavior(),
189                                                                             container::setCorrectionAngle1)),
190 
191     /** Angle 2 correction entry. */
192     CORRECTION_ANGLE_2((token, context, container) -> token.processAsDouble(Unit.DEGREE, context.getParsedUnitsBehavior(),
193                                                                             container::setCorrectionAngle2)),
194 
195     /** Doppler correction entry. */
196     CORRECTION_DOPPLER((token, context, container) -> token.processAsDouble(Units.KM_PER_S, context.getParsedUnitsBehavior(),
197                                                                             container::setCorrectionDoppler)),
198 
199     /** Magnitude correction entry. */
200     CORRECTION_MAG((token, context, container) -> token.processAsDouble(Unit.ONE, context.getParsedUnitsBehavior(),
201                                                                         container::setCorrectionMagnitude)),
202 
203     /** Range correction entry (beware the unit is Range Units here). */
204     CORRECTION_RANGE((token, context, container) -> token.processAsDouble(Unit.ONE, context.getParsedUnitsBehavior(),
205                                                                           container::setRawCorrectionRange)),
206 
207     /** Radar Cross Section correction entry. */
208     CORRECTION_RCS((token, context, container) -> token.processAsDouble(Units.M2, context.getParsedUnitsBehavior(),
209                                                                         container::setCorrectionRcs)),
210 
211     /** Receive correction entry. */
212     CORRECTION_RECEIVE((token, context, container) -> token.processAsDouble(Unit.HERTZ, context.getParsedUnitsBehavior(),
213                                                                             container::setCorrectionReceive)),
214 
215     /** Transmit correction entry. */
216     CORRECTION_TRANSMIT((token, context, container) -> token.processAsDouble(Unit.HERTZ, context.getParsedUnitsBehavior(),
217                                                                              container::setCorrectionTransmit)),
218 
219     /** Yearly aberration correction entry. */
220     CORRECTION_ABERRATION_YEARLY((token, context, container) -> token.processAsDouble(Unit.DEGREE, context.getParsedUnitsBehavior(),
221                                                                                       container::setCorrectionAberrationYearly)),
222 
223     /** Diurnal aberration correction entry. */
224     CORRECTION_ABERRATION_DIURNAL((token, context, container) -> token.processAsDouble(Unit.DEGREE, context.getParsedUnitsBehavior(),
225                                                                                        container::setCorrectionAberrationDiurnal)),
226 
227     /** Applied correction entry. */
228     CORRECTIONS_APPLIED((token, context, container) -> token.processAsEnum(CorrectionApplied.class, container::setCorrectionsApplied));
229 
230     /** Processing method. */
231     private final transient TokenProcessor processor;
232 
233     /** Simple constructor.
234      * @param processor processing method
235      */
236     TdmMetadataKey(final TokenProcessor processor) {
237         this.processor = processor;
238     }
239 
240     /** Process an token.
241      * @param token token to process
242      * @param context context binding
243      * @param container container to fill
244      * @return true if token was accepted
245      */
246     public boolean process(final ParseToken token, final ContextBinding context, final TdmMetadata container) {
247         return processor.process(token, context, container);
248     }
249 
250     /** Interface for processing one token. */
251     interface TokenProcessor {
252         /** Process one token.
253          * @param token token to process
254          * @param context context binding
255          * @param container container to fill
256      * @return true if token was accepted
257          */
258         boolean process(ParseToken token, ContextBinding context, TdmMetadata container);
259     }
260 
261 }