OEMFile.java

  1. /* Copyright 2002-2018 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.      *  @exception OrekitException if some blocks do not have the same time system
  61.      */
  62.     void checkTimeSystems() throws OrekitException {
  63.         final CcsdsTimeScale timeSystem = getEphemeridesBlocks().get(0).getMetaData().getTimeSystem();
  64.         for (final EphemeridesBlock block : ephemeridesBlocks) {
  65.             if (!timeSystem.equals(block.getMetaData().getTimeSystem())) {
  66.                 throw new OrekitException(OrekitMessages.CCSDS_OEM_INCONSISTENT_TIME_SYSTEMS,
  67.                                           timeSystem, block.getMetaData().getTimeSystem());
  68.             }
  69.         }
  70.     }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  319.     }

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

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

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

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

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

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

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

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

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

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

  384.     }

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

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

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

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

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

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

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

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

  429.     }

  430. }