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 java.io.IOException;
20  import java.util.List;
21  
22  import org.orekit.files.ccsds.definitions.TimeConverter;
23  import org.orekit.files.ccsds.definitions.Units;
24  import org.orekit.files.ccsds.section.AbstractWriter;
25  import org.orekit.files.ccsds.section.KvnStructureKey;
26  import org.orekit.files.ccsds.section.MetadataKey;
27  import org.orekit.files.ccsds.section.XmlStructureKey;
28  import org.orekit.files.ccsds.utils.generation.Generator;
29  import org.orekit.utils.units.Unit;
30  
31  
32  /**
33   * Writer for CCSDS Tracking Data Message metadata.
34   *
35   * @author Luc Maisonobe
36   * @since 11.0
37   */
38  class TdmMetadataWriter extends AbstractWriter {
39  
40      /** Metadata. */
41      private final TdmMetadata metadata;
42  
43      /** Converter for dates. */
44      private final TimeConverter timeConverter;
45  
46      /** Simple constructor.
47       * @param metadata metadata to write
48       * @param timeConverter converter for dates
49       */
50      TdmMetadataWriter(final TdmMetadata metadata, final TimeConverter timeConverter) {
51          super(XmlStructureKey.metadata.name(), KvnStructureKey.META.name());
52          this.metadata     = metadata;
53          this.timeConverter = timeConverter;
54      }
55  
56      /** {@inheritDoc} */
57      @Override
58      protected void writeContent(final Generator generator) throws IOException {
59  
60          generator.writeComments(metadata.getComments());
61  
62          generator.writeEntry(TdmMetadataKey.TRACK_ID.name(), metadata.getTrackId(), null, false);
63          final List<ObservationType> dataTypes = metadata.getDataTypes();
64          if (dataTypes != null && !dataTypes.isEmpty()) {
65              final StringBuilder dataTypesNames = new StringBuilder();
66              for (int i = 0; i < dataTypes.size(); ++i) {
67                  if (i > 0) {
68                      dataTypesNames.append(',');
69                  }
70                  dataTypesNames.append(dataTypes.get(i).name());
71              }
72              generator.writeEntry(TdmMetadataKey.DATA_TYPES.name(), dataTypesNames.toString(), null, false);
73          }
74  
75          // time
76          generator.writeEntry(MetadataKey.TIME_SYSTEM.name(),                  metadata.getTimeSystem(), true);
77          generator.writeEntry(TdmMetadataKey.START_TIME.name(), timeConverter, metadata.getStartTime(),  false, false);
78          generator.writeEntry(TdmMetadataKey.STOP_TIME.name(),  timeConverter, metadata.getStopTime(),   false, false);
79  
80          // participants
81          generator.writeEntry(TdmMetadataKey.PARTICIPANT_1.name(), metadata.getParticipants().get(1), null, true);
82          generator.writeEntry(TdmMetadataKey.PARTICIPANT_2.name(), metadata.getParticipants().get(2), null, false);
83          generator.writeEntry(TdmMetadataKey.PARTICIPANT_3.name(), metadata.getParticipants().get(3), null, false);
84          generator.writeEntry(TdmMetadataKey.PARTICIPANT_4.name(), metadata.getParticipants().get(4), null, false);
85          generator.writeEntry(TdmMetadataKey.PARTICIPANT_5.name(), metadata.getParticipants().get(5), null, false);
86  
87          final TrackingMode mode = metadata.getMode();
88          generator.writeEntry(TdmMetadataKey.MODE.name(), mode, false);
89          if (mode == TrackingMode.SEQUENTIAL) {
90              generator.writeEntry(TdmMetadataKey.PATH.name(), intArrayToString(metadata.getPath()),  null, true);
91          } else if (mode == TrackingMode.SINGLE_DIFF) {
92              generator.writeEntry(TdmMetadataKey.PATH_1.name(), intArrayToString(metadata.getPath1()), null, true);
93              generator.writeEntry(TdmMetadataKey.PATH_2.name(), intArrayToString(metadata.getPath2()), null, true);
94          }
95  
96          generator.writeEntry(TdmMetadataKey.EPHEMERIS_NAME_1.name(),       metadata.getEphemerisNames().get(1), null, false);
97          generator.writeEntry(TdmMetadataKey.EPHEMERIS_NAME_2.name(),       metadata.getEphemerisNames().get(2), null, false);
98          generator.writeEntry(TdmMetadataKey.EPHEMERIS_NAME_3.name(),       metadata.getEphemerisNames().get(3), null, false);
99          generator.writeEntry(TdmMetadataKey.EPHEMERIS_NAME_4.name(),       metadata.getEphemerisNames().get(4), null, false);
100         generator.writeEntry(TdmMetadataKey.EPHEMERIS_NAME_5.name(),       metadata.getEphemerisNames().get(5), null, false);
101 
102         generator.writeEntry(TdmMetadataKey.TRANSMIT_BAND.name(),          metadata.getTransmitBand(), null, false);
103         generator.writeEntry(TdmMetadataKey.RECEIVE_BAND.name(),           metadata.getReceiveBand(),  null, false);
104         if (metadata.getTurnaroundNumerator() != 0 || metadata.getTurnaroundDenominator() != 0) {
105             generator.writeEntry(TdmMetadataKey.TURNAROUND_NUMERATOR.name(),   metadata.getTurnaroundNumerator(),   false);
106             generator.writeEntry(TdmMetadataKey.TURNAROUND_DENOMINATOR.name(), metadata.getTurnaroundDenominator(), false);
107         }
108         generator.writeEntry(TdmMetadataKey.TIMETAG_REF.name(),            metadata.getTimetagRef(),                       false);
109         generator.writeEntry(TdmMetadataKey.INTEGRATION_INTERVAL.name(),   metadata.getIntegrationInterval(), Unit.SECOND, false);
110         generator.writeEntry(TdmMetadataKey.INTEGRATION_REF.name(),        metadata.getIntegrationRef(),                   false);
111         generator.writeEntry(TdmMetadataKey.FREQ_OFFSET.name(),            metadata.getFreqOffset(),          Unit.HERTZ,  false);
112         generator.writeEntry(TdmMetadataKey.RANGE_MODE.name(),             metadata.getRangeMode(),                        false);
113         if (metadata.getRawRangeModulus() != 0) {
114             generator.writeEntry(TdmMetadataKey.RANGE_MODULUS.name(),      metadata.getRawRangeModulus(),     Unit.ONE,    false);
115         }
116         generator.writeEntry(TdmMetadataKey.RANGE_UNITS.name(),            metadata.getRangeUnits(),                       false);
117         generator.writeEntry(TdmMetadataKey.ANGLE_TYPE.name(),             metadata.getAngleType(),                        false);
118         if (metadata.getReferenceFrame() != null) {
119             generator.writeEntry(TdmMetadataKey.REFERENCE_FRAME.name(),    metadata.getReferenceFrame().getName(), null, false);
120         }
121 
122         // interpolation
123         if (metadata.getInterpolationMethod() != null) {
124             generator.writeEntry(TdmMetadataKey.INTERPOLATION.name(),
125                                  metadata.getInterpolationMethod(),
126                                  null, true);
127             generator.writeEntry(TdmMetadataKey.INTERPOLATION_DEGREE.name(),
128                                  Integer.toString(metadata.getInterpolationDegree()),
129                                  null, true);
130         }
131 
132         // Doppler
133         if (metadata.getDopplerCountBias() != 0) {
134             generator.writeEntry(TdmMetadataKey.DOPPLER_COUNT_BIAS.name(),  metadata.getDopplerCountBias(),  Unit.HERTZ, false);
135         }
136         if (metadata.getDopplerCountScale() != 1) {
137             generator.writeEntry(TdmMetadataKey.DOPPLER_COUNT_SCALE.name(), metadata.getDopplerCountScale(), Unit.ONE,   false);
138         }
139         if (metadata.hasDopplerCountRollover()) {
140             generator.writeEntry(TdmMetadataKey.DOPPLER_COUNT_BIAS.name(),  metadata.hasDopplerCountRollover() ? "YES" : "NO", null, false);
141         }
142 
143         generator.writeEntry(TdmMetadataKey.TRANSMIT_DELAY_1.name(),       metadata.getTransmitDelays().get(1), Unit.SECOND, false);
144         generator.writeEntry(TdmMetadataKey.TRANSMIT_DELAY_2.name(),       metadata.getTransmitDelays().get(2), Unit.SECOND, false);
145         generator.writeEntry(TdmMetadataKey.TRANSMIT_DELAY_3.name(),       metadata.getTransmitDelays().get(3), Unit.SECOND, false);
146         generator.writeEntry(TdmMetadataKey.TRANSMIT_DELAY_4.name(),       metadata.getTransmitDelays().get(4), Unit.SECOND, false);
147         generator.writeEntry(TdmMetadataKey.TRANSMIT_DELAY_5.name(),       metadata.getTransmitDelays().get(5), Unit.SECOND, false);
148         generator.writeEntry(TdmMetadataKey.RECEIVE_DELAY_1.name(),        metadata.getReceiveDelays().get(1),  Unit.SECOND, false);
149         generator.writeEntry(TdmMetadataKey.RECEIVE_DELAY_2.name(),        metadata.getReceiveDelays().get(2),  Unit.SECOND, false);
150         generator.writeEntry(TdmMetadataKey.RECEIVE_DELAY_3.name(),        metadata.getReceiveDelays().get(3),  Unit.SECOND, false);
151         generator.writeEntry(TdmMetadataKey.RECEIVE_DELAY_4.name(),        metadata.getReceiveDelays().get(4),  Unit.SECOND, false);
152         generator.writeEntry(TdmMetadataKey.RECEIVE_DELAY_5.name(),        metadata.getReceiveDelays().get(5),  Unit.SECOND, false);
153         generator.writeEntry(TdmMetadataKey.DATA_QUALITY.name(),           metadata.getDataQuality(),                        false);
154         if (metadata.getCorrectionAngle1() != 0) {
155             generator.writeEntry(TdmMetadataKey.CORRECTION_ANGLE_1.name(),  metadata.getCorrectionAngle1(), Unit.DEGREE,     false);
156         }
157         if (metadata.getCorrectionAngle2() != 0) {
158             generator.writeEntry(TdmMetadataKey.CORRECTION_ANGLE_2.name(),  metadata.getCorrectionAngle2(), Unit.DEGREE,     false);
159         }
160         if (metadata.getCorrectionDoppler() != 0) {
161             generator.writeEntry(TdmMetadataKey.CORRECTION_DOPPLER.name(),  metadata.getCorrectionDoppler(), Units.KM_PER_S, false);
162         }
163         if (metadata.getCorrectionMagnitude() != 0) {
164             generator.writeEntry(TdmMetadataKey.CORRECTION_MAG.name(),      metadata.getCorrectionMagnitude(), Unit.ONE,     false);
165         }
166         if (metadata.getRawCorrectionRange() != 0) {
167             generator.writeEntry(TdmMetadataKey.CORRECTION_RANGE.name(),    metadata.getRawCorrectionRange(), Unit.ONE,      false);
168         }
169         if (metadata.getCorrectionRcs() != 0) {
170             generator.writeEntry(TdmMetadataKey.CORRECTION_RCS.name(),      metadata.getCorrectionRcs(),      Units.M2,      false);
171         }
172         if (metadata.getCorrectionReceive() != 0) {
173             generator.writeEntry(TdmMetadataKey.CORRECTION_RECEIVE.name(),  metadata.getCorrectionReceive(), Unit.HERTZ,     false);
174         }
175         if (metadata.getCorrectionTransmit() != 0) {
176             generator.writeEntry(TdmMetadataKey.CORRECTION_TRANSMIT.name(), metadata.getCorrectionTransmit(), Unit.HERTZ,    false);
177         }
178         if (metadata.getCorrectionAberrationYearly() != 0) {
179             generator.writeEntry(TdmMetadataKey.CORRECTION_ABERRATION_YEARLY.name(), metadata.getCorrectionAberrationYearly(), Unit.DEGREE,    false);
180         }
181         if (metadata.getCorrectionAberrationDiurnal() != 0) {
182             generator.writeEntry(TdmMetadataKey.CORRECTION_ABERRATION_DIURNAL.name(), metadata.getCorrectionAberrationDiurnal(), Unit.DEGREE,    false);
183         }
184         generator.writeEntry(TdmMetadataKey.CORRECTIONS_APPLIED.name(),     metadata.getCorrectionsApplied(),                false);
185 
186     }
187 
188 }