1   /* Copyright 2024-2025 The Johns Hopkins University Applied Physics Laboratory
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    * ADS 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.iirv;
18  
19  import org.orekit.annotation.DefaultDataContext;
20  import org.orekit.files.general.EphemerisFile;
21  import org.orekit.frames.Frame;
22  import org.orekit.time.AbsoluteDate;
23  import org.orekit.utils.CartesianDerivativesFilter;
24  import org.orekit.utils.Constants;
25  import org.orekit.utils.TimeStampedPVCoordinates;
26  
27  import java.util.ArrayList;
28  import java.util.Collections;
29  import java.util.List;
30  
31  /**
32   * Ephemeris segment from an IIRV file. Each IIRV file (i.e. {@link IIRVMessage}) is defined as containing only one
33   * {@link IIRVSegment}.
34   *
35   * @author Nick LaFarge
36   * @since 13.0
37   */
38  public class IIRVSegment implements EphemerisFile.EphemerisSegment<TimeStampedPVCoordinates> {
39  
40      /** Gravitational parameter (m^3/s^2). */
41      private final double mu;
42  
43      /** Number of samples to use in interpolation. */
44      private final int interpolationSamples;
45  
46      /** Cartesian derivatives filter: IIRV always contains position & velocity data. */
47      private final CartesianDerivativesFilter cartesianDerivativesFilter;
48  
49      /** Year of the first vector in the file (day of year, but not year itself, is embedded within an IIRV message). */
50      private final int startYear;
51  
52      /** IIRV message consisting of sequential {@link IIRVVector} instances, sorted by {@link org.orekit.files.iirv.terms.SequenceNumberTerm}. */
53      private final IIRVMessage iirvMessage;
54  
55      /**
56       * Constructs a {@link IIRVSegment} instance  with default values.
57       * <p>
58       * Default gravitational parameter is {@link Constants#IERS96_EARTH_MU}. Default number of
59       * interpolation samples is 7.
60       *
61       * @param startYear   Year associated with the beginning of the IIRV message
62       * @param iirvMessage IIRV message consisting of sequential {@link IIRVVector} instances, sorted by
63       *                    {@link org.orekit.files.iirv.terms.SequenceNumberTerm}.
64       */
65      public IIRVSegment(final int startYear, final IIRVMessage iirvMessage) {
66          this(Constants.IERS96_EARTH_MU, 7, startYear, iirvMessage);
67      }
68  
69      /**
70       * Constructs a {@link IIRVSegment} instance.
71       *
72       * @param mu                   gravitational parameter (m^3/s^2)
73       * @param interpolationSamples number of samples to use in interpolation
74       * @param startYear            Year associated with the beginning of the IIRV message
75       * @param iirvMessage          IIRV message consisting of sequential {@link IIRVVector} instances, sorted by
76       *                             {@link org.orekit.files.iirv.terms.SequenceNumberTerm}.
77       */
78      public IIRVSegment(final double mu, final int interpolationSamples, final int startYear, final IIRVMessage iirvMessage) {
79          this.mu = mu;
80          this.interpolationSamples = interpolationSamples;
81          this.cartesianDerivativesFilter = CartesianDerivativesFilter.USE_PV;
82          this.startYear = startYear;
83          this.iirvMessage = iirvMessage;
84      }
85  
86      /** {@inheritDoc} */
87      @Override
88      public double getMu() {
89          return mu;
90      }
91  
92      /** {@inheritDoc} */
93      @Override
94      @DefaultDataContext
95      public Frame getFrame() {
96          return iirvMessage.getVectors().get(0).getFrame();
97      }
98  
99      /** {@inheritDoc} */
100     @Override
101     public int getInterpolationSamples() {
102         return interpolationSamples;
103     }
104 
105     /** {@inheritDoc} */
106     @Override
107     public CartesianDerivativesFilter getAvailableDerivatives() {
108         return cartesianDerivativesFilter;
109     }
110 
111     /** {@inheritDoc} */
112     @Override
113     public AbsoluteDate getStart() {
114         return getCoordinates().get(0).getDate();
115     }
116 
117     /** {@inheritDoc} */
118     @Override
119     public AbsoluteDate getStop() {
120         return getCoordinates().get(getCoordinates().size() - 1).getDate();
121     }
122 
123     /** {@inheritDoc} */
124     @Override
125     public List<TimeStampedPVCoordinates> getCoordinates() {
126         int year = startYear;
127         final List<IIRVVector> iirvVectors = iirvMessage.getVectors();
128 
129         final ArrayList<TimeStampedPVCoordinates> coordinates = new ArrayList<>();
130         coordinates.add(iirvVectors.get(0).getTimeStampedPVCoordinates(year));
131 
132         for (int i = 1; i < iirvVectors.size(); i++) {
133             final IIRVVector prev = iirvVectors.get(i - 1);
134             final IIRVVector next = iirvVectors.get(i);
135 
136             // Increase the year counter if the previous day is greater than the current day
137             if (prev.getDayOfYear().value() > next.getDayOfYear().value()) {
138                 year++;
139             }
140             coordinates.add(next.getTimeStampedPVCoordinates(year));
141         }
142         return Collections.unmodifiableList(coordinates);
143     }
144 
145     /**
146      * Gets the IIRV message for this segment.
147      *
148      * @return IIRV message for this segment
149      */
150     public IIRVMessage getIIRVMessage() {
151         return iirvMessage;
152     }
153 
154     /**
155      * Gets the start year for this segment.
156      *
157      * @return start year for this segment.
158      */
159     public int getStartYear() {
160         return startYear;
161     }
162 }