Casting np.array into JArray_double2D

Hello everyone,

I am trying to use the second constructor in this class to feed my PV measurements to the BatchLeastSquare method:

PV(AbsoluteDate date, Vector3D position, Vector3D velocity, double[][] covarianceMatrix, double baseWeight, ObservableSatellite satellite)

Well, I believe everything is correct except the covarianceMatrix. I have a numpy array, while the constuctor accepts JArray_double2D. So I need to convert my covarianceMatrix from numpy array to 2 dimensional (6x6) JArray. I am not hundred percent sure but some casting must be done in order to accomplish this.

from orekit.pyhelpers import datetime_to_absolutedate, JArray, JArray_double2D
from org.orekit.estimation.measurements import PV, ObservableSatellite
from org.hipparchus.geometry.euclidean.threed import Vector3D
from orekit import JArray_double
from org.hipparchus.linear import Array2DRowRealMatrix

observableSatellite = ObservableSatellite(0) # Propagator index = 0

covarianceMatrix  = np.zeros((6, 6))

for i in range(1000): #4321
    pos3D = Vector3D(float(truedata_df['pos_x'][i])*1000,
                     float(truedata_df['pos_y'][i])*1000,
                     float(truedata_df['pos_z'][i])*1000)                  # in [m]

   vel3D = Vector3D(float(truedata_df['vel_x'][i])*1000,
                     float(truedata_df['vel_y'][i])*1000,
                     float(truedata_df['vel_z'][i])*1000)                  # in [m/s]
    
    date = AbsoluteDate(truedata_df['date'][i].year,
                        truedata_df['date'][i].month,
                        truedata_df['date'][i].day,
                        truedata_df['date'][i].hour,
                        truedata_df['date'][i].minute,
                        float(truedata_df['date'][i].second)+0.566,
                        UTC)
    
    covarianceMatrix = np.array([[float(df_cov[i][0]), float(df_cov[i][1]), float(df_cov[i][3]), float(df_cov[i][6]), float(df_cov[i][10]), float(df_cov[i][15])],
                                 [float(df_cov[i][1]), float(df_cov[i][2]), float(df_cov[i][4]), float(df_cov[i][7]), float(df_cov[i][11]), float(df_cov[i][16])],
                                 [float(df_cov[i][3]), float(df_cov[i][4]), float(df_cov[i][5]), float(df_cov[i][8]), float(df_cov[i][12]), float(df_cov[i][17])],
                                 [float(df_cov[i][6]), float(df_cov[i][7]), float(df_cov[i][8]), float(df_cov[i][9]), float(df_cov[i][13]), float(df_cov[i][18])],
                                 [float(df_cov[i][10]), float(df_cov[i][11]), float(df_cov[i][12]), float(df_cov[i][13]), float(df_cov[i][14]), float(df_cov[i][19])],
                                 [float(df_cov[i][15]), float(df_cov[i][16]), float(df_cov[i][17]), float(df_cov[i][18]), float(df_cov[i][19]), float(df_cov[i][20])]])

    covarianceMatrix_1 = JArray_double.cast_(JArray('double')(covarianceMatrix[0]))
    covarianceMatrix_2 = JArray_double.cast_(JArray('double')(covarianceMatrix[1]))
    covarianceMatrix_3 = JArray_double.cast_(JArray('double')(covarianceMatrix[2]))
    covarianceMatrix_4 = JArray_double.cast_(JArray('double')(covarianceMatrix[3]))
    covarianceMatrix_5 = JArray_double.cast_(JArray('double')(covarianceMatrix[4]))
    covarianceMatrix_6 = JArray_double.cast_(JArray('double')(covarianceMatrix[5]))
    
    orekitPV_est = PV(date, pos3D, vel3D, covarianceMatrix, baseweight, observableSatellite)
    estimator.addMeasurement(orekitPV_est)

Individual elements in numpy covariance matrix can be cast into JArray_double object, but how can I get a 2D JArray using these elements? Below line returns an empty 2D JArray, but how can I assign above casted elements into this 2D JArray?

    covarianceMatrix = JArray_double2D(6,6)

Also, after creating JArray_double2D method we again need another .cast_ right? Do you have any idea how can it be done @petrus.hyvonen?

Basically, I couldn’t add my covariance matrix (np.array) to my estimations and this is my problem in a nutshell :sweat_smile: Anyone else faced a similar issue before? Any advice is appreciated.

