1   /* Copyright 2002-2022 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  
18  package org.orekit.files.ccsds.ndm.odm.ocm;
19  
20  import java.io.IOException;
21  import java.util.List;
22  
23  import org.hipparchus.linear.RealMatrix;
24  import org.hipparchus.util.FastMath;
25  import org.orekit.files.ccsds.definitions.TimeConverter;
26  import org.orekit.files.ccsds.section.AbstractWriter;
27  import org.orekit.files.ccsds.utils.FileFormat;
28  import org.orekit.files.ccsds.utils.generation.Generator;
29  import org.orekit.utils.AccurateFormatter;
30  import org.orekit.utils.units.Unit;
31  
32  /** Writer for covariance history data.
33   * @author Luc Maisonobe
34   * @since 11.0
35   */
36  class CovarianceHistoryWriter extends AbstractWriter {
37  
38      /** Covariance history block. */
39      private final CovarianceHistory history;
40  
41      /** Converter for dates. */
42      private final TimeConverter timeConverter;
43  
44      /** Create a writer.
45       * @param covarianceHistory covariance history to write
46       * @param timeConverter converter for dates
47       */
48      CovarianceHistoryWriter(final CovarianceHistory covarianceHistory,
49                              final TimeConverter timeConverter) {
50          super(OcmDataSubStructureKey.covar.name(), OcmDataSubStructureKey.COV.name());
51          this.history       = covarianceHistory;
52          this.timeConverter = timeConverter;
53      }
54  
55      /** {@inheritDoc} */
56      @Override
57      protected void writeContent(final Generator generator) throws IOException {
58  
59          // covariance history block
60          final CovarianceHistoryMetadata metadata = history.getMetadata();
61          generator.writeComments(metadata.getComments());
62  
63          // identifiers
64          generator.writeEntry(CovarianceHistoryMetadataKey.COV_ID.name(),       metadata.getCovID(),      null, false);
65          generator.writeEntry(CovarianceHistoryMetadataKey.COV_PREV_ID.name(),  metadata.getCovPrevID(),  null, false);
66          generator.writeEntry(CovarianceHistoryMetadataKey.COV_NEXT_ID.name(),  metadata.getCovNextID(),  null, false);
67          generator.writeEntry(CovarianceHistoryMetadataKey.COV_BASIS.name(),    metadata.getCovBasis(),   null, false);
68          generator.writeEntry(CovarianceHistoryMetadataKey.COV_BASIS_ID.name(), metadata.getCovBasisID(), null, false);
69  
70          // references
71          generator.writeEntry(CovarianceHistoryMetadataKey.COV_REF_FRAME.name(),   metadata.getCovReferenceFrame().getName(),  null, false);
72          generator.writeEntry(CovarianceHistoryMetadataKey.COV_FRAME_EPOCH.name(), timeConverter, metadata.getCovFrameEpoch(),       false);
73  
74          // scaling
75          generator.writeEntry(CovarianceHistoryMetadataKey.COV_SCALE_MIN.name(),  metadata.getCovScaleMin(), Unit.ONE,       false);
76          generator.writeEntry(CovarianceHistoryMetadataKey.COV_SCALE_MAX.name(),  metadata.getCovScaleMax(), Unit.ONE,       false);
77          generator.writeEntry(CovarianceHistoryMetadataKey.COV_CONFIDENCE.name(), metadata.getCovConfidence(), Unit.PERCENT, false);
78  
79          // elements
80          generator.writeEntry(CovarianceHistoryMetadataKey.COV_TYPE.name(),     metadata.getCovType(),                                     false);
81          generator.writeEntry(CovarianceHistoryMetadataKey.COV_ORDERING.name(), metadata.getCovOrdering(),                                 false);
82          generator.writeEntry(CovarianceHistoryMetadataKey.COV_UNITS.name(),    generator.unitsListToString(metadata.getCovUnits()), null, false);
83  
84          // data
85          final List<Unit> units = metadata.getCovType().getUnits();
86          for (final Covariance covariance : history.getCovariances()) {
87              final RealMatrix        matrix   = covariance.getMatrix();
88              final Ordering          ordering = metadata.getCovOrdering();
89              final CovarianceIndexer indexer  = new CovarianceIndexer(units.size());
90              final StringBuilder     line     = new StringBuilder();
91              line.append(generator.dateToString(timeConverter, covariance.getDate()));
92              for (int k = 0; k < ordering.nbElements(units.size()); ++k) {
93                  final int i = indexer.getRow();
94                  final int j = indexer.getColumn();
95                  final double cij;
96                  if (indexer.isCrossCorrelation()) {
97                      // we need to compute the cross-correlation
98                      cij = matrix.getEntry(i, j) /
99                                      FastMath.sqrt(matrix.getEntry(i, i) * matrix.getEntry(j, j));
100                 } else {
101                     // we need to get the covariance
102                     cij = units.get(i).fromSI(units.get(j).fromSI(matrix.getEntry(i, j)));
103                 }
104                 line.append(' ');
105                 line.append(AccurateFormatter.format(cij));
106                 ordering.update(indexer);
107             }
108             if (generator.getFormat() == FileFormat.XML) {
109                 generator.writeEntry(Ocm.COV_LINE, line.toString(), null, true);
110             } else {
111                 generator.writeRawData(line);
112                 generator.newLine();
113             }
114 
115         }
116 
117     }
118 
119 }