AbstractKalmanEstimationCommon.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.estimation.sequential;

  18. import java.util.ArrayList;
  19. import java.util.Arrays;
  20. import java.util.Comparator;
  21. import java.util.HashMap;
  22. import java.util.List;
  23. import java.util.Map;

  24. import org.hipparchus.filtering.kalman.ProcessEstimate;
  25. import org.hipparchus.linear.ArrayRealVector;
  26. import org.hipparchus.linear.MatrixUtils;
  27. import org.hipparchus.linear.RealMatrix;
  28. import org.hipparchus.linear.RealVector;
  29. import org.orekit.errors.OrekitException;
  30. import org.orekit.errors.OrekitMessages;
  31. import org.orekit.estimation.measurements.EstimatedMeasurement;
  32. import org.orekit.propagation.Propagator;
  33. import org.orekit.propagation.SpacecraftState;
  34. import org.orekit.propagation.conversion.PropagatorBuilder;
  35. import org.orekit.time.AbsoluteDate;
  36. import org.orekit.utils.ParameterDriver;
  37. import org.orekit.utils.ParameterDriversList;
  38. import org.orekit.utils.ParameterDriversList.DelegatingDriver;

  39. /** Class defining the process model dynamics to use with a {@link KalmanEstimator}.
  40.  * @author Romain Gerbaud
  41.  * @author Maxime Journot
  42.  * @since 9.2
  43.  */
  44. abstract class AbstractKalmanEstimationCommon implements KalmanEstimation {

  45.     /** Builders for propagators. */
  46.     private final List<PropagatorBuilder> builders;

  47.     /** Estimated orbital parameters. */
  48.     private final ParameterDriversList allEstimatedOrbitalParameters;

  49.     /** Estimated propagation drivers. */
  50.     private final ParameterDriversList allEstimatedPropagationParameters;

  51.     /** Per-builder estimated orbita parameters drivers.
  52.      * @since 11.1
  53.      */
  54.     private final ParameterDriversList[] estimatedOrbitalParameters;

  55.     /** Per-builder estimated propagation drivers. */
  56.     private final ParameterDriversList[] estimatedPropagationParameters;

  57.     /** Estimated measurements parameters. */
  58.     private final ParameterDriversList estimatedMeasurementsParameters;

  59.     /** Start columns for each estimated orbit. */
  60.     private final int[] orbitsStartColumns;

  61.     /** End columns for each estimated orbit. */
  62.     private final int[] orbitsEndColumns;

  63.     /** Map for propagation parameters columns. */
  64.     private final Map<String, Integer> propagationParameterColumns;

  65.     /** Map for measurements parameters columns. */
  66.     private final Map<String, Integer> measurementParameterColumns;

  67.     /** Providers for covariance matrices. */
  68.     private final List<CovarianceMatrixProvider> covarianceMatricesProviders;

  69.     /** Process noise matrix provider for measurement parameters. */
  70.     private final CovarianceMatrixProvider measurementProcessNoiseMatrix;

  71.     /** Indirection arrays to extract the noise components for estimated parameters. */
  72.     private final int[][] covarianceIndirection;

  73.     /** Scaling factors. */
  74.     private final double[] scale;

  75.     /** Current corrected estimate. */
  76.     private ProcessEstimate correctedEstimate;

  77.     /** Current number of measurement. */
  78.     private int currentMeasurementNumber;

  79.     /** Reference date. */
  80.     private final AbsoluteDate referenceDate;

  81.     /** Current date. */
  82.     private AbsoluteDate currentDate;

  83.     /** Predicted spacecraft states. */
  84.     private final SpacecraftState[] predictedSpacecraftStates;

  85.     /** Corrected spacecraft states. */
  86.     private final SpacecraftState[] correctedSpacecraftStates;

  87.     /** Predicted measurement. */
  88.     private EstimatedMeasurement<?> predictedMeasurement;

  89.     /** Corrected measurement. */
  90.     private EstimatedMeasurement<?> correctedMeasurement;

  91.     /** Kalman process model constructor.
  92.      * @param propagatorBuilders propagators builders used to evaluate the orbits.
  93.      * @param covarianceMatricesProviders providers for covariance matrices
  94.      * @param estimatedMeasurementParameters measurement parameters to estimate
  95.      * @param measurementProcessNoiseMatrix provider for measurement process noise matrix
  96.      */
  97.     protected AbstractKalmanEstimationCommon(final List<PropagatorBuilder> propagatorBuilders,
  98.                                              final List<CovarianceMatrixProvider> covarianceMatricesProviders,
  99.                                              final ParameterDriversList estimatedMeasurementParameters,
  100.                                              final CovarianceMatrixProvider measurementProcessNoiseMatrix) {

  101.         this.builders                        = propagatorBuilders;
  102.         this.estimatedMeasurementsParameters = estimatedMeasurementParameters;
  103.         this.measurementParameterColumns     = new HashMap<>(estimatedMeasurementsParameters.getDrivers().size());
  104.         this.currentMeasurementNumber        = 0;
  105.         this.referenceDate                   = propagatorBuilders.get(0).getInitialOrbitDate();
  106.         this.currentDate                     = referenceDate;

  107.         final Map<String, Integer> orbitalParameterColumns = new HashMap<>(6 * builders.size());
  108.         orbitsStartColumns      = new int[builders.size()];
  109.         orbitsEndColumns        = new int[builders.size()];
  110.         int columns = 0;
  111.         allEstimatedOrbitalParameters = new ParameterDriversList();
  112.         estimatedOrbitalParameters    = new ParameterDriversList[builders.size()];
  113.         for (int k = 0; k < builders.size(); ++k) {
  114.             estimatedOrbitalParameters[k] = new ParameterDriversList();
  115.             orbitsStartColumns[k] = columns;
  116.             final String suffix = propagatorBuilders.size() > 1 ? "[" + k + "]" : null;
  117.             for (final ParameterDriver driver : builders.get(k).getOrbitalParametersDrivers().getDrivers()) {
  118.                 if (driver.getReferenceDate() == null) {
  119.                     driver.setReferenceDate(currentDate);
  120.                 }
  121.                 if (suffix != null && !driver.getName().endsWith(suffix)) {
  122.                     // we add suffix only conditionally because the method may already have been called
  123.                     // and suffixes may have already been appended
  124.                     driver.setName(driver.getName() + suffix);
  125.                 }
  126.                 if (driver.isSelected()) {
  127.                     allEstimatedOrbitalParameters.add(driver);
  128.                     estimatedOrbitalParameters[k].add(driver);
  129.                     orbitalParameterColumns.put(driver.getName(), columns++);
  130.                 }
  131.             }
  132.             orbitsEndColumns[k] = columns;
  133.         }

  134.         // Gather all the propagation drivers names in a list
  135.         allEstimatedPropagationParameters = new ParameterDriversList();
  136.         estimatedPropagationParameters    = new ParameterDriversList[builders.size()];
  137.         final List<String> estimatedPropagationParametersNames = new ArrayList<>();
  138.         for (int k = 0; k < builders.size(); ++k) {
  139.             estimatedPropagationParameters[k] = new ParameterDriversList();
  140.             for (final ParameterDriver driver : builders.get(k).getPropagationParametersDrivers().getDrivers()) {
  141.                 if (driver.getReferenceDate() == null) {
  142.                     driver.setReferenceDate(currentDate);
  143.                 }
  144.                 if (driver.isSelected()) {
  145.                     allEstimatedPropagationParameters.add(driver);
  146.                     estimatedPropagationParameters[k].add(driver);
  147.                     final String driverName = driver.getName();
  148.                     // Add the driver name if it has not been added yet
  149.                     if (!estimatedPropagationParametersNames.contains(driverName)) {
  150.                         estimatedPropagationParametersNames.add(driverName);
  151.                     }
  152.                 }
  153.             }
  154.         }
  155.         estimatedPropagationParametersNames.sort(Comparator.naturalOrder());

  156.         // Populate the map of propagation drivers' columns and update the total number of columns
  157.         propagationParameterColumns = new HashMap<>(estimatedPropagationParametersNames.size());
  158.         for (final String driverName : estimatedPropagationParametersNames) {
  159.             propagationParameterColumns.put(driverName, columns);
  160.             ++columns;
  161.         }

  162.         // Populate the map of measurement drivers' columns and update the total number of columns
  163.         for (final ParameterDriver parameter : estimatedMeasurementsParameters.getDrivers()) {
  164.             if (parameter.getReferenceDate() == null) {
  165.                 parameter.setReferenceDate(currentDate);
  166.             }
  167.             measurementParameterColumns.put(parameter.getName(), columns);
  168.             ++columns;
  169.         }

  170.         // Store providers for process noise matrices
  171.         this.covarianceMatricesProviders = covarianceMatricesProviders;
  172.         this.measurementProcessNoiseMatrix = measurementProcessNoiseMatrix;
  173.         this.covarianceIndirection       = new int[builders.size()][columns];
  174.         for (int k = 0; k < covarianceIndirection.length; ++k) {
  175.             final ParameterDriversList orbitDrivers      = builders.get(k).getOrbitalParametersDrivers();
  176.             final ParameterDriversList parametersDrivers = builders.get(k).getPropagationParametersDrivers();
  177.             Arrays.fill(covarianceIndirection[k], -1);
  178.             int i = 0;
  179.             for (final ParameterDriver driver : orbitDrivers.getDrivers()) {
  180.                 final Integer c = orbitalParameterColumns.get(driver.getName());
  181.                 if (c != null) {
  182.                     covarianceIndirection[k][i++] = c;
  183.                 }
  184.             }
  185.             for (final ParameterDriver driver : parametersDrivers.getDrivers()) {
  186.                 final Integer c = propagationParameterColumns.get(driver.getName());
  187.                 if (c != null) {
  188.                     covarianceIndirection[k][i++] = c;
  189.                 }
  190.             }
  191.             for (final ParameterDriver driver : estimatedMeasurementParameters.getDrivers()) {
  192.                 final Integer c = measurementParameterColumns.get(driver.getName());
  193.                 if (c != null) {
  194.                     covarianceIndirection[k][i++] = c;
  195.                 }
  196.             }
  197.         }

  198.         // Compute the scale factors
  199.         this.scale = new double[columns];
  200.         int index = 0;
  201.         for (final ParameterDriver driver : allEstimatedOrbitalParameters.getDrivers()) {
  202.             scale[index++] = driver.getScale();
  203.         }
  204.         for (final ParameterDriver driver : allEstimatedPropagationParameters.getDrivers()) {
  205.             scale[index++] = driver.getScale();
  206.         }
  207.         for (final ParameterDriver driver : estimatedMeasurementsParameters.getDrivers()) {
  208.             scale[index++] = driver.getScale();
  209.         }

  210.         // Populate predicted and corrected states
  211.         this.predictedSpacecraftStates = new SpacecraftState[builders.size()];
  212.         for (int i = 0; i < builders.size(); ++i) {
  213.             predictedSpacecraftStates[i] = builders.get(i).buildPropagator().getInitialState();
  214.         }
  215.         this.correctedSpacecraftStates = predictedSpacecraftStates.clone();

  216.         // Initialize the estimated normalized state and fill its values
  217.         final RealVector correctedState      = MatrixUtils.createRealVector(columns);

  218.         int p = 0;
  219.         for (final ParameterDriver driver : allEstimatedOrbitalParameters.getDrivers()) {
  220.             correctedState.setEntry(p++, driver.getNormalizedValue());
  221.         }
  222.         for (final ParameterDriver driver : allEstimatedPropagationParameters.getDrivers()) {
  223.             correctedState.setEntry(p++, driver.getNormalizedValue());
  224.         }
  225.         for (final ParameterDriver driver : estimatedMeasurementsParameters.getDrivers()) {
  226.             correctedState.setEntry(p++, driver.getNormalizedValue());
  227.         }

  228.         // Set up initial covariance
  229.         final RealMatrix physicalProcessNoise = MatrixUtils.createRealMatrix(columns, columns);
  230.         for (int k = 0; k < covarianceMatricesProviders.size(); ++k) {

  231.             // Number of estimated measurement parameters
  232.             final int nbMeas = estimatedMeasurementParameters.getNbParams();

  233.             // Number of estimated dynamic parameters (orbital + propagation)
  234.             final int nbDyn  = orbitsEndColumns[k] - orbitsStartColumns[k] +
  235.                     estimatedPropagationParameters[k].getNbParams();

  236.             // Covariance matrix
  237.             final RealMatrix noiseK = MatrixUtils.createRealMatrix(nbDyn + nbMeas, nbDyn + nbMeas);
  238.             if (nbDyn > 0) {
  239.                 final RealMatrix noiseP = covarianceMatricesProviders.get(k).
  240.                         getInitialCovarianceMatrix(correctedSpacecraftStates[k]);
  241.                 if (measurementProcessNoiseMatrix == null && noiseP.getRowDimension() != nbDyn + nbMeas) {
  242.                     throw new OrekitException(OrekitMessages.WRONG_PROCESS_COVARIANCE_DIMENSION,
  243.                             nbDyn + nbMeas, noiseP.getRowDimension());
  244.                 } else if (measurementProcessNoiseMatrix != null && noiseP.getRowDimension() != nbDyn) {
  245.                     throw new OrekitException(OrekitMessages.WRONG_PROCESS_COVARIANCE_DIMENSION,
  246.                             nbDyn, noiseP.getRowDimension());
  247.                 }
  248.                 noiseK.setSubMatrix(noiseP.getData(), 0, 0);
  249.             }
  250.             if (measurementProcessNoiseMatrix != null) {
  251.                 final RealMatrix noiseM = measurementProcessNoiseMatrix.
  252.                         getInitialCovarianceMatrix(correctedSpacecraftStates[k]);
  253.                 if (noiseM.getRowDimension() != nbMeas) {
  254.                     throw new OrekitException(OrekitMessages.WRONG_MEASUREMENT_COVARIANCE_DIMENSION,
  255.                             nbMeas, noiseM.getRowDimension());
  256.                 }
  257.                 noiseK.setSubMatrix(noiseM.getData(), nbDyn, nbDyn);
  258.             }

  259.             KalmanEstimatorUtil.checkDimension(noiseK.getRowDimension(),
  260.                     builders.get(k).getOrbitalParametersDrivers(),
  261.                     builders.get(k).getPropagationParametersDrivers(),
  262.                     estimatedMeasurementsParameters);

  263.             final int[] indK = covarianceIndirection[k];
  264.             for (int i = 0; i < indK.length; ++i) {
  265.                 if (indK[i] >= 0) {
  266.                     for (int j = 0; j < indK.length; ++j) {
  267.                         if (indK[j] >= 0) {
  268.                             physicalProcessNoise.setEntry(indK[i], indK[j], noiseK.getEntry(i, j));
  269.                         }
  270.                     }
  271.                 }
  272.             }

  273.         }
  274.         final RealMatrix correctedCovariance = KalmanEstimatorUtil.normalizeCovarianceMatrix(physicalProcessNoise, scale);

  275.         correctedEstimate = new ProcessEstimate(0.0, correctedState, correctedCovariance);
  276.     }


  277.     /** {@inheritDoc} */
  278.     @Override
  279.     public RealMatrix getPhysicalStateTransitionMatrix() {
  280.         //  Un-normalize the state transition matrix (φ) from Hipparchus and return it.
  281.         // φ is an mxm matrix where m = nbOrb + nbPropag + nbMeas
  282.         // For each element [i,j] of normalized φ (φn), the corresponding physical value is:
  283.         // φ[i,j] = φn[i,j] * scale[i] / scale[j]
  284.         return correctedEstimate.getStateTransitionMatrix() == null ?
  285.                 null : KalmanEstimatorUtil.unnormalizeStateTransitionMatrix(correctedEstimate.getStateTransitionMatrix(), scale);
  286.     }

  287.     /** {@inheritDoc} */
  288.     @Override
  289.     public RealMatrix getPhysicalMeasurementJacobian() {
  290.         // Un-normalize the measurement matrix (H) from Hipparchus and return it.
  291.         // H is an nxm matrix where:
  292.         //  - m = nbOrb + nbPropag + nbMeas is the number of estimated parameters
  293.         //  - n is the size of the measurement being processed by the filter
  294.         // For each element [i,j] of normalized H (Hn) the corresponding physical value is:
  295.         // H[i,j] = Hn[i,j] * σ[i] / scale[j]
  296.         return correctedEstimate.getMeasurementJacobian() == null ?
  297.                 null : KalmanEstimatorUtil.unnormalizeMeasurementJacobian(correctedEstimate.getMeasurementJacobian(),
  298.                 scale,
  299.                 correctedMeasurement.getObservedMeasurement().getTheoreticalStandardDeviation());
  300.     }

  301.     /** {@inheritDoc} */
  302.     @Override
  303.     public RealMatrix getPhysicalInnovationCovarianceMatrix() {
  304.         // Un-normalize the innovation covariance matrix (S) from Hipparchus and return it.
  305.         // S is an nxn matrix where n is the size of the measurement being processed by the filter
  306.         // For each element [i,j] of normalized S (Sn) the corresponding physical value is:
  307.         // S[i,j] = Sn[i,j] * σ[i] * σ[j]
  308.         return correctedEstimate.getInnovationCovariance() == null ?
  309.                 null : KalmanEstimatorUtil.unnormalizeInnovationCovarianceMatrix(correctedEstimate.getInnovationCovariance(),
  310.                 predictedMeasurement.getObservedMeasurement().getTheoreticalStandardDeviation());
  311.     }

  312.     /** {@inheritDoc} */
  313.     @Override
  314.     public RealMatrix getPhysicalKalmanGain() {
  315.         // Un-normalize the Kalman gain (K) from Hipparchus and return it.
  316.         // K is an mxn matrix where:
  317.         //  - m = nbOrb + nbPropag + nbMeas is the number of estimated parameters
  318.         //  - n is the size of the measurement being processed by the filter
  319.         // For each element [i,j] of normalized K (Kn) the corresponding physical value is:
  320.         // K[i,j] = Kn[i,j] * scale[i] / σ[j]
  321.         return correctedEstimate.getKalmanGain() == null ?
  322.                 null : KalmanEstimatorUtil.unnormalizeKalmanGainMatrix(correctedEstimate.getKalmanGain(),
  323.                 scale,
  324.                 correctedMeasurement.getObservedMeasurement().getTheoreticalStandardDeviation());
  325.     }

  326.     /** {@inheritDoc} */
  327.     @Override
  328.     public SpacecraftState[] getPredictedSpacecraftStates() {
  329.         return predictedSpacecraftStates.clone();
  330.     }

  331.     /** {@inheritDoc} */
  332.     @Override
  333.     public SpacecraftState[] getCorrectedSpacecraftStates() {
  334.         return correctedSpacecraftStates.clone();
  335.     }

  336.     /** {@inheritDoc} */
  337.     @Override
  338.     public int getCurrentMeasurementNumber() {
  339.         return currentMeasurementNumber;
  340.     }

  341.     /** {@inheritDoc} */
  342.     @Override
  343.     public AbsoluteDate getCurrentDate() {
  344.         return currentDate;
  345.     }

  346.     /** {@inheritDoc} */
  347.     @Override
  348.     public EstimatedMeasurement<?> getPredictedMeasurement() {
  349.         return predictedMeasurement;
  350.     }

  351.     /** {@inheritDoc} */
  352.     @Override
  353.     public EstimatedMeasurement<?> getCorrectedMeasurement() {
  354.         return correctedMeasurement;
  355.     }

  356.     /** {@inheritDoc} */
  357.     @Override
  358.     public RealVector getPhysicalEstimatedState() {
  359.         // Method {@link ParameterDriver#getValue()} is used to get
  360.         // the physical values of the state.
  361.         // The scales'array is used to get the size of the state vector
  362.         final RealVector physicalEstimatedState = new ArrayRealVector(scale.length);
  363.         int i = 0;
  364.         for (final DelegatingDriver driver : getEstimatedOrbitalParameters().getDrivers()) {
  365.             physicalEstimatedState.setEntry(i++, driver.getValue());
  366.         }
  367.         for (final DelegatingDriver driver : getEstimatedPropagationParameters().getDrivers()) {
  368.             physicalEstimatedState.setEntry(i++, driver.getValue());
  369.         }
  370.         for (final DelegatingDriver driver : getEstimatedMeasurementsParameters().getDrivers()) {
  371.             physicalEstimatedState.setEntry(i++, driver.getValue());
  372.         }

  373.         return physicalEstimatedState;
  374.     }

  375.     /** {@inheritDoc} */
  376.     @Override
  377.     public RealMatrix getPhysicalEstimatedCovarianceMatrix() {
  378.         // Un-normalize the estimated covariance matrix (P) from Hipparchus and return it.
  379.         // The covariance P is an mxm matrix where m = nbOrb + nbPropag + nbMeas
  380.         // For each element [i,j] of P the corresponding normalized value is:
  381.         // Pn[i,j] = P[i,j] / (scale[i]*scale[j])
  382.         // Consequently: P[i,j] = Pn[i,j] * scale[i] * scale[j]
  383.         return KalmanEstimatorUtil.unnormalizeCovarianceMatrix(correctedEstimate.getCovariance(), scale);
  384.     }

  385.     /** {@inheritDoc} */
  386.     @Override
  387.     public ParameterDriversList getEstimatedOrbitalParameters() {
  388.         return allEstimatedOrbitalParameters;
  389.     }

  390.     /** {@inheritDoc} */
  391.     @Override
  392.     public ParameterDriversList getEstimatedPropagationParameters() {
  393.         return allEstimatedPropagationParameters;
  394.     }

  395.     /** {@inheritDoc} */
  396.     @Override
  397.     public ParameterDriversList getEstimatedMeasurementsParameters() {
  398.         return estimatedMeasurementsParameters;
  399.     }

  400.     /** Get the current corrected estimate.
  401.      * @return current corrected estimate
  402.      */
  403.     public ProcessEstimate getEstimate() {
  404.         return correctedEstimate;
  405.     }

  406.     /** Getter for the propagators.
  407.      * @return the propagators
  408.      */
  409.     public List<PropagatorBuilder> getBuilders() {
  410.         return builders;
  411.     }

  412.     /** Get the propagators estimated with the values set in the propagators builders.
  413.      * @return propagators based on the current values in the builder
  414.      */
  415.     public Propagator[] getEstimatedPropagators() {
  416.         // Return propagators built with current instantiation of the propagator builders
  417.         final Propagator[] propagators = new Propagator[getBuilders().size()];
  418.         for (int k = 0; k < getBuilders().size(); ++k) {
  419.             propagators[k] = getBuilders().get(k).buildPropagator();
  420.         }
  421.         return propagators;
  422.     }

  423.     /** Get the normalized process noise matrix.
  424.      *
  425.      * @param stateDimension state dimension
  426.      * @return the normalized process noise matrix
  427.      */
  428.     protected RealMatrix getNormalizedProcessNoise(final int stateDimension) {
  429.         final RealMatrix physicalProcessNoise = MatrixUtils.createRealMatrix(stateDimension, stateDimension);
  430.         for (int k = 0; k < covarianceMatricesProviders.size(); ++k) {

  431.             // Number of estimated measurement parameters
  432.             final int nbMeas = estimatedMeasurementsParameters.getNbParams();

  433.             // Number of estimated dynamic parameters (orbital + propagation)
  434.             final int nbDyn  = orbitsEndColumns[k] - orbitsStartColumns[k] +
  435.                     estimatedPropagationParameters[k].getNbParams();

  436.             // Covariance matrix
  437.             final RealMatrix noiseK = MatrixUtils.createRealMatrix(nbDyn + nbMeas, nbDyn + nbMeas);
  438.             if (nbDyn > 0) {
  439.                 final RealMatrix noiseP = covarianceMatricesProviders.get(k).
  440.                         getProcessNoiseMatrix(correctedSpacecraftStates[k],
  441.                                 predictedSpacecraftStates[k]);
  442.                 if (measurementProcessNoiseMatrix == null && noiseP.getRowDimension() != nbDyn + nbMeas) {
  443.                     throw new OrekitException(OrekitMessages.WRONG_PROCESS_COVARIANCE_DIMENSION,
  444.                             nbDyn + nbMeas, noiseP.getRowDimension());
  445.                 } else if (measurementProcessNoiseMatrix != null && noiseP.getRowDimension() != nbDyn) {
  446.                     throw new OrekitException(OrekitMessages.WRONG_PROCESS_COVARIANCE_DIMENSION,
  447.                             nbDyn, noiseP.getRowDimension());
  448.                 }
  449.                 noiseK.setSubMatrix(noiseP.getData(), 0, 0);
  450.             }
  451.             if (measurementProcessNoiseMatrix != null) {
  452.                 final RealMatrix noiseM = measurementProcessNoiseMatrix.
  453.                         getProcessNoiseMatrix(correctedSpacecraftStates[k],
  454.                                 predictedSpacecraftStates[k]);
  455.                 if (noiseM.getRowDimension() != nbMeas) {
  456.                     throw new OrekitException(OrekitMessages.WRONG_MEASUREMENT_COVARIANCE_DIMENSION,
  457.                             nbMeas, noiseM.getRowDimension());
  458.                 }
  459.                 noiseK.setSubMatrix(noiseM.getData(), nbDyn, nbDyn);
  460.             }

  461.             KalmanEstimatorUtil.checkDimension(noiseK.getRowDimension(),
  462.                     builders.get(k).getOrbitalParametersDrivers(),
  463.                     builders.get(k).getPropagationParametersDrivers(),
  464.                     estimatedMeasurementsParameters);

  465.             final int[] indK = covarianceIndirection[k];
  466.             for (int i = 0; i < indK.length; ++i) {
  467.                 if (indK[i] >= 0) {
  468.                     for (int j = 0; j < indK.length; ++j) {
  469.                         if (indK[j] >= 0) {
  470.                             physicalProcessNoise.setEntry(indK[i], indK[j], noiseK.getEntry(i, j));
  471.                         }
  472.                     }
  473.                 }
  474.             }

  475.         }
  476.         return KalmanEstimatorUtil.normalizeCovarianceMatrix(physicalProcessNoise, scale);
  477.     }

  478.     /** Getter for the orbitsStartColumns.
  479.      * @return the orbitsStartColumns
  480.      */
  481.     protected int[] getOrbitsStartColumns() {
  482.         return orbitsStartColumns;
  483.     }

  484.     /** Getter for the propagationParameterColumns.
  485.      * @return the propagationParameterColumns
  486.      */
  487.     protected Map<String, Integer> getPropagationParameterColumns() {
  488.         return propagationParameterColumns;
  489.     }

  490.     /** Getter for the measurementParameterColumns.
  491.      * @return the measurementParameterColumns
  492.      */
  493.     protected Map<String, Integer> getMeasurementParameterColumns() {
  494.         return measurementParameterColumns;
  495.     }

  496.     /** Getter for the estimatedPropagationParameters.
  497.      * @return the estimatedPropagationParameters
  498.      */
  499.     protected ParameterDriversList[] getEstimatedPropagationParametersArray() {
  500.         return estimatedPropagationParameters;
  501.     }

  502.     /** Getter for the estimatedOrbitalParameters.
  503.      * @return the estimatedOrbitalParameters
  504.      */
  505.     protected ParameterDriversList[] getEstimatedOrbitalParametersArray() {
  506.         return estimatedOrbitalParameters;
  507.     }

  508.     /** Getter for the covarianceIndirection.
  509.      * @return the covarianceIndirection
  510.      */
  511.     protected int[][] getCovarianceIndirection() {
  512.         return covarianceIndirection;
  513.     }

  514.     /** Getter for the scale.
  515.      * @return the scale
  516.      */
  517.     protected double[] getScale() {
  518.         return scale;
  519.     }

  520.     /** Getter for the correctedEstimate.
  521.      * @return the correctedEstimate
  522.      */
  523.     protected ProcessEstimate getCorrectedEstimate() {
  524.         return correctedEstimate;
  525.     }

  526.     /** Setter for the correctedEstimate.
  527.      * @param correctedEstimate the correctedEstimate
  528.      */
  529.     protected void setCorrectedEstimate(final ProcessEstimate correctedEstimate) {
  530.         this.correctedEstimate = correctedEstimate;
  531.     }

  532.     /** Getter for the referenceDate.
  533.      * @return the referenceDate
  534.      */
  535.     protected AbsoluteDate getReferenceDate() {
  536.         return referenceDate;
  537.     }

  538.     /** Increment current measurement number. */
  539.     protected void incrementCurrentMeasurementNumber() {
  540.         currentMeasurementNumber += 1;
  541.     }

  542.     /** Setter for the currentDate.
  543.      * @param currentDate the currentDate
  544.      */
  545.     protected void setCurrentDate(final AbsoluteDate currentDate) {
  546.         this.currentDate = currentDate;
  547.     }

  548.     /** Set correctedSpacecraftState at index.
  549.      *
  550.      * @param correctedSpacecraftState corrected S/C state o set
  551.      * @param index index where to set in the array
  552.      */
  553.     protected void setCorrectedSpacecraftState(final SpacecraftState correctedSpacecraftState, final int index) {
  554.         this.correctedSpacecraftStates[index] = correctedSpacecraftState;
  555.     }

  556.     /** Set predictedSpacecraftState at index.
  557.      *
  558.      * @param predictedSpacecraftState predicted S/C state o set
  559.      * @param index index where to set in the array
  560.      */
  561.     protected void setPredictedSpacecraftState(final SpacecraftState predictedSpacecraftState, final int index) {
  562.         this.predictedSpacecraftStates[index] = predictedSpacecraftState;
  563.     }

  564.     /** Setter for the predictedMeasurement.
  565.      * @param predictedMeasurement the predictedMeasurement
  566.      */
  567.     protected void setPredictedMeasurement(final EstimatedMeasurement<?> predictedMeasurement) {
  568.         this.predictedMeasurement = predictedMeasurement;
  569.     }

  570.     /** Setter for the correctedMeasurement.
  571.      * @param correctedMeasurement the correctedMeasurement
  572.      */
  573.     protected void setCorrectedMeasurement(final EstimatedMeasurement<?> correctedMeasurement) {
  574.         this.correctedMeasurement = correctedMeasurement;
  575.     }
  576. }