EstimatedMeasurement.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.estimation.measurements;

  18. import java.util.IdentityHashMap;
  19. import java.util.Map;
  20. import java.util.stream.Stream;

  21. import org.orekit.errors.OrekitIllegalArgumentException;
  22. import org.orekit.errors.OrekitMessages;
  23. import org.orekit.propagation.SpacecraftState;
  24. import org.orekit.time.AbsoluteDate;
  25. import org.orekit.utils.ParameterDriver;
  26. import org.orekit.utils.TimeStampedPVCoordinates;

  27. /** Class holding an estimated theoretical value associated to an {@link ObservedMeasurement observed measurement}.
  28.  * @param <T> the type of the measurement
  29.  * @author Luc Maisonobe
  30.  * @since 8.0
  31.  */
  32. public class EstimatedMeasurement<T extends ObservedMeasurement<T>> implements ComparableMeasurement {

  33.     /** Associated observed measurement. */
  34.     private final T observedMeasurement;

  35.     /** Iteration number. */
  36.     private final int iteration;

  37.     /** Evaluations counter. */
  38.     private final int count;

  39.     /** States of the spacecrafts. */
  40.     private final SpacecraftState[] states;

  41.     /** Coordinates of the participants in signal travel order. */
  42.     private final TimeStampedPVCoordinates[] participants;

  43.     /** Estimated value. */
  44.     private double[] estimatedValue;

  45.     /** Current weight.
  46.      * @deprecated as of 9.2, weight should not be changed anymore,
  47.      * rejected measurements are identified by their {@link #getStatus() status}
  48.      */
  49.     @Deprecated
  50.     private double[] currentWeight;

  51.     /** Measurement status. */
  52.     private Status status;

  53.     /** Partial derivatives with respect to states. */
  54.     private double[][][] stateDerivatives;

  55.     /** Partial derivatives with respect to parameters. */
  56.     private final Map<ParameterDriver, double[]> parametersDerivatives;

  57.     /** Simple constructor.
  58.      * @param observedMeasurement associated observed measurement
  59.      * @param iteration iteration number
  60.      * @param count evaluations counter
  61.      * @param states states of the spacecrafts
  62.      * @param participants coordinates of the participants in signal travel order
  63.      * in inertial frame
  64.      */
  65.     public EstimatedMeasurement(final T observedMeasurement,
  66.                                 final int iteration, final int count,
  67.                                 final SpacecraftState[] states,
  68.                                 final TimeStampedPVCoordinates[] participants) {
  69.         this.observedMeasurement   = observedMeasurement;
  70.         this.iteration             = iteration;
  71.         this.count                 = count;
  72.         this.states                = states.clone();
  73.         this.participants          = participants.clone();
  74.         this.status                = Status.PROCESSED;
  75.         this.stateDerivatives      = new double[states.length][][];
  76.         this.parametersDerivatives = new IdentityHashMap<ParameterDriver, double[]>();
  77.     }

  78.     /** Get the associated observed measurement.
  79.      * @return associated observed measurement
  80.      */
  81.     public T getObservedMeasurement() {
  82.         return observedMeasurement;
  83.     }

  84.     /** {@inheritDoc} */
  85.     @Override
  86.     public AbsoluteDate getDate() {
  87.         return observedMeasurement.getDate();
  88.     }

  89.     /** Get the iteration number.
  90.      * @return iteration number
  91.      */
  92.     public int getIteration() {
  93.         return iteration;
  94.     }

  95.     /** Get the evaluations counter.
  96.      * @return evaluations counter
  97.      */
  98.     public int getCount() {
  99.         return count;
  100.     }

  101.     /** Get the states of the spacecrafts.
  102.      * @return states of the spacecrafts
  103.      */
  104.     public SpacecraftState[] getStates() {
  105.         return states.clone();
  106.     }

  107.     /** Get the coordinates of the measurements participants in signal travel order.
  108.      * <p>
  109.      * First participant (at index 0) emits the signal (it is for example a ground
  110.      * station for two-way range measurement). Last participant receives the signal
  111.      * (it is also the ground station for two-way range measurement, but a few
  112.      * milliseconds later). Intermediate participants relfect the signal (it is the
  113.      * spacecraft for two-way range measurement).
  114.      * </p>
  115.      * @return coordinates of the measurements participants in signal travel order
  116.      * in inertial frame
  117.      */
  118.     public TimeStampedPVCoordinates[] getParticipants() {
  119.         return participants.clone();
  120.     }

  121.     /** Get the time offset from first state date to measurement date.
  122.      * @return time offset from first state date to measurement date
  123.      */
  124.     public double getTimeOffset() {
  125.         return observedMeasurement.getDate().durationFrom(states[0].getDate());
  126.     }

  127.     /** {@inheritDoc} */
  128.     @Override
  129.     public double[] getObservedValue() {
  130.         return observedMeasurement.getObservedValue();
  131.     }

  132.     /** Get the estimated value.
  133.      * @return estimated value
  134.      */
  135.     public double[] getEstimatedValue() {
  136.         return estimatedValue.clone();
  137.     }

  138.     /** Set the estimated value.
  139.      * @param estimatedValue estimated value
  140.      */
  141.     public void setEstimatedValue(final double... estimatedValue) {
  142.         this.estimatedValue = estimatedValue.clone();
  143.     }

  144.     /** Get the current weight.
  145.      * <p>
  146.      * By default, the current weight is measurement {@link
  147.      * ObservedMeasurement#getBaseWeight() base weight}.
  148.      * </p>
  149.      * @return current weight
  150.      * @deprecated as of 9.2, weight should not be changed anymore,
  151.      * rejected measurements are identified by their {@link #getStatus() status}
  152.      */
  153.     @Deprecated
  154.     public double[] getCurrentWeight() {
  155.         return currentWeight == null ? observedMeasurement.getBaseWeight() : currentWeight.clone();
  156.     }

  157.     /** Set the current weight.
  158.      * @param currentWeight current weight
  159.      * @deprecated as of 9.2, weight should not be changed anymore,
  160.      * rejected measurements are identified by their {@link #getStatus() status}
  161.      */
  162.     @Deprecated
  163.     public void setCurrentWeight(final double... currentWeight) {
  164.         this.currentWeight = currentWeight.clone();
  165.     }

  166.     /** Get the status.
  167.      * <p>
  168.      * The status is set to {@link Status#PROCESSED PROCESSED} at construction, and
  169.      * can be reset to {@link Status#REJECTED REJECTED} later on, typically by
  170.      * {@link org.orekit.estimation.measurements.modifiers.OutlierFilter OutlierFilter}
  171.      * or {@link org.orekit.estimation.measurements.modifiers.DynamicOutlierFilter DynamicOutlierFilter}
  172.      * </p>
  173.      * @return status
  174.      */
  175.     public Status getStatus() {
  176.         return status;
  177.     }

  178.     /** Set the status.
  179.      * @param status status to set
  180.      */
  181.     public void setStatus(final Status status) {
  182.         this.status = status;
  183.     }

  184.     /** Get the partial derivatives of the {@link #getEstimatedValue()
  185.      * simulated measurement} with respect to state Cartesian coordinates.
  186.      * @param index index of the state, according to the {@code states}
  187.      * passed at construction
  188.      * @return partial derivatives of the simulated value (array of size
  189.      * {@link ObservedMeasurement#getDimension() dimension} x 6)
  190.      */
  191.     public double[][] getStateDerivatives(final int index) {
  192.         final double[][] sd = new double[observedMeasurement.getDimension()][];
  193.         for (int i = 0; i < observedMeasurement.getDimension(); ++i) {
  194.             sd[i] = stateDerivatives[index][i].clone();
  195.         }
  196.         return sd;
  197.     }

  198.     /** Set the partial derivatives of the {@link #getEstimatedValue()
  199.      * simulated measurement} with respect to state Cartesian coordinates.
  200.      * @param index index of the state, according to the {@code states}
  201.      * passed at construction
  202.      * @param derivatives partial derivatives with respect to state
  203.      */
  204.     public void setStateDerivatives(final int index, final double[]... derivatives) {
  205.         this.stateDerivatives[index] = new double[observedMeasurement.getDimension()][];
  206.         for (int i = 0; i < observedMeasurement.getDimension(); ++i) {
  207.             this.stateDerivatives[index][i] = derivatives[i].clone();
  208.         }
  209.     }

  210.     /** Get all the drivers with set derivatives.
  211.      * @return all the drivers with set derivatives
  212.      * @since 9.0
  213.      */
  214.     public Stream<ParameterDriver> getDerivativesDrivers() {
  215.         return parametersDerivatives.entrySet().stream().map(entry -> entry.getKey());
  216.     }

  217.     /** Get the partial derivatives of the {@link #getEstimatedValue()
  218.      * simulated measurement} with respect to a parameter.
  219.      * @param driver driver for the parameter
  220.      * @return partial derivatives of the simulated value
  221.      * @exception OrekitIllegalArgumentException if parameter is unknown
  222.      */
  223.     public double[] getParameterDerivatives(final ParameterDriver driver)
  224.         throws OrekitIllegalArgumentException {
  225.         final double[] p = parametersDerivatives.get(driver);
  226.         if (p == null) {
  227.             final StringBuilder builder = new StringBuilder();
  228.             for (final Map.Entry<ParameterDriver, double[]> entry : parametersDerivatives.entrySet()) {
  229.                 if (builder.length() > 0) {
  230.                     builder.append(", ");
  231.                 }
  232.                 builder.append(entry.getKey().getName());
  233.             }
  234.             throw new OrekitIllegalArgumentException(OrekitMessages.UNSUPPORTED_PARAMETER_NAME,
  235.                                                      driver.getName(),
  236.                                                      builder.length() > 0 ? builder.toString() : "<none>");
  237.         }
  238.         return p;
  239.     }

  240.     /** Set the partial derivatives of the {@link #getEstimatedValue()
  241.      * simulated measurement} with respect to parameter.
  242.      * @param driver driver for the parameter
  243.      * @param parameterDerivatives partial derivatives with respect to parameter
  244.      */
  245.     public void setParameterDerivatives(final ParameterDriver driver, final double... parameterDerivatives) {
  246.         parametersDerivatives.put(driver, parameterDerivatives);
  247.     }

  248.     /** Enumerate for the status of the measurement. */
  249.     public enum Status {

  250.         /** Status for processed measurements. */
  251.         PROCESSED,

  252.         /** Status for rejected measurements. */
  253.         REJECTED;

  254.     }

  255. }