diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 1cedfe1a28156002a80b80fc6b3f1f76228702e6..13257e2ff907e2d3051b0854e06f63d3b6278f6e 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -21,6 +21,10 @@
   </properties>
   <body>
     <release version="10.0" date="TBD" description="TBD">
+      <action dev="maxime" type="add" issue="403">
+        Added tests for class UnivariateProcessNoise.
+        Working tests for non-Cartesian orbit propagation are still needed.
+      </action>
       <action dev="maxime" type="fix" issue="514">
         Deprecated unused DerivativeStructure acceleration computation methods.
         In interfaces radiationPressureAcceleration and dragAcceleration, and all their implementations and their tests. 
diff --git a/src/main/java/org/orekit/estimation/sequential/UnivariateProcessNoise.java b/src/main/java/org/orekit/estimation/sequential/UnivariateProcessNoise.java
index a5c3d7d895441469e601338777b8b6bd6c246199..def7b1cfd56b60321df567f6b12efd19449b8655 100644
--- a/src/main/java/org/orekit/estimation/sequential/UnivariateProcessNoise.java
+++ b/src/main/java/org/orekit/estimation/sequential/UnivariateProcessNoise.java
@@ -24,6 +24,7 @@ import org.orekit.errors.OrekitException;
 import org.orekit.frames.LOFType;
 import org.orekit.orbits.PositionAngle;
 import org.orekit.propagation.SpacecraftState;
+import org.orekit.utils.CartesianDerivativesFilter;
 
 /** Provider for a temporal evolution of the process noise matrix.
  * All parameters (orbital or propagation) are time dependent and provided as {@link UnivariateFunction}.
@@ -184,40 +185,25 @@ public class UnivariateProcessNoise extends AbstractCovarianceMatrixProvider {
         // Form the diagonal matrix in LOF frame and Cartesian formalism
         final RealMatrix lofCartesianProcessNoiseMatrix = MatrixUtils.createRealDiagonalMatrix(lofOrbitalProcessNoiseValues);
 
-        // Get the rotation matrix from LOF to inertial frame
-        final double[][] lofToInertialRotation = lofType.rotationFromInertial(current.getPVCoordinates()).
-                                                 revert().getMatrix();
-
-        // Jacobian from LOF to inertial frame
-        final RealMatrix jacLofToInertial = MatrixUtils.createRealMatrix(6, 6);
-        jacLofToInertial.setSubMatrix(lofToInertialRotation, 0, 0);
-        jacLofToInertial.setSubMatrix(lofToInertialRotation, 3, 3);
-
-        // FIXME: Trying to fix the transform from LOF to inertial
-        //final Transform lofToInertial = lofType.transformFromInertial(current.getDate(), current.getPVCoordinates()).getInverse();
-        //final Vector3D OM = lofToInertial.getRotationRate().negate();
-        //final double[][] MOM = new double[3][3];
-        //MOM[0][1] = -OM.getZ();
-        //MOM[0][2] = OM.getY();
-        //MOM[1][0] = OM.getZ();
-        //MOM[1][2] = -OM.getX();
-        //MOM[2][0] = -OM.getY();
-        //MOM[2][1] = OM.getX();
-        //jacLofToInertial.setSubMatrix(MOM, 3, 0);
-        //debug
+        // Get the Jacobian from LOF to Inertial
+        final double[][] dLofdInertial = new double[6][6];
+        lofType.transformFromInertial(current.getDate(),
+                                      current.getPVCoordinates()).getInverse().getJacobian(CartesianDerivativesFilter.USE_PV,
+                                                                                           dLofdInertial);
+        final RealMatrix jacLofToInertial = MatrixUtils.createRealMatrix(dLofdInertial);
 
         // Jacobian of orbit parameters with respect to Cartesian parameters
         final double[][] dYdC = new double[6][6];
         current.getOrbit().getJacobianWrtCartesian(positionAngle, dYdC);
-        final RealMatrix jacParametersWrtCartesian = MatrixUtils.createRealMatrix(dYdC);
+        final RealMatrix jacOrbitWrtCartesian = MatrixUtils.createRealMatrix(dYdC);
 
         // Complete Jacobian of the transformation
-        final RealMatrix jacobian = jacParametersWrtCartesian.multiply(jacLofToInertial);
+        final RealMatrix jacobian = jacOrbitWrtCartesian.multiply(jacLofToInertial);
 
         // Return the orbital process noise matrix in inertial frame and proper orbit type
         final RealMatrix inertialOrbitalProcessNoiseMatrix = jacobian.
                          multiply(lofCartesianProcessNoiseMatrix).
-                         multiply(jacobian.transpose());
+                         multiplyTransposed(jacobian);
         return inertialOrbitalProcessNoiseMatrix;
     }
 
diff --git a/src/test/java/org/orekit/estimation/sequential/UnivariateprocessNoiseTest.java b/src/test/java/org/orekit/estimation/sequential/UnivariateprocessNoiseTest.java
index 7f07dd170fe723246114c078f9cb2c2ee2cd3eae..e97bbf3641dda6f48dae3fb8f2e673718eb17365 100644
--- a/src/test/java/org/orekit/estimation/sequential/UnivariateprocessNoiseTest.java
+++ b/src/test/java/org/orekit/estimation/sequential/UnivariateprocessNoiseTest.java
@@ -3,21 +3,27 @@ package org.orekit.estimation.sequential;
 import static org.junit.Assert.assertArrayEquals;
 
 import java.util.Arrays;
+import java.util.Locale;
 
 import org.hipparchus.analysis.UnivariateFunction;
 import org.hipparchus.analysis.polynomials.PolynomialFunction;
-import org.hipparchus.geometry.euclidean.threed.Vector3D;
+import org.hipparchus.linear.Array2DRowRealMatrix;
+import org.hipparchus.linear.ArrayRealVector;
 import org.hipparchus.linear.MatrixUtils;
 import org.hipparchus.linear.RealMatrix;
+import org.hipparchus.linear.RealVector;
 import org.hipparchus.random.CorrelatedRandomVectorGenerator;
 import org.hipparchus.random.GaussianRandomGenerator;
 import org.hipparchus.random.Well1024a;
 import org.hipparchus.stat.descriptive.StreamingStatistics;
 import org.hipparchus.util.FastMath;
+import org.junit.Assert;
 import org.junit.Ignore;
 import org.junit.Test;
+import org.orekit.errors.OrekitIllegalArgumentException;
 import org.orekit.estimation.Context;
 import org.orekit.estimation.EstimationTestUtils;
+import org.orekit.estimation.Force;
 import org.orekit.frames.LOFType;
 import org.orekit.frames.Transform;
 import org.orekit.orbits.OrbitType;
@@ -25,17 +31,66 @@ import org.orekit.orbits.PositionAngle;
 import org.orekit.propagation.Propagator;
 import org.orekit.propagation.SpacecraftState;
 import org.orekit.propagation.conversion.NumericalPropagatorBuilder;
+import org.orekit.utils.CartesianDerivativesFilter;
 import org.orekit.utils.PVCoordinates;
 import org.orekit.utils.TimeStampedPVCoordinates;
 
 public class UnivariateprocessNoiseTest {
     
-    /** Test different functions and check the conversion from LOF to ECI (and back) of the covariances. */
+    /** Basic test for getters. */
     @Test
