OEMFile.java

  1. /* Copyright 2002-2019 CS Systèmes d'Information
  2.  * Licensed to CS Systèmes d'Information (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;

  18. import java.util.ArrayList;
  19. import java.util.Collections;
  20. import java.util.HashMap;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.Map.Entry;

  24. import org.hipparchus.linear.RealMatrix;
  25. import org.orekit.errors.OrekitException;
  26. import org.orekit.errors.OrekitMessages;
  27. import org.orekit.files.general.EphemerisFile;
  28. import org.orekit.frames.Frame;
  29. import org.orekit.frames.LOFType;
  30. import org.orekit.time.AbsoluteDate;
  31. import org.orekit.time.TimeScale;
  32. import org.orekit.utils.CartesianDerivativesFilter;
  33. import org.orekit.utils.TimeStampedPVCoordinates;

  34. /** This class stocks all the information of the OEM File parsed by OEMParser. It
  35.  * contains the header and a list of Ephemerides Blocks each containing
  36.  * metadata, a list of ephemerides data lines and optional covariance matrices
  37.  * (and their metadata).
  38.  * @author sports
  39.  * @author Evan Ward
  40.  * @since 6.1
  41.  */
  42. public class OEMFile extends ODMFile implements EphemerisFile {

  43.     /** List of ephemeris blocks. */
  44.     private List<EphemeridesBlock> ephemeridesBlocks;

  45.     /** OEMFile constructor. */
  46.     public OEMFile() {
  47.         ephemeridesBlocks = new ArrayList<EphemeridesBlock>();
  48.     }

  49.     /** Add a block to the list of ephemeris blocks. */
  50.     void addEphemeridesBlock() {
  51.         ephemeridesBlocks.add(new EphemeridesBlock());
  52.     }

  53.     /**Get the list of ephemerides blocks as an unmodifiable list.
  54.      * @return the list of ephemerides blocks
  55.      */
  56.     public List<EphemeridesBlock> getEphemeridesBlocks() {
  57.         return Collections.unmodifiableList(ephemeridesBlocks);
  58.     }

  59.     /** Check that, according to the CCSDS standard, every OEMBlock has the same time system.
  60.      */
  61.     void checkTimeSystems() {
  62.         final CcsdsTimeScale timeSystem = getEphemeridesBlocks().get(0).getMetaData().getTimeSystem();
  63.         for (final EphemeridesBlock block : ephemeridesBlocks) {
  64.             if (!timeSystem.equals(block.getMetaData().getTimeSystem())) {
  65.                 throw new OrekitException(OrekitMessages.CCSDS_OEM_INCONSISTENT_TIME_SYSTEMS,
  66.                                           timeSystem, block.getMetaData().getTimeSystem());
  67.             }
  68.         }
  69.     }

  70.     @Override
  71.     public Map<String, OemSatelliteEphemeris> getSatellites() {
  72.         final Map<String, List<EphemeridesBlock>> satellites = new HashMap<>();
  73.         for (final EphemeridesBlock ephemeridesBlock : ephemeridesBlocks) {
  74.             final String id = ephemeridesBlock.getMetaData().getObjectID();
  75.             satellites.putIfAbsent(id, new ArrayList<>());
  76.             satellites.get(id).add(ephemeridesBlock);
  77.         }
  78.         final Map<String, OemSatelliteEphemeris> ret = new HashMap<>();
  79.         for (final Entry<String, List<EphemeridesBlock>> entry : satellites.entrySet()) {
  80.             final String id = entry.getKey();
  81.             ret.put(id, new OemSatelliteEphemeris(id, getMuUsed(), entry.getValue()));
  82.         }
  83.         return ret;
  84.     }

  85.     /** The Ephemerides Blocks class contain metadata, the list of ephemerides data
  86.      * lines and optional covariance matrices (and their metadata). The reason
  87.      * for which the ephemerides have been separated into blocks is that the
  88.      * ephemerides of two different blocks are not suited for interpolation.
  89.      * @author sports
  90.      */
  91.     public class EphemeridesBlock implements EphemerisSegment {

  92.         /** Meta-data for the block. */
  93.         private ODMMetaData metaData;

  94.         /** Start of total time span covered by ephemerides data and covariance
  95.          * data. */
  96.         private AbsoluteDate startTime;

  97.         /** End of total time span covered by ephemerides data and covariance
  98.          * data. */
  99.         private AbsoluteDate stopTime;

  100.         /** Start of useable time span covered by ephemerides data, it may be
  101.          * necessary to allow for proper interpolation. */
  102.         private AbsoluteDate useableStartTime;

  103.         /** End of useable time span covered by ephemerides data, it may be
  104.          * necessary to allow for proper interpolation. */
  105.         private AbsoluteDate useableStopTime;

  106.         /** The interpolation method to be used. */
  107.         private String interpolationMethod;

  108.         /** The interpolation degree. */
  109.         private int interpolationDegree;

  110.         /** List of ephemerides data lines. */
  111.         private List<TimeStampedPVCoordinates> ephemeridesDataLines;

  112.         /** True iff all data points in this block have accelleration data. */
  113.         private boolean hasAcceleration;

  114.         /** List of covariance matrices. */
  115.         private List<CovarianceMatrix> covarianceMatrices;

  116.         /** Tests whether the reference frame has an epoch associated to it. */
  117.         private boolean hasRefFrameEpoch;

  118.         /** Ephemerides Data Lines comments. The list contains a string for each
  119.          * line of comment. */
  120.         private List<String> ephemeridesDataLinesComment;

  121.         /** EphemeridesBlock constructor. */
  122.         public EphemeridesBlock() {
  123.             metaData = new ODMMetaData(OEMFile.this);
  124.             ephemeridesDataLines = new ArrayList<>();
  125.             covarianceMatrices = new ArrayList<CovarianceMatrix>();
  126.             hasAcceleration = true;
  127.         }

  128.         /** Get the list of Ephemerides data lines.
  129.          * @return a reference to the internal list of Ephemerides data lines
  130.          */
  131.         List<TimeStampedPVCoordinates> getEphemeridesDataLines() {
  132.             return this.ephemeridesDataLines;
  133.         }

  134.         @Override
  135.         public CartesianDerivativesFilter getAvailableDerivatives() {
  136.             return hasAcceleration ? CartesianDerivativesFilter.USE_PVA :
  137.                     CartesianDerivativesFilter.USE_PV;
  138.         }

  139.         /**
  140.          * Update the value of {@link #hasAcceleration}.
  141.          *
  142.          * @param pointHasAcceleration true iff the current data point has acceleration
  143.          *                             data.
  144.          */
  145.         void updateHasAcceleration(final boolean pointHasAcceleration) {
  146.             this.hasAcceleration = this.hasAcceleration && pointHasAcceleration;
  147.         }

  148.         @Override
  149.         public List<TimeStampedPVCoordinates> getCoordinates() {
  150.             return Collections.unmodifiableList(this.ephemeridesDataLines);
  151.         }

  152.         /** Get the list of Covariance Matrices.
  153.          * @return the list of Covariance Matrices
  154.          */
  155.         public List<CovarianceMatrix> getCovarianceMatrices() {
  156.             return covarianceMatrices;
  157.         }

  158.         /** Get the meta-data for the block.
  159.          * @return meta-data for the block
  160.          */
  161.         public ODMMetaData getMetaData() {
  162.             return metaData;
  163.         }

  164.         @Override
  165.         public double getMu() {
  166.             return getMuUsed();
  167.         }

  168.         @Override
  169.         public String getFrameCenterString() {
  170.             return this.getMetaData().getCenterName();
  171.         }

  172.         @Override
  173.         public String getFrameString() {
  174.             return this.getMetaData().getFrameString();
  175.         }

  176.         @Override
  177.         public Frame getFrame() {
  178.             return this.getMetaData().getFrame();
  179.         }

  180.         @Override
  181.         public String getTimeScaleString() {
  182.             return this.getMetaData().getTimeSystem().toString();
  183.         }

  184.         @Override
  185.         public TimeScale getTimeScale() {
  186.             return this.getMetaData().getTimeSystem().getTimeScale(getConventions());
  187.         }

  188.         /** Get start of total time span covered by ephemerides data and
  189.          * covariance data.
  190.          * @return the start time
  191.          */
  192.         public AbsoluteDate getStartTime() {
  193.             return startTime;
  194.         }

  195.         /** Set start of total time span covered by ephemerides data and
  196.          * covariance data.
  197.          * @param startTime the time to be set
  198.          */
  199.         void setStartTime(final AbsoluteDate startTime) {
  200.             this.startTime = startTime;
  201.         }

  202.         /** Get end of total time span covered by ephemerides data and covariance
  203.          * data.
  204.          * @return the stop time
  205.          */
  206.         public AbsoluteDate getStopTime() {
  207.             return stopTime;
  208.         }

  209.         /** Set end of total time span covered by ephemerides data and covariance
  210.          * data.
  211.          * @param stopTime the time to be set
  212.          */
  213.         void setStopTime(final AbsoluteDate stopTime) {
  214.             this.stopTime = stopTime;
  215.         }

  216.         /** Get start of useable time span covered by ephemerides data, it may be
  217.          * necessary to allow for proper interpolation.
  218.          * @return the useable start time
  219.          */
  220.         public AbsoluteDate getUseableStartTime() {
  221.             return useableStartTime;
  222.         }

  223.         /** Set start of useable time span covered by ephemerides data, it may be
  224.          * necessary to allow for proper interpolation.
  225.          * @param useableStartTime the time to be set
  226.          */
  227.         void setUseableStartTime(final AbsoluteDate useableStartTime) {
  228.             this.useableStartTime = useableStartTime;
  229.         }

  230.         /** Get end of useable time span covered by ephemerides data, it may be
  231.          * necessary to allow for proper interpolation.
  232.          * @return the useable stop time
  233.          */
  234.         public AbsoluteDate getUseableStopTime() {
  235.             return useableStopTime;
  236.         }

  237.         /** Set end of useable time span covered by ephemerides data, it may be
  238.          * necessary to allow for proper interpolation.
  239.          * @param useableStopTime the time to be set
  240.          */
  241.         void setUseableStopTime(final AbsoluteDate useableStopTime) {
  242.             this.useableStopTime = useableStopTime;
  243.         }

  244.         @Override
  245.         public AbsoluteDate getStart() {
  246.             // usable start time overrides start time if it is set
  247.             final AbsoluteDate start = this.getUseableStartTime();
  248.             if (start != null) {
  249.                 return start;
  250.             } else {
  251.                 return this.getStartTime();
  252.             }
  253.         }

  254.         @Override
  255.         public AbsoluteDate getStop() {
  256.             // useable stop time overrides stop time if it is set
  257.             final AbsoluteDate stop = this.getUseableStopTime();
  258.             if (stop != null) {
  259.                 return stop;
  260.             } else {
  261.                 return this.getStopTime();
  262.             }
  263.         }

  264.         /** Get the interpolation method to be used.
  265.          * @return the interpolation method
  266.          */
  267.         public String getInterpolationMethod() {
  268.             return interpolationMethod;
  269.         }

  270.         /** Set the interpolation method to be used.
  271.          * @param interpolationMethod the interpolation method to be set
  272.          */
  273.         void setInterpolationMethod(final String interpolationMethod) {
  274.             this.interpolationMethod = interpolationMethod;
  275.         }

  276.         /** Get the interpolation degree.
  277.          * @return the interpolation degree
  278.          */
  279.         public int getInterpolationDegree() {
  280.             return interpolationDegree;
  281.         }

  282.         /** Set the interpolation degree.
  283.          * @param interpolationDegree the interpolation degree to be set
  284.          */
  285.         void setInterpolationDegree(final int interpolationDegree) {
  286.             this.interpolationDegree = interpolationDegree;
  287.         }

  288.         @Override
  289.         public int getInterpolationSamples() {
  290.             // From the standard it is not entirely clear how to interpret the degree.
  291.             return getInterpolationDegree() + 1;
  292.         }

  293.         /** Get boolean testing whether the reference frame has an epoch associated to it.
  294.          * @return true if the reference frame has an epoch associated to it
  295.          *         false otherwise
  296.          */
  297.         public boolean getHasRefFrameEpoch() {
  298.             return hasRefFrameEpoch;
  299.         }

  300.         /** Set boolean testing whether the reference frame has an epoch associated to it.
  301.          * @param hasRefFrameEpoch the boolean to be set.
  302.          */
  303.         void setHasRefFrameEpoch(final boolean hasRefFrameEpoch) {
  304.             this.hasRefFrameEpoch = hasRefFrameEpoch;
  305.         }

  306.         /** Get the ephemerides data lines comment.
  307.          * @return the comment
  308.          */
  309.         public List<String> getEphemeridesDataLinesComment() {
  310.             return ephemeridesDataLinesComment;
  311.         }

  312.         /** Set the ephemerides data lines comment.
  313.          * @param ephemeridesDataLinesComment the comment to be set
  314.          */
  315.         void setEphemeridesDataLinesComment(final List<String> ephemeridesDataLinesComment) {
  316.             this.ephemeridesDataLinesComment = new ArrayList<String>(ephemeridesDataLinesComment);
  317.         }

  318.     }

  319.     /** The CovarianceMatrix class represents a covariance matrix and its
  320.      * metadata: epoch and frame.
  321.      * @author sports
  322.      */
  323.     public static class CovarianceMatrix {

  324.         /** Covariance matrix. */
  325.         private RealMatrix matrix;

  326.         /** Epoch relative to the covariance matrix. */
  327.         private AbsoluteDate epoch;

  328.         /** Coordinate system for covariance matrix, for Local Orbital Frames. */
  329.         private LOFType lofType;

  330.         /** Coordinate system for covariance matrix, for absolute frames.
  331.          * If not given it is set equal to refFrame. */
  332.         private Frame frame;

  333.         /** Covariance Matrix constructor.
  334.          * @param epoch the epoch
  335.          * @param lofType coordinate system for covariance matrix, for Local Orbital Frames
  336.          * @param frame coordinate system for covariance matrix, for absolute frames
  337.          * @param lastMatrix the covariance matrix
  338.          */
  339.         CovarianceMatrix(final AbsoluteDate epoch,
  340.                          final LOFType lofType, final Frame frame,
  341.                          final RealMatrix lastMatrix) {
  342.             this.matrix  = lastMatrix;
  343.             this.epoch   = epoch;
  344.             this.lofType = lofType;
  345.             this.frame   = frame;
  346.         }

  347.         /** Get the covariance matrix.
  348.          * @return the covariance matrix
  349.          */
  350.         public RealMatrix getMatrix() {
  351.             return matrix;
  352.         }

  353.         /** Get the epoch relative to the covariance matrix.
  354.          * @return the epoch
  355.          */
  356.         public AbsoluteDate getEpoch() {
  357.             return epoch;
  358.         }

  359.         /** Get coordinate system for covariance matrix, for Local Orbital Frames.
  360.          * <p>
  361.          * The value returned is null if the covariance matrix is given in an
  362.          * absolute frame rather than a Local Orbital Frame. In this case, the
  363.          * method {@link #getFrame()} must be used instead.
  364.          * </p>
  365.          * @return the coordinate system for covariance matrix, or null if the
  366.          * covariance matrix is given in an absolute frame rather than a Local
  367.          * Orbital Frame
  368.          */
  369.         public LOFType getLofType() {
  370.             return lofType;
  371.         }

  372.         /** Get coordinate system for covariance matrix, for absolute frames.
  373.          * <p>
  374.          * The value returned is null if the covariance matrix is given in a
  375.          * Local Orbital Frame rather than an absolute frame. In this case, the
  376.          * method {@link #getLofType()} must be used instead.
  377.          * </p>
  378.          * @return the coordinate system for covariance matrix
  379.          */
  380.         public Frame getFrame() {
  381.             return frame;
  382.         }

  383.     }

  384.     /** OEM ephemeris blocks for a single satellite. */
  385.     public static class OemSatelliteEphemeris implements SatelliteEphemeris {

  386.         /** ID of the satellite. */
  387.         private final String id;
  388.         /** Gravitational prameter for the satellite, in m^3 / s^2. */
  389.         private final double mu;
  390.         /** The ephemeris data for the satellite. */
  391.         private final List<EphemeridesBlock> blocks;

  392.         /**
  393.          * Create a container for the set of ephemeris blocks in the file that pertain to
  394.          * a single satellite.
  395.          *
  396.          * @param id     of the satellite.
  397.          * @param mu     standard gravitational parameter used to create orbits for the
  398.          *               satellite, in m^3 / s^2.
  399.          * @param blocks containing ephemeris data for the satellite.
  400.          */
  401.         OemSatelliteEphemeris(final String id,
  402.                               final double mu,
  403.                               final List<EphemeridesBlock> blocks) {
  404.             this.id = id;
  405.             this.mu = mu;
  406.             this.blocks = blocks;
  407.         }

  408.         @Override
  409.         public String getId() {
  410.             return this.id;
  411.         }

  412.         @Override
  413.         public double getMu() {
  414.             return this.mu;
  415.         }

  416.         @Override
  417.         public List<EphemeridesBlock> getSegments() {
  418.             return Collections.unmodifiableList(blocks);
  419.         }

  420.         @Override
  421.         public AbsoluteDate getStart() {
  422.             return blocks.get(0).getStart();
  423.         }

  424.         @Override
  425.         public AbsoluteDate getStop() {
  426.             return blocks.get(blocks.size() - 1).getStop();
  427.         }

  428.     }

  429. }