IIRVParser.java
- /* Copyright 2024-2025 The Johns Hopkins University Applied Physics Laboratory
- * Licensed to CS GROUP (CS) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * CS licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.orekit.files.iirv;
- import org.hipparchus.exception.LocalizedCoreFormats;
- import org.orekit.data.DataSource;
- import org.orekit.errors.OrekitException;
- import org.orekit.errors.OrekitIllegalArgumentException;
- import org.orekit.errors.OrekitMessages;
- import org.orekit.files.general.EphemerisFileParser;
- import org.orekit.time.UTCScale;
- import org.orekit.utils.Constants;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.Reader;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.List;
- import java.util.regex.Pattern;
- /**
- * Parser of {@link IIRVEphemerisFile}s.
- *
- * @author Nick LaFarge
- * @since 13.0
- */
- public class IIRVParser implements EphemerisFileParser<IIRVEphemerisFile> {
- /** Default number of sample for interpolating data (See: reference documents). */
- public static final int DEFAULT_INTERPOLATION_SAMPLE = 10;
- /** Line separator. */
- private static final Pattern LINE_SEPARATOR_PATTERN = Pattern.compile(IIRVVector.LINE_SEPARATOR);
- /** Standard gravitational parameter in m³/s². */
- private final double mu;
- /** Number of data points to use in interpolation. */
- private final int interpolationSamples;
- /** Year of the initial vector in the IIRV ephemeris file. */
- private final int year;
- /** UTC time scale. */
- private final UTCScale utc;
- /**
- * Constructs a {@link IIRVParser} instance with default values.
- * <p>
- * Default gravitational parameter is {@link Constants#IERS96_EARTH_MU}. Default number of
- * interpolation samples is 7.
- *
- * @param year year of the initial vector in the IIRV ephemeris file.
- * @param utc UTC time scale
- */
- public IIRVParser(final int year, final UTCScale utc) {
- this(Constants.IERS96_EARTH_MU, DEFAULT_INTERPOLATION_SAMPLE, year, utc);
- }
- /**
- * Constructs a {@link IIRVParser} instance.
- *
- * @param mu gravitational parameter (m^3/s^2)
- * @param interpolationSamples is the number of samples to use when interpolating.
- * @param year year of the initial vector in the IIRV ephemeris file.
- * @param utc UTC time scale
- */
- public IIRVParser(final double mu, final int interpolationSamples, final int year, final UTCScale utc) {
- this.mu = mu;
- this.interpolationSamples = interpolationSamples;
- this.year = year;
- this.utc = utc;
- }
- /** {@inheritDoc} */
- @Override
- public IIRVEphemerisFile parse(final DataSource source) {
- if (source == null) {
- throw new OrekitIllegalArgumentException(OrekitMessages.NULL_ARGUMENT, "source");
- }
- final ArrayList<String> messageLines = new ArrayList<>();
- try (Reader reader = source.getOpener().openReaderOnce();
- BufferedReader bufferedReader = (reader == null) ? null : new BufferedReader(reader)) {
- if (bufferedReader == null) {
- throw new OrekitException(OrekitMessages.UNABLE_TO_FIND_FILE, source.getName());
- }
- // Message lines
- final List<String> vectorLines = new ArrayList<>(Collections.nCopies(6, ""));
- int currentIIRVLine = vectorLines.indexOf("");
- String line = bufferedReader.readLine(); // Initialize on first line
- if (line == null) {
- throw new OrekitException(OrekitMessages.NO_DATA_IN_FILE, source.getName());
- }
- while (line != null) {
- messageLines.add(line);
- vectorLines.set(currentIIRVLine, line); // Set the line in the list
- // If every line is set, create an IIRV vector and clear out the strings. Otherwise, increment
- // the line counter
- if (currentIIRVLine == 5) {
- for (int i = 0; i < 6; i++) { // Reset each line + line counter
- vectorLines.set(i, "");
- }
- currentIIRVLine = 0;
- } else {
- currentIIRVLine++;
- }
- // Expect two line breaks here (except end of file
- final String linebreak1 = bufferedReader.readLine();
- final String linebreak2 = bufferedReader.readLine();
- if (linebreak1 == null || linebreak2 == null) {
- break;
- } else if (!linebreak1.isEmpty() || !linebreak2.isEmpty()) {
- throw new OrekitException(OrekitMessages.IIRV_MISSING_LINEBREAK_IN_FILE, currentIIRVLine, source.getName());
- }
- line = bufferedReader.readLine();
- }
- } catch (IOException ioe) {
- throw new OrekitException(ioe, LocalizedCoreFormats.SIMPLE_MESSAGE, ioe.getLocalizedMessage());
- }
- return parse(messageLines);
- }
- /**
- * Parses a string representing an IIRV message.
- *
- * @param iirv String representation of an IIRV message
- * @return newly created {@link IIRVSegment} object populated with ephemeris data parsed from
- * {@code iirvVectorStrings}
- */
- public IIRVEphemerisFile parse(final String iirv) {
- return parse(Arrays.asList(LINE_SEPARATOR_PATTERN.split(iirv)));
- }
- /**
- * Parses a list of strings that comprise an {@link IIRVMessage}.
- *
- * @param iirvVectorStrings list of Strings that comprise an {@link IIRVMessage}
- * @return newly created {@link IIRVSegment} object populated with ephemeris data parsed from
- * {@code iirvVectorStrings}
- */
- public IIRVEphemerisFile parse(final List<String> iirvVectorStrings) {
- final ArrayList<IIRVVector> vectors = new ArrayList<>();
- if (iirvVectorStrings == null) {
- throw new OrekitIllegalArgumentException(OrekitMessages.NULL_ARGUMENT, "iirvVectorStrings");
- }
- if (iirvVectorStrings.isEmpty()) {
- throw new OrekitIllegalArgumentException(OrekitMessages.IIRV_INVALID_LINE_IN_VECTOR, 1, "");
- }
- // The first vector in a message must *always* include metadata
- Pattern line1Pattern = IIRVVector.LINE_1_PATTERN_METADATA_INCLUDED;
- // Message lines
- final List<String> vectorLines = new ArrayList<>(Collections.nCopies(6, ""));
- int currentIIRVLine = vectorLines.indexOf("");
- for (String line : iirvVectorStrings) {
- // The second vector tells us whether to expect metadata in line 1 for the
- // remainder of the file
- if (vectors.size() == 1 && currentIIRVLine == 0 && IIRVVector.LINE_1_PATTERN_METADATA_OMITTED.matcher(line).matches()) {
- line1Pattern = IIRVVector.LINE_1_PATTERN_METADATA_OMITTED;
- }
- // Check if this line matches an IIRV pattern based on the current line index
- final boolean line1Valid = currentIIRVLine == 0 && line1Pattern.matcher(line).matches();
- boolean isValidLine2to6 = false;
- for (int i = currentIIRVLine; i < 6; i++) {
- final boolean isValidForLineI = IIRVVector.validateLine(i, line);
- if (isValidForLineI) {
- if (currentIIRVLine == i) {
- isValidLine2to6 = true; // Only valid if the line is validated at the right location
- break;
- } else {
- // Valid for the wrong line-> invalid file
- throw new OrekitException(OrekitMessages.IIRV_INVALID_LINE_IN_VECTOR,
- currentIIRVLine, line);
- }
- }
- }
- // Continue if this line matches a pattern
- if (line1Valid || isValidLine2to6) {
- vectorLines.set(currentIIRVLine, line); // Set the line in the list
- // If every line is set, create an IIRV vector and clear out the strings. Otherwise, increment
- // the line counter
- if (currentIIRVLine == 5) {
- IIRVVector newVector = new IIRVVector(vectorLines, utc);
- // Add metadata (if applicable)
- if (!vectors.isEmpty() && line1Pattern == IIRVVector.LINE_1_PATTERN_METADATA_OMITTED) {
- vectorLines.set(0, vectors.get(0).buildLine1(true));
- newVector = new IIRVVector(vectorLines, utc);
- }
- vectors.add(newVector);
- for (int i = 0; i < 6; i++) { // Reset each line + line counter
- vectorLines.set(i, "");
- }
- currentIIRVLine = 0;
- } else {
- currentIIRVLine++;
- }
- }
- }
- return new IIRVEphemerisFile(mu, interpolationSamples, year, new IIRVMessage(vectors));
- }
- }