Java tutorial
/* Copyright 2002-2015 CS Systmes d'Information * Licensed to CS Systmes d'Information (CS) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * CS licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.orekit.files.ccsds; import java.util.AbstractList; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.ListIterator; import java.util.Set; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import org.apache.commons.math3.linear.RealMatrix; import org.apache.commons.math3.util.Pair; import org.orekit.errors.OrekitException; import org.orekit.errors.OrekitMessages; import org.orekit.files.general.OrbitFile; import org.orekit.files.general.SatelliteInformation; import org.orekit.files.general.SatelliteTimeCoordinate; import org.orekit.frames.Frame; import org.orekit.frames.LOFType; import org.orekit.orbits.CartesianOrbit; import org.orekit.time.AbsoluteDate; /** This class stocks all the information of the OEM File parsed by OEMParser. It * contains the header and a list of Ephemerides Blocks each containing * metadata, a list of ephemerides data lines and optional covariance matrices * (and their metadata). * @author sports * @since 6.1 */ public class OEMFile extends ODMFile { /** List of ephemeris blocks. */ private List<EphemeridesBlock> ephemeridesBlocks; /** OEMFile constructor. */ public OEMFile() { ephemeridesBlocks = new ArrayList<EphemeridesBlock>(); } /** Add a block to the list of ephemeris blocks. */ void addEphemeridesBlock() { ephemeridesBlocks.add(new EphemeridesBlock()); } /**Get the list of ephemerides blocks as an unmodifiable list. * @return the list of ephemerides blocks */ public List<EphemeridesBlock> getEphemeridesBlocks() { return Collections.unmodifiableList(ephemeridesBlocks); } /** Check that, according to the CCSDS standard, every OEMBlock has the same time system. * @exception OrekitException if some blocks do not have the same time system */ void checkTimeSystems() throws OrekitException { final OrbitFile.TimeSystem timeSystem = getEphemeridesBlocks().get(0).getMetaData().getTimeSystem(); for (final EphemeridesBlock block : ephemeridesBlocks) { if (!timeSystem.equals(block.getMetaData().getTimeSystem())) { throw new OrekitException(OrekitMessages.CCSDS_OEM_INCONSISTENT_TIME_SYSTEMS, timeSystem, block.getMetaData().getTimeSystem()); } } } /** {@inheritDoc} * <p> * We return here only the coordinate systems of the first ephemerides block. * </p> */ @Override public String getCoordinateSystem() { return ephemeridesBlocks.get(0).getMetaData().getFrame().toString(); } /** {@inheritDoc} */ @Override public OrbitFile.TimeSystem getTimeSystem() { return ephemeridesBlocks.get(0).getMetaData().getTimeSystem(); } /** {@inheritDoc} * <p> * We return here only the start time of the first ephemerides block. * </p> */ @Override public AbsoluteDate getEpoch() { return ephemeridesBlocks.get(0).getStartTime(); } /** {@inheritDoc} */ @Override public Collection<SatelliteInformation> getSatellites() { final Set<String> availableSatellites = getAvailableSatelliteIds(); final List<SatelliteInformation> satellites = new ArrayList<SatelliteInformation>( availableSatellites.size()); for (String satId : availableSatellites) { satellites.add(new SatelliteInformation(satId)); } return satellites; } /** {@inheritDoc} */ @Override public int getSatelliteCount() { return getAvailableSatelliteIds().size(); } /** {@inheritDoc} */ @Override public SatelliteInformation getSatellite(final String satId) { final Set<String> availableSatellites = getAvailableSatelliteIds(); if (availableSatellites.contains(satId)) { return new SatelliteInformation(satId); } else { return null; } } /** {@inheritDoc} */ @Override public List<SatelliteTimeCoordinate> getSatelliteCoordinates(final String satId) { // first we collect all available EphemeridesBlocks for this satellite // and return a list view of the actual EphemeridesBlocks transforming the // EphemeridesDataLines into SatelliteTimeCoordinates in a lazy manner. final List<Pair<Integer, Integer>> ephemeridesBlockMapping = new ArrayList<Pair<Integer, Integer>>(); final ListIterator<EphemeridesBlock> it = ephemeridesBlocks.listIterator(); int totalDataLines = 0; while (it.hasNext()) { final int index = it.nextIndex(); final EphemeridesBlock block = it.next(); if (block.getMetaData().getObjectID().equals(satId)) { final int dataLines = block.getEphemeridesDataLines().size(); totalDataLines += dataLines; ephemeridesBlockMapping.add(new Pair<Integer, Integer>(index, dataLines)); } } // the total number of coordinates for this satellite final int totalNumberOfCoordinates = totalDataLines; return new AbstractList<SatelliteTimeCoordinate>() { @Override public SatelliteTimeCoordinate get(final int index) { if (index < 0 || index >= size()) { throw new IndexOutOfBoundsException(); } // find the corresponding ephemerides block and data line int ephemeridesBlockIndex = -1; int dataLineIndex = index; for (Pair<Integer, Integer> pair : ephemeridesBlockMapping) { if (dataLineIndex < pair.getValue()) { ephemeridesBlockIndex = pair.getKey(); break; } else { dataLineIndex -= pair.getValue(); } } if (ephemeridesBlockIndex == -1 || dataLineIndex == -1) { throw new IndexOutOfBoundsException(); } final EphemeridesDataLine dataLine = ephemeridesBlocks.get(ephemeridesBlockIndex) .getEphemeridesDataLines().get(dataLineIndex); final CartesianOrbit orbit = dataLine.getOrbit(); return new SatelliteTimeCoordinate(orbit.getDate(), orbit.getPVCoordinates()); } @Override public int size() { return totalNumberOfCoordinates; } }; } /** Returns a set of all available satellite Ids in this OEMFile. * @return a set of all available satellite Ids */ private Set<String> getAvailableSatelliteIds() { final Set<String> availableSatellites = new LinkedHashSet<String>(); for (EphemeridesBlock block : ephemeridesBlocks) { availableSatellites.add(block.getMetaData().getObjectID()); } return availableSatellites; } /** The Ephemerides Blocks class contain metadata, the list of ephemerides data * lines and optional covariance matrices (and their metadata). The reason * for which the ephemerides have been separated into blocks is that the * ephemerides of two different blocks are not suited for interpolation. * @author sports */ public class EphemeridesBlock { /** Meta-data for the block. */ private ODMMetaData metaData; /** Start of total time span covered by ephemerides data and covariance * data. */ private AbsoluteDate startTime; /** End of total time span covered by ephemerides data and covariance * data. */ private AbsoluteDate stopTime; /** Start of useable time span covered by ephemerides data, it may be * necessary to allow for proper interpolation. */ private AbsoluteDate useableStartTime; /** End of useable time span covered by ephemerides data, it may be * necessary to allow for proper interpolation. */ private AbsoluteDate useableStopTime; /** The interpolation method to be used. */ private String interpolationMethod; /** The interpolation degree. */ private int interpolationDegree; /** List of ephemerides data lines. */ private List<EphemeridesDataLine> ephemeridesDataLines; /** List of covariance matrices. */ private List<CovarianceMatrix> covarianceMatrices; /** Tests whether the reference frame has an epoch associated to it. */ private boolean hasRefFrameEpoch; /** Ephemerides Data Lines comments. The list contains a string for each * line of comment. */ private List<String> ephemeridesDataLinesComment; /** EphemeridesBlock constructor. */ public EphemeridesBlock() { metaData = new ODMMetaData(OEMFile.this); ephemeridesDataLines = new ArrayList<EphemeridesDataLine>(); covarianceMatrices = new ArrayList<CovarianceMatrix>(); } /** Get the list of Ephemerides data lines. * @return the list of Ephemerides data lines */ public List<EphemeridesDataLine> getEphemeridesDataLines() { return ephemeridesDataLines; } /** Get the list of Covariance Matrices. * @return the list of Covariance Matrices */ public List<CovarianceMatrix> getCovarianceMatrices() { return covarianceMatrices; } /** Get the meta-data for the block. * @return meta-data for the block */ public ODMMetaData getMetaData() { return metaData; } /** Get start of total time span covered by ephemerides data and * covariance data. * @return the start time */ public AbsoluteDate getStartTime() { return startTime; } /** Set start of total time span covered by ephemerides data and * covariance data. * @param startTime the time to be set */ void setStartTime(final AbsoluteDate startTime) { this.startTime = startTime; } /** Get end of total time span covered by ephemerides data and covariance * data. * @return the stop time */ public AbsoluteDate getStopTime() { return stopTime; } /** Set end of total time span covered by ephemerides data and covariance * data. * @param stopTime the time to be set */ void setStopTime(final AbsoluteDate stopTime) { this.stopTime = stopTime; } /** Get start of useable time span covered by ephemerides data, it may be * necessary to allow for proper interpolation. * @return the useable start time */ public AbsoluteDate getUseableStartTime() { return useableStartTime; } /** Set start of useable time span covered by ephemerides data, it may be * necessary to allow for proper interpolation. * @param useableStartTime the time to be set */ void setUseableStartTime(final AbsoluteDate useableStartTime) { this.useableStartTime = useableStartTime; } /** Get end of useable time span covered by ephemerides data, it may be * necessary to allow for proper interpolation. * @return the useable stop time */ public AbsoluteDate getUseableStopTime() { return useableStopTime; } /** Set end of useable time span covered by ephemerides data, it may be * necessary to allow for proper interpolation. * @param useableStopTime the time to be set */ void setUseableStopTime(final AbsoluteDate useableStopTime) { this.useableStopTime = useableStopTime; } /** Get the interpolation method to be used. * @return the interpolation method */ public String getInterpolationMethod() { return interpolationMethod; } /** Set the interpolation method to be used. * @param interpolationMethod the interpolation method to be set */ void setInterpolationMethod(final String interpolationMethod) { this.interpolationMethod = interpolationMethod; } /** Get the interpolation degree. * @return the interpolation degree */ public int getInterpolationDegree() { return interpolationDegree; } /** Set the interpolation degree. * @param interpolationDegree the interpolation degree to be set */ void setInterpolationDegree(final int interpolationDegree) { this.interpolationDegree = interpolationDegree; } /** Get boolean testing whether the reference frame has an epoch associated to it. * @return true if the reference frame has an epoch associated to it * false otherwise */ public boolean getHasRefFrameEpoch() { return hasRefFrameEpoch; } /** Set boolean testing whether the reference frame has an epoch associated to it. * @param hasRefFrameEpoch the boolean to be set. */ void setHasRefFrameEpoch(final boolean hasRefFrameEpoch) { this.hasRefFrameEpoch = hasRefFrameEpoch; } /** Get the ephemerides data lines comment. * @return the comment */ public List<String> getEphemeridesDataLinesComment() { return ephemeridesDataLinesComment; } /** Set the ephemerides data lines comment. * @param ephemeridesDataLinesComment the comment to be set */ void setEphemeridesDataLinesComment(final List<String> ephemeridesDataLinesComment) { this.ephemeridesDataLinesComment = new ArrayList<String>(ephemeridesDataLinesComment); } } /** The EphemeridesDataLine class represents the content of an OEM ephemerides * data line and consists of a cartesian orbit and an optional acceleration * vector. * @author sports */ public static class EphemeridesDataLine { /** The cartesian orbit relative to the ephemeris. */ private CartesianOrbit orbit; /** The acceleration vector. */ private Vector3D acceleration; /** The EphemeridesDataLine constructor. * @param orbit the orbit corresponding to the ephemeris * @param acceleration the acceleration vector */ EphemeridesDataLine(final CartesianOrbit orbit, final Vector3D acceleration) { this.acceleration = acceleration; this.orbit = orbit; } /** Get the ephemerides data line orbit. * @return the orbit */ public CartesianOrbit getOrbit() { return orbit; } /** Get the ephemerides data line acceleration vector. * @return the acceleration vector */ public Vector3D getAcceleration() { return acceleration; } } /** The CovarianceMatrix class represents a covariance matrix and its * metadata: epoch and frame. * @author sports */ public static class CovarianceMatrix { /** Covariance matrix. */ private RealMatrix matrix; /** Epoch relative to the covariance matrix. */ private AbsoluteDate epoch; /** Coordinate system for covariance matrix, for Local Orbital Frames. */ private LOFType lofType; /** Coordinate system for covariance matrix, for absolute frames. * If not given it is set equal to refFrame. */ private Frame frame; /** Covariance Matrix constructor. * @param epoch the epoch * @param lofType coordinate system for covariance matrix, for Local Orbital Frames * @param frame coordinate system for covariance matrix, for absolute frames * @param lastMatrix the covariance matrix */ CovarianceMatrix(final AbsoluteDate epoch, final LOFType lofType, final Frame frame, final RealMatrix lastMatrix) { this.matrix = lastMatrix; this.epoch = epoch; this.lofType = lofType; this.frame = frame; } /** Get the covariance matrix. * @return the covariance matrix */ public RealMatrix getMatrix() { return matrix; } /** Get the epoch relative to the covariance matrix. * @return the epoch */ public AbsoluteDate getEpoch() { return epoch; } /** Get coordinate system for covariance matrix, for Local Orbital Frames. * <p> * The value returned is null if the covariance matrix is given in an * absolute frame rather than a Local Orbital Frame. In this case, the * method {@link #getFrame()} must be used instead. * </p> * @return the coordinate system for covariance matrix, or null if the * covariance matrix is given in an absolute frame rather than a Local * Orbital Frame */ public LOFType getLofType() { return lofType; } /** Get coordinate system for covariance matrix, for absolute frames. * <p> * The value returned is null if the covariance matrix is given in a * Local Orbital Frame rather than an absolute frame. In this case, the * method {@link #getLofType()} must be used instead. * </p> * @return the coordinate system for covariance matrix */ public Frame getFrame() { return frame; } } }