Issue constructing CartesianCovariance for an OEM file

I am currently implementing ephemeris writing via the CCSDS classes, and am having trouble creating entries for the CartesianCovariance class. From the API doc, instantiating requires a Supplier of FrameFacade CartesianCovariance(Supplier<FrameFacade> defaultFrameSupplier), however I am not sure how to construct this Supplier of FrameFacade.

The only example I found in the main Orekit for constructing that class was in at the following link, however I am not sure how to translate it to Python OemParser_L289

currentCovariance = new CartesianCovariance(() -> savedMetadata.getReferenceFrame());

I tried the subclassing approach, but there is no way to subclass a Supplier since it does not show up in java.utils.function (only DoubleConsumer, IntConsumer, & LongConsumer are available). A normal Python class with a get() method does not work either (below).

class ff_supplier:
    def __init__(self):
        self.ff = FrameFacade(FramesFactory.getEME2000(), CelestialBodyFrame.EME2000, None, None, '')
        super(test, self).__init__()
    def get(self):
        return self.ff

Is there something I am missing about instantiating this class?

Thanks!

Hi Aerow610,

Interesting, have not seen this before.

Subclassing java.utils.function.Supplier is not possible at the moment, this requires a PythonSupplier class (that is specific for the orekit wrapping) with the Supplier interface, and that could be then subclassed as your example class.

I could add this for the next release, it will probably not be possible to add it to java.utils but would land in org.orekit.python where these off-package wrapping helpers go.

Hi @petrus.hyvonen ,

Thank you for including this in 11.1 - I just installed and was able to subclass the FramesFacade with the new PythonSupplier. However, when trying to instantiate the CartesianCovariance, I am getting the following error:

class ff_supplier(PythonSupplier):
    def get(self):
        return FrameFacade(FramesFactory.getEME2000(), CelestialBodyFrame.EME2000, None, None, '')
supplier_class = ff_supplier()
covariance = CartesianCovariance(supplier_class)

Traceback (most recent call last):

  Input In [26] in <module>
    covariance = CartesianCovariance(supplier_class)

NotImplementedError: ('instantiating java class', <class 'org.orekit.files.ccsds.ndm.odm.CartesianCovariance'>)

I also tried giving the CartesianCovariance the supplier_class itself (not instantiated), but got the same error.

Were you able to successfully test this interface on any other classes? Or is it perhaps something not exposed on the CartesianCovariance class?

Thanks!

Hi,

I think there is an error in the PythonSupplier wrapping, missing the typing parameter. Will check.

Thanks

There’s a new build version 3 of v11.1 on the conda-forge, this have an updated PythonSupplier class and some wrapping modifications to allow for the get method name.

I think it should work now, let us know…

Thank you @petrus.hyvonen - this is working nicely now!

If anyone is looking for the way to implement this in python, you can use the following (note you need to use the .map function on the FrameFacade, otherwise the covariance in the OEM will come out as the text of whatever you named the FrameFacade on init

# Supplier Class
class FrameFacadeSupplier(PythonSupplier):
    def __init__(self):
        frame_facade = FrameFacade(FramesFactory.getEME2000(), CelestialBodyFrame.EME2000, OrbitRelativeFrame.RTN, None, 'covariance_frame_facade')
        self.frame_facade_static = frame_facade.map(FramesFactory.getEME2000())
        super(FrameFacadeSupplier, self).__init__()
    def get(self):
        return self.frame_facade_static

# Init the supplier
supplier_class = FrameFacadeSupplier()

# Create Covariance entries
covar_out_list_java = ArrayList()
covar_entries = list[dict[AbsoluteDate, Array2DRowRealMatrix]]
# ^^Or however you want to organize, I have it with keys of 'epoch' and 'covariance_matrix'
for entry in covar_entries:
    covariance = CartesianCovariance(supplier_class)
    covariance.setEpoch(entry['epoch'])
    for i in range(6):
        for j in range(6):
            covariance.setCovarianceMatrixEntry(i, j, entry['covariance_matrix'].getEntry(i, j))
    covar_out_list_java.add(covariance)

# Now the covar_out_list_java can be added to an OemData instance via:
oem_data = OemData()
for i in range(covar_out_list_java.size()):
    oem_data.addCovarianceMatrix(covar_out_list_java.get(i))

Thanks for sharing the final code!