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 }