CPF.java

  1. /* Copyright 2002-2025 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.ilrs;

  18. import java.util.ArrayList;
  19. import java.util.Collections;
  20. import java.util.List;
  21. import java.util.Map;
  22. import java.util.concurrent.ConcurrentHashMap;

  23. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  24. import org.orekit.attitudes.AttitudeProvider;
  25. import org.orekit.files.general.EphemerisFile;
  26. import org.orekit.frames.Frame;
  27. import org.orekit.propagation.BoundedPropagator;
  28. import org.orekit.time.AbsoluteDate;
  29. import org.orekit.time.TimeScale;
  30. import org.orekit.utils.CartesianDerivativesFilter;
  31. import org.orekit.utils.TimeStampedPVCoordinates;

  32. /**
  33.  * This class stores all the information of the Consolidated laser ranging Prediction File (CPF) parsed
  34.  * by CPFParser. It contains the header and a list of ephemeris entry.
  35.  * @author Bryan Cazabonne
  36.  * @since 10.3
  37.  */
  38. public class CPF implements EphemerisFile<CPF.CPFCoordinate, CPF.CPFEphemeris> {

  39.     /** Default satellite ID, used if header is null when initializing the ephemeris. */
  40.     public static final String DEFAULT_ID = "9999999";

  41.     /** Gravitational coefficient. */
  42.     private double mu;

  43.     /** The interpolation sample. */
  44.     private int interpolationSample;

  45.     /** Time scale of dates in the ephemeris file. */
  46.     private TimeScale timeScale;

  47.     /** Indicates if data contains velocity or not. */
  48.     private CartesianDerivativesFilter filter;

  49.     /** CPF file header. */
  50.     private final CPFHeader header;

  51.     /** Map containing satellite information. */
  52.     private final Map<String, CPFEphemeris> ephemeris;

  53.     /** List of comments contained in the file. */
  54.     private final List<String> comments;

  55.     /**
  56.      * Constructor.
  57.      */
  58.     public CPF() {
  59.         this.mu        = Double.NaN;
  60.         this.ephemeris = new ConcurrentHashMap<>();
  61.         this.header    = new CPFHeader();
  62.         this.comments  = new ArrayList<>();
  63.     }

  64.     /** {@inheritDoc}
  65.      * First key corresponds to String value of {@link CPFHeader#getIlrsSatelliteId()}
  66.      */
  67.     @Override
  68.     public Map<String, CPFEphemeris> getSatellites() {
  69.         // Return the map
  70.         return Collections.unmodifiableMap(ephemeris);
  71.     }

  72.     /**
  73.      * Get the CPF file header.
  74.      * @return the CPF file header
  75.      */
  76.     public CPFHeader getHeader() {
  77.         return header;
  78.     }

  79.     /**
  80.      * Get the time scale used in CPF file.
  81.      * @return the time scale used to parse epochs in CPF file.
  82.      */
  83.     public TimeScale getTimeScale() {
  84.         return timeScale;
  85.     }

  86.     /**
  87.      * Get the comments contained in the file.
  88.      * @return the comments contained in the file
  89.      */
  90.     public List<String> getComments() {
  91.         return comments;
  92.     }

  93.     /**
  94.      * Adds a set of P/V coordinates to the satellite.
  95.      * @param id satellite ILRS identifier
  96.      * @param coord set of coordinates
  97.      * @since 11.0.1
  98.      */
  99.     public void addSatelliteCoordinates(final String id, final List<CPFCoordinate> coord) {
  100.         final CPFEphemeris e;
  101.         synchronized (this) {
  102.             e = ephemeris.computeIfAbsent(id, CPFEphemeris::new);
  103.         }
  104.         e.coordinates.addAll(coord);
  105.     }

  106.     /**
  107.      * Add a new P/V coordinates to the satellite.
  108.      * @param id satellite ILRS identifier
  109.      * @param coord the P/V coordinate of the satellite
  110.      * @since 11.0.1
  111.      */
  112.     public void addSatelliteCoordinate(final String id, final CPFCoordinate coord) {
  113.         final CPFEphemeris e;
  114.         synchronized (this) {
  115.             e = ephemeris.computeIfAbsent(id, CPFEphemeris::new);
  116.         }
  117.         e.coordinates.add(coord);
  118.     }

  119.     /**
  120.      * Add the velocity to the last CPF coordinate entry.
  121.      * @param id satellite ILRS identifier
  122.      * @param velocity the velocity vector of the satellite
  123.      * @since 11.2
  124.      */
  125.     public void addSatelliteVelocityToCPFCoordinate(final String id, final Vector3D velocity) {
  126.         // Get the last coordinate entry, which contains the position vector
  127.         final CPFCoordinate lastCoordinate = ephemeris.get(id).coordinates.get(ephemeris.get(id).coordinates.size() - 1);

  128.         // Create a new CPFCoordinate object with both position and velocity information
  129.         final CPFCoordinate CPFCoordUpdated = new CPFCoordinate(lastCoordinate.getDate(),
  130.                 lastCoordinate.getPosition(),
  131.                 velocity,
  132.                 lastCoordinate.getLeap());

  133.         // Patch the last record
  134.         ephemeris.get(id).coordinates.set(ephemeris.get(id).coordinates.size() - 1, CPFCoordUpdated);
  135.     }

  136.     /**
  137.      * Set the interpolation sample.
  138.      * @param interpolationSample interpolation sample
  139.      */
  140.     public void setInterpolationSample(final int interpolationSample) {
  141.         this.interpolationSample = interpolationSample;
  142.     }

  143.     /**
  144.      * Set the gravitational coefficient.
  145.      * @param mu the coefficient to be set
  146.      */
  147.     public void setMu(final double mu) {
  148.         this.mu = mu;
  149.     }

  150.     /**
  151.      * Set the time scale.
  152.      * @param timeScale use to parse dates in this file.
  153.      */
  154.     public void setTimeScale(final TimeScale timeScale) {
  155.         this.timeScale = timeScale;
  156.     }

  157.     /**
  158.      * Set the derivatives filter.
  159.      * @param filter that indicates which derivatives of position are available.
  160.      */
  161.     public void setFilter(final CartesianDerivativesFilter filter) {
  162.         this.filter = filter;
  163.     }

  164.     /** An ephemeris entry  for a single satellite contains in a CPF file. */
  165.     public class CPFEphemeris
  166.         implements EphemerisFile.SatelliteEphemeris<CPFCoordinate, CPFEphemeris>,
  167.                    EphemerisFile.EphemerisSegment<CPFCoordinate> {

  168.         /** Satellite ID. */
  169.         private final String id;

  170.         /** Ephemeris Data. */
  171.         private final List<CPFCoordinate> coordinates;

  172.         /**
  173.          * Constructor.
  174.          * @param id satellite ID
  175.          */
  176.         public CPFEphemeris(final String id) {
  177.             this.id          = id;
  178.             this.coordinates = new ArrayList<>();
  179.         }


  180.         /** {@inheritDoc} */
  181.         @Override
  182.         public Frame getFrame() {
  183.             return header.getRefFrame();
  184.         }

  185.         /** {@inheritDoc} */
  186.         @Override
  187.         public int getInterpolationSamples() {
  188.             return interpolationSample;
  189.         }

  190.         /** {@inheritDoc} */
  191.         @Override
  192.         public CartesianDerivativesFilter getAvailableDerivatives() {
  193.             return filter;
  194.         }

  195.         /** {@inheritDoc} */
  196.         @Override
  197.         public List<CPFCoordinate> getCoordinates() {
  198.             return Collections.unmodifiableList(this.coordinates);
  199.         }

  200.         /** {@inheritDoc} */
  201.         @Override
  202.         public String getId() {
  203.             return id == null ? DEFAULT_ID : id;
  204.         }

  205.         /** {@inheritDoc} */
  206.         @Override
  207.         public double getMu() {
  208.             return mu;
  209.         }

  210.         /** Returns a list containing only {@code this}. */
  211.         @Override
  212.         public List<CPFEphemeris> getSegments() {
  213.             return Collections.singletonList(this);
  214.         }

  215.         /** {@inheritDoc} */
  216.         @Override
  217.         public AbsoluteDate getStart() {
  218.             return coordinates.get(0).getDate();
  219.         }

  220.         /** {@inheritDoc} */
  221.         @Override
  222.         public AbsoluteDate getStop() {
  223.             return coordinates.get(coordinates.size() - 1).getDate();
  224.         }

  225.         /** {@inheritDoc} */
  226.         @Override
  227.         public BoundedPropagator getPropagator() {
  228.             return EphemerisSegment.super.getPropagator();
  229.         }

  230.         /** {@inheritDoc} */
  231.         @Override
  232.         public BoundedPropagator getPropagator(final AttitudeProvider attitudeProvider) {
  233.             return EphemerisSegment.super.getPropagator(attitudeProvider);
  234.         }

  235.         /** Get the list of Ephemerides data lines.
  236.          * @return a reference to the internal list of Ephemerides data lines
  237.          */
  238.         public List<CPFCoordinate> getEphemeridesDataLines() {
  239.             return this.coordinates;
  240.         }

  241.     }

  242.     /** A single record of position and possibility velocity in an SP3 file. */
  243.     public static class CPFCoordinate extends TimeStampedPVCoordinates {

  244.         /** Leap second flag. */
  245.         private final int leap;

  246.         /**
  247.          * Constructor with null velocity vector.
  248.          * @param date date of coordinates validity
  249.          * @param position position vector
  250.          * @param leap leap second flag (= 0 or the value of the new leap second)
  251.          */
  252.         public CPFCoordinate(final AbsoluteDate date,
  253.                              final Vector3D position,
  254.                              final int leap) {
  255.             this(date, position, Vector3D.ZERO, leap);
  256.         }

  257.         /**
  258.          * Constructor.
  259.          * @param date date of coordinates validity
  260.          * @param position position vector
  261.          * @param velocity velocity vector
  262.          * @param leap leap second flag (= 0 or the value of the new leap second)
  263.          */
  264.         public CPFCoordinate(final AbsoluteDate date,
  265.                              final Vector3D position,
  266.                              final Vector3D velocity,
  267.                              final int leap) {
  268.             super(date, position, velocity);
  269.             this.leap = leap;
  270.         }

  271.         /**
  272.          * Get the leap second flag (= 0 or the value of the new leap second).
  273.          * @return the leap second flag
  274.          */
  275.         public int getLeap() {
  276.             return leap;
  277.         }

  278.     }

  279. }