1   /* Copyright 2002-2026 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.odm.opm;
18  
19  import java.util.Collections;
20  import java.util.List;
21  import java.util.Optional;
22  
23  import org.orekit.annotation.Nullable;
24  import org.orekit.files.ccsds.ndm.odm.CartesianCovariance;
25  import org.orekit.files.ccsds.ndm.odm.KeplerianElements;
26  import org.orekit.files.ccsds.ndm.odm.KeplerianElementsKey;
27  import org.orekit.files.ccsds.ndm.odm.SpacecraftParameters;
28  import org.orekit.files.ccsds.ndm.odm.StateVector;
29  import org.orekit.files.ccsds.ndm.odm.UserDefined;
30  import org.orekit.files.ccsds.section.Data;
31  import org.orekit.files.ccsds.utils.Initializer;
32  
33  /**
34   * Container for Orbit Parameter Message data.
35   * @author Luc Maisonobe
36   * @since 11.0
37   */
38  public class OpmData implements Data {
39  
40      /** State vector block. */
41      private final StateVector stateVectorBlock;
42  
43      /** Keplerian elements block. */
44      @Nullable
45      private final KeplerianElements keplerianElementsBlock;
46  
47      /** Spacecraft parameters block. */
48      @Nullable
49      private final SpacecraftParameters spacecraftParametersBlock;
50  
51      /** Covariance matrix logical block being read. */
52      @Nullable
53      private final CartesianCovariance covarianceBlock;
54  
55      /** Maneuvers. */
56      private final List<Maneuver> maneuverBlocks;
57  
58      /** User defined parameters. */
59      @Nullable
60      private final UserDefined userDefinedBlock;
61  
62      /** Mass. */
63      private final double mass;
64  
65      /** Simple constructor.
66       * @param stateVectorBlock state vector logical block
67       * @param keplerianElementsBlock Keplerian elements logical block (may be null)
68       * @param spacecraftParametersBlock spacecraft parameters logical block (may be null)
69       * @param covarianceBlock covariance matrix logical block (may be null)
70       * @param maneuverBlocks maneuvers block list
71       * @param userDefinedBlock user-defined logical block
72       * @param mass mass (always defined, even if there is no {@code spacecraftParameters} block
73       */
74      public OpmData(final StateVector stateVectorBlock,
75                     final KeplerianElements keplerianElementsBlock,
76                     final SpacecraftParameters spacecraftParametersBlock,
77                     final CartesianCovariance covarianceBlock,
78                     final List<Maneuver> maneuverBlocks,
79                     final UserDefined userDefinedBlock,
80                     final double mass) {
81          this.stateVectorBlock          = stateVectorBlock;
82          this.keplerianElementsBlock    = keplerianElementsBlock;
83          this.spacecraftParametersBlock = spacecraftParametersBlock;
84          this.covarianceBlock           = covarianceBlock;
85          this.maneuverBlocks            = Initializer.emptyListIfNull(maneuverBlocks);
86          this.userDefinedBlock          = userDefinedBlock;
87          this.mass                      = mass;
88      }
89  
90      /** {@inheritDoc} */
91      @Override
92      public void validate(final double version) {
93          stateVectorBlock.validate(version);
94          if (keplerianElementsBlock != null) {
95              keplerianElementsBlock.validate(version);
96              // in OPM, only semi-major axis is allowed, not mean motion
97              keplerianElementsBlock.checkNotNaN(keplerianElementsBlock.getA().orElse(Double.NaN),
98                                                 KeplerianElementsKey.SEMI_MAJOR_AXIS.name());
99          }
100         if (spacecraftParametersBlock != null) {
101             spacecraftParametersBlock.validate(version);
102         }
103         if (covarianceBlock != null) {
104             covarianceBlock.setEpoch(stateVectorBlock.getEpoch());
105             covarianceBlock.validate(version);
106         }
107         maneuverBlocks.forEach(maneuver -> maneuver.validate(version));
108         if (userDefinedBlock != null) {
109             userDefinedBlock.validate(version);
110         }
111     }
112 
113     /** Get the state vector logical block.
114      * @return state vector block
115      */
116     public StateVector getStateVectorBlock() {
117         return stateVectorBlock;
118     }
119 
120     /** Get the Keplerian elements logical block.
121      * @return Keplerian elements block
122      */
123     public Optional<KeplerianElements> getKeplerianElementsBlock() {
124         return Optional.ofNullable(keplerianElementsBlock);
125     }
126 
127     /** Get the spacecraft parameters logical block.
128      * @return spacecraft parameters block
129      */
130     public Optional<SpacecraftParameters> getSpacecraftParametersBlock() {
131         return Optional.ofNullable(spacecraftParametersBlock);
132     }
133 
134     /** Get the covariance matrix logical block.
135      * @return covariance matrix block
136      */
137     public Optional<CartesianCovariance> getCovarianceBlock() {
138         return Optional.ofNullable(covarianceBlock);
139     }
140 
141     /** Get the mass.
142      * @return mass
143      */
144     public double getMass() {
145         return mass;
146     }
147 
148     /**
149      * Get the number of maneuvers present in the APM.
150      * @return the number of maneuvers
151      */
152     public int getNbManeuvers() {
153         return maneuverBlocks.size();
154     }
155 
156     /**
157      * Get a list of all maneuvers.
158      * @return unmodifiable list of all maneuvers.
159      */
160     public List<Maneuver> getManeuvers() {
161         return Collections.unmodifiableList(maneuverBlocks);
162     }
163 
164     /**
165      * Get a maneuver.
166      * @param index maneuver index, counting from 0
167      * @return maneuver
168      */
169     public Maneuver getManeuver(final int index) {
170         return maneuverBlocks.get(index);
171     }
172 
173     /**
174      * Get boolean testing whether the APM contains at least one maneuver.
175      * @return true if APM contains at least one maneuver
176      *         false otherwise
177      */
178     public boolean hasManeuvers() {
179         return !maneuverBlocks.isEmpty();
180     }
181 
182     /** Get the user defined parameters logical block.
183      * @return user defined parameters block
184      */
185     public Optional<UserDefined> getUserDefinedBlock() {
186         return Optional.ofNullable(userDefinedBlock);
187     }
188 
189 }