All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.orekit.frames.EOPC04FilesLoader Maven / Gradle / Ivy

Go to download

OREKIT (ORbits Extrapolation KIT) is a low level space dynamics library. It provides basic elements (orbits, dates, attitude, frames ...) and various algorithms to handle them (conversions, analytical and numerical propagation, pointing ...).

There is a newer version: 12.2
Show newest version
/* Copyright 2002-2022 CS GROUP
 * 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.frames;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.SortedSet;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.orekit.data.DataProvidersManager;
import org.orekit.errors.OrekitException;
import org.orekit.errors.OrekitMessages;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.DateComponents;
import org.orekit.time.TimeScale;
import org.orekit.utils.Constants;
import org.orekit.utils.IERSConventions;
import org.orekit.utils.IERSConventions.NutationCorrectionConverter;

/** Loader for EOP xx C04 files.
 * 

EOP xx C04 files contain {@link EOPEntry * Earth Orientation Parameters} consistent with ITRF20xx for one year periods, with various * xx (05, 08, 14) depending on the data source.

*

The EOP xx C04 files retrieved from the ftp site * ftp://ftp.iers.org/products/eop/long-term/ * are recognized thanks to their base names, which must match one of the patterns * {@code eopc04_##_IAU2000.##} or {@code eopc04_##.##} (or the same ending with .gz for * gzip-compressed files) where # stands for a digit character.

*

* Beware that files retrieved from the web site * http://hpiers.obspm.fr/eoppc/eop/ do * not follow the same naming convention. They lack the _05, _08 or _14 * marker (and for EOP 14 C04 even the directory does not have this marker anymore...), * so all the files in this site have the same name and can easily be confused. This is the reason * why the default regular expression in {@link FramesFactory} does not recognize them and * enforces the year marker presence. *

*

Between 2002 and 2007, another series of Earth Orientation Parameters was * in use: EOPC04 (without the _##). These parameters were consistent with the * previous ITRS realization: ITRF2000.

*

Since 2008, several series of Earth Orientation Parameters have been available: * EOP 05 C04 consistent with ITRF 2005, EOP 08 C04 consistent with ITRF 2008, and * EOP 14 C04 consistent with ITRF 2014. As of mid 2017, only the EOP 08 C04 and * EOP 14 C04 are updated for current years.

*

Files are available at IERS FTP site: ftp://ftp.iers.org/products/eop/long-term/.

*

* This class is immutable and hence thread-safe *

* @author Luc Maisonobe */ class EOPC04FilesLoader extends AbstractEopLoader implements EOPHistoryLoader { /** Pattern for delimiting regular expressions. */ private static final Pattern SEPARATOR; /** Pattern to match the columns header. */ private static final Pattern COLUMNS_HEADER_PATTERN; /** Pattern for data lines. */ private static final Pattern DATA_LINE_PATTERN; /** Year field. */ private static final int YEAR_FIELD; /** Month field. */ private static final int MONTH_FIELD; /** Day field. */ private static final int DAY_FIELD; /** MJD field. */ private static final int MJD_FIELD; /** X component of pole motion field. */ private static final int POLE_X_FIELD; /** Y component of pole motion field. */ private static final int POLE_Y_FIELD; /** UT1-UTC field. */ private static final int UT1_UTC_FIELD; /** LoD field. */ private static final int LOD_FIELD; /** Correction for nutation first field (either dX or dPsi). */ private static final int NUT_0_FIELD; /** Correction for nutation second field (either dY or dEps). */ private static final int NUT_1_FIELD; static { SEPARATOR = Pattern.compile(" +"); // Header have either the following form: // Date MJD x y UT1-UTC LOD dPsi dEps x Err y Err UT1-UTC Err LOD Err dPsi Err dEpsilon Err // " " s s " " " " s s " " // (0h UTC) // or the following form: // Date MJD x y UT1-UTC LOD dX dY x Err y Err UT1-UTC Err LOD Err dX Err dY Err // " " s s " " " " s s " " // (0h UTC) // COLUMNS_HEADER_PATTERN = Pattern.compile("^ *Date +MJD +x +y +UT1-UTC +LOD +((?:dPsi +dEps)|(?:dX +dY)) .*"); // The data lines in the EOP C04 yearly data files have the following fixed form: // year month day MJD ...12 floating values fields in decimal format... // 2000 1 1 51544 0.043242 0.377915 0.3554777 ... // 2000 1 2 51545 0.043515 0.377753 0.3546065 ... // 2000 1 3 51546 0.043623 0.377452 0.3538444 ... // the corresponding fortran format is: // 3(I4),I7,2(F11.6),2(F12.7),2(F12.6),2(F11.6),2(F12.7),2F12.6 DATA_LINE_PATTERN = Pattern.compile("^\\d+ +\\d+ +\\d+ +\\d+(?: +-?\\d+\\.\\d+){12}$"); YEAR_FIELD = 0; MONTH_FIELD = 1; DAY_FIELD = 2; MJD_FIELD = 3; POLE_X_FIELD = 4; POLE_Y_FIELD = 5; UT1_UTC_FIELD = 6; LOD_FIELD = 7; NUT_0_FIELD = 8; NUT_1_FIELD = 9; } /** Build a loader for IERS EOP C04 files. * @param supportedNames regular expression for supported files names * @param manager provides access to the EOP C04 files. * @param utcSupplier UTC time scale. */ EOPC04FilesLoader(final String supportedNames, final DataProvidersManager manager, final Supplier utcSupplier) { super(supportedNames, manager, utcSupplier); } /** {@inheritDoc} */ public void fillHistory(final IERSConventions.NutationCorrectionConverter converter, final SortedSet history) { final ItrfVersionProvider itrfVersionProvider = new ITRFVersionLoader( ITRFVersionLoader.SUPPORTED_NAMES, getDataProvidersManager()); final Parser parser = new Parser(converter, itrfVersionProvider, getUtc()); final EopParserLoader loader = new EopParserLoader(parser); this.feed(loader); history.addAll(loader.getEop()); } /** Internal class performing the parsing. */ static class Parser extends AbstractEopParser { /** * Simple constructor. * * @param converter converter to use * @param itrfVersionProvider to use for determining the ITRF version of the EOP. * @param utc time scale for parsing dates. */ Parser(final NutationCorrectionConverter converter, final ItrfVersionProvider itrfVersionProvider, final TimeScale utc) { super(converter, itrfVersionProvider, utc); } /** {@inheritDoc} */ public Collection parse(final InputStream input, final String name) throws IOException, OrekitException { final List history = new ArrayList<>(); ITRFVersionLoader.ITRFVersionConfiguration configuration = null; // set up a reader for line-oriented bulletin B files try (BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8))) { // reset parse info to start new file (do not clear history!) int lineNumber = 0; boolean inHeader = true; boolean isNonRotatingOrigin = false; // read all file for (String line = reader.readLine(); line != null; line = reader.readLine()) { ++lineNumber; boolean parsed = false; if (inHeader) { final Matcher matcher = COLUMNS_HEADER_PATTERN.matcher(line); if (matcher.matches()) { if (matcher.group(1).startsWith("dX")) { isNonRotatingOrigin = true; } } } if (DATA_LINE_PATTERN.matcher(line).matches()) { inHeader = false; // this is a data line, build an entry from the extracted fields final String[] fields = SEPARATOR.split(line); final DateComponents dc = new DateComponents(Integer.parseInt(fields[YEAR_FIELD]), Integer.parseInt(fields[MONTH_FIELD]), Integer.parseInt(fields[DAY_FIELD])); final int mjd = Integer.parseInt(fields[MJD_FIELD]); if (dc.getMJD() != mjd) { throw new OrekitException(OrekitMessages.INCONSISTENT_DATES_IN_IERS_FILE, name, dc.getYear(), dc.getMonth(), dc.getDay(), mjd); } final AbsoluteDate date = new AbsoluteDate(dc, getUtc()); // the first six fields are consistent with the expected format final double x = Double.parseDouble(fields[POLE_X_FIELD]) * Constants.ARC_SECONDS_TO_RADIANS; final double y = Double.parseDouble(fields[POLE_Y_FIELD]) * Constants.ARC_SECONDS_TO_RADIANS; final double dtu1 = Double.parseDouble(fields[UT1_UTC_FIELD]); final double lod = Double.parseDouble(fields[LOD_FIELD]); final double[] equinox; final double[] nro; if (isNonRotatingOrigin) { nro = new double[] { Double.parseDouble(fields[NUT_0_FIELD]) * Constants.ARC_SECONDS_TO_RADIANS, Double.parseDouble(fields[NUT_1_FIELD]) * Constants.ARC_SECONDS_TO_RADIANS }; equinox = getConverter().toEquinox(date, nro[0], nro[1]); } else { equinox = new double[] { Double.parseDouble(fields[NUT_0_FIELD]) * Constants.ARC_SECONDS_TO_RADIANS, Double.parseDouble(fields[NUT_1_FIELD]) * Constants.ARC_SECONDS_TO_RADIANS }; nro = getConverter().toNonRotating(date, equinox[0], equinox[1]); } if (configuration == null || !configuration.isValid(mjd)) { // get a configuration for current name and date range configuration = getItrfVersionProvider().getConfiguration(name, mjd); } history.add(new EOPEntry(mjd, dtu1, lod, x, y, equinox[0], equinox[1], nro[0], nro[1], configuration.getVersion(), date)); parsed = true; } if (!(inHeader || parsed)) { throw new OrekitException(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE, lineNumber, name, line); } } // check if we have read something if (inHeader) { throw new OrekitException(OrekitMessages.NOT_A_SUPPORTED_IERS_DATA_FILE, name); } } return history; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy