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.     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 Frame getInertialFrame() {
  182.             final Frame frame = getFrame();
  183.             if (frame.isPseudoInertial()) {
  184.                 return frame;
  185.             }
  186.             return metaData.getODMFile().getDataContext().getFrames().getGCRF();
  187.         }

  188.         @Override
  189.         public String getTimeScaleString() {
  190.             return this.getMetaData().getTimeSystem().toString();
  191.         }

  192.         @Override
  193.         public TimeScale getTimeScale() {
  194.             return this.getMetaData().getTimeScale();
  195.         }

  196.         /** Get start of total time span covered by ephemerides data and
  197.          * covariance data.
  198.          * @return the start time
  199.          */
  200.         public AbsoluteDate getStartTime() {
  201.             return startTime;
  202.         }

  203.         /** Set start of total time span covered by ephemerides data and
  204.          * covariance data.
  205.          * @param startTime the time to be set
  206.          */
  207.         void setStartTime(final AbsoluteDate startTime) {
  208.             this.startTime = startTime;
  209.         }

  210.         /** Get end of total time span covered by ephemerides data and covariance
  211.          * data.
  212.          * @return the stop time
  213.          */
  214.         public AbsoluteDate getStopTime() {
  215.             return stopTime;
  216.         }

  217.         /** Set end of total time span covered by ephemerides data and covariance
  218.          * data.
  219.          * @param stopTime the time to be set
  220.          */
  221.         void setStopTime(final AbsoluteDate stopTime) {
  222.             this.stopTime = stopTime;
  223.         }

  224.         /** Get start of useable time span covered by ephemerides data, it may be
  225.          * necessary to allow for proper interpolation.
  226.          * @return the useable start time
  227.          */
  228.         public AbsoluteDate getUseableStartTime() {
  229.             return useableStartTime;
  230.         }

  231.         /** Set start of useable time span covered by ephemerides data, it may be
  232.          * necessary to allow for proper interpolation.
  233.          * @param useableStartTime the time to be set
  234.          */
  235.         void setUseableStartTime(final AbsoluteDate useableStartTime) {
  236.             this.useableStartTime = useableStartTime;
  237.         }

  238.         /** Get end of useable time span covered by ephemerides data, it may be
  239.          * necessary to allow for proper interpolation.
  240.          * @return the useable stop time
  241.          */
  242.         public AbsoluteDate getUseableStopTime() {
  243.             return useableStopTime;
  244.         }

  245.         /** Set end of useable time span covered by ephemerides data, it may be
  246.          * necessary to allow for proper interpolation.
  247.          * @param useableStopTime the time to be set
  248.          */
  249.         void setUseableStopTime(final AbsoluteDate useableStopTime) {
  250.             this.useableStopTime = useableStopTime;
  251.         }

  252.         @Override
  253.         public AbsoluteDate getStart() {
  254.             // usable start time overrides start time if it is set
  255.             final AbsoluteDate start = this.getUseableStartTime();
  256.             if (start != null) {
  257.                 return start;
  258.             } else {
  259.                 return this.getStartTime();
  260.             }
  261.         }

  262.         @Override
  263.         public AbsoluteDate getStop() {
  264.             // useable stop time overrides stop time if it is set
  265.             final AbsoluteDate stop = this.getUseableStopTime();
  266.             if (stop != null) {
  267.                 return stop;
  268.             } else {
  269.                 return this.getStopTime();
  270.             }
  271.         }

  272.         /** Get the interpolation method to be used.
  273.          * @return the interpolation method
  274.          */
  275.         public String getInterpolationMethod() {
  276.             return interpolationMethod;
  277.         }

  278.         /** Set the interpolation method to be used.
  279.          * @param interpolationMethod the interpolation method to be set
  280.          */
  281.         void setInterpolationMethod(final String interpolationMethod) {
  282.             this.interpolationMethod = interpolationMethod;
  283.         }

  284.         /** Get the interpolation degree.
  285.          * @return the interpolation degree
  286.          */
  287.         public int getInterpolationDegree() {
  288.             return interpolationDegree;
  289.         }

  290.         /** Set the interpolation degree.
  291.          * @param interpolationDegree the interpolation degree to be set
  292.          */
  293.         void setInterpolationDegree(final int interpolationDegree) {
  294.             this.interpolationDegree = interpolationDegree;
  295.         }

  296.         @Override
  297.         public int getInterpolationSamples() {
  298.             // From the standard it is not entirely clear how to interpret the degree.
  299.             return getInterpolationDegree() + 1;
  300.         }

  301.         /** Get boolean testing whether the reference frame has an epoch associated to it.
  302.          * @return true if the reference frame has an epoch associated to it
  303.          *         false otherwise
  304.          */
  305.         public boolean getHasRefFrameEpoch() {
  306.             return hasRefFrameEpoch;
  307.         }

  308.         /** Set boolean testing whether the reference frame has an epoch associated to it.
  309.          * @param hasRefFrameEpoch the boolean to be set.
  310.          */
  311.         void setHasRefFrameEpoch(final boolean hasRefFrameEpoch) {
  312.             this.hasRefFrameEpoch = hasRefFrameEpoch;
  313.         }

  314.         /** Get the ephemerides data lines comment.
  315.          * @return the comment
  316.          */
  317.         public List<String> getEphemeridesDataLinesComment() {
  318.             return ephemeridesDataLinesComment;
  319.         }

  320.         /** Set the ephemerides data lines comment.
  321.          * @param ephemeridesDataLinesComment the comment to be set
  322.          */
  323.         void setEphemeridesDataLinesComment(final List<String> ephemeridesDataLinesComment) {
  324.             this.ephemeridesDataLinesComment = new ArrayList<String>(ephemeridesDataLinesComment);
  325.         }

  326.     }

  327.     /** The CovarianceMatrix class represents a covariance matrix and its
  328.      * metadata: epoch and frame.
  329.      * @author sports
  330.      */
  331.     public static class CovarianceMatrix {

  332.         /** Covariance matrix. */
  333.         private RealMatrix matrix;

  334.         /** Epoch relative to the covariance matrix. */
  335.         private AbsoluteDate epoch;

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

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

  341.         /** Covariance Matrix constructor.
  342.          * @param epoch the epoch
  343.          * @param lofType coordinate system for covariance matrix, for Local Orbital Frames
  344.          * @param frame coordinate system for covariance matrix, for absolute frames
  345.          * @param lastMatrix the covariance matrix
  346.          */
  347.         CovarianceMatrix(final AbsoluteDate epoch,
  348.                          final LOFType lofType, final Frame frame,
  349.                          final RealMatrix lastMatrix) {
  350.             this.matrix  = lastMatrix;
  351.             this.epoch   = epoch;
  352.             this.lofType = lofType;
  353.             this.frame   = frame;
  354.         }

  355.         /** Get the covariance matrix.
  356.          * @return the covariance matrix
  357.          */
  358.         public RealMatrix getMatrix() {
  359.             return matrix;
  360.         }

  361.         /** Get the epoch relative to the covariance matrix.
  362.          * @return the epoch
  363.          */
  364.         public AbsoluteDate getEpoch() {
  365.             return epoch;
  366.         }

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

  380.         /** Get coordinate system for covariance matrix, for absolute frames.
  381.          * <p>
  382.          * The value returned is null if the covariance matrix is given in a
  383.          * Local Orbital Frame rather than an absolute frame. In this case, the
  384.          * method {@link #getLofType()} must be used instead.
  385.          * </p>
  386.          * @return the coordinate system for covariance matrix
  387.          */
  388.         public Frame getFrame() {
  389.             return frame;
  390.         }

  391.     }

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

  394.         /** ID of the satellite. */
  395.         private final String id;
  396.         /** Gravitational prameter for the satellite, in m^3 / s^2. */
  397.         private final double mu;
  398.         /** The ephemeris data for the satellite. */
  399.         private final List<EphemeridesBlock> blocks;

  400.         /**
  401.          * Create a container for the set of ephemeris blocks in the file that pertain to
  402.          * a single satellite.
  403.          *
  404.          * @param id     of the satellite.
  405.          * @param mu     standard gravitational parameter used to create orbits for the
  406.          *               satellite, in m^3 / s^2.
  407.          * @param blocks containing ephemeris data for the satellite.
  408.          */
  409.         OemSatelliteEphemeris(final String id,
  410.                               final double mu,
  411.                               final List<EphemeridesBlock> blocks) {
  412.             this.id = id;
  413.             this.mu = mu;
  414.             this.blocks = blocks;
  415.         }

  416.         @Override
  417.         public String getId() {
  418.             return this.id;
  419.         }

  420.         @Override
  421.         public double getMu() {
  422.             return this.mu;
  423.         }

  424.         @Override
  425.         public List<EphemeridesBlock> getSegments() {
  426.             return Collections.unmodifiableList(blocks);
  427.         }

  428.         @Override
  429.         public AbsoluteDate getStart() {
  430.             return blocks.get(0).getStart();
  431.         }

  432.         @Override
  433.         public AbsoluteDate getStop() {
  434.             return blocks.get(blocks.size() - 1).getStop();
  435.         }

  436.     }

  437. }