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.ocm;
19  
20  import java.util.List;
21  
22  import org.orekit.data.DataContext;
23  import org.orekit.files.ccsds.definitions.TimeSystem;
24  import org.orekit.files.ccsds.ndm.odm.OdmMetadata;
25  import org.orekit.files.ccsds.section.MetadataKey;
26  import org.orekit.time.AbsoluteDate;
27  
28  /** Meta-data for {@link OcmMetadata Orbit Comprehensive Message}.
29   * @since 11.0
30   */
31  public class OcmMetadata extends OdmMetadata {
32  
33      /** Default value for SCLK_OFFSET_AT_EPOCH.
34       * @since 12.0
35       */
36      public static final double DEFAULT_SCLK_OFFSET_AT_EPOCH = 0.0;
37  
38      /** Default value for SCLK_SEC_PER_SI_SEC.
39       * @since 12.0
40       */
41      public static final double DEFAULT_SCLK_SEC_PER_SI_SEC = 1.0;
42  
43      /** International designator for the object as assigned by the UN Committee
44       * on Space Research (COSPAR) and the US National Space Science Data Center (NSSDC). */
45      private String internationalDesignator;
46  
47      /** Specification of satellite catalog source. */
48      private String catalogName;
49  
50      /** Unique satellite identification designator for the object. */
51      private String objectDesignator;
52  
53      /** Alternate names for this space object. */
54      private List<String> alternateNames;
55  
56      /** Programmatic Point Of Contact at originator. */
57      private String originatorPOC;
58  
59      /** Position of Programmatic Point Of Contact at originator. */
60      private String originatorPosition;
61  
62      /** Phone number of Programmatic Point Of Contact at originator. */
63      private String originatorPhone;
64  
65      /** Email address of Programmatic Point Of Contact at originator.
66       * @since 11.2
67       */
68      private String originatorEmail;
69  
70      /** Address of Programmatic Point Of Contact at originator. */
71      private String originatorAddress;
72  
73      /** Creating agency or operator. */
74      private String techOrg;
75  
76      /** Technical Point Of Contact at originator. */
77      private String techPOC;
78  
79      /** Position of Technical Point Of Contact at originator. */
80      private String techPosition;
81  
82      /** Phone number of Technical Point Of Contact at originator. */
83      private String techPhone;
84  
85      /** Email address of Technical Point Of Contact at originator.
86       * @since 11.2
87       */
88      private String techEmail;
89  
90      /** Address of Technical Point Of Contact at originator. */
91      private String techAddress;
92  
93      /** Unique ID identifying previous message from a given originator. */
94      private String previousMessageID;
95  
96      /** Unique ID identifying next message from a given originator. */
97      private String nextMessageID;
98  
99      /** Unique identifier of Attitude Data Message linked to this Orbit Data Message. */
100     private String admMessageLink;
101 
102     /** Unique identifier of Conjunction Data Message linked to this Orbit Data Message. */
103     private String cdmMessageLink;
104 
105     /** Unique identifier of Pointing Request Message linked to this Orbit Data Message. */
106     private String prmMessageLink;
107 
108     /** Unique identifier of Reentry Data Messages linked to this Orbit Data Message. */
109     private String rdmMessageLink;
110 
111     /** Unique identifier of Tracking Data Messages linked to this Orbit Data Message. */
112     private String tdmMessageLink;
113 
114     /** Operator of the space object. */
115     private String operator;
116 
117     /** Owner of the space object. */
118     private String owner;
119 
120     /** Name of the country where the space object owner is based. */
121     private String country;
122 
123     /** Name of the constellation this space object belongs to. */
124     private String constellation;
125 
126     /** Type of object. */
127     private ObjectType objectType;
128 
129     /** Epoch to which <em>all</em> relative times are referenced in data blocks;
130      * unless overridden by block-specific {@code EPOCH_TZERO} values. */
131     private AbsoluteDate epochT0;
132 
133     /** Operational status. */
134     private OpsStatus opsStatus;
135 
136     /** Orbit category. */
137     private OrbitCategory orbitCategory;
138 
139     /** List of elements of information data blocks included in this message. */
140     private List<OcmElements> ocmDataElements;
141 
142     /** Spacecraft clock count at {@link #getEpochT0()}. */
143     private double sclkOffsetAtEpoch;
144 
145     /** Number of spacecraft clock seconds occurring during one SI second. */
146     private double sclkSecPerSISec;
147 
148     /** Creation date of previous message from a given originator. */
149     private AbsoluteDate previousMessageEpoch;
150 
151     /** Creation date of next message from a given originator. */
152     private AbsoluteDate nextMessageEpoch;
153 
154     /** Time of the earliest data contained in the OCM. */
155     private AbsoluteDate startTime;
156 
157     /** Time of the latest data contained in the OCM. */
158     private AbsoluteDate stopTime;
159 
160     /** Span of time that the OCM covers. */
161     private double timeSpan;
162 
163     /** Difference (TAI – UTC) in seconds at epoch {@link #epochT0}. */
164     private double taimutcT0;
165 
166     /** Epoch of next leap second.
167      * @since 11.2
168      */
169     private AbsoluteDate nextLeapEpoch;
170 
171     /** Difference (TAI – UTC) in seconds incorporated at {@link #nextLeapEpoch}.
172      * @since 11.2
173      */
174     private double nextLeapTaimutc;
175 
176     /** Difference (UT1 – UTC) in seconds at epoch {@link #epochT0}. */
177     private double ut1mutcT0;
178 
179     /** Source and version of Earth Orientation Parameters. */
180     private String eopSource;
181 
182     /** Interpolation method for Earth Orientation Parameters. */
183     private String interpMethodEOP;
184 
185     /** Source and version of celestial body (e.g. Sun/Earth/Planetary). */
186     private String celestialSource;
187 
188     /** Data context.
189      * @since 12.0
190      */
191     private final DataContext dataContext;
192 
193     /** Create a new meta-data.
194      * @param dataContext data context
195      */
196     public OcmMetadata(final DataContext dataContext) {
197 
198         // set up the few fields that have default values as per CCSDS standard
199         super(TimeSystem.UTC);
200         sclkOffsetAtEpoch = DEFAULT_SCLK_OFFSET_AT_EPOCH;
201         sclkSecPerSISec   = DEFAULT_SCLK_SEC_PER_SI_SEC;
202         timeSpan          = Double.NaN;
203         taimutcT0         = Double.NaN;
204         ut1mutcT0         = Double.NaN;
205         nextLeapTaimutc   = Double.NaN;
206         this.dataContext  = dataContext;
207 
208     }
209 
210     /** {@inheritDoc} */
211     @Override
212     public void validate(final double version) {
213         // we don't call super.checkMandatoryEntries() because
214         // all of the parameters considered mandatory at ODM level
215         // for OPM, OMM and OEM are in fact optional in OCM
216         // only TIME_SYSTEM and EPOCH_TZERO are mandatory
217         checkNotNull(getTimeSystem(), MetadataKey.TIME_SYSTEM.name());
218         checkNotNull(epochT0,         OcmMetadataKey.EPOCH_TZERO.name());
219         if (nextLeapEpoch != null) {
220             checkNotNaN(nextLeapTaimutc, OcmMetadataKey.NEXT_LEAP_TAIMUTC.name());
221         }
222     }
223 
224     /** Get the international designator for the object.
225      * @return international designator for the object
226      */
227     public String getInternationalDesignator() {
228         return internationalDesignator;
229     }
230 
231     /** Set the international designator for the object.
232      * @param internationalDesignator international designator for the object
233      */
234     public void setInternationalDesignator(final String internationalDesignator) {
235         refuseFurtherComments();
236         this.internationalDesignator = internationalDesignator;
237     }
238 
239     /** Get the specification of satellite catalog source.
240      * @return specification of satellite catalog source
241      */
242     public String getCatalogName() {
243         return catalogName;
244     }
245 
246     /** Set the specification of satellite catalog source.
247      * @param catalogName specification of satellite catalog source
248      */
249     public void setCatalogName(final String catalogName) {
250         refuseFurtherComments();
251         this.catalogName = catalogName;
252     }
253 
254     /** Get the unique satellite identification designator for the object.
255      * @return unique satellite identification designator for the object.
256      */
257     public String getObjectDesignator() {
258         return objectDesignator;
259     }
260 
261     /** Set the unique satellite identification designator for the object.
262      * @param objectDesignator unique satellite identification designator for the object
263      */
264     public void setObjectDesignator(final String objectDesignator) {
265         refuseFurtherComments();
266         this.objectDesignator = objectDesignator;
267     }
268 
269     /** Get the alternate names for this space object.
270      * @return alternate names
271      */
272     public List<String> getAlternateNames() {
273         return alternateNames;
274     }
275 
276     /** Set the alternate names for this space object.
277      * @param alternateNames alternate names
278      */
279     public void setAlternateNames(final List<String> alternateNames) {
280         refuseFurtherComments();
281         this.alternateNames = alternateNames;
282     }
283 
284     /** Get the programmatic Point Of Contact at originator.
285      * @return programmatic Point Of Contact at originator
286      */
287     public String getOriginatorPOC() {
288         return originatorPOC;
289     }
290 
291     /** Set the programmatic Point Of Contact at originator.
292      * @param originatorPOC programmatic Point Of Contact at originator
293      */
294     public void setOriginatorPOC(final String originatorPOC) {
295         refuseFurtherComments();
296         this.originatorPOC = originatorPOC;
297     }
298 
299     /** Get the position of Programmatic Point Of Contact at originator.
300      * @return position of Programmatic Point Of Contact at originator
301      */
302     public String getOriginatorPosition() {
303         return originatorPosition;
304     }
305 
306     /** Set the position of Programmatic Point Of Contact at originator.
307      * @param originatorPosition position of Programmatic Point Of Contact at originator
308      */
309     public void setOriginatorPosition(final String originatorPosition) {
310         refuseFurtherComments();
311         this.originatorPosition = originatorPosition;
312     }
313 
314     /** Get the phone number of Programmatic Point Of Contact at originator.
315      * @return phone number of Programmatic Point Of Contact at originator
316      */
317     public String getOriginatorPhone() {
318         return originatorPhone;
319     }
320 
321     /** Set the phone number of Programmatic Point Of Contact at originator.
322      * @param originatorPhone phone number of Programmatic Point Of Contact at originator
323      */
324     public void setOriginatorPhone(final String originatorPhone) {
325         refuseFurtherComments();
326         this.originatorPhone = originatorPhone;
327     }
328 
329     /** Get the email address of Programmatic Point Of Contact at originator.
330      * @return email address of Programmatic Point Of Contact at originator
331      * @since 11.2
332      */
333     public String getOriginatorEmail() {
334         return originatorEmail;
335     }
336 
337     /** Set the email address of Programmatic Point Of Contact at originator.
338      * @param originatorEmail email address of Programmatic Point Of Contact at originator
339      * @since 11.2
340      */
341     public void setOriginatorEmail(final String originatorEmail) {
342         refuseFurtherComments();
343         this.originatorEmail = originatorEmail;
344     }
345 
346     /** Get the address of Programmatic Point Of Contact at originator.
347      * @return address of Programmatic Point Of Contact at originator
348      */
349     public String getOriginatorAddress() {
350         return originatorAddress;
351     }
352 
353     /** Set the address of Programmatic Point Of Contact at originator.
354      * @param originatorAddress address of Programmatic Point Of Contact at originator
355      */
356     public void setOriginatorAddress(final String originatorAddress) {
357         refuseFurtherComments();
358         this.originatorAddress = originatorAddress;
359     }
360 
361     /** Get the creating agency or operator.
362      * @return creating agency or operator
363      */
364     public String getTechOrg() {
365         return techOrg;
366     }
367 
368     /** Set the creating agency or operator.
369      * @param techOrg creating agency or operator
370      */
371     public void setTechOrg(final String techOrg) {
372         refuseFurtherComments();
373         this.techOrg = techOrg;
374     }
375 
376     /** Get the Technical Point Of Contact at originator.
377      * @return Technical Point Of Contact at originator
378      */
379     public String getTechPOC() {
380         return techPOC;
381     }
382 
383     /** Set the Technical Point Of Contact at originator.
384      * @param techPOC Technical Point Of Contact at originator
385      */
386     public void setTechPOC(final String techPOC) {
387         refuseFurtherComments();
388         this.techPOC = techPOC;
389     }
390 
391     /** Get the position of Technical Point Of Contact at originator.
392      * @return position of Technical Point Of Contact at originator
393      */
394     public String getTechPosition() {
395         return techPosition;
396     }
397 
398     /** Set the position of Technical Point Of Contact at originator.
399      * @param techPosition position of Technical Point Of Contact at originator
400      */
401     public void setTechPosition(final String techPosition) {
402         refuseFurtherComments();
403         this.techPosition = techPosition;
404     }
405 
406     /** Get the phone number of Technical Point Of Contact at originator.
407      * @return phone number of Technical Point Of Contact at originator
408      */
409     public String getTechPhone() {
410         return techPhone;
411     }
412 
413     /** Set the phone number of Technical Point Of Contact at originator.
414      * @param techPhone phone number of Technical Point Of Contact at originator
415      */
416     public void setTechPhone(final String techPhone) {
417         refuseFurtherComments();
418         this.techPhone = techPhone;
419     }
420 
421     /** Get the email address of Technical Point Of Contact at originator.
422      * @return email address of Technical Point Of Contact at originator
423      * @since 11.2
424      */
425     public String getTechEmail() {
426         return techEmail;
427     }
428 
429     /** Set the email address of Technical Point Of Contact at originator.
430      * @param techEmail email address of Technical Point Of Contact at originator
431      * @since 11.2
432      */
433     public void setTechEmail(final String techEmail) {
434         refuseFurtherComments();
435         this.techEmail = techEmail;
436     }
437 
438     /** Get the address of Technical Point Of Contact at originator.
439      * @return address of Technical Point Of Contact at originator
440      */
441     public String getTechAddress() {
442         return techAddress;
443     }
444 
445     /** Set the address of Technical Point Of Contact at originator.
446      * @param techAddress address of Technical Point Of Contact at originator
447      */
448     public void setTechAddress(final String techAddress) {
449         refuseFurtherComments();
450         this.techAddress = techAddress;
451     }
452 
453     /** Get the unique ID identifying previous message from a given originator.
454      * @return unique ID identifying previous message from a given originator
455      */
456     public String getPreviousMessageID() {
457         return previousMessageID;
458     }
459 
460     /** Set the unique ID identifying previous message from a given originator.
461      * @param previousMessageID unique ID identifying previous message from a given originator
462      */
463     public void setPreviousMessageID(final String previousMessageID) {
464         refuseFurtherComments();
465         this.previousMessageID = previousMessageID;
466     }
467 
468     /** Get the unique ID identifying next message from a given originator.
469      * @return unique ID identifying next message from a given originator
470      */
471     public String getNextMessageID() {
472         return nextMessageID;
473     }
474 
475     /** Set the unique ID identifying next message from a given originator.
476      * @param nextMessageID unique ID identifying next message from a given originator
477      */
478     public void setNextMessageID(final String nextMessageID) {
479         refuseFurtherComments();
480         this.nextMessageID = nextMessageID;
481     }
482 
483     /** Get the Unique identifier of Attitude Data Message linked to this Orbit Data Message.
484      * @return Unique identifier of Attitude Data Message linked to this Orbit Data Message
485      */
486     public String getAdmMessageLink() {
487         return admMessageLink;
488     }
489 
490     /** Set the Unique identifier of Attitude Data Message linked to this Orbit Data Message.
491      * @param admMessageLink Unique identifier of Attitude Data Message linked to this Orbit Data Message
492      */
493     public void setAdmMessageLink(final String admMessageLink) {
494         refuseFurtherComments();
495         this.admMessageLink = admMessageLink;
496     }
497 
498     /** Get the Unique identifier of Conjunction Data Message linked to this Orbit Data Message.
499      * @return Unique identifier of Conjunction Data Message linked to this Orbit Data Message
500      */
501     public String getCdmMessageLink() {
502         return cdmMessageLink;
503     }
504 
505     /** Set the Unique identifier of Conjunction Data Message linked to this Orbit Data Message.
506      * @param cdmMessageLink Unique identifier of Conjunction Data Message linked to this Orbit Data Message
507      */
508     public void setCdmMessageLink(final String cdmMessageLink) {
509         refuseFurtherComments();
510         this.cdmMessageLink = cdmMessageLink;
511     }
512 
513     /** Get the Unique identifier of Pointing Request Message linked to this Orbit Data Message.
514      * @return Unique identifier of Pointing Request Message linked to this Orbit Data Message
515      */
516     public String getPrmMessageLink() {
517         return prmMessageLink;
518     }
519 
520     /** Set the Unique identifier of Pointing Request Message linked to this Orbit Data Message.
521      * @param prmMessageLink Unique identifier of Pointing Request Message linked to this Orbit Data Message
522      */
523     public void setPrmMessageLink(final String prmMessageLink) {
524         refuseFurtherComments();
525         this.prmMessageLink = prmMessageLink;
526     }
527 
528     /** Get the Unique identifier of Reentry Data Message linked to this Orbit Data Message.
529      * @return Unique identifier of Reentry Data Message linked to this Orbit Data Message
530      */
531     public String getRdmMessageLink() {
532         return rdmMessageLink;
533     }
534 
535     /** Set the Unique identifier of Reentry Data Message linked to this Orbit Data Message.
536      * @param rdmMessageLink Unique identifier of Reentry Data Message linked to this Orbit Data Message
537      */
538     public void setRdmMessageLink(final String rdmMessageLink) {
539         refuseFurtherComments();
540         this.rdmMessageLink = rdmMessageLink;
541     }
542 
543     /** Get the Unique identifier of Tracking Data Message linked to this Orbit Data Message.
544      * @return Unique identifier of Tracking Data Message linked to this Orbit Data Message
545      */
546     public String getTdmMessageLink() {
547         return tdmMessageLink;
548     }
549 
550     /** Set the Unique identifier of Tracking Data Message linked to this Orbit Data Message.
551      * @param tdmMessageLink Unique identifier of Tracking Data Message linked to this Orbit Data Message
552      */
553     public void setTdmMessageLink(final String tdmMessageLink) {
554         refuseFurtherComments();
555         this.tdmMessageLink = tdmMessageLink;
556     }
557 
558     /** Get the operator of the space object.
559      * @return operator of the space object
560      */
561     public String getOperator() {
562         return operator;
563     }
564 
565     /** Set the operator of the space object.
566      * @param operator operator of the space object
567      */
568     public void setOperator(final String operator) {
569         refuseFurtherComments();
570         this.operator = operator;
571     }
572 
573     /** Get the owner of the space object.
574      * @return owner of the space object
575      */
576     public String getOwner() {
577         return owner;
578     }
579 
580     /** Set the owner of the space object.
581      * @param owner owner of the space object
582      */
583     public void setOwner(final String owner) {
584         refuseFurtherComments();
585         this.owner = owner;
586     }
587 
588     /** Get the name of the country where the space object owner is based.
589      * @return name of the country where the space object owner is based
590      */
591     public String getCountry() {
592         return country;
593     }
594 
595     /** Set the name of the country where the space object owner is based.
596      * @param country name of the country where the space object owner is based
597      */
598     public void setCountry(final String country) {
599         refuseFurtherComments();
600         this.country = country;
601     }
602 
603     /** Get the name of the constellation this space object belongs to.
604      * @return name of the constellation this space object belongs to
605      */
606     public String getConstellation() {
607         return constellation;
608     }
609 
610     /** Set the name of the constellation this space object belongs to.
611      * @param constellation name of the constellation this space object belongs to
612      */
613     public void setConstellation(final String constellation) {
614         refuseFurtherComments();
615         this.constellation = constellation;
616     }
617 
618     /** Get the type of object.
619      * @return type of object
620      */
621     public ObjectType getObjectType() {
622         return objectType;
623     }
624 
625     /** Set the type of object.
626      * @param objectType type of object
627      */
628     public void setObjectType(final ObjectType objectType) {
629         refuseFurtherComments();
630         this.objectType = objectType;
631     }
632 
633     /** Get the epoch to which <em>all</em> relative times are referenced in data blocks.
634      * @return epoch to which <em>all</em> relative times are referenced in data blocks
635      */
636     public AbsoluteDate getEpochT0() {
637         return epochT0;
638     }
639 
640     /** Set the epoch to which <em>all</em> relative times are referenced in data blocks.
641      * @param epochT0 epoch to which <em>all</em> relative times are referenced in data blocks
642      */
643     public void setEpochT0(final AbsoluteDate epochT0) {
644         refuseFurtherComments();
645         this.epochT0 = epochT0;
646     }
647 
648     /** Get the operational status.
649      * @return operational status
650      */
651     public OpsStatus getOpsStatus() {
652         return opsStatus;
653     }
654 
655     /** Set the operational status.
656      * @param opsStatus operational status
657      */
658     public void setOpsStatus(final OpsStatus opsStatus) {
659         refuseFurtherComments();
660         this.opsStatus = opsStatus;
661     }
662 
663     /** Get the orbit category.
664      * @return orbit category
665      */
666     public OrbitCategory getOrbitCategory() {
667         return orbitCategory;
668     }
669 
670     /** Set the orbit category.
671      * @param orbitCategory orbit category
672      */
673     public void setOrbitCategory(final OrbitCategory orbitCategory) {
674         refuseFurtherComments();
675         this.orbitCategory = orbitCategory;
676     }
677 
678     /** Get the list of elements of information data blocks included in this message.
679      * @return list of elements of information data blocks included in this message
680      */
681     public List<OcmElements> getOcmDataElements() {
682         return ocmDataElements;
683     }
684 
685     /** Set the list of elements of information data blocks included in this message.
686      * @param ocmDataElements list of elements of information data blocks included in this message
687      */
688     public void setOcmDataElements(final List<OcmElements> ocmDataElements) {
689         refuseFurtherComments();
690         this.ocmDataElements = ocmDataElements;
691     }
692 
693     /** Get the spacecraft clock count at {@link #getEpochT0()}.
694      * @return spacecraft clock count at {@link #getEpochT0()}
695      */
696     public double getSclkOffsetAtEpoch() {
697         return sclkOffsetAtEpoch;
698     }
699 
700     /** Set the spacecraft clock count at {@link #getEpochT0()}.
701      * @param sclkOffsetAtEpoch spacecraft clock count at {@link #getEpochT0()}
702      */
703     public void setSclkOffsetAtEpoch(final double sclkOffsetAtEpoch) {
704         refuseFurtherComments();
705         this.sclkOffsetAtEpoch = sclkOffsetAtEpoch;
706     }
707 
708     /** Get the number of spacecraft clock seconds occurring during one SI second.
709      * @return number of spacecraft clock seconds occurring during one SI second
710      */
711     public double getSclkSecPerSISec() {
712         return sclkSecPerSISec;
713     }
714 
715     /** Set the number of spacecraft clock seconds occurring during one SI second.
716      * @param secClockPerSISec number of spacecraft clock seconds occurring during one SI second
717      */
718     public void setSclkSecPerSISec(final double secClockPerSISec) {
719         refuseFurtherComments();
720         this.sclkSecPerSISec = secClockPerSISec;
721     }
722 
723     /** Get the creation date of previous message from a given originator.
724      * @return creation date of previous message from a given originator
725      */
726     public AbsoluteDate getPreviousMessageEpoch() {
727         return previousMessageEpoch;
728     }
729 
730     /** Set the creation date of previous message from a given originator.
731      * @param previousMessageEpoch creation date of previous message from a given originator
732      */
733     public void setPreviousMessageEpoch(final AbsoluteDate previousMessageEpoch) {
734         refuseFurtherComments();
735         this.previousMessageEpoch = previousMessageEpoch;
736     }
737 
738     /** Get the creation date of next message from a given originator.
739      * @return creation date of next message from a given originator
740      */
741     public AbsoluteDate getNextMessageEpoch() {
742         return nextMessageEpoch;
743     }
744 
745     /** Set the creation date of next message from a given originator.
746      * @param nextMessageEpoch creation date of next message from a given originator
747      */
748     public void setNextMessageEpoch(final AbsoluteDate nextMessageEpoch) {
749         refuseFurtherComments();
750         this.nextMessageEpoch = nextMessageEpoch;
751     }
752 
753     /** Get the time of the earliest data contained in the OCM.
754      * @return time of the earliest data contained in the OCM
755      */
756     public AbsoluteDate getStartTime() {
757         return startTime;
758     }
759 
760     /** Set the time of the earliest data contained in the OCM.
761      * @param startTime time of the earliest data contained in the OCM
762      */
763     public void setStartTime(final AbsoluteDate startTime) {
764         refuseFurtherComments();
765         this.startTime = startTime;
766     }
767 
768     /** Get the time of the latest data contained in the OCM.
769      * @return time of the latest data contained in the OCM
770      */
771     public AbsoluteDate getStopTime() {
772         return stopTime;
773     }
774 
775     /** Set the time of the latest data contained in the OCM.
776      * @param stopTime time of the latest data contained in the OCM
777      */
778     public void setStopTime(final AbsoluteDate stopTime) {
779         refuseFurtherComments();
780         this.stopTime = stopTime;
781     }
782 
783     /** Get the span of time in seconds that the OCM covers.
784      * @return span of time in seconds that the OCM covers
785      */
786     public double getTimeSpan() {
787         return timeSpan;
788     }
789 
790     /** Set the span of time in seconds that the OCM covers.
791      * @param timeSpan span of time in seconds that the OCM covers
792      */
793     public void setTimeSpan(final double timeSpan) {
794         refuseFurtherComments();
795         this.timeSpan = timeSpan;
796     }
797 
798     /** Get the difference (TAI – UTC) in seconds at epoch {@link #getEpochT0()}.
799      * @return difference (TAI – UTC) in seconds at epoch {@link #getEpochT0()}
800      */
801     public double getTaimutcT0() {
802         return taimutcT0;
803     }
804 
805     /** Set the difference (TAI – UTC) in seconds at epoch {@link #getEpochT0()}.
806      * @param taimutcT0 difference (TAI – UTC) in seconds at epoch {@link #getEpochT0()}
807      */
808     public void setTaimutcT0(final double taimutcT0) {
809         refuseFurtherComments();
810         this.taimutcT0 = taimutcT0;
811     }
812 
813     /** Get the epoch of next leap second.
814      * @return epoch of next leap second
815      * @since 11.2
816      */
817     public AbsoluteDate getNextLeapEpoch() {
818         return nextLeapEpoch;
819     }
820 
821     /** Set the epoch of next leap second.
822      * @param nextLeapEpoch epoch of next leap second
823      * @since 11.2
824      */
825     public void setNextLeapEpoch(final AbsoluteDate nextLeapEpoch) {
826         refuseFurtherComments();
827         this.nextLeapEpoch = nextLeapEpoch;
828     }
829 
830     /** Get the difference (TAI – UTC) in seconds incorporated at epoch {@link #getNextLeapEpoch()}.
831      * @return difference (TAI – UTC) in seconds incorporated at epoch {@link #getNextLeapEpoch()}
832      * @since 11.2
833      */
834     public double getNextLeapTaimutc() {
835         return nextLeapTaimutc;
836     }
837 
838     /** Set the difference (TAI – UTC) in seconds incorporated at epoch {@link #getNextLeapEpoch()}.
839      * @param nextLeapTaimutc difference (TAI – UTC) in seconds incorporated at epoch {@link #getNextLeapEpoch()}
840      * @since 11.2
841      */
842     public void setNextLeapTaimutc(final double nextLeapTaimutc) {
843         refuseFurtherComments();
844         this.nextLeapTaimutc = nextLeapTaimutc;
845     }
846 
847     /** Get the difference (UT1 – UTC) in seconds at epoch {@link #getEpochT0()}.
848      * @return difference (UT1 – UTC) in seconds at epoch {@link #getEpochT0()}
849      */
850     public double getUt1mutcT0() {
851         return ut1mutcT0;
852     }
853 
854     /** Set the difference (UT1 – UTC) in seconds at epoch {@link #getEpochT0()}.
855      * @param ut1mutcT0 difference (UT1 – UTC) in seconds at epoch {@link #getEpochT0()}
856      */
857     public void setUt1mutcT0(final double ut1mutcT0) {
858         refuseFurtherComments();
859         this.ut1mutcT0 = ut1mutcT0;
860     }
861 
862     /** Get the source and version of Earth Orientation Parameters.
863      * @return source and version of Earth Orientation Parameters
864      */
865     public String getEopSource() {
866         return eopSource;
867     }
868 
869     /** Set the source and version of Earth Orientation Parameters.
870      * @param eopSource source and version of Earth Orientation Parameters
871      */
872     public void setEopSource(final String eopSource) {
873         refuseFurtherComments();
874         this.eopSource = eopSource;
875     }
876 
877     /** Get the interpolation method for Earth Orientation Parameters.
878      * @return interpolation method for Earth Orientation Parameters
879      */
880     public String getInterpMethodEOP() {
881         return interpMethodEOP;
882     }
883 
884     /** Set the interpolation method for Earth Orientation Parameters.
885      * @param interpMethodEOP interpolation method for Earth Orientation Parameters
886      */
887     public void setInterpMethodEOP(final String interpMethodEOP) {
888         refuseFurtherComments();
889         this.interpMethodEOP = interpMethodEOP;
890     }
891 
892     /** Get the source and version of celestial body (e.g. Sun/Earth/Planetary).
893      * @return source and version of celestial body (e.g. Sun/Earth/Planetary)
894      */
895     public String getCelestialSource() {
896         return celestialSource;
897     }
898 
899     /** Set the source and version of celestial body (e.g. Sun/Earth/Planetary).
900      * @param celestialSource source and version of celestial body (e.g. Sun/Earth/Planetary)
901      */
902     public void setCelestialSource(final String celestialSource) {
903         refuseFurtherComments();
904         this.celestialSource = celestialSource;
905     }
906 
907     /** Copy the instance, making sure mandatory fields have been initialized.
908      * <p>
909      * Message ID, previous/next references, start and stop times are not copied.
910      * </p>
911      * @param version format version
912      * @return a new copy
913      * @since 12.0
914      */
915     public OcmMetadata copy(final double version) {
916 
917         validate(version);
918 
919         // allocate new instance
920         final OcmMetadata copy = new OcmMetadata(dataContext);
921 
922         // copy comments
923         for (String comment : getComments()) {
924             copy.addComment(comment);
925         }
926 
927         // copy metadata
928         copy.setInternationalDesignator(getInternationalDesignator());
929         copy.setCatalogName(getCatalogName());
930         copy.setObjectDesignator(getObjectDesignator());
931         copy.setAlternateNames(getAlternateNames());
932         copy.setOriginatorPOC(getOriginatorPOC());
933         copy.setOriginatorPosition(getOriginatorPosition());
934         copy.setOriginatorPhone(getOriginatorPhone());
935         copy.setOriginatorEmail(getOriginatorEmail());
936         copy.setOriginatorAddress(getOriginatorAddress());
937         copy.setTechOrg(getTechOrg());
938         copy.setTechPOC(getTechPOC());
939         copy.setTechPosition(getTechPosition());
940         copy.setTechPhone(getTechPhone());
941         copy.setTechEmail(getTechEmail());
942         copy.setTechAddress(getTechAddress());
943         copy.setAdmMessageLink(getAdmMessageLink());
944         copy.setCdmMessageLink(getCdmMessageLink());
945         copy.setPrmMessageLink(getPrmMessageLink());
946         copy.setRdmMessageLink(getRdmMessageLink());
947         copy.setTdmMessageLink(getTdmMessageLink());
948         copy.setOperator(getOperator());
949         copy.setOwner(getOwner());
950         copy.setCountry(getCountry());
951         copy.setConstellation(getConstellation());
952         copy.setObjectType(getObjectType());
953         copy.setEpochT0(getEpochT0());
954         copy.setOpsStatus(getOpsStatus());
955         copy.setOrbitCategory(getOrbitCategory());
956         copy.setOcmDataElements(getOcmDataElements());
957         copy.setSclkOffsetAtEpoch(getSclkOffsetAtEpoch());
958         copy.setSclkSecPerSISec(getSclkSecPerSISec());
959         copy.setTaimutcT0(getTaimutcT0());
960         copy.setNextLeapEpoch(getNextLeapEpoch());
961         copy.setNextLeapTaimutc(getNextLeapTaimutc());
962         copy.setUt1mutcT0(getUt1mutcT0());
963         copy.setEopSource(getEopSource());
964         copy.setInterpMethodEOP(getInterpMethodEOP());
965         copy.setCelestialSource(getCelestialSource());
966 
967         return copy;
968 
969     }
970 
971 }