OEMFile.java

  1. /* Copyright 2002-2013 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.AbstractList;
  19. import java.util.ArrayList;
  20. import java.util.Collection;
  21. import java.util.Collections;
  22. import java.util.LinkedHashSet;
  23. import java.util.List;
  24. import java.util.ListIterator;
  25. import java.util.Set;

  26. import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
  27. import org.apache.commons.math3.linear.RealMatrix;
  28. import org.apache.commons.math3.util.Pair;
  29. import org.orekit.errors.OrekitException;
  30. import org.orekit.errors.OrekitMessages;
  31. import org.orekit.files.general.OrbitFile;
  32. import org.orekit.files.general.SatelliteInformation;
  33. import org.orekit.files.general.SatelliteTimeCoordinate;
  34. import org.orekit.frames.Frame;
  35. import org.orekit.frames.LOFType;
  36. import org.orekit.orbits.CartesianOrbit;
  37. import org.orekit.time.AbsoluteDate;

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

  46.     /** List of ephemeris blocks. */
  47.     private List<EphemeridesBlock> ephemeridesBlocks;

  48.     /** OEMFile constructor. */
  49.     public OEMFile() {
  50.         ephemeridesBlocks = new ArrayList<EphemeridesBlock>();
  51.     }

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

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

  62.     /** Check that, according to the CCSDS standard, every OEMBlock has the same time system.
  63.      *  @exception OrekitException if some blocks do not have the same time system
  64.      */
  65.     void checkTimeSystems() throws OrekitException {
  66.         final OrbitFile.TimeSystem timeSystem = getEphemeridesBlocks().get(0).getMetaData().getTimeSystem();
  67.         for (final EphemeridesBlock block : ephemeridesBlocks) {
  68.             if (!timeSystem.equals(block.getMetaData().getTimeSystem())) {
  69.                 throw new OrekitException(OrekitMessages.CCSDS_OEM_INCONSISTENT_TIME_SYSTEMS,
  70.                                           timeSystem, block.getMetaData().getTimeSystem());
  71.             }
  72.         }
  73.     }

  74.     /** {@inheritDoc}
  75.      * <p>
  76.      * We return here only the coordinate systems of the first ephemerides block.
  77.      * </p>
  78.      */
  79.     @Override
  80.     public String getCoordinateSystem() {
  81.         return ephemeridesBlocks.get(0).getMetaData().getFrame().toString();
  82.     }

  83.     /** {@inheritDoc} */
  84.     @Override
  85.     public OrbitFile.TimeSystem getTimeSystem() {
  86.         return ephemeridesBlocks.get(0).getMetaData().getTimeSystem();
  87.     }

  88.     /** {@inheritDoc}
  89.      * <p>
  90.      * We return here only the start time of the first ephemerides block.
  91.      * </p>
  92.      */
  93.     @Override
  94.     public AbsoluteDate getEpoch() {
  95.         return ephemeridesBlocks.get(0).getStartTime();
  96.     }

  97.     /** {@inheritDoc} */
  98.     @Override
  99.     public Collection<SatelliteInformation> getSatellites() {
  100.         final Set<String> availableSatellites = getAvailableSatelliteIds();
  101.         final List<SatelliteInformation> satellites =
  102.                 new ArrayList<SatelliteInformation>(availableSatellites.size());
  103.         for (String satId : availableSatellites) {
  104.             satellites.add(new SatelliteInformation(satId));
  105.         }
  106.         return satellites;
  107.     }

  108.     /** {@inheritDoc} */
  109.     @Override
  110.     public int getSatelliteCount() {
  111.         return getAvailableSatelliteIds().size();
  112.     }

  113.     /** {@inheritDoc} */
  114.     @Override
  115.     public SatelliteInformation getSatellite(final String satId) {
  116.         final Set<String> availableSatellites = getAvailableSatelliteIds();
  117.         if (availableSatellites.contains(satId)) {
  118.             return new SatelliteInformation(satId);
  119.         } else {
  120.             return null;
  121.         }
  122.     }

  123.     /** {@inheritDoc} */
  124.     @Override
  125.     public List<SatelliteTimeCoordinate> getSatelliteCoordinates(final String satId) {
  126.         // first we collect all available EphemeridesBlocks for this satellite
  127.         // and return a list view of the actual EphemeridesBlocks transforming the
  128.         // EphemeridesDataLines into SatelliteTimeCoordinates in a lazy manner.
  129.         final List<Pair<Integer, Integer>> ephemeridesBlockMapping = new ArrayList<Pair<Integer, Integer>>();
  130.         final ListIterator<EphemeridesBlock> it = ephemeridesBlocks.listIterator();
  131.         int totalDataLines = 0;
  132.         while (it.hasNext()) {
  133.             final int index = it.nextIndex();
  134.             final EphemeridesBlock block = it.next();

  135.             if (block.getMetaData().getObjectID().equals(satId)) {
  136.                 final int dataLines = block.getEphemeridesDataLines().size();
  137.                 totalDataLines += dataLines;
  138.                 ephemeridesBlockMapping.add(new Pair<Integer, Integer>(index, dataLines));
  139.             }
  140.         }

  141.         // the total number of coordinates for this satellite
  142.         final int totalNumberOfCoordinates = totalDataLines;

  143.         return new AbstractList<SatelliteTimeCoordinate>() {

  144.             @Override
  145.             public SatelliteTimeCoordinate get(final int index) {
  146.                 if (index < 0 || index >= size()) {
  147.                     throw new IndexOutOfBoundsException();
  148.                 }

  149.                 // find the corresponding ephemerides block and data line
  150.                 int ephemeridesBlockIndex = -1;
  151.                 int dataLineIndex = index;
  152.                 for (Pair<Integer, Integer> pair : ephemeridesBlockMapping) {
  153.                     if (dataLineIndex < pair.getValue()) {
  154.                         ephemeridesBlockIndex = pair.getKey();
  155.                         break;
  156.                     } else {
  157.                         dataLineIndex -= pair.getValue();
  158.                     }
  159.                 }

  160.                 if (ephemeridesBlockIndex == -1 || dataLineIndex == -1) {
  161.                     throw new IndexOutOfBoundsException();
  162.                 }

  163.                 final EphemeridesDataLine dataLine =
  164.                         ephemeridesBlocks.get(ephemeridesBlockIndex).getEphemeridesDataLines().get(dataLineIndex);
  165.                 final CartesianOrbit orbit = dataLine.getOrbit();
  166.                 return new SatelliteTimeCoordinate(orbit.getDate(), orbit.getPVCoordinates());
  167.             }

  168.             @Override
  169.             public int size() {
  170.                 return totalNumberOfCoordinates;
  171.             }

  172.         };
  173.     }

  174.     /** Returns a set of all available satellite Ids in this OEMFile.
  175.      * @return a set of all available satellite Ids
  176.      */
  177.     private Set<String> getAvailableSatelliteIds() {
  178.         final Set<String> availableSatellites = new LinkedHashSet<String>();
  179.         for (EphemeridesBlock block : ephemeridesBlocks) {
  180.             availableSatellites.add(block.getMetaData().getObjectID());
  181.         }
  182.         return availableSatellites;
  183.     }

  184.     /** The Ephemerides Blocks class contain metadata, the list of ephemerides data
  185.      * lines and optional covariance matrices (and their metadata). The reason
  186.      * for which the ephemerides have been separated into blocks is that the
  187.      * ephemerides of two different blocks are not suited for interpolation.
  188.      * @author sports
  189.      */
  190.     public class EphemeridesBlock {

  191.         /** Meta-data for the block. */
  192.         private ODMMetaData metaData;

  193.         /** Start of total time span covered by ephemerides data and covariance
  194.          * data. */
  195.         private AbsoluteDate startTime;

  196.         /** End of total time span covered by ephemerides data and covariance
  197.          * data. */
  198.         private AbsoluteDate stopTime;

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

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

  205.         /** The interpolation method to be used. */
  206.         private String interpolationMethod;

  207.         /** The interpolation degree. */
  208.         private int interpolationDegree;

  209.         /** List of ephemerides data lines. */
  210.         private List<EphemeridesDataLine> ephemeridesDataLines;

  211.         /** List of covariance matrices. */
  212.         private List<CovarianceMatrix> covarianceMatrices;

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

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

  218.         /** EphemeridesBlock constructor. */
  219.         public EphemeridesBlock() {
  220.             metaData = new ODMMetaData(OEMFile.this);
  221.             ephemeridesDataLines = new ArrayList<EphemeridesDataLine>();
  222.             covarianceMatrices = new ArrayList<CovarianceMatrix>();
  223.         }

  224.         /** Get the list of Ephemerides data lines.
  225.          * @return the list of Ephemerides data lines
  226.          */
  227.         public List<EphemeridesDataLine> getEphemeridesDataLines() {
  228.             return ephemeridesDataLines;
  229.         }

  230.         /** Get the list of Covariance Matrices.
  231.          * @return the list of Covariance Matrices
  232.          */
  233.         public List<CovarianceMatrix> getCovarianceMatrices() {
  234.             return covarianceMatrices;
  235.         }

  236.         /** Get the meta-data for the block.
  237.          * @return meta-data for the block
  238.          */
  239.         public ODMMetaData getMetaData() {
  240.             return metaData;
  241.         }

  242.         /** Get start of total time span covered by ephemerides data and
  243.          * covariance data.
  244.          * @return the start time
  245.          */
  246.         public AbsoluteDate getStartTime() {
  247.             return startTime;
  248.         }

  249.         /** Set start of total time span covered by ephemerides data and
  250.          * covariance data.
  251.          * @param startTime the time to be set
  252.          */
  253.         void setStartTime(final AbsoluteDate startTime) {
  254.             this.startTime = startTime;
  255.         }

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

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

  270.         /** Get start of useable time span covered by ephemerides data, it may be
  271.          * necessary to allow for proper interpolation.
  272.          * @return the useable start time
  273.          */
  274.         public AbsoluteDate getUseableStartTime() {
  275.             return useableStartTime;
  276.         }

  277.         /** Set start of useable time span covered by ephemerides data, it may be
  278.          * necessary to allow for proper interpolation.
  279.          * @param useableStartTime the time to be set
  280.          */
  281.         void setUseableStartTime(final AbsoluteDate useableStartTime) {
  282.             this.useableStartTime = useableStartTime;
  283.         }

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

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

  298.         /** Get the interpolation method to be used.
  299.          * @return the interpolation method
  300.          */
  301.         public String getInterpolationMethod() {
  302.             return interpolationMethod;
  303.         }

  304.         /** Set the interpolation method to be used.
  305.          * @param interpolationMethod the interpolation method to be set
  306.          */
  307.         void setInterpolationMethod(final String interpolationMethod) {
  308.             this.interpolationMethod = interpolationMethod;
  309.         }

  310.         /** Get the interpolation degree.
  311.          * @return the interpolation degree
  312.          */
  313.         public int getInterpolationDegree() {
  314.             return interpolationDegree;
  315.         }

  316.         /** Set the interpolation degree.
  317.          * @param interpolationDegree the interpolation degree to be set
  318.          */
  319.         void setInterpolationDegree(final int interpolationDegree) {
  320.             this.interpolationDegree = interpolationDegree;
  321.         }

  322.         /** Get boolean testing whether the reference frame has an epoch associated to it.
  323.          * @return true if the reference frame has an epoch associated to it
  324.          *         false otherwise
  325.          */
  326.         public boolean getHasRefFrameEpoch() {
  327.             return hasRefFrameEpoch;
  328.         }

  329.         /** Set boolean testing whether the reference frame has an epoch associated to it.
  330.          * @param hasRefFrameEpoch the boolean to be set.
  331.          */
  332.         void setHasRefFrameEpoch(final boolean hasRefFrameEpoch) {
  333.             this.hasRefFrameEpoch = hasRefFrameEpoch;
  334.         }

  335.         /** Get the ephemerides data lines comment.
  336.          * @return the comment
  337.          */
  338.         public List<String> getEphemeridesDataLinesComment() {
  339.             return ephemeridesDataLinesComment;
  340.         }

  341.         /** Set the ephemerides data lines comment.
  342.          * @param ephemeridesDataLinesComment the comment to be set
  343.          */
  344.         void setEphemeridesDataLinesComment(final List<String> ephemeridesDataLinesComment) {
  345.             this.ephemeridesDataLinesComment = new ArrayList<String>(ephemeridesDataLinesComment);
  346.         }
  347.     }

  348.     /** The EphemeridesDataLine class represents the content of an OEM ephemerides
  349.      * data line and consists of a cartesian orbit and an optional acceleration
  350.      * vector.
  351.      * @author sports
  352.      */
  353.     public static class EphemeridesDataLine {

  354.         /** The cartesian orbit relative to the ephemeris. */
  355.         private CartesianOrbit orbit;

  356.         /** The acceleration vector. */
  357.         private Vector3D acceleration;

  358.         /** The EphemeridesDataLine constructor.
  359.          * @param orbit the orbit corresponding to the ephemeris
  360.          * @param acceleration the acceleration vector
  361.          */
  362.         EphemeridesDataLine(final CartesianOrbit orbit, final Vector3D acceleration) {
  363.             this.acceleration = acceleration;
  364.             this.orbit = orbit;
  365.         }

  366.         /** Get the ephemerides data line orbit.
  367.          * @return the orbit
  368.          */
  369.         public CartesianOrbit getOrbit() {
  370.             return orbit;
  371.         }

  372.         /** Get the ephemerides data line acceleration vector.
  373.          * @return the acceleration vector
  374.          */
  375.         public Vector3D getAcceleration() {
  376.             return acceleration;
  377.         }

  378.     }

  379.     /** The CovarianceMatrix class represents a covariance matrix and its
  380.      * metadata: epoch and frame.
  381.      * @author sports
  382.      */
  383.     public static class CovarianceMatrix {

  384.         /** Covariance matrix. */
  385.         private RealMatrix matrix;

  386.         /** Epoch relative to the covariance matrix. */
  387.         private AbsoluteDate epoch;

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

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

  393.         /** Covariance Matrix constructor.
  394.          * @param epoch the epoch
  395.          * @param lofType coordinate system for covariance matrix, for Local Orbital Frames
  396.          * @param frame coordinate system for covariance matrix, for absolute frames
  397.          * @param lastMatrix the covariance matrix
  398.          */
  399.         CovarianceMatrix(final AbsoluteDate epoch,
  400.                          final LOFType lofType, final Frame frame,
  401.                          final RealMatrix lastMatrix) {
  402.             this.matrix  = lastMatrix;
  403.             this.epoch   = epoch;
  404.             this.lofType = lofType;
  405.             this.frame   = frame;
  406.         }

  407.         /** Get the covariance matrix.
  408.          * @return the covariance matrix
  409.          */
  410.         public RealMatrix getMatrix() {
  411.             return matrix;
  412.         }

  413.         /** Get the epoch relative to the covariance matrix.
  414.          * @return the epoch
  415.          */
  416.         public AbsoluteDate getEpoch() {
  417.             return epoch;
  418.         }

  419.         /** Get coordinate system for covariance matrix, for Local Orbital Frames.
  420.          * <p>
  421.          * The value returned is null if the covariance matrix is given in an
  422.          * absolute frame rather than a Local Orbital Frame. In this case, the
  423.          * method {@link #getFrame()} must be used instead.
  424.          * </p>
  425.          * @return the coordinate system for covariance matrix, or null if the
  426.          * covariance matrix is given in an absolute frame rather than a Local
  427.          * Orbital Frame
  428.          */
  429.         public LOFType getLofType() {
  430.             return lofType;
  431.         }

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

  443.     }


  444. }