Thanks,
Baris

Hi there,

I have never used Jarray to create a matrix for Orekit, but instead you can instantiate an Array2DRowRealMatrix and fill its elements with setEntry.

Best,
Romain.

Hi,

Hard to test without an working example (truedata_df missing), but I think you should be able to similar as in the JArray_double2D routine:

  arr = JArray('object')(x)

    for i in range(x):
        arr[i] = JArray('double')(y)

There arr[i] is your casted arrays and merging these into a JArray object and arr would be your final 2D matrix.

Hello @petrus.hyvonen , thanks for the reply. I’ve tried your suggestion as following:

arr = JArray('object')(6)

for i in range(6):        
   arr[i] = JArray('double')(covarianceMatrix[i])
            
orekitPV_est = PV(date, pos3D, vel3D, arr, baseweight, observableSatellite)    
estimator.addMeasurement(orekitPV_est)    

and recieved an error that looks like this:


JavaError                                 Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_19536\1758518618.py in <module>     
85     
86     covarianceMatrix = Array2DRowRealMatrix(arr)
---> 87     orekitPV_est = PV(date, pos3D, vel3D, arr, baseweight, observableSatellite)     
88     estimator.addMeasurement(orekitPV_est)     
89
JavaError: <super: <class 'JavaError'>, <JavaError object>>
    Java stacktrace:
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [[D
	at org.orekit.estimation.measurements.PV.<init>(PV.java:173)

so it seems like after casting elements we are supposed to cast them once again but it does not let me. Could not proceed with this way.

On the other hand, hello @Serrof, I will try your suggestion and keep you updated.

@Echulion I use @Serrof 's method for setting the covariance matrix element by element and haven’t had any problems - though I am setting the initial covariance matrix for the Kalman Filter, not in a PV measurement like you.

from org.hipparchus.linear import Array2DRowRealMatrix

covariance_matrix = [<here I have 6 rows of 6-element lists (should be similar to your numpy approach)>]
num_params = len(covariance_matrix)
covariance_matrix_java = Array2DRowRealMatrix(num_params, num_params)
for row in range(num_params):
    for col in range(num_params):
        covariance_matrix_java.setEntry(row, col, covariance_matrix[row][col])

I’m having the same issue that I cannot construct a PV measurement with a covariance matrix. Does anyone have a working example? I’m having doubts the interface for setting the covariance is correctly exposed.

Approach A

The second constructor OP refers to is:

PV(AbsoluteDate date, Vector3D position, Vector3D velocity, double[][] covarianceMatrix, double baseWeight, ObservableSatellite satellite)

This should correspond with:

@typing.overload
    def __init__(self, absoluteDate: org.orekit.time.AbsoluteDate, vector3D: org.hipparchus.geometry.euclidean.threed.Vector3D, vector3D2: org.hipparchus.geometry.euclidean.threed.Vector3D, doubleArray: typing.List[typing.List[float]], double2: float, observableSatellite: ObservableSatellite): ...

This suggest a simple list of lists of floats should do. I construct mine from a numpy array using:

c_inertial : typing.List[typing.List[float]] = c_numpy.tolist()

This results in an ‘InvalidArgsError’

PV(date, pv_inertial.getPosition(), pv_inertial.getVelocity(), c_inertial, float(1.0), self.target_satellite)
*** orekit.InvalidArgsError: (<class 'org.orekit.estimation.measurements.PV'>, '__init__', (<AbsoluteDate: 2023-02-15T12:00:00.000Z>, <Vector3D: {3,387,827.030357755; -5,654,903.875181666; -8,761.6192870896}>, <Vector3D: {2,540.2427141317; 1,584.8845619678; 7,187.4378710901}>, [[1.0000000000000027, -5.551115123125783e-17, 4.336808689942018e-19, 0.0, 0.0, 0.0], [-5.551115123125783e-17, 1.0000000000000027, -1.0842021724855044e-18, 0.0, 0.0, 0.0], [4.336808689942018e-19, -1.0842021724855044e-18, 1.0000000000000029, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 1.0000000000000027, -5.551115123125783e-17, 4.336808689942018e-19], [0.0, 0.0, 0.0, -5.551115123125783e-17, 1.0000000000000027, -1.0842021724855044e-18], [0.0, 0.0, 0.0, 4.336808689942018e-19, -1.0842021724855044e-18, 1.0000000000000029]], 1.0, <ObservableSatellite: org.orekit.estimation.measurements.ObservableSatellite@67c119b7>))

Approach B

When I try the JArray('object')(6) approach suggested by @petrus.hyvonen the arguments gets accepted, but I get the same casting error, but I think this is a red herring.

PV(date, pv_inertial.getPosition(), pv_inertial.getVelocity(), arr, float(1.0), self.target_satellite)
*** orekit.JavaError: <super: <class 'JavaError'>, <JavaError object>>
    Java stacktrace:
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [[D
	at org.orekit.estimation.measurements.PV.<init>(PV.java:173)

Approach C

Using the suggest approach of @Serrof , I still get the same InvalidArgsError. See the example below:

PV(date, pv_inertial.getPosition(), pv_inertial.getVelocity(), arr2, float(1.0), self.target_satellite)
*** orekit.InvalidArgsError: (<class 'org.orekit.estimation.measurements.PV'>, '__init__', (<AbsoluteDate: 2023-02-15T12:00:00.000Z>, <Vector3D: {3,387,827.030357755; -5,654,903.875181666; -8,761.6192870896}>, <Vector3D: {2,540.2427141317; 1,584.8845619678; 7,187.4378710901}>, <Array2DRowRealMatrix: Array2DRowRealMatrix{{1.0,-0.0,0.0,0.0,0.0,0.0},{-0.0,1.0,-0.0,0.0,0.0,0.0},{0.0,-0.0,1.0,0.0,0.0,0.0},{0.0,0.0,0.0,1.0,-0.0,0.0},{0.0,0.0,0.0,-0.0,1.0,-0.0},{0.0,0.0,0.0,0.0,-0.0,1.0}}>, 1.0, <ObservableSatellite: org.orekit.estimation.measurements.ObservableSatellite@67c119b7>))

Hey there,

The constructor wants double[][] so you need to call getData() on your matrix in approach C.

Edit: also, you don’t need to do float(1.). Writing the dot is enough.

Best,
Romain.

Hi @Serrof Many thanks for the swift reply. Unfortunately, I still get the same casting error.

Hopefully, by explaining what I do in more detail can help to narrow down the cause/proper way to call PV from Python.

I arrive at my starting matrix as follows:

cov : typing.List[typing.List[float]] = np.dot(R,np.dot(c_itrf, R.transpose())).tolist()

Its properties are:

> (type(cov),type(cov[0]),type(cov[0][0]))
(<class 'list'>, <class 'list'>, <class 'float'>)

> cov
[[1503277.1368901345, -1.1641532182693481e-10, 6.821210263296962e-13, 0.0, 0.0, 0.0], [0.0, 1503277.1368901348, 1.1368683772161603e-12, 0.0, 0.0, 0.0], [4.547473508864641e-13, 6.821210263296962e-13, 1503277.1368901345, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 150.32771368901345, 0.0, 8.326672684688674e-17], [0.0, 0.0, 0.0, 0.0, 150.32771368901345, 1.1102230246251565e-16], [0.0, 0.0, 0.0, 8.326672684688674e-17, 1.1102230246251565e-16, 150.32771368901345]]

To convert to an input matrix for the PV class, I apply the process suggested by Serrof (approach C in my earlier post).

cov_java = Array2DRowRealMatrix(6, 6)
for row in range(6):
    for col in range(6):
        cov_java.setEntry(row, col, cov[row][col])

This results in the following cov_java object and construction of pv_meas.

> (type(cov_java),type(cov_java.getData()))
(<class 'org.hipparchus.linear.Array2DRowRealMatrix'>, <class 'orekit._orekit.JArray_object'>)

cov_java.getData()
JArray<object>[<Object: [D@27f74733>, <Object: [D@7bef452c>, <Object: [D@4bb8855f>, <Object: [D@57fae983>, <Object: [D@4a29f290>, <Object: [D@4bee18dc>]

> pv_meas = PV(date, position, velocity, cov_java.getData(), 1.0, self.target_satellite)
*** orekit.JavaError: <super: <class 'JavaError'>, <JavaError object>>
    Java stacktrace:
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [[D
	at org.orekit.estimation.measurements.PV.<init>(PV.java:173)

As you can see, I still get the same casting errors.