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
18 package org.orekit.files.ccsds.ndm.odm;
19
20 import java.util.function.Supplier;
21
22 import org.hipparchus.linear.MatrixUtils;
23 import org.hipparchus.linear.RealMatrix;
24 import org.orekit.errors.OrekitException;
25 import org.orekit.errors.OrekitMessages;
26 import org.orekit.files.ccsds.definitions.FrameFacade;
27 import org.orekit.files.ccsds.section.CommentsContainer;
28 import org.orekit.files.ccsds.section.Data;
29 import org.orekit.time.AbsoluteDate;
30
31 /** Container for OPM/OMM/OCM Cartesian covariance matrix.
32 * <p>
33 * Beware that the Orekit getters and setters all rely on SI units. The parsers
34 * and writers take care of converting these SI units into CCSDS mandatory units.
35 * The {@link org.orekit.utils.units.Unit Unit} class provides useful
36 * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
37 * {@link org.orekit.utils.units.Unit#toSI(double) toSI} methods in case the callers
38 * already use CCSDS units instead of the API SI units. The general-purpose
39 * {@link org.orekit.utils.units.Unit Unit} class (without an 's') and the
40 * CCSDS-specific {@link org.orekit.files.ccsds.definitions.Units Units} class
41 * (with an 's') also provide some predefined units. These predefined units and the
42 * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
43 * {@link org.orekit.utils.units.Unit#toSI(double) toSI} conversion methods are indeed
44 * what the parsers and writers use for the conversions.
45 * </p>
46 * @author sports
47 * @since 6.1
48 */
49 public class CartesianCovariance extends CommentsContainer implements Data {
50
51 /** Labels for matrix row/columns. */
52 private static final String[] LABELS = {
53 "X", "Y", "Z", "X_DOT", "Y_DOT", "Z_DOT"
54 };
55
56 /** Supplier for default reference frame. */
57 private final Supplier<FrameFacade> defaultFrameSupplier;
58
59 /** Matrix epoch. */
60 private AbsoluteDate epoch;
61
62 /** Reference frame in which data are given. */
63 private FrameFacade referenceFrame;
64
65 /** Position/Velocity covariance matrix. */
66 private final RealMatrix covarianceMatrix;
67
68 /** Create an empty data set.
69 * @param defaultFrameSupplier supplier for default reference frame
70 * if no frame is specified in the CCSDS message
71 */
72 public CartesianCovariance(final Supplier<FrameFacade> defaultFrameSupplier) {
73 this.defaultFrameSupplier = defaultFrameSupplier;
74 covarianceMatrix = MatrixUtils.createRealMatrix(6, 6);
75 for (int i = 0; i < covarianceMatrix.getRowDimension(); ++i) {
76 for (int j = 0; j <= i; ++j) {
77 covarianceMatrix.setEntry(i, j, Double.NaN);
78 }
79 }
80 }
81
82 /** {@inheritDoc} */
83 @Override
84 public void validate(final double version) {
85 super.validate(version);
86 checkNotNull(epoch, CartesianCovarianceKey.EPOCH.name());
87 for (int i = 0; i < covarianceMatrix.getRowDimension(); ++i) {
88 for (int j = 0; j <= i; ++j) {
89 if (Double.isNaN(covarianceMatrix.getEntry(i, j))) {
90 throw new OrekitException(OrekitMessages.CCSDS_MISSING_KEYWORD,
91 "C" + LABELS[i] + "_" + LABELS[j]);
92 }
93 }
94 }
95 }
96
97 /** Get matrix epoch.
98 * @return matrix epoch
99 */
100 public AbsoluteDate getEpoch() {
101 return epoch;
102 }
103
104 /** Set matrix epoch.
105 * @param epoch matrix epoch
106 */
107 public void setEpoch(final AbsoluteDate epoch) {
108 refuseFurtherComments();
109 this.epoch = epoch;
110 }
111
112 /**
113 * Get the reference frame.
114 *
115 * @return The reference frame specified by the {@code COV_REF_FRAME} keyword
116 * or inherited from metadata
117 */
118 public FrameFacade getReferenceFrame() {
119 return referenceFrame == null ? defaultFrameSupplier.get() : referenceFrame;
120 }
121
122 /** Set the reference frame in which data are given.
123 * @param referenceFrame the reference frame to be set
124 */
125 public void setReferenceFrame(final FrameFacade referenceFrame) {
126 refuseFurtherComments();
127 this.referenceFrame = referenceFrame;
128 }
129
130 /** Get the Position/Velocity covariance matrix.
131 * @return the Position/Velocity covariance matrix
132 */
133 public RealMatrix getCovarianceMatrix() {
134 return covarianceMatrix;
135 }
136
137 /** Set an entry in the Position/Velocity covariance matrix.
138 * <p>
139 * Both m(j, k) and m(k, j) are set.
140 * </p>
141 * @param j row index (must be between 0 and 5 (inclusive)
142 * @param k column index (must be between 0 and 5 (inclusive)
143 * @param entry value of the matrix entry
144 */
145 public void setCovarianceMatrixEntry(final int j, final int k, final double entry) {
146 refuseFurtherComments();
147 covarianceMatrix.setEntry(j, k, entry);
148 covarianceMatrix.setEntry(k, j, entry);
149 }
150
151 }