-    public void testUnivariateProcessNoise() {
+    public void testUnivariateProcessNoiseGetters() {
+        
+        Context context = EstimationTestUtils.eccentricContext("regular-data:potential:tides");
+        
+        // Define the univariate functions for the standard deviations      
+        final UnivariateFunction[] lofCartesianOrbitalParametersEvolution = new UnivariateFunction[6];
+        // Evolution for position error
+        lofCartesianOrbitalParametersEvolution[0] = new PolynomialFunction(new double[] {100., 0., 1e-4});
+        lofCartesianOrbitalParametersEvolution[1] = new PolynomialFunction(new double[] {100., 1e-1, 0.});
+        lofCartesianOrbitalParametersEvolution[2] = new PolynomialFunction(new double[] {100., 0., 0.});
+        // Evolution for velocity error
+        lofCartesianOrbitalParametersEvolution[3] = new PolynomialFunction(new double[] {1., 0., 1.e-6});
+        lofCartesianOrbitalParametersEvolution[4] = new PolynomialFunction(new double[] {1., 1e-3, 0.});
+        lofCartesianOrbitalParametersEvolution[5] = new PolynomialFunction(new double[] {1., 0., 0.});
 
+        final UnivariateFunction[] propagationParametersEvolution =
+                        new UnivariateFunction[] {new PolynomialFunction(new double[] {10, 1., 1e-4}),
+                                                  new PolynomialFunction(new double[] {1000., 0., 0.})};
+        
+        // Create a dummy initial covariance matrix
+        final RealMatrix initialCovarianceMatrix = MatrixUtils.createRealIdentityMatrix(7);
+        
+        // Set the process noise object
+        // Define input LOF and output position angle
+        final LOFType lofType = LOFType.TNW;
+        final UnivariateProcessNoise processNoise = new UnivariateProcessNoise(initialCovarianceMatrix,
+                                                                               lofType,
+                                                                               PositionAngle.TRUE,
+                                                                               lofCartesianOrbitalParametersEvolution,
+                                                                               propagationParametersEvolution);
+        
+        Assert.assertEquals(LOFType.TNW, processNoise.getLofType());
+        Assert.assertEquals(PositionAngle.TRUE, processNoise.getPositionAngle());
+        Assert.assertEquals(initialCovarianceMatrix,
+                            processNoise.getInitialCovarianceMatrix(new SpacecraftState(context.initialOrbit)));
+        Assert.assertArrayEquals(lofCartesianOrbitalParametersEvolution, processNoise.getLofCartesianOrbitalParametersEvolution());
+        Assert.assertArrayEquals(propagationParametersEvolution, processNoise.getPropagationParametersEvolution());
+    }
+    
+    /** Test UnivariateProcessNoise class.
+     * - Initialize with different univariate functions for orbital/propagation parameters variation
+     * - Check that the inertial process noise covariance matrix is consistent with the inputs
+     * - Propagation in Cartesian formalism
+     */
+    @Test
+    public void testProcessNoiseMatrixCartesian() {
+        
         // Create context
         Context context = EstimationTestUtils.eccentricContext("regular-data:potential:tides");
+        
+        // Print result on console ?
+        final boolean print = false;
 
         // Create initial orbit and propagator builder
         final OrbitType     orbitType     = OrbitType.CARTESIAN;
@@ -45,8 +100,10 @@ public class UnivariateprocessNoiseTest {
         final double        maxStep       = 60.;
         final double        dP            = 1.;
         final NumericalPropagatorBuilder propagatorBuilder = context.createBuilder(orbitType, positionAngle, perfectStart,
-                                                                                   minStep, maxStep, dP);
-
+                                                                                   minStep, maxStep, dP,
+                                                                                   Force.POTENTIAL, Force.THIRD_BODY_MOON,
+                                                                                   Force.THIRD_BODY_SUN,
+                                                                                   Force.SOLAR_RADIATION_PRESSURE);
         // Create a propagator
         final Propagator propagator = EstimationTestUtils.createPropagator(context.initialOrbit,
                                                                            propagatorBuilder);
@@ -61,7 +118,8 @@ public class UnivariateprocessNoiseTest {
         lofCartesianOrbitalParametersEvolution[3] = new PolynomialFunction(new double[] {1., 0., 1.e-6});
         lofCartesianOrbitalParametersEvolution[4] = new PolynomialFunction(new double[] {1., 1e-3, 0.});
         lofCartesianOrbitalParametersEvolution[5] = new PolynomialFunction(new double[] {1., 0., 0.});
-
+        
+        // Propagation parameters' evolution
         final UnivariateFunction[] propagationParametersEvolution =
                         new UnivariateFunction[] {new PolynomialFunction(new double[] {10, 1., 1e-4}),
                                                   new PolynomialFunction(new double[] {1000., 0., 0.})};
@@ -77,30 +135,129 @@ public class UnivariateprocessNoiseTest {
                                                                                positionAngle,
                                                                                lofCartesianOrbitalParametersEvolution,
                                                                                propagationParametersEvolution);
-        // Test on initial value, after 1 min and after a
+        // Test on initial value, after 1 hour and after one orbit
         final SpacecraftState state0 = propagator.getInitialState();
-        final SpacecraftState state1 = propagator.propagate(context.initialOrbit.getDate().shiftedBy(60.));
+        final SpacecraftState state1 = propagator.propagate(context.initialOrbit.getDate().shiftedBy(3600.));
         final SpacecraftState state2 = propagator.propagate(context.initialOrbit.getDate()
-                                                            .shiftedBy(context.initialOrbit.getKeplerianPeriod()/4.));
+                                                            .shiftedBy(2*context.initialOrbit.getKeplerianPeriod()));
         
         // Number of samples for the statistics
         final int sampleNumber = 10000;
         
-        // Relative tolerance on final standard deviations observed (< 2% here)
-        final double relativeTolerance = 1.28e-2;;
+        // Relative tolerance on final standard deviations observed (< 1.5% for 10000 samples)
+        final double relativeTolerance = 1.5e-2;
         
-        checkCovarianceValue(state0, state0, processNoise, sampleNumber, relativeTolerance);
-        checkCovarianceValue(state0, state1, processNoise, sampleNumber, relativeTolerance);
-        checkCovarianceValue(state0, state2, processNoise, sampleNumber, relativeTolerance);
+        if (print) {
+            System.out.println("Orbit Type    : " + orbitType);
+            System.out.println("Position Angle: " + positionAngle + "\n");
+        }
+        checkCovarianceValue(print, state0, state0, processNoise, sampleNumber, relativeTolerance);
+        checkCovarianceValue(print, state0, state1, processNoise, sampleNumber, relativeTolerance);
+        checkCovarianceValue(print, state0, state2, processNoise, sampleNumber, relativeTolerance);
     }
     
+    /** Test process noise matrix computation.
+     * - Initialize with different univariate functions for orbital/propagation parameters variation
+     * - Check that the inertial process noise covariance matrix is consistent with the inputs
+     * - Propagation in Non-Cartesian formalism (Keplerian, Circular or Equinoctial)
+     *  TO DO: Find out why position in LOF frame is off after one hour of propagation
+     */
+    @Ignore
+    @Test
+    public void testProcessNoiseMatrixNonCartesian() {
+
+        // Create context
+        Context context = EstimationTestUtils.eccentricContext("regular-data:potential:tides");
+
+        // Print result on console ?
+        final boolean print = true;
+        
+        // Create initial orbit and propagator builder
+        final OrbitType     orbitType     = OrbitType.KEPLERIAN;
+        final PositionAngle positionAngle = PositionAngle.TRUE;
+        final boolean       perfectStart  = true;
+        final double        minStep       = 1.e-6;
+        final double        maxStep       = 60.;
+        final double        dP            = 1.;
+        final NumericalPropagatorBuilder propagatorBuilder = context.createBuilder(orbitType, positionAngle, perfectStart,
+                                                                                   minStep, maxStep, dP);//
+//                                                                                   Force.POTENTIAL, Force.THIRD_BODY_MOON,
+//                                                                                   Force.THIRD_BODY_SUN,
+//                                                                                   Force.SOLAR_RADIATION_PRESSURE);
+
+        // Create a propagator
+        final Propagator propagator = EstimationTestUtils.createPropagator(context.initialOrbit,
+                                                                           propagatorBuilder);
+        
+        // Define the univariate functions for the standard deviations      
+        final UnivariateFunction[] lofCartesianOrbitalParametersEvolution = new UnivariateFunction[6];
+        // Evolution for position error
+        lofCartesianOrbitalParametersEvolution[0] = new PolynomialFunction(new double[] {100., 0., 1e-4});
+        lofCartesianOrbitalParametersEvolution[1] = new PolynomialFunction(new double[] {100., 1e-1, 0.});
+        lofCartesianOrbitalParametersEvolution[2] = new PolynomialFunction(new double[] {100., 0., 0.});
+        // Evolution for velocity error
+        lofCartesianOrbitalParametersEvolution[3] = new PolynomialFunction(new double[] {1., 0., 1.e-6});
+        lofCartesianOrbitalParametersEvolution[4] = new PolynomialFunction(new double[] {1., 1e-3, 0.});
+        lofCartesianOrbitalParametersEvolution[5] = new PolynomialFunction(new double[] {1., 0., 0.});
+
+        final UnivariateFunction[] propagationParametersEvolution =
+                        new UnivariateFunction[] {new PolynomialFunction(new double[] {10, 1., 1e-4}),
+                                                  new PolynomialFunction(new double[] {1000., 0., 0.})};
+        
+        // Create a dummy initial covariance matrix
+        final RealMatrix initialCovarianceMatrix = MatrixUtils.createRealIdentityMatrix(7);
+        
+        // Set the process noise object
+        // Define input LOF and output position angle
+        final LOFType lofType = LOFType.TNW;
+        final UnivariateProcessNoise processNoise = new UnivariateProcessNoise(initialCovarianceMatrix,
+                                                                               lofType,
+                                                                               positionAngle,
+                                                                               lofCartesianOrbitalParametersEvolution,
+                                                                               propagationParametersEvolution);
+        // Test on initial value, after 1 hour and after 2 orbits
+        final SpacecraftState state0 = propagator.getInitialState();
+        final SpacecraftState state1 = propagator.propagate(context.initialOrbit.getDate().shiftedBy(3600.));
+//        final SpacecraftState state2 = propagator.propagate(context.initialOrbit.getDate()
+//                                                            .shiftedBy(2*context.initialOrbit.getKeplerianPeriod()));
+        
+        // Number of samples for the statistics
+        final int sampleNumber = 10000;
+        
+        // Relative tolerance on final standard deviations observed
+        final double relativeTolerance = 0.02;
+        
+        if (print) {
+            System.out.println("Orbit Type    : " + orbitType);
+            System.out.println("Position Angle: " + positionAngle + "\n");
+        }
+        checkCovarianceValue(print, state0, state0, processNoise, sampleNumber, relativeTolerance);
+        checkCovarianceValue(print, state0, state1, processNoise, sampleNumber, relativeTolerance);
+        
+        // Orbit too far off after 2 orbital periods
+        // It becomes inconsistent when applying random vector values
+        //checkCovarianceValue(print, state0, state2, processNoise, sampleNumber, relativeTolerance);
+    }
     
     
-    private static void checkCovarianceValue(final SpacecraftState previous,
-                                     final SpacecraftState current,
-                                     final UnivariateProcessNoise univariateProcessNoise,
-                                     final int sampleNumber,
-                                     final double relativeTolerance) {
+    /** Check the values of the covariance given in inertial frame by the UnivariateProcessNoise object.
+     *  - Get the process noise covariance matrix P in inertial frame
+     *  - Use a random vector generator based on P to produce a set of N error vectors in inertial frame
+     *  - Compare the standard deviations of the noisy data to the univariate functions given in input of the UnivariateProcessNoise class.
+     *  - For orbit parameters this involve converting the inertial orbital vector to LOF frame and Cartesian formalism first
+     * @param print print results in console ?
+     * @param previous previous state
+     * @param current current state
+     * @param univariateProcessNoise UnivariateProcessNoise object to test
+     * @param sampleNumber number of sample vectors for the statistics
+     * @param relativeTolerance relative tolerance on the standard deviations for the tests
+     */
+    private void checkCovarianceValue(final boolean print,
+                                      final SpacecraftState previous,
+                                      final SpacecraftState current,
+                                      final UnivariateProcessNoise univariateProcessNoise,
+                                      final int sampleNumber,
+                                      final double relativeTolerance) {
         
         // Get the process noise matrix
         final RealMatrix processNoiseMatrix = univariateProcessNoise.getProcessNoiseMatrix(previous, current);
@@ -138,8 +295,8 @@ public class UnivariateprocessNoiseTest {
                                                      null);
         // Transform from inertial to current spacecraft LOF frame
         final Transform inertialToLof = univariateProcessNoise.getLofType().transformFromInertial(current.getDate(),
-                                                                                                  current.getOrbit().getPVCoordinates());
-        // Create the vectors and compute the stats
+                                                                                                  current.getOrbit().getPVCoordinates());        
+        // Create the vectors and compute the states
         for (int i = 0; i < sampleNumber; i++) {
             
             // Create a random vector
@@ -148,22 +305,31 @@ public class UnivariateprocessNoiseTest {
             // Orbital parameters values
             // -------------------------
                         
-            // Get the full inertial orbit by adding up the values of current orbit and orbit error (first 6 cop. of random vector)
+            // Get the full inertial orbit by adding up the values of current orbit and orbit error (first 6 components of random vector)
             final double[] modifiedOrbitArray = new double[6];
             for (int j = 0; j < 6; j++) {
                 modifiedOrbitArray[j] = currentOrbitArray[j] + randomVector[j];
             }
             
             // Get the corresponding PV coordinates
-            final TimeStampedPVCoordinates inertialPV = 
-                            current.getOrbit().getType().mapArrayToOrbit(modifiedOrbitArray,
-                                                                         null,
-                                                                         univariateProcessNoise.getPositionAngle(),
-                                                                         current.getDate(),
-                                                                         current.getMu(),
-                                                                         current.getFrame())
-                            .getPVCoordinates();
-            
+            TimeStampedPVCoordinates inertialPV = null;
+            try {
+                inertialPV = current.getOrbit().getType().mapArrayToOrbit(modifiedOrbitArray,
+                                                                          null,
+                                                                          univariateProcessNoise.getPositionAngle(),
+                                                                          current.getDate(),
+                                                                          current.getMu(),
+                                                                          current.getFrame())
+                                .getPVCoordinates();
+            } catch (OrekitIllegalArgumentException e) {
+                // If orbit becomes inconsistent due to errors that are too large, print orbital values
+                System.out.println("i = " + i + " / Inconsistent Orbit");
+                System.out.println("\tCurrent Orbit  = " + Arrays.toString(currentOrbitArray));
+                System.out.println("\tModified Orbit = " + Arrays.toString(modifiedOrbitArray));
+                System.out.println("\tDelta Orbit    = " + Arrays.toString(randomVector));
+                e.printStackTrace();
+                System.err.println(e.getMessage());
+            }
             
             // Transform from inertial to current LOF
             // The value obtained is the Cartesian error vector in LOF (w/r to current spacecraft position)
@@ -225,6 +391,18 @@ public class UnivariateprocessNoiseTest {
             }
         }
         
+        // Print values
+        if (print) {
+            System.out.println("\tdt = " + dt + " / N = " + sampleNumber + "\n");
+            System.out.println("\tσ orbit ref   = " + Arrays.toString(orbitalValues));
+            System.out.println("\tσ orbit stat  = " + Arrays.toString(orbitalStatisticsValues));
+            System.out.println("\tσ orbit %     = " + Arrays.toString(Arrays.stream(orbitalRelativeValues).map(i -> i*100.).toArray()) + "\n");
+            
+            System.out.println("\tσ propag ref   = " + Arrays.toString(propagationValues));
+            System.out.println("\tσ propag stat  = " + Arrays.toString(propagationStatisticsValues));
+            System.out.println("\tσ propag %     = " + Arrays.toString(Arrays.stream(propagationRelativeValues).map(i -> i*100.).toArray()) + "\n");
+        }
+        
         // Test the values
         assertArrayEquals(new double[6], 
                           orbitalRelativeValues,
@@ -238,7 +416,7 @@ public class UnivariateprocessNoiseTest {
      * @param covarianceMatrix input covariance matrix
      * @return correlated gaussian random vectors generator
      */
-    private static CorrelatedRandomVectorGenerator createSampler(final RealMatrix covarianceMatrix) {
+    private CorrelatedRandomVectorGenerator createSampler(final RealMatrix covarianceMatrix) {
         double small = 10e-20 * covarianceMatrix.getNorm();
         return new CorrelatedRandomVectorGenerator(
                 covarianceMatrix,
@@ -246,25 +424,33 @@ public class UnivariateprocessNoiseTest {
                 new GaussianRandomGenerator(new Well1024a(0x366a26b94e520f41l)));
     }
     
-    /** Bug on Vy when dt gets large (here 1/2 Torb is enough to make it crash).
-     *  Other components are ok.
+    /** Test LOF orbital covariance matrix value against reference.
+     * 1. Initialize with different univariate functions for orbital/propagation parameters variation
+     * 2. Get the inertial process noise covariance matrix
+     * 3. Convert the inertial covariance from 2 in Cartesian and LOF
+     * 4. Compare values of 3 with reference values from 1
      */
-    @Ignore
     @Test
-    public void testBugVy() {
+    public void testLofCartesianOrbitalCovarianceFormal() {
 
         // Create context
         Context context = EstimationTestUtils.eccentricContext("regular-data:potential:tides");
 
+        // Print result on console ?
+        final boolean print = false;
+        
         // Create initial orbit and propagator builder
-        final OrbitType     orbitType     = OrbitType.CARTESIAN;
-        final PositionAngle positionAngle = PositionAngle.TRUE; // Not used here
+        final OrbitType     orbitType     = OrbitType.KEPLERIAN;
+        final PositionAngle positionAngle = PositionAngle.MEAN;
         final boolean       perfectStart  = true;
         final double        minStep       = 1.e-6;
         final double        maxStep       = 60.;
         final double        dP            = 1.;
         final NumericalPropagatorBuilder propagatorBuilder = context.createBuilder(orbitType, positionAngle, perfectStart,
-                                                                                   minStep, maxStep, dP);
+                                                                                   minStep, maxStep, dP,
+                                                                                   Force.POTENTIAL, Force.THIRD_BODY_MOON,
+                                                                                   Force.THIRD_BODY_SUN,
+                                                                                   Force.SOLAR_RADIATION_PRESSURE);
 
         // Create a propagator
         final Propagator propagator = EstimationTestUtils.createPropagator(context.initialOrbit,
@@ -296,274 +482,96 @@ public class UnivariateprocessNoiseTest {
                                                                                positionAngle,
                                                                                lofCartesianOrbitalParametersEvolution,
                                                                                propagationParametersEvolution);
-        // Test on initial value, after 1 min and after a
+        // Initial value
         final SpacecraftState state0 = propagator.getInitialState();
         
-        // dt = 1/2 Torb
+        // 1 orbit
         final SpacecraftState state1 = propagator.propagate(context.initialOrbit.getDate()
-                                                            .shiftedBy(context.initialOrbit.getKeplerianPeriod()/2.));
-        // dt = 1 Torb
-        final SpacecraftState state2 = propagator.propagate(context.initialOrbit.getDate()
                                                             .shiftedBy(context.initialOrbit.getKeplerianPeriod()));
+        // 1 day
+        final SpacecraftState state2 = propagator.propagate(context.initialOrbit.getDate().shiftedBy(86400.));
         
-        // dt = 2 Torb
-        final SpacecraftState state3 = propagator.propagate(context.initialOrbit.getDate()
-                                                            .shiftedBy(2. * context.initialOrbit.getKeplerianPeriod()));
-        
-        // Number of samples for the statistics
-        final int sampleNumber = 10000;
-        
-        // FIXME: Relative tolerance = 87% so that the first two tests pass 
-        final double relativeTolerance = 87e-2;;
-        
-        // dt = 1/2 Torb, error on Vy is 2.63%
-        checkBugCovarianceValue(false, state0, state1, processNoise, sampleNumber, relativeTolerance, false);
-        // dt = 1 Torb, error on Vy is 26%
-        checkBugCovarianceValue(false, state0, state2, processNoise, sampleNumber, relativeTolerance, false);
-        // dt = 2Torb, with a wrong velocity composition, it works well, error on Vy is about 0.26%
-        checkBugCovarianceValue(false, state0, state3, processNoise, sampleNumber, relativeTolerance, true);
-        // dt = 2Torb, error on Vy is 87%
-        checkBugCovarianceValue(false, state0, state3, processNoise, sampleNumber, relativeTolerance, false);
-        
-    }
-    
-    /** Bugs with Keplerian formalism, all components are out. */
-    @Ignore
-    @Test
-    public void testBugKeplerian() {
-
-        // Create context
-        Context context = EstimationTestUtils.eccentricContext("regular-data:potential:tides");
-
-        // Create initial orbit and propagator builder
-        final OrbitType     orbitType     = OrbitType.KEPLERIAN;
-        final PositionAngle positionAngle = PositionAngle.TRUE;
-        final boolean       perfectStart  = true;
-        final double        minStep       = 1.e-6;
-        final double        maxStep       = 60.;
-        final double        dP            = 1.;
-        final NumericalPropagatorBuilder propagatorBuilder = context.createBuilder(orbitType, positionAngle, perfectStart,
-                                                                                   minStep, maxStep, dP);
-
-        // Create a propagator
-        final Propagator propagator = EstimationTestUtils.createPropagator(context.initialOrbit,
-                                                                           propagatorBuilder);
-        
-        // Define the univariate functions for the standard deviations      
-        final UnivariateFunction[] lofCartesianOrbitalParametersEvolution = new UnivariateFunction[6];
-        // Evolution for position error
-        lofCartesianOrbitalParametersEvolution[0] = new PolynomialFunction(new double[] {100., 0., 1e-4});
-        lofCartesianOrbitalParametersEvolution[1] = new PolynomialFunction(new double[] {100., 1e-1, 0.});
-        lofCartesianOrbitalParametersEvolution[2] = new PolynomialFunction(new double[] {100., 0., 0.});
-        // Evolution for velocity error
-        lofCartesianOrbitalParametersEvolution[3] = new PolynomialFunction(new double[] {1., 0., 1.e-6});
-        lofCartesianOrbitalParametersEvolution[4] = new PolynomialFunction(new double[] {1., 1e-3, 0.});
-        lofCartesianOrbitalParametersEvolution[5] = new PolynomialFunction(new double[] {1., 0., 0.});
-
-        final UnivariateFunction[] propagationParametersEvolution =
-                        new UnivariateFunction[] {new PolynomialFunction(new double[] {10, 1., 1e-4}),
-                                                  new PolynomialFunction(new double[] {1000., 0., 0.})};
-        
-        // Create a dummy initial covariance
-        final RealMatrix initialCovarianceMatrix = MatrixUtils.createRealIdentityMatrix(7);
-        
-        // Set the process noise object
-        // Define input LOF and output position angle
-        final LOFType lofType = LOFType.TNW;
-        final UnivariateProcessNoise processNoise = new UnivariateProcessNoise(initialCovarianceMatrix,
-                                                                               lofType,
-                                                                               positionAngle,
-                                                                               lofCartesianOrbitalParametersEvolution,
-                                                                               propagationParametersEvolution);
-        // Test on initial value, after 1 min and after 1 hour
-        final SpacecraftState state0 = propagator.getInitialState();
-        final SpacecraftState state1 = propagator.propagate(context.initialOrbit.getDate()
-                                                            .shiftedBy(context.initialOrbit.getKeplerianPeriod()/4.));
-        
-//        //FIXME: debug
-//        final Orbit initialOrbit = propagator.getInitialState().getOrbit(); 
-//        final double posNorm = initialOrbit.getPVCoordinates().getPosition().getNorm();
-//        final double velNorm = initialOrbit.getPVCoordinates().getVelocity().getNorm();
-//        final Orbit orbit1 = new CartesianOrbit(new PVCoordinates(new Vector3D(posNorm, 0, 0),
-//                                                                  new Vector3D(0, 0, velNorm)),
-//                                                initialOrbit.getFrame(),
-//                                                initialOrbit.getDate(), initialOrbit.getMu());
-//        final SpacecraftState state1 = new SpacecraftState(orbitType.convertType(orbit1));
-//        final SpacecraftState state0 = state1.shiftedBy(-initialOrbit.getKeplerianPeriod()/4.);
-//        // debug
-        
-        // Number of samples for the statistics
-        final int sampleNumber = 10000;
-        
-        // FIXME: Relative tolerance = 134% so that the first two tests pass 
-        final double relativeTolerance = 134e-2;;
+        if (print) {
+            System.out.println("Orbit Type    : " + orbitType);
+            System.out.println("Position Angle: " + positionAngle);
+        }
         
-        checkBugCovarianceValue(false, state0, state0, processNoise, sampleNumber, relativeTolerance, false);
-        checkBugCovarianceValue(false, state0, state1, processNoise, sampleNumber, relativeTolerance, false);
-        checkBugCovarianceValue(false, state0, state1, processNoise, sampleNumber, relativeTolerance, true);
+        // Worst case, KEPLERIAN MEAN - 1.62e-11
+        checkLofOrbitalCovarianceMatrix(print, state0, state0, processNoise, 1.62e-11);
+        // Worst case, CIRCULAR ECCENTRIC - 2.78e-10
+        checkLofOrbitalCovarianceMatrix(print, state0, state1, processNoise, 2.78e-10);
+        // Worst case, CIRCULAR TRUE - 9.15e-9
+        checkLofOrbitalCovarianceMatrix(print, state0, state2, processNoise, 9.15e-9);
     }
     
-    private static void checkBugCovarianceValue(final boolean print,
-                                                final SpacecraftState previous,
-                                                final SpacecraftState current,
-                                                final UnivariateProcessNoise univariateProcessNoise,
-                                                final int sampleNumber,
-                                                final double relativeTolerance,
-                                                final boolean wrongVelocityComposition) {
-
-        // Get the process noise matrix
-        final RealMatrix processNoiseMatrix = univariateProcessNoise.getProcessNoiseMatrix(previous, current);
-
-        // Initialize a random vector generator
-        final CorrelatedRandomVectorGenerator randomVectorGenerator = createSampler(processNoiseMatrix);
-
-        // Propagation parameters length
-        int propagationParametersLength = processNoiseMatrix.getColumnDimension() - 6;
-        if ( propagationParametersLength < 0) {
-            propagationParametersLength = 0; 
-        }
-
-        // Prepare the statistics
-        final StreamingStatistics[] orbitalStatistics = new StreamingStatistics[6];
+    /** Check orbital covariance matrix in LOF wrt reference.
+     * Here we do the reverse calculcation
+     */
+    private void checkLofOrbitalCovarianceMatrix(final boolean print,
+                                                 final SpacecraftState previous,
+                                                 final SpacecraftState current,
+                                                 final UnivariateProcessNoise univariateProcessNoise,
+                                                 final double relativeTolerance) {
+        
+        // Get the process noise matrix in inertial frame 
+        final RealMatrix inertialQ = univariateProcessNoise.getProcessNoiseMatrix(previous, current);
+        
+        // Extract the orbit part
+        final RealMatrix inertialOrbitalQ = inertialQ.getSubMatrix(0, 5, 0, 5);
+        
+        // Jacobian from parameters to Cartesian
+        final double[][] dCdY = new double[6][6];
+        current.getOrbit().getJacobianWrtParameters(univariateProcessNoise.getPositionAngle(), dCdY);
+        final RealMatrix jacOrbToCar = new Array2DRowRealMatrix(dCdY, false);
+        
+        // Jacobian from inertial to LOF
+        final double[][] dLOFdI = new double[6][6];
+        univariateProcessNoise.getLofType().transformFromInertial(current.getDate(),
+                                                                  current.getOrbit().getPVCoordinates()).getJacobian(CartesianDerivativesFilter.USE_PV, dLOFdI);
+        final RealMatrix jacIToLOF = new Array2DRowRealMatrix(dLOFdI, false);
+        
+        // Complete Jacobian
+        final RealMatrix jac = jacIToLOF.multiply(jacOrbToCar);
+        
+        // Q in LOF and Cartesian
+        final RealMatrix lofQ = jac.multiply(inertialOrbitalQ).multiplyTransposed(jac);
+
+        // Build reference LOF Cartesian orbital sigmas
+        final RealVector refLofSig = new ArrayRealVector(6); 
+        double dt = current.getDate().durationFrom(previous.getDate());
         for (int i = 0; i < 6; i++) {
-            orbitalStatistics[i] = new StreamingStatistics();
-        }
-        StreamingStatistics[] propagationStatistics;
-        if (propagationParametersLength > 0) {
-            propagationStatistics = new StreamingStatistics[propagationParametersLength];
-            for (int i = 0; i < propagationParametersLength; i++) {
-                propagationStatistics[i] = new StreamingStatistics();
-            }
-        } else {
-            propagationStatistics = null;  
+            refLofSig.setEntry(i, univariateProcessNoise.getLofCartesianOrbitalParametersEvolution()[i].value(dt));
         }
-
-        // Current orbit stored in an array
-        // With the position angle defined in the univariate process noise function
-        final double[] currentOrbitArray = new double[6];
-        current.getOrbit().getType().mapOrbitToArray(current.getOrbit(),
-                                                     univariateProcessNoise.getPositionAngle(),
-                                                     currentOrbitArray,
-                                                     null);
-        // Transform from inertial to current spacecraft LOF frame
-        final Transform inertialToLof = univariateProcessNoise.getLofType().transformFromInertial(current.getDate(),
-                                                                                                  current.getOrbit().getPVCoordinates());
-        // Create the vectors and compute the stats
-        for (int i = 0; i < sampleNumber; i++) {
-
-            // Create a random vector
-            final double[] randomVector = randomVectorGenerator.nextVector();
-
-            // Orbital parameters values
-            // -------------------------
-
-            // Get the full inertial orbit by adding up the values of current orbit and orbit error (first 6 components of random vector)
-            final double[] modifiedOrbitArray = new double[6];
+        
+        // Compare diagonal values with reference (relative difference) and suppress them from the matrix
+        // Ensure non-diagonal values are into numerical noise sensitivity
+        RealVector dLofDiag = new ArrayRealVector(6);
+        for (int i = 0; i < 6; i++) {
             for (int j = 0; j < 6; j++) {
-                modifiedOrbitArray[j] = currentOrbitArray[j] + randomVector[j];
-            }
-
-            // Get the corresponding PV coordinates
-            final TimeStampedPVCoordinates inertialPV = 
-                            current.getOrbit().getType().mapArrayToOrbit(modifiedOrbitArray,
-                                                                         null,
-                                                                         univariateProcessNoise.getPositionAngle(),
-                                                                         current.getDate(),
-                                                                         current.getMu(),
-                                                                         current.getFrame())
-                            .getPVCoordinates();
-
-
-            // Transform from inertial to current LOF
-            // The values obtained should be the Cartesian error vector in LOF (w/r to current spacecraft position)
-            final PVCoordinates lofPV;
-            if (!wrongVelocityComposition) {
-                // Proper velocity composition
-                lofPV = inertialToLof.transformPVCoordinates(inertialPV);
-            } else {
-                // Wrong velocity composition, ignoring orbital angular velocity
-                final Vector3D pos = inertialToLof.transformPosition(inertialPV.getPosition());
-                final Vector3D vel = inertialToLof.transformVector(inertialPV.getVelocity());
-                lofPV = new PVCoordinates(pos, vel);
-            }                    
-
-            // Store the LOF PV values in the statistics summaries
-            orbitalStatistics[0].addValue(lofPV.getPosition().getX());
-            orbitalStatistics[1].addValue(lofPV.getPosition().getY());
-            orbitalStatistics[2].addValue(lofPV.getPosition().getZ());
-            orbitalStatistics[3].addValue(lofPV.getVelocity().getX());
-            orbitalStatistics[4].addValue(lofPV.getVelocity().getY());
-            orbitalStatistics[5].addValue(lofPV.getVelocity().getZ());
-
-            // Propagation parameters
-            // ----------------------
-
-            // Extract the propagation parameters random vector and store them in the statistics
-            if (propagationParametersLength > 0) {
-                for (int j = 6; j < randomVector.length; j++) {
-                    propagationStatistics[j - 6].addValue(randomVector[j]);
+                double refI = refLofSig.getEntry(i);
+                if (i == j) {
+                    // Diagonal term
+                    dLofDiag.setEntry(i, FastMath.abs(1. - lofQ.getEntry(i, i) / refI / refI));
+                    lofQ.setEntry(i, i, 0.);
+                } else {
+                    // Non-diagonal term, ref is 0.
+                    lofQ.setEntry(i, j, FastMath.abs(lofQ.getEntry(i,j) / refI / refLofSig.getEntry(j)));
                 }
-            }                      
-        }
-
-        // Get the real values and the statistics
-        // --------------------------------------
-
-        // DT
-        final double dt = current.getDate().durationFrom(previous.getDate());
-
-        // Get the values of the orbital functions and the statistics
-        final double[] orbitalValues = new double[6];
-        final double[] orbitalStatisticsValues = new double[6];
-        final double[] orbitalRelativeValues = new double[6];
-
-        for (int i = 0; i < 6; i++) {
-            orbitalValues[i] = FastMath.abs(univariateProcessNoise.getLofCartesianOrbitalParametersEvolution()[i].value(dt));
-            orbitalStatisticsValues[i] = orbitalStatistics[i].getStandardDeviation();
-
-            if (FastMath.abs(orbitalValues[i]) > 1e-15) {
-                orbitalRelativeValues[i] = FastMath.abs(1. - orbitalStatisticsValues[i]/orbitalValues[i]);
-            } else {
-                orbitalRelativeValues[i] = orbitalStatisticsValues[i];
-            }
-        }
-
-        // Get the values of the propagation functions and statistics
-        final double[] propagationValues = new double[propagationParametersLength];
-        final double[] propagationStatisticsValues = new double[propagationParametersLength];
-        final double[] propagationRelativeValues = new double[propagationParametersLength];
-        for (int i = 0; i < propagationParametersLength; i++) {
-            propagationValues[i] = FastMath.abs(univariateProcessNoise.getPropagationParametersEvolution()[i].value(dt));
-            propagationStatisticsValues[i] = propagationStatistics[i].getStandardDeviation();
-            if (FastMath.abs(propagationValues[i]) > 1e-15) {
-                propagationRelativeValues[i] = FastMath.abs(1. - propagationStatisticsValues[i]/propagationValues[i]);
-            } else {
-                propagationRelativeValues[i] = propagationStatisticsValues[i];
             }
+            
         }
-
+        
+        // Norm of diagonal and non-diagonal
+        double dDiag = dLofDiag.getNorm();
+        double dNonDiag = lofQ.getNorm();
+        
+        // Print values ?
         if (print) {
-            // FIXME: Test the values
-            System.out.println("dt = " + dt + " / N = " + sampleNumber + "\n");
-            if (wrongVelocityComposition) {
-                System.out.println("Using wrong velocity computation here" + "\n");
-            }
-
-            System.out.println("σ orbit ref   = " + Arrays.toString(orbitalValues));
-            System.out.println("σ orbit stat  = " + Arrays.toString(orbitalStatisticsValues));
-            System.out.println("σ orbit %     = " + Arrays.toString(Arrays.stream(orbitalRelativeValues).map(i -> i*100.).toArray()) + "\n");
-
-            System.out.println("σ propag ref   = " + Arrays.toString(propagationValues));
-            System.out.println("σ propag stat  = " + Arrays.toString(propagationStatisticsValues));
-            System.out.println("σ propag %     = " + Arrays.toString(Arrays.stream(propagationRelativeValues).map(i -> i*100.).toArray()) + "\n");
-            //debug
+            System.out.println("\tdt = " + dt);
+            System.out.format(Locale.US, "\tΔDiagonal norm in Cartesian LOF     = %10.4e%n", dDiag);
+            System.out.format(Locale.US, "\tΔNon-Diagonal norm in Cartesian LOF = %10.4e%n%n", dNonDiag);
         }
-
-        assertArrayEquals(new double[6], 
-                          orbitalRelativeValues,
-                          relativeTolerance);
-        assertArrayEquals(new double[propagationParametersLength],
-                          propagationRelativeValues,
-                          relativeTolerance);
+        Assert.assertEquals(0.,  dDiag   , relativeTolerance);
+        Assert.assertEquals(0.,  dNonDiag, relativeTolerance);
     }
 }