OEMFile.java

  1. /* Copyright 2002-2020 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. 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.     public 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.     public 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.     /** {@inheritDoc} */
  71.     @Override
  72.     public Map<String, OemSatelliteEphemeris> getSatellites() {
  73.         final Map<String, List<EphemeridesBlock>> satellites = new HashMap<>();
  74.         for (final EphemeridesBlock ephemeridesBlock : ephemeridesBlocks) {
  75.             final String id = ephemeridesBlock.getMetaData().getObjectID();
  76.             satellites.putIfAbsent(id, new ArrayList<>());
  77.             satellites.get(id).add(ephemeridesBlock);
  78.         }
  79.         final Map<String, OemSatelliteEphemeris> ret = new HashMap<>();
  80.         for (final Entry<String, List<EphemeridesBlock>> entry : satellites.entrySet()) {
  81.             final String id = entry.getKey();
  82.             ret.put(id, new OemSatelliteEphemeris(id, getMuUsed(), entry.getValue()));
  83.         }
  84.         return ret;
  85.     }


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

  88.         /** ID of the satellite. */
  89.         private final String id;

  90.         /** Gravitational parameter for the satellite, in m^3 / s^2. */
  91.         private final double mu;

  92.         /** The ephemeris data for the satellite. */
  93.         private final List<EphemeridesBlock> blocks;

  94.         /**
  95.          * Create a container for the set of ephemeris blocks in the file that pertain to
  96.          * a single satellite.
  97.          *
  98.          * @param id     of the satellite.
  99.          * @param mu     standard gravitational parameter used to create orbits for the
  100.          *               satellite, in m^3 / s^2.
  101.          * @param blocks containing ephemeris data for the satellite.
  102.          */
  103.         public OemSatelliteEphemeris(final String id,
  104.                                      final double mu,
  105.                                      final List<EphemeridesBlock> blocks) {
  106.             this.id = id;
  107.             this.mu = mu;
  108.             this.blocks = blocks;
  109.         }

  110.         /** {@inheritDoc} */
  111.         @Override
  112.         public String getId() {
  113.             return this.id;
  114.         }

  115.         /** {@inheritDoc} */
  116.         @Override
  117.         public double getMu() {
  118.             return this.mu;
  119.         }

  120.         /** {@inheritDoc} */
  121.         @Override
  122.         public List<EphemeridesBlock> getSegments() {
  123.             return Collections.unmodifiableList(blocks);
  124.         }

  125.         /** {@inheritDoc} */
  126.         @Override
  127.         public AbsoluteDate getStart() {
  128.             return blocks.get(0).getStart();
  129.         }

  130.         /** {@inheritDoc} */
  131.         @Override
  132.         public AbsoluteDate getStop() {
  133.             return blocks.get(blocks.size() - 1).getStop();
  134.         }

  135.     }

  136.     /** The Ephemerides Blocks class contain metadata, the list of ephemerides data
  137.      * lines and optional covariance matrices (and their metadata). The reason
  138.      * for which the ephemerides have been separated into blocks is that the
  139.      * ephemerides of two different blocks are not suited for interpolation.
  140.      * @author sports
  141.      */
  142.     public class EphemeridesBlock implements EphemerisSegment {

  143.         /** Meta-data for the block. */
  144.         private ODMMetaData metaData;

  145.         /** Start of total time span covered by ephemerides data and covariance
  146.          * data. */
  147.         private AbsoluteDate startTime;

  148.         /** End of total time span covered by ephemerides data and covariance
  149.          * data. */
  150.         private AbsoluteDate stopTime;

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

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

  157.         /** The interpolation method to be used. */
  158.         private String interpolationMethod;

  159.         /** The interpolation degree. */
  160.         private int interpolationDegree;

  161.         /** List of ephemerides data lines. */
  162.         private List<TimeStampedPVCoordinates> ephemeridesDataLines;

  163.         /** True iff all data points in this block have acceleration data. */
  164.         private boolean hasAcceleration;

  165.         /** List of covariance matrices. */
  166.         private List<CovarianceMatrix> covarianceMatrices;

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

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

  172.         /** EphemeridesBlock constructor. */
  173.         public EphemeridesBlock() {
  174.             metaData = new ODMMetaData(OEMFile.this);
  175.             ephemeridesDataLines = new ArrayList<>();
  176.             covarianceMatrices = new ArrayList<CovarianceMatrix>();
  177.             hasAcceleration = true;
  178.         }

  179.         /** Get the list of Ephemerides data lines.
  180.          * @return a reference to the internal list of Ephemerides data lines
  181.          */
  182.         public List<TimeStampedPVCoordinates> getEphemeridesDataLines() {
  183.             return this.ephemeridesDataLines;
  184.         }

  185.         /** {@inheritDoc} */
  186.         @Override
  187.         public CartesianDerivativesFilter getAvailableDerivatives() {
  188.             return hasAcceleration ? CartesianDerivativesFilter.USE_PVA :
  189.                     CartesianDerivativesFilter.USE_PV;
  190.         }

  191.         /**
  192.          * Update the value of {@link #hasAcceleration}.
  193.          *
  194.          * @param pointHasAcceleration true if the current data point has acceleration
  195.          *                             data.
  196.          */
  197.         void updateHasAcceleration(final boolean pointHasAcceleration) {
  198.             this.hasAcceleration = this.hasAcceleration && pointHasAcceleration;
  199.         }

  200.         /** {@inheritDoc} */
  201.         @Override
  202.         public List<TimeStampedPVCoordinates> getCoordinates() {
  203.             return Collections.unmodifiableList(this.ephemeridesDataLines);
  204.         }

  205.         /** Get the list of Covariance Matrices.
  206.          * @return the list of Covariance Matrices
  207.          */
  208.         public List<CovarianceMatrix> getCovarianceMatrices() {
  209.             return covarianceMatrices;
  210.         }

  211.         /** Get the meta-data for the block.
  212.          * @return meta-data for the block
  213.          */
  214.         public ODMMetaData getMetaData() {
  215.             return metaData;
  216.         }

  217.         /** {@inheritDoc} */
  218.         @Override
  219.         public double getMu() {
  220.             return getMuUsed();
  221.         }

  222.         /** {@inheritDoc} */
  223.         @Override
  224.         public String getFrameCenterString() {
  225.             return this.getMetaData().getCenterName();
  226.         }

  227.         /** {@inheritDoc} */
  228.         @Override
  229.         public String getFrameString() {
  230.             return this.getMetaData().getFrameString();
  231.         }

  232.         /** {@inheritDoc} */
  233.         @Override
  234.         public Frame getFrame() {
  235.             return this.getMetaData().getFrame();
  236.         }

  237.         /** {@inheritDoc} */
  238.         @Override
  239.         public Frame getInertialFrame() {
  240.             final Frame frame = getFrame();
  241.             if (frame.isPseudoInertial()) {
  242.                 return frame;
  243.             }
  244.             return metaData.getODMFile().getDataContext().getFrames().getGCRF();
  245.         }

  246.         /** {@inheritDoc} */
  247.         @Override
  248.         public String getTimeScaleString() {
  249.             return this.getMetaData().getTimeSystem().toString();
  250.         }

  251.         /** {@inheritDoc} */
  252.         @Override
  253.         public TimeScale getTimeScale() {
  254.             return this.getMetaData().getTimeScale();
  255.         }

  256.         /** Get start of total time span covered by ephemerides data and
  257.          * covariance data.
  258.          * @return the start time
  259.          */
  260.         public AbsoluteDate getStartTime() {
  261.             return startTime;
  262.         }

  263.         /** Set start of total time span covered by ephemerides data and
  264.          * covariance data.
  265.          * @param startTime the time to be set
  266.          */
  267.         public void setStartTime(final AbsoluteDate startTime) {
  268.             this.startTime = startTime;
  269.         }

  270.         /** Get end of total time span covered by ephemerides data and covariance
  271.          * data.
  272.          * @return the stop time
  273.          */
  274.         public AbsoluteDate getStopTime() {
  275.             return stopTime;
  276.         }

  277.         /** Set end of total time span covered by ephemerides data and covariance
  278.          * data.
  279.          * @param stopTime the time to be set
  280.          */
  281.         public void setStopTime(final AbsoluteDate stopTime) {
  282.             this.stopTime = stopTime;
  283.         }

  284.         /** Get start of useable time span covered by ephemerides data, it may be
  285.          * necessary to allow for proper interpolation.
  286.          * @return the useable start time
  287.          */
  288.         public AbsoluteDate getUseableStartTime() {
  289.             return useableStartTime;
  290.         }

  291.         /** Set start of useable time span covered by ephemerides data, it may be
  292.          * necessary to allow for proper interpolation.
  293.          * @param useableStartTime the time to be set
  294.          */
  295.         public void setUseableStartTime(final AbsoluteDate useableStartTime) {
  296.             this.useableStartTime = useableStartTime;
  297.         }

  298.         /** Get end of useable time span covered by ephemerides data, it may be
  299.          * necessary to allow for proper interpolation.
  300.          * @return the useable stop time
  301.          */
  302.         public AbsoluteDate getUseableStopTime() {
  303.             return useableStopTime;
  304.         }

  305.         /** Set end of useable time span covered by ephemerides data, it may be
  306.          * necessary to allow for proper interpolation.
  307.          * @param useableStopTime the time to be set
  308.          */
  309.         public void setUseableStopTime(final AbsoluteDate useableStopTime) {
  310.             this.useableStopTime = useableStopTime;
  311.         }

  312.         /** {@inheritDoc} */
  313.         @Override
  314.         public AbsoluteDate getStart() {
  315.             // useable start time overrides start time if it is set
  316.             final AbsoluteDate start = this.getUseableStartTime();
  317.             if (start != null) {
  318.                 return start;
  319.             } else {
  320.                 return this.getStartTime();
  321.             }
  322.         }

  323.         /** {@inheritDoc} */
  324.         @Override
  325.         public AbsoluteDate getStop() {
  326.             // useable stop time overrides stop time if it is set
  327.             final AbsoluteDate stop = this.getUseableStopTime();
  328.             if (stop != null) {
  329.                 return stop;
  330.             } else {
  331.                 return this.getStopTime();
  332.             }
  333.         }

  334.         /** Get the interpolation method to be used.
  335.          * @return the interpolation method
  336.          */
  337.         public String getInterpolationMethod() {
  338.             return interpolationMethod;
  339.         }

  340.         /** Set the interpolation method to be used.
  341.          * @param interpolationMethod the interpolation method to be set
  342.          */
  343.         public void setInterpolationMethod(final String interpolationMethod) {
  344.             this.interpolationMethod = interpolationMethod;
  345.         }

  346.         /** Get the interpolation degree.
  347.          * @return the interpolation degree
  348.          */
  349.         public int getInterpolationDegree() {
  350.             return interpolationDegree;
  351.         }

  352.         /** Set the interpolation degree.
  353.          * @param interpolationDegree the interpolation degree to be set
  354.          */
  355.         public void setInterpolationDegree(final int interpolationDegree) {
  356.             this.interpolationDegree = interpolationDegree;
  357.         }

  358.         /** {@inheritDoc} */
  359.         @Override
  360.         public int getInterpolationSamples() {
  361.             // From the standard it is not entirely clear how to interpret the degree.
  362.             return getInterpolationDegree() + 1;
  363.         }

  364.         /** Get boolean testing whether the reference frame has an epoch associated to it.
  365.          * @return true if the reference frame has an epoch associated to it
  366.          *         false otherwise
  367.          */
  368.         public boolean getHasRefFrameEpoch() {
  369.             return hasRefFrameEpoch;
  370.         }

  371.         /** Set boolean testing whether the reference frame has an epoch associated to it.
  372.          * @param hasRefFrameEpoch the boolean to be set.
  373.          */
  374.         public void setHasRefFrameEpoch(final boolean hasRefFrameEpoch) {
  375.             this.hasRefFrameEpoch = hasRefFrameEpoch;
  376.         }

  377.         /** Get the ephemerides data lines comment.
  378.          * @return the comment
  379.          */
  380.         public List<String> getEphemeridesDataLinesComment() {
  381.             return ephemeridesDataLinesComment;
  382.         }

  383.         /** Set the ephemerides data lines comment.
  384.          * @param ephemeridesDataLinesComment the comment to be set
  385.          */
  386.         public void setEphemeridesDataLinesComment(final List<String> ephemeridesDataLinesComment) {
  387.             this.ephemeridesDataLinesComment = new ArrayList<String>(ephemeridesDataLinesComment);
  388.         }

  389.     }

  390.     /** The CovarianceMatrix class represents a covariance matrix and its
  391.      * metadata: epoch and frame.
  392.      * @author sports
  393.      */
  394.     public static class CovarianceMatrix {

  395.         /** Covariance matrix. */
  396.         private RealMatrix matrix;

  397.         /** Epoch relative to the covariance matrix. */
  398.         private AbsoluteDate epoch;

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

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

  404.         /** Covariance Matrix constructor.
  405.          * @param epoch the epoch
  406.          * @param lofType coordinate system for covariance matrix, for Local Orbital Frames
  407.          * @param frame coordinate system for covariance matrix, for absolute frames
  408.          * @param lastMatrix the covariance matrix
  409.          */
  410.         public CovarianceMatrix(final AbsoluteDate epoch,
  411.                                 final LOFType lofType, final Frame frame,
  412.                                 final RealMatrix lastMatrix) {
  413.             this.matrix  = lastMatrix;
  414.             this.epoch   = epoch;
  415.             this.lofType = lofType;
  416.             this.frame   = frame;
  417.         }

  418.         /** Get the covariance matrix.
  419.          * @return the covariance matrix
  420.          */
  421.         public RealMatrix getMatrix() {
  422.             return matrix;
  423.         }

  424.         /** Get the epoch relative to the covariance matrix.
  425.          * @return the epoch
  426.          */
  427.         public AbsoluteDate getEpoch() {
  428.             return epoch;
  429.         }

  430.         /** Get coordinate system for covariance matrix, for Local Orbital Frames.
  431.          * <p>
  432.          * The value returned is null if the covariance matrix is given in an
  433.          * absolute frame rather than a Local Orbital Frame. In this case, the
  434.          * method {@link #getFrame()} must be used instead.
  435.          * </p>
  436.          * @return the coordinate system for covariance matrix, or null if the
  437.          * covariance matrix is given in an absolute frame rather than a Local
  438.          * Orbital Frame
  439.          */
  440.         public LOFType getLofType() {
  441.             return lofType;
  442.         }

  443.         /** Get coordinate system for covariance matrix, for absolute frames.
  444.          * <p>
  445.          * The value returned is null if the covariance matrix is given in a
  446.          * Local Orbital Frame rather than an absolute frame. In this case, the
  447.          * method {@link #getLofType()} must be used instead.
  448.          * </p>
  449.          * @return the coordinate system for covariance matrix
  450.          */
  451.         public Frame getFrame() {
  452.             return frame;
  453.         }

  454.     }

  455. }