NDM object from strings

Hi Orekit community,

I was wondering if there is a way to create an Ndm object such as Opm or Cdm from a String?
So without reading a file.

Best,
Romain.

Yes, but beware, some Java is involved!
CCSDS parsing is based on an Orekit interface called DataSource, which acts as a proxy to underlying binary streams or character readers and delays opening of the channel until it is really needed. The delaying property is of no use in your case, since you already have the string, but you must anyway provide a way to open a reader on your string. The following should work:

  String message = getTheStringMessage();
  DataSource ds  = new DataSource("some-name-for-my-message",
                                  () -> new StringReader(message));
  Opm opm        = new ParserBuilder().parseMessage(ds);

Dear Luc,

thank you! I see that this involves Java’s lambda expression. I think you can guess my next question :sweat_smile:: how to replicate that with the Python wrapper???

Cheers,
Romain.

Anybody out there to figure this one out?
Or better, could this constructor of DataSource be added to the Java code?

Romain.

Hello,

sorry to bring this back up, but is it acceptable from a design perspective to have the way to initialize DataSource of Luc basically turned into a proper constructor?
This would simplify the life of the Pythoners out there trying to parse NDMs from strings.

Cheers,
Romain.

Perhaps we could add a StringDataSource (or some better name) that would extend the DataSource class.

Hi,

Sorry for a bit late response, but what is needed is that we introduce a new class PythonReaderOpener that represents the ReaderOpener interface and can be subclassed in Python to implement the openOnece() method.

I can add this in coming version of the wrapper.

1 Like

@petrus.hyvonen Sorry to bother you, but I’ve been looking for documentation for this method or an example of how to use it everywhere and I can’t find it. I can’t even find the source code for it (though I don’t understand how that’s possible). Would it be possible for you to write a code snippet demonstrating how to use PythonReaderOpener? To be clear, I was able to import the method into python, just not use it. Thank you.

Hi,

I won’t be able to make an example and test in near future, but in principle you should make a own class that is inheriting PythonReaderOpener to signal that the class conforms to that interface:

DataSource(String name, DataSource.ReaderOpener readerOpener)

So something in line with:

class MyReaderOpener(PythonReaderOpener):

   def openOnce():
       dosomething.. or return StringReader(message)

And then

DataSource("some-name-for-my-message", MyReaderOpener())


1 Like

Thank you!

I got it working! For the record:

from java.io import StringReader

from org.orekit.data import DataSource
from org.orekit.data import PythonReaderOpener
from org.orekit.files.ccsds.ndm import ParserBuilder
from org.orekit.files.ccsds.ndm.odm.oem import Oem as OrekitOEM
from org.orekit.files.ccsds.ndm.odm.oem import OemParser

class MyReaderOpener(PythonReaderOpener):
    
    def __init__(self, msgStr):
        
        self.msgStr = msgStr
        
        super(MyReaderOpener, self).__init__()

    def init(self, m):
        pass

    def openOnce(self):
        return StringReader(self.msgStr)

def get_oem_propagators() :

    #import your oem data string here

    orekitOemParser = ParserBuilder().buildOemParser()
    readerOpener = MyReaderOpener(oemString)
    dataSource = DataSource("your-string-here", readerOpener )
    oemData = OemParser.parse(dataSource)

Note: the interpreter has to be able to find the orekit-data.zip folder - otherwise the parse command will not work.

1 Like

Great you solved it! And thanks for sharing the solution, this could be quite useful in several cases, to avoid shuffling to files.

1 Like