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  
18  package org.orekit.files.ccsds.ndm.odm.ocm;
19  
20  import java.util.Collections;
21  import java.util.List;
22  import java.util.Optional;
23  
24  import org.orekit.annotation.Nullable;
25  import org.orekit.files.ccsds.definitions.OdMethodFacade;
26  import org.orekit.files.ccsds.section.CommentsContainer;
27  import org.orekit.time.AbsoluteDate;
28  
29  /** Orbit determination data.
30   * <p>
31   * Beware that the Orekit getters and setters all rely on SI units. The parsers
32   * and writers take care of converting these SI units into CCSDS mandatory units.
33   * The {@link org.orekit.utils.units.Unit Unit} class provides useful
34   * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
35   * {@link org.orekit.utils.units.Unit#toSI(double) toSI} methods in case the callers
36   * already use CCSDS units instead of the API SI units. The general-purpose
37   * {@link org.orekit.utils.units.Unit Unit} class (without an 's') and the
38   * CCSDS-specific {@link org.orekit.files.ccsds.definitions.Units Units} class
39   * (with an 's') also provide some predefined units. These predefined units and the
40   * {@link org.orekit.utils.units.Unit#fromSI(double) fromSi} and
41   * {@link org.orekit.utils.units.Unit#toSI(double) toSI} conversion methods are indeed
42   * what the parsers and writers use for the conversions.
43   * </p>
44   * @author Luc Maisonobe
45   * @since 11.0
46   */
47  public class OrbitDetermination extends CommentsContainer {
48  
49      /** Identification number. */
50      private String id;
51  
52      /** Identification of previous orbit determination. */
53      @Nullable
54      private String prevId;
55  
56      /** Orbit determination method. */
57      private OdMethodFacade method;
58  
59      /** Time tag for orbit determination solved-for state. */
60      private AbsoluteDate epoch;
61  
62      /** Time elapsed between first accepted observation on epoch. */
63      @Nullable
64      private Double timeSinceFirstObservation;
65  
66      /** Time elapsed between last accepted observation on epoch. */
67      @Nullable
68      private Double timeSinceLastObservation;
69  
70      /** Time span of observation recommended for the OD of the object. */
71      @Nullable
72      private Double recommendedOdSpan;
73  
74      /** Actual time span used for the OD of the object. */
75      @Nullable
76      private Double actualOdSpan;
77  
78      /** Number of observations available within the actual OD span. */
79      @Nullable
80      private Integer obsAvailable;
81  
82      /** Number of observations accepted within the actual OD span. */
83      @Nullable
84      private Integer obsUsed;
85  
86      /** Number of sensors tracks available for the OD within the actual OD span. */
87      @Nullable
88      private Integer tracksAvailable;
89  
90      /** Number of sensors tracks accepted for the OD within the actual OD span. */
91      @Nullable
92      private Integer tracksUsed;
93  
94      /** Maximum time between observations in the OD of the object. */
95      @Nullable
96      private Double maximumObsGap;
97  
98      /** Positional error ellipsoid 1σ major eigenvalue at the epoch of OD. */
99      @Nullable
100     private Double epochEigenMaj;
101 
102     /** Positional error ellipsoid 1σ intermediate eigenvalue at the epoch of OD. */
103     @Nullable
104     private Double epochEigenInt;
105 
106     /** Positional error ellipsoid 1σ minor eigenvalue at the epoch of OD. */
107     @Nullable
108     private Double epochEigenMin;
109 
110     /** Maximum predicted major eigenvalue of 1σ positional error ellipsoid over entire time span of the OCM. */
111     @Nullable
112     private Double maxPredictedEigenMaj;
113 
114     /** Minimum predicted minor eigenvalue of 1σ positional error ellipsoid over entire time span of the OCM. */
115     @Nullable
116     private Double minPredictedEigenMin;
117 
118     /** Confidence metric. */
119     @Nullable
120     private Double confidence;
121 
122     /** Generalize Dilution Of Precision. */
123     @Nullable
124     private Double gdop;
125 
126     /** Number of solved-for states. */
127     @Nullable
128     private Integer solveN;
129 
130     /** Description of state elements solved-for. */
131     private List<String> solveStates;
132 
133     /** Number of consider parameters. */
134     @Nullable
135     private Integer considerN;
136 
137     /** Description of consider parameters. */
138     private List<String> considerParameters;
139 
140     /** Specific Energy Dissipation Rate.
141      * @since 12.0
142      */
143     @Nullable
144     private Double sedr;
145 
146     /** Number of sensors used. */
147     @Nullable
148     private Integer sensorsN;
149 
150     /** Description of sensors used. */
151     private List<String> sensors;
152 
153     /** Weighted RMS residual ratio. */
154     @Nullable
155     private Double weightedRms;
156 
157     /** Observation data types used. */
158     private List<String> dataTypes;
159 
160     /** Simple constructor.
161      */
162     public OrbitDetermination() {
163         solveStates        = Collections.emptyList();
164         considerParameters = Collections.emptyList();
165         sensors            = Collections.emptyList();
166         dataTypes          = Collections.emptyList();
167     }
168 
169     /** {@inheritDoc} */
170     @Override
171     public void validate(final double version) {
172         super.validate(version);
173         checkNotNull(id,     OrbitDeterminationKey.OD_ID.name());
174         checkNotNull(method, OrbitDeterminationKey.OD_METHOD.name());
175         checkNotNull(epoch,  OrbitDeterminationKey.OD_EPOCH.name());
176     }
177 
178     /** Get identification number.
179      * @return identification number
180      */
181     public String getId() {
182         return id;
183     }
184 
185     /** Set identification number.
186      * @param id identification number
187      */
188     public void setId(final String id) {
189         this.id = id;
190     }
191 
192     /** Get identification of previous orbit determination.
193      * @return identification of previous orbit determination
194      */
195     public Optional<String> getPrevId() {
196         return Optional.ofNullable(prevId);
197     }
198 
199     /** Set identification of previous orbit determination.
200      * @param prevId identification of previous orbit determination
201      */
202     public void setPrevId(final String prevId) {
203         this.prevId = prevId;
204     }
205 
206     /** Get orbit determination method.
207      * @return orbit determination method
208      */
209     public OdMethodFacade getMethod() {
210         return method;
211     }
212 
213     /** Set orbit determination method.
214      * @param method orbit determination method
215      */
216     public void setMethod(final OdMethodFacade method) {
217         this.method = method;
218     }
219 
220     /** Get time tag for orbit determination solved-for state.
221      * @return time tag for orbit determination solved-for state
222      */
223     public AbsoluteDate getEpoch() {
224         return epoch;
225     }
226 
227     /** Set time tag for orbit determination solved-for state.
228      * @param epoch time tag for orbit determination solved-for state
229      */
230     public void setEpoch(final AbsoluteDate epoch) {
231         this.epoch = epoch;
232     }
233 
234     /** Get time elapsed between first accepted observation on epoch.
235      * @return time elapsed between first accepted observation on epoch
236      */
237     public Optional<Double> getTimeSinceFirstObservation() {
238         return Optional.ofNullable(timeSinceFirstObservation);
239     }
240 
241     /** Set time elapsed between first accepted observation on epoch.
242      * @param timeSinceFirstObservation time elapsed between first accepted observation on epoch
243      */
244     public void setTimeSinceFirstObservation(final double timeSinceFirstObservation) {
245         this.timeSinceFirstObservation = timeSinceFirstObservation;
246     }
247 
248     /** Get time elapsed between last accepted observation on epoch.
249      * @return time elapsed between last accepted observation on epoch
250      */
251     public Optional<Double> getTimeSinceLastObservation() {
252         return Optional.ofNullable(timeSinceLastObservation);
253     }
254 
255     /** Set time elapsed between last accepted observation on epoch.
256      * @param timeSinceLastObservation time elapsed between last accepted observation on epoch
257      */
258     public void setTimeSinceLastObservation(final double timeSinceLastObservation) {
259         this.timeSinceLastObservation = timeSinceLastObservation;
260     }
261 
262     /** Get time span of observation recommended for the OD of the object.
263      * @return time span of observation recommended for the OD of the object
264      */
265     public Optional<Double> getRecommendedOdSpan() {
266         return Optional.ofNullable(recommendedOdSpan);
267     }
268 
269     /** Set time span of observation recommended for the OD of the object.
270      * @param recommendedOdSpan time span of observation recommended for the OD of the object
271      */
272     public void setRecommendedOdSpan(final double recommendedOdSpan) {
273         this.recommendedOdSpan = recommendedOdSpan;
274     }
275 
276     /** Get actual time span used for the OD of the object.
277      * @return actual time span used for the OD of the object
278      */
279     public Optional<Double> getActualOdSpan() {
280         return Optional.ofNullable(actualOdSpan);
281     }
282 
283     /** Set actual time span used for the OD of the object.
284      * @param actualOdSpan actual time span used for the OD of the object
285      */
286     public void setActualOdSpan(final double actualOdSpan) {
287         this.actualOdSpan = actualOdSpan;
288     }
289 
290     /** Get number of observations available within the actual OD span.
291      * @return number of observations available within the actual OD span
292      */
293     public Optional<Integer> getObsAvailable() {
294         return Optional.ofNullable(obsAvailable);
295     }
296 
297     /** Set number of observations available within the actual OD span.
298      * @param obsAvailable number of observations available within the actual OD span
299      */
300     public void setObsAvailable(final Integer obsAvailable) {
301         this.obsAvailable = obsAvailable;
302     }
303 
304     /** Get number of observations accepted within the actual OD span.
305      * @return number of observations accepted within the actual OD span
306      */
307     public Optional<Integer> getObsUsed() {
308         return Optional.ofNullable(obsUsed);
309     }
310 
311     /** Set number of observations accepted within the actual OD span.
312      * @param obsUsed number of observations accepted within the actual OD span
313      */
314     public void setObsUsed(final Integer obsUsed) {
315         this.obsUsed = obsUsed;
316     }
317 
318     /** Get number of sensors tracks available for the OD within the actual OD span.
319      * @return number of sensors tracks available for the OD within the actual OD span
320      */
321     public Optional<Integer> getTracksAvailable() {
322         return Optional.ofNullable(tracksAvailable);
323     }
324 
325     /** Set number of sensors tracks available for the OD within the actual OD span.
326      * @param tracksAvailable number of sensors tracks available for the OD within the actual OD span
327      */
328     public void setTracksAvailable(final Integer tracksAvailable) {
329         this.tracksAvailable = tracksAvailable;
330     }
331 
332     /** Get number of sensors tracks accepted for the OD within the actual OD span.
333      * @return number of sensors tracks accepted for the OD within the actual OD span
334      */
335     public Optional<Integer> getTracksUsed() {
336         return Optional.ofNullable(tracksUsed);
337     }
338 
339     /** Set number of sensors tracks accepted for the OD within the actual OD span.
340      * @param tracksUsed number of sensors tracks accepted for the OD within the actual OD span
341      */
342     public void setTracksUsed(final Integer tracksUsed) {
343         this.tracksUsed = tracksUsed;
344     }
345 
346     /** Get maximum time between observations in the OD of the object.
347      * @return maximum time between observations in the OD of the object
348      */
349     public Optional<Double> getMaximumObsGap() {
350         return Optional.ofNullable(maximumObsGap);
351     }
352 
353     /** Set maximum time between observations in the OD of the object.
354      * @param maximumObsGap maximum time between observations in the OD of the object
355      */
356     public void setMaximumObsGap(final double maximumObsGap) {
357         this.maximumObsGap = maximumObsGap;
358     }
359 
360     /** Get positional error ellipsoid 1σ major eigenvalue at the epoch of OD.
361      * @return positional error ellipsoid 1σ major eigenvalue at the epoch of OD
362      */
363     public Optional<Double> getEpochEigenMaj() {
364         return Optional.ofNullable(epochEigenMaj);
365     }
366 
367     /** Set positional error ellipsoid 1σ major eigenvalue at the epoch of OD.
368      * @param epochEigenMaj positional error ellipsoid 1σ major eigenvalue at the epoch of OD
369      */
370     public void setEpochEigenMaj(final double epochEigenMaj) {
371         this.epochEigenMaj = epochEigenMaj;
372     }
373 
374     /** Get positional error ellipsoid 1σ intermediate eigenvalue at the epoch of OD.
375      * @return positional error ellipsoid 1σ intermediate eigenvalue at the epoch of OD
376      */
377     public Optional<Double> getEpochEigenInt() {
378         return Optional.ofNullable(epochEigenInt);
379     }
380 
381     /** Set positional error ellipsoid 1σ intermediate eigenvalue at the epoch of OD.
382      * @param epochEigenInt positional error ellipsoid 1σ intermediate eigenvalue at the epoch of OD
383      */
384     public void setEpochEigenInt(final double epochEigenInt) {
385         this.epochEigenInt = epochEigenInt;
386     }
387 
388     /** Get positional error ellipsoid 1σ minor eigenvalue at the epoch of OD.
389      * @return positional error ellipsoid 1σ minor eigenvalue at the epoch of OD
390      */
391     public Optional<Double> getEpochEigenMin() {
392         return Optional.ofNullable(epochEigenMin);
393     }
394 
395     /** Set positional error ellipsoid 1σ minor eigenvalue at the epoch of OD.
396      * @param epochEigenMin positional error ellipsoid 1σ minor eigenvalue at the epoch of OD
397      */
398     public void setEpochEigenMin(final double epochEigenMin) {
399         this.epochEigenMin = epochEigenMin;
400     }
401 
402     /** Get maximum predicted major eigenvalue of 1σ positional error ellipsoid over entire time span of the OCM.
403      * @return maximum predicted major eigenvalue of 1σ positional error ellipsoid over entire time span of the OCM
404      */
405     public Optional<Double> getMaxPredictedEigenMaj() {
406         return Optional.ofNullable(maxPredictedEigenMaj);
407     }
408 
409     /** Set maximum predicted major eigenvalue of 1σ positional error ellipsoid over entire time span of the OCM.
410      * @param maxPredictedEigenMaj maximum predicted major eigenvalue of 1σ positional error ellipsoid over entire time span of the OCM
411      */
412     public void setMaxPredictedEigenMaj(final double maxPredictedEigenMaj) {
413         this.maxPredictedEigenMaj = maxPredictedEigenMaj;
414     }
415 
416     /** Get minimum predicted minor eigenvalue of 1σ positional error ellipsoid over entire time span of the OCM.
417      * @return minimum predicted v eigenvalue of 1σ positional error ellipsoid over entire time span of the OCM
418      */
419     public Optional<Double> getMinPredictedEigenMin() {
420         return Optional.ofNullable(minPredictedEigenMin);
421     }
422 
423     /** Set minimum predicted minor eigenvalue of 1σ positional error ellipsoid over entire time span of the OCM.
424      * @param minPredictedEigenMin minimum predicted minor eigenvalue of 1σ positional error ellipsoid over entire time span of the OCM
425      */
426     public void setMinPredictedEigenMin(final double minPredictedEigenMin) {
427         this.minPredictedEigenMin = minPredictedEigenMin;
428     }
429 
430     /** Get confidence metric.
431      * @return confidence metric
432      */
433     public Optional<Double> getConfidence() {
434         return Optional.ofNullable(confidence);
435     }
436 
437     /** Set confidence metric.
438      * @param confidence confidence metric
439      */
440     public void setConfidence(final double confidence) {
441         this.confidence = confidence;
442     }
443 
444     /** Get generalize Dilution Of Precision.
445      * @return generalize Dilution Of Precision
446      */
447     public Optional<Double> getGdop() {
448         return Optional.ofNullable(gdop);
449     }
450 
451     /** Set generalize Dilution Of Precision.
452      * @param gdop generalize Dilution Of Precision
453      */
454     public void setGdop(final double gdop) {
455         this.gdop = gdop;
456     }
457 
458     /** Get number of solved-for states.
459      * @return number of solved-for states
460      */
461     public Optional<Integer> getSolveN() {
462         return Optional.ofNullable(solveN);
463     }
464 
465     /** Set number of solved-for states.
466      * @param solveN number of solved-for states
467      */
468     public void setSolveN(final Integer solveN) {
469         this.solveN = solveN;
470     }
471 
472     /** Get description of state elements solved-for.
473      * @return description of state elements solved-for
474      */
475     public List<String> getSolveStates() {
476         return solveStates;
477     }
478 
479     /** Set description of state elements solved-for.
480      * @param solveStates description of state elements solved-for
481      */
482     public void setSolveStates(final List<String> solveStates) {
483         this.solveStates = solveStates;
484     }
485 
486     /** Get number of consider parameters.
487      * @return number of consider parameters
488      */
489     public Optional<Integer> getConsiderN() {
490         return Optional.ofNullable(considerN);
491     }
492 
493     /** Set number of consider parameters.
494      * @param considerN number of consider parameters
495      */
496     public void setConsiderN(final Integer considerN) {
497         this.considerN = considerN;
498     }
499 
500     /** Get description of consider parameters.
501      * @return description of consider parameters
502      */
503     public List<String> getConsiderParameters() {
504         return considerParameters;
505     }
506 
507     /** Set description of consider parameters.
508      * @param considerParameters description of consider parameters
509      */
510     public void setConsiderParameters(final List<String> considerParameters) {
511         this.considerParameters = considerParameters;
512     }
513 
514     /** Get Specific Energy Dissipation Rate.
515      * @return Specific Energy Dissipation Rate
516      * @since 12.0
517      */
518     public Optional<Double> getSedr() {
519         return Optional.ofNullable(sedr);
520     }
521 
522     /** Set Specific Energy Dissipation Rate.
523      * @param sedr Specific Energy Dissipation Rate (W/kg)
524      * @since 12.0
525      */
526     public void setSedr(final double sedr) {
527         this.sedr = sedr;
528     }
529 
530     /** Get number of sensors used.
531      * @return number of sensors used
532      */
533     public Optional<Integer> getSensorsN() {
534         return Optional.ofNullable(sensorsN);
535     }
536 
537     /** Set number of sensors used.
538      * @param sensorsN number of sensors used
539      */
540     public void setSensorsN(final Integer sensorsN) {
541         this.sensorsN = sensorsN;
542     }
543 
544     /** Get description of sensors used.
545      * @return description of sensors used
546      */
547     public List<String> getSensors() {
548         return sensors;
549     }
550 
551     /** Set description of sensors used.
552      * @param sensors description of sensors used
553      */
554     public void setSensors(final List<String> sensors) {
555         this.sensors = sensors;
556     }
557 
558     /** Get weighted RMS residual ratio.
559      * @return weighted RMS residual ratio
560      */
561     public Optional<Double> getWeightedRms() {
562         return Optional.ofNullable(weightedRms);
563     }
564 
565     /** Set weighted RMS residual ratio.
566      * @param weightedRms weighted RMS residual ratio
567      */
568     public void setWeightedRms(final double weightedRms) {
569         this.weightedRms = weightedRms;
570     }
571 
572     /** Get observation data types used.
573      * @return observation data types used
574      */
575     public List<String> getDataTypes() {
576         return dataTypes;
577     }
578 
579     /** Set observation data types used.
580      * @param dataTypes observation data types used
581      */
582     public void setDataTypes(final List<String> dataTypes) {
583         this.dataTypes = dataTypes;
584     }
585 
586 }