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  package org.orekit.files.ccsds.ndm.cdm;
18  
19  import java.util.List;
20  
21  import org.orekit.bodies.CelestialBodyFactory;
22  import org.orekit.errors.OrekitException;
23  import org.orekit.errors.OrekitMessages;
24  import org.orekit.files.ccsds.definitions.BodyFacade;
25  import org.orekit.files.ccsds.definitions.CelestialBodyFrame;
26  import org.orekit.files.ccsds.definitions.FrameFacade;
27  import org.orekit.files.ccsds.definitions.ModifiedFrame;
28  import org.orekit.files.ccsds.definitions.TimeSystem;
29  import org.orekit.files.ccsds.definitions.YesNoUnknown;
30  import org.orekit.files.ccsds.ndm.odm.ocm.ObjectType;
31  import org.orekit.files.ccsds.section.Metadata;
32  import org.orekit.frames.Frame;
33  
34  /**
35   * This class gathers the meta-data present in the Conjunction Data Message (CDM).
36   * @author Melina Vanel
37   * @since 11.2
38   */
39  public class CdmMetadata extends Metadata {
40  
41      /** CDM relative metadata. */
42      private CdmRelativeMetadata relativeMetadata;
43  
44      /** Refering to object 1 or 2. */
45      private String object;
46  
47      /** Unique satellite identification designator for the object. */
48      private String objectDesignator;
49  
50      /** Specification of satellite catalog source. */
51      private String catalogName;
52  
53      /** Object name. */
54      private String objectName;
55  
56      /** International designator for the object as assigned by the UN Committee
57       * on Space Research (COSPAR) and the US National Space Science Data Center (NSSDC). */
58      private String internationalDesignator;
59  
60      /** Type of object. */
61      private ObjectType objectType;
62  
63      /** Operator contact position for the space object. */
64      private String operatorContact;
65  
66      /** Operator organization for the space object. */
67      private String operatorOrganization;
68  
69      /** Operator phone for the space object. */
70      private String operatorPhone;
71  
72      /** Operator email for the space object. */
73      private String operatorEmail;
74  
75      /** Unique identifier of Orbit Data Message(s) that are linked (relevant) to this Conjunction Data Message. */
76      private String odmMsgLink;
77  
78      /** Unique identifier of Attitude Data Message(s) that are linked (relevant) to this Conjunction Data Message. */
79      private String admMsgLink;
80  
81      /** Unique name of the external ephemeris file used for the object or NONE. */
82      private String ephemName;
83  
84      /** Flag indicating whether new tracking observations are anticipated prior to the issue of the next CDM associated with the event
85       * specified by CONJUNCTION_ID. */
86      private YesNoUnknown obsBeforeNextMessage;
87  
88      /** Operator email for the space object. */
89      private CovarianceMethod covarianceMethod;
90  
91      /** Maneuver capacity. */
92      private Maneuvrable maneuverable;
93  
94      /** Central body around which Object1 and 2 are orbiting. */
95      private BodyFacade orbitCenter;
96  
97      /** Reference frame in which state vector data are given. */
98      private FrameFacade refFrame;
99  
100     /** Gravity model name. */
101     private String gravityModel;
102 
103     /** Degree of the gravity model. */
104     private int gravityDegree;
105 
106     /** Order of the gravity model. */
107     private int gravityOrder;
108 
109     /** Name of atmospheric model. */
110     private String atmosphericModel;
111 
112     /** N-body perturbation bodies. */
113     private List<BodyFacade> nBodyPerturbations;
114 
115     /** Is solar radiation pressure taken into account or not ? */
116     private boolean isSolarRadPressure;
117 
118     /** Is solid Earth and ocean tides taken into account or not ? */
119     private boolean isEarthTides;
120 
121     /** Is in-track thrust modelling used or not ? */
122     private boolean isIntrackThrustModeled;
123 
124     /** The source from which the covariance data used in the report for both Object 1 and Object 2 originates. */
125     private String covarianceSource;
126 
127     /** Flag indicating the type of alternate covariance information provided. */
128     private AltCovarianceType altCovType;
129 
130     /** Reference frame in which the alternate covariance data are given. */
131     private FrameFacade altCovRefFrame;
132 
133     /** Simple constructor.
134      */
135     public CdmMetadata() {
136         super(null);
137     }
138 
139     /** {@inheritDoc} */
140     @Override
141     public void validate(final double version) {
142         // We only check values that are mandatory in a cdm file
143         checkNotNull(object,                  CdmMetadataKey.OBJECT);
144         checkNotNull(objectDesignator,        CdmMetadataKey.OBJECT_DESIGNATOR);
145         checkNotNull(catalogName,             CdmMetadataKey.CATALOG_NAME);
146         checkNotNull(objectName,              CdmMetadataKey.OBJECT_NAME);
147         checkNotNull(internationalDesignator, CdmMetadataKey.INTERNATIONAL_DESIGNATOR);
148         checkNotNull(ephemName,               CdmMetadataKey.EPHEMERIS_NAME);
149         checkNotNull(covarianceMethod,        CdmMetadataKey.COVARIANCE_METHOD);
150         checkNotNull(maneuverable,            CdmMetadataKey.MANEUVERABLE);
151         checkNotNull(refFrame,                CdmMetadataKey.REF_FRAME);
152     }
153 
154     /**
155      * Get the relative metadata following header, they are the common metadata for the CDM.
156      * @return relativeMetadata relative metadata
157      */
158     public CdmRelativeMetadata getRelativeMetadata() {
159         return relativeMetadata;
160     }
161 
162     /**
163      * Set the relative metadata following header, they are the common metadata for the CDM.
164      * @param relativeMetadata relative metadata
165      */
166     public void setRelativeMetadata(final CdmRelativeMetadata relativeMetadata) {
167         this.relativeMetadata = relativeMetadata;
168     }
169 
170     /**
171      * Get the object name for which metadata are given.
172      * @return the object name
173      */
174     public String getObject() {
175         return object;
176     }
177 
178     /**
179      * Set the object name for which metadata are given.
180      * @param object = object 1 or 2 to be set
181      */
182     public void setObject(final String object) {
183         this.setTimeSystem(TimeSystem.UTC);
184         refuseFurtherComments();
185         this.object = object;
186     }
187 
188     /**
189      * Get the object satellite catalog designator for which metadata are given.
190      * @return the satellite catalog designator for the object
191      */
192     public String getObjectDesignator() {
193         return objectDesignator;
194     }
195 
196     /**
197      * Set the satellite designator for the object for which metadata are given.
198      * @param objectDesignator for the spacecraft to be set
199      */
200     public void setObjectDesignator(final String objectDesignator) {
201         refuseFurtherComments();
202         this.objectDesignator = objectDesignator;
203     }
204 
205     /**
206      * Get the satellite catalog used for the object.
207      * @return the catalog name
208      */
209     public String getCatalogName() {
210         return catalogName;
211     }
212 
213     /**
214      * Set the satellite catalog name used for object.
215      * @param catalogName for the spacecraft to be set
216      */
217     public void setCatalogName(final String catalogName) {
218         refuseFurtherComments();
219         this.catalogName = catalogName;
220     }
221 
222     /**
223      * Get the spacecraft name for the object.
224      * @return the spacecraft name
225      */
226     public String getObjectName() {
227         return objectName;
228     }
229 
230     /**
231      * Set the spacecraft name used for object.
232      * @param objectName for the spacecraft to be set
233      */
234     public void setObjectName(final String objectName) {
235         refuseFurtherComments();
236         this.objectName = objectName;
237     }
238 
239     /**
240      * Get the international designator for the object.
241      * @return the international designator
242      */
243     public String getInternationalDes() {
244         return internationalDesignator;
245     }
246 
247     /**
248      * Set the international designator used for object.
249      * @param internationalDes for the object to be set
250      */
251     public void setInternationalDes(final String internationalDes) {
252         refuseFurtherComments();
253         this.internationalDesignator = internationalDes;
254     }
255 
256     /**
257      * Get the type of object.
258      * @return the object type
259      */
260     public ObjectType getObjectType() {
261         return objectType;
262     }
263 
264     /**
265      * Set the type of object.
266      * @param objectType type of object
267      */
268     public void setObjectType(final ObjectType objectType) {
269         refuseFurtherComments();
270         this.objectType = objectType;
271     }
272 
273     /**
274      * Get the contact position of the owner / operator of the object.
275      * @return the contact position
276      */
277     public String getOperatorContactPosition() {
278         return operatorContact;
279     }
280 
281     /**
282      * Set the contact position for the object owner / operator.
283      * @param opContact for the object to be set
284      */
285     public void setOperatorContactPosition(final String opContact) {
286         refuseFurtherComments();
287         this.operatorContact = opContact;
288     }
289 
290     /**
291      * Get the contact organisation of the object.
292      * @return the contact organisation
293      */
294     public String getOperatorOrganization() {
295         return operatorOrganization;
296     }
297 
298     /**
299      * Set the contact organisation of the object.
300      * @param operatorOrganization contact organisation for the object to be set
301      */
302     public void setOperatorOrganization(final String operatorOrganization) {
303         refuseFurtherComments();
304         this.operatorOrganization = operatorOrganization;
305     }
306 
307     /**
308      * Get the contact phone of the operator of the object.
309      * @return the operator phone
310      */
311     public String getOperatorPhone() {
312         return operatorPhone;
313     }
314 
315     /**
316      * Set the operator phone of the object.
317      * @param operatorPhone contact phone for the object to be set
318      */
319     public void setOperatorPhone(final String operatorPhone) {
320         refuseFurtherComments();
321         this.operatorPhone = operatorPhone;
322     }
323 
324     /**
325      * Get the email of the operator of the object.
326      * @return the operator email
327      */
328     public String getOperatorEmail() {
329         return operatorEmail;
330     }
331 
332     /**
333      * Set the object operator email.
334      * @param operatorEmail operator email for the object to be set
335      */
336     public void setOperatorEmail(final String operatorEmail) {
337         refuseFurtherComments();
338         this.operatorEmail = operatorEmail;
339     }
340 
341     /**
342      * Get the unique name of the external ephemeris used for OD.
343      * @return the name of ephemeris used
344      */
345     public String getEphemName() {
346         return ephemName;
347     }
348 
349     /**
350      * Set the name of external ephemeris used for OD.
351      * @param ephemName me of external ephemeris used
352      */
353     public void setEphemName(final String ephemName) {
354         refuseFurtherComments();
355         this.ephemName = ephemName;
356     }
357 
358     /**
359      * Get the method name used to calculate covariance during OD.
360      * @return the name of covariance calculation method
361      */
362     public CovarianceMethod getCovarianceMethod() {
363         return covarianceMethod;
364     }
365 
366     /**
367      * Set the method name used to calculate covariance during OD.
368      * @param covarianceMethod method name for covariance calculation
369      */
370     public void setCovarianceMethod(final CovarianceMethod covarianceMethod) {
371         refuseFurtherComments();
372         this.covarianceMethod = covarianceMethod;
373     }
374 
375     /**
376      * Get the ability of object to maneuver or not.
377      * @return the ability to maneuver
378      */
379     public Maneuvrable getManeuverable() {
380         return maneuverable;
381     }
382 
383     /**
384      * Set the object maneuver ability.
385      * @param maneuverable ability to maneuver
386      */
387     public void setManeuverable(final Maneuvrable maneuverable) {
388         refuseFurtherComments();
389         this.maneuverable = maneuverable;
390     }
391 
392     /**
393      * Get the central body for object 1 and 2.
394      * @return the name of the central body
395      */
396     public BodyFacade getOrbitCenter() {
397         return orbitCenter;
398     }
399 
400     /**
401      * Set the central body name for object 1 and 2.
402      * @param orbitCenter name of the central body
403      */
404     public void setOrbitCenter(final BodyFacade orbitCenter) {
405         refuseFurtherComments();
406         this.orbitCenter = orbitCenter;
407     }
408 
409     /**
410      * Get the reference frame in which data are given: used for state vector and
411      * Keplerian elements data (and for the covariance reference frame if none is given).
412      *
413      * @return the reference frame
414      */
415     public Frame getFrame() {
416         if (orbitCenter == null || orbitCenter.getBody() == null) {
417             throw new OrekitException(OrekitMessages.NO_DATA_LOADED_FOR_CELESTIAL_BODY, "No Orbit center name");
418         }
419         if (refFrame.asFrame() == null) {
420             throw new OrekitException(OrekitMessages.CCSDS_INVALID_FRAME, refFrame.getName());
421         }
422         // Just return frame if we don't need to shift the center based on CENTER_NAME
423         // MCI and ICRF are the only non-Earth centered frames specified in Annex A.
424         final boolean isMci  = refFrame.asCelestialBodyFrame() == CelestialBodyFrame.MCI;
425         final boolean isIcrf = refFrame.asCelestialBodyFrame() == CelestialBodyFrame.ICRF;
426         final boolean isSolarSystemBarycenter =
427                 CelestialBodyFactory.SOLAR_SYSTEM_BARYCENTER.equals(orbitCenter.getBody().getName());
428         if (!(isMci || isIcrf) && CelestialBodyFactory.EARTH.equals(orbitCenter.getBody().getName()) ||
429             isMci && CelestialBodyFactory.MARS.equals(orbitCenter.getBody().getName()) ||
430             isIcrf && isSolarSystemBarycenter) {
431             return refFrame.asFrame();
432         }
433         // else, translate frame to specified center.
434         return new ModifiedFrame(refFrame.asFrame(), refFrame.asCelestialBodyFrame(),
435                                  orbitCenter.getBody(), orbitCenter.getName());
436     }
437 
438     /**
439      * Get the value of {@code REF_FRAME} as an Orekit {@link Frame}. The {@code
440      * ORBIT_CENTER} key word has not been applied yet, so the returned frame may not
441      * correspond to the reference frame of the data in the file.
442      * @return the reference frame
443      */
444     public FrameFacade getRefFrame() {
445         return refFrame;
446     }
447 
448     /**
449      * Set the name of the reference frame in which the state vector data are given.
450      * @param refFrame reference frame
451      */
452     public void setRefFrame(final FrameFacade refFrame) {
453         refuseFurtherComments();
454         this.refFrame = refFrame;
455     }
456 
457     /** Get gravity model name.
458      * @return gravity model name
459      */
460     public String getGravityModel() {
461         return gravityModel;
462     }
463 
464     /** Get degree of the gravity model.
465      * @return degree of the gravity model
466      */
467     public int getGravityDegree() {
468         return gravityDegree;
469     }
470 
471     /** Get order of the gravity model.
472      * @return order of the gravity model
473      */
474     public int getGravityOrder() {
475         return gravityOrder;
476     }
477 
478     /** Set gravity model.
479      * @param name name of the model
480      * @param degree degree of the model
481      * @param order order of the model
482      */
483     public void setGravityModel(final String name, final int degree, final int order) {
484         refuseFurtherComments();
485         this.gravityModel  = name;
486         this.gravityDegree = degree;
487         this.gravityOrder  = order;
488     }
489 
490     /** Get name of atmospheric model.
491      * @return name of atmospheric model
492      */
493     public String getAtmosphericModel() {
494         return atmosphericModel;
495     }
496 
497     /** Set name of atmospheric model.
498      * @param atmosphericModel name of atmospheric model
499      */
500     public void setAtmosphericModel(final String atmosphericModel) {
501         refuseFurtherComments();
502         this.atmosphericModel = atmosphericModel;
503     }
504 
505     /** Get n-body perturbation bodies.
506      * @return n-body perturbation bodies
507      */
508     public List<BodyFacade> getNBodyPerturbations() {
509         return nBodyPerturbations;
510     }
511 
512     /** Set n-body perturbation bodies.
513      * @param nBody n-body perturbation bodies
514      */
515     public void setNBodyPerturbations(final List<BodyFacade> nBody) {
516         refuseFurtherComments();
517         this.nBodyPerturbations = nBody;
518     }
519 
520     /**
521      * Get boolean that indicates if Solar Radiation Pressure is taken into account or not.
522      * @return isSolarRadPressure boolean
523      */
524     public boolean getSolarRadiationPressure() {
525         return isSolarRadPressure;
526     }
527 
528     /**
529      * Set boolean that indicates if Solar Radiation Pressure is taken into account or not.
530      * @param isSolRadPressure boolean
531      */
532     public void setSolarRadiationPressure(final boolean isSolRadPressure) {
533         refuseFurtherComments();
534         this.isSolarRadPressure = isSolRadPressure;
535     }
536 
537     /**
538      * Get boolean that indicates if Earth and ocean tides are taken into account or not.
539      * @return isEarthTides boolean
540      */
541     public boolean getEarthTides() {
542         return isEarthTides;
543     }
544 
545     /**
546      * Set boolean that indicates if Earth and ocean tides are taken into account or not.
547      * @param EarthTides boolean
548      */
549     public void setEarthTides(final boolean EarthTides) {
550         refuseFurtherComments();
551         this.isEarthTides = EarthTides;
552     }
553 
554     /**
555      * Get boolean that indicates if intrack thrust modeling was into account or not.
556      * @return isEarthTides boolean
557      */
558     public boolean getIntrackThrust() {
559         return isIntrackThrustModeled;
560     }
561 
562     /**
563      * Set boolean that indicates if intrack thrust modeling was into account or not.
564      * @param IntrackThrustModeled boolean
565      */
566     public void setIntrackThrust(final boolean IntrackThrustModeled) {
567         refuseFurtherComments();
568         this.isIntrackThrustModeled = IntrackThrustModeled;
569     }
570 
571     /** Get the source of the covariance data.
572      * @return the covarianceSource
573      */
574     public String getCovarianceSource() {
575         return covarianceSource;
576     }
577 
578     /** Set the source of the covariance data.
579      * @param covarianceSource the covarianceSource to set
580      */
581     public void setCovarianceSource(final String covarianceSource) {
582         refuseFurtherComments();
583         this.covarianceSource = covarianceSource;
584     }
585 
586     /** Get the flag indicating the type of alternate covariance information provided.
587      * @return the altCovType
588      */
589     public AltCovarianceType getAltCovType() {
590         return altCovType;
591     }
592 
593     /** Set the flag indicating the type of alternate covariance information provided.
594      * @param altCovType the altCovType to set
595      */
596     public void setAltCovType(final AltCovarianceType altCovType) {
597         refuseFurtherComments();
598         this.altCovType = altCovType;
599     }
600 
601      /**
602      * Get the value of {@code ALT_COV_REF_FRAME} as an Orekit {@link Frame}.
603      * @return the reference frame
604      */
605     public FrameFacade getAltCovRefFrame() {
606         return altCovRefFrame;
607     }
608 
609     /**
610      * Set the name of the reference frame in which the alternate covariance data are given.
611      * @param altCovRefFrame alternate covariance reference frame
612      */
613     public void setAltCovRefFrame(final FrameFacade altCovRefFrame) {
614         refuseFurtherComments();
615 
616         if (getAltCovType() == null) {
617             throw new OrekitException(OrekitMessages.CCSDS_MISSING_KEYWORD, CdmMetadataKey.ALT_COV_TYPE);
618         }
619 
620         if (altCovRefFrame.asFrame() == null) {
621             throw new OrekitException(OrekitMessages.CCSDS_INVALID_FRAME, altCovRefFrame.getName());
622         }
623 
624         // Only set the frame if within the allowed options: GCRF, EME2000, ITRF
625         if ( altCovRefFrame.asCelestialBodyFrame() == CelestialBodyFrame.GCRF ||
626                  altCovRefFrame.asCelestialBodyFrame() == CelestialBodyFrame.EME2000 ||
627                      altCovRefFrame.asCelestialBodyFrame().name().contains("ITRF") ) {
628             this.altCovRefFrame = altCovRefFrame;
629         } else {
630             throw new OrekitException(OrekitMessages.CCSDS_INVALID_FRAME, altCovRefFrame.getName());
631         }
632     }
633 
634     /** Get the unique identifier of Orbit Data Message(s) that are linked (relevant) to this Conjunction Data Message.
635      * @return the odmMsgLink
636      */
637     public String getOdmMsgLink() {
638         return odmMsgLink;
639     }
640 
641     /** Set the unique identifier of Orbit Data Message(s) that are linked (relevant) to this Conjunction Data Message.
642      * @param odmMsgLink the odmMsgLink to set
643      */
644     public void setOdmMsgLink(final String odmMsgLink) {
645         refuseFurtherComments();
646         this.odmMsgLink = odmMsgLink;
647     }
648 
649     /** Get the unique identifier of Attitude Data Message(s) that are linked (relevant) to this Conjunction Data Message.
650      * @return the admMsgLink
651      */
652     public String getAdmMsgLink() {
653         return admMsgLink;
654     }
655 
656     /** Set the unique identifier of Attitude Data Message(s) that are linked (relevant) to this Conjunction Data Message.
657      * @param admMsgLink the admMsgLink to set
658      */
659     public void setAdmMsgLink(final String admMsgLink) {
660         refuseFurtherComments();
661         this.admMsgLink = admMsgLink;
662     }
663 
664     /** Get the flag indicating whether new tracking observations are anticipated prior to the issue of the next CDM associated with the event
665      * specified by CONJUNCTION_ID.
666      * @return the obsBeforeNextMessage
667      */
668     public YesNoUnknown getObsBeforeNextMessage() {
669         return obsBeforeNextMessage;
670     }
671 
672     /** Set the flag indicating whether new tracking observations are anticipated prior to the issue of the next CDM associated with the event
673      * specified by CONJUNCTION_ID.
674      * @param obsBeforeNextMessage the obsBeforeNextMessage to set
675      */
676     public void setObsBeforeNextMessage(final YesNoUnknown obsBeforeNextMessage) {
677         refuseFurtherComments();
678         this.obsBeforeNextMessage = obsBeforeNextMessage;
679     }
680 }