Opened 11 years ago

Last modified 11 years ago

#2222 new defect

OMPython interface loses sequence info and OMPython exit bug

Reported by: petfr Owned by: alash325
Priority: critical Milestone: Future
Component: OMPython Version: trunk
Keywords: Cc: openmodelicadevelopers@…, janssen@…

Description

This is related to
#2221: Documentation of Scripting and Communication Protocol
Ticket URL: <https://trac.openmodelica.org/OpenModelica/ticket/2221#comment:1>

The bad state of documentation contributes to bugs
as the one below.

Initially Reported July 7, 2012, by Bill Janssen, Xerox Parc
(email: janssen@…)
Reported once more in person to Peter Frizson during
Modelica Design meeting June 4,2013

I'm trying to use the new Python interface to OpenModelica to pull the graphics annotations out of a model, so that I can render them as SVG.

However, when I pull the graphics for an icon, for example:

OMPython.execute("getIconAnnotation(Modelica.Electrical.Analog.Basic
.Ground)")

I get something like this (pretty-printed):

{'SET1': {'Set1': [-100.0, -100.0, 100.0, 100.0, True, 0.1, 2.0, 2.0]},

'SET2': {'Elements': {'Line1': {'Properties': {'Set1': [0.0, 0.0],

'Set2': [0, 0, 255],
'Set3': ['Arrow.None',

'Arrow.None'],

'Subset1': {'Set1': [-60,

50],

'Set2': [60,

50]},

'Values': [True,

0,
'LinePattern.Solid',
0.25,
3,
'Smooth.None']}},

[ ... more Line elements deleted ...]

Now, just for comparison, pulling it via OMShell-terminal looks like

{-100.0,-100.0,100.0,100.0,true,0.1,2.0,2.0,{Line(true, {0.0, 0.0}, 0, {{-60, 50}, {60, 50}}, {0, 0, 255}, LinePattern.Solid, 0.25, {Arrow.None, Arrow.None}, 3, Smooth.None), [... more Line elements deleted ...]

The additional and pointless key-value layers are simply a design flaw and an annoyance, but mapping ordered lists into unordered sets of name-value pairs is a bug. Take SET2:Elements:Line1:Properties:Subset1,
for instance. Apparently a Line can have many points (the Modelica spec is unclear on this), and they are given in order in the annotation.
However, the order in the Python value is only given by a properly constructed sort of the keys of that dict, and the default sort will not produce the correct results for sufficiently large sets of points ('Set10' will sort before 'Set2').

Let me suggest that all {} Modelica arrays be turned into Python lists, and that typed 'objects' (like Line) be turned into Python tuples giving the object type name ('Line'), and a list of values. So in that mapping, we'd see

{-100.0,-100.0,100.0,100.0,true,0.1,2.0,2.0,{Line(true, {0.0, 0.0}, 0,
{{-60, 50}, {60, 50}}, {0, 0, 255}, LinePattern.Solid, 0.25,
{Arrow.None, Arrow.None}, 3, Smooth.None), ...

become

[-100.0,-100.0,100.0,100.0,true,0.1,2.0,2.0,

('Line', [true, [0.0, 0.0], 0,
-60, 50], [60, 50?, [0, 0, 255], 'LinePattern.Solid', 0.25,
['Arrow.None', 'Arrow.None'], 3, 'Smooth.None'), ...

It's a shame we're not actually using the cumbersome CORBA system that's somewhat pointlessly built into the Python interface. If the IDL was fleshed out with the various method calls and data types that go across it, we could use it to generate network API documentation, and coherent APIs in Python and other languages. 'Arrow' would actually be an enumeration, and 'Arrow.None' would be a real Python value.

Bill

One more bug:

Bill: I find that running a Python program which invokes OMPython results in
an omc server *still running* after the Python program exits. There
should be an "atexit" hook there to shut down the server.

To make matters worse, if you try to do OMPython.execute('quit()'), the
module calls sys.exit(1) itself, a major no-no for a library module.
Just mark it as 'omc not running', and re-start omc if the user tries to
use it again.

Bill

Change History (2)

comment:1 in reply to: ↑ description Changed 11 years ago by adeas31

Replying to petfr:

This is related to
#2221: Documentation of Scripting and Communication Protocol
Ticket URL: <https://trac.openmodelica.org/OpenModelica/ticket/2221#comment:1>

The bad state of documentation contributes to bugs
as the one below.

Initially Reported July 7, 2012, by Bill Janssen, Xerox Parc
(email: janssen@…)
Reported once more in person to Peter Frizson during
Modelica Design meeting June 4,2013

I'm trying to use the new Python interface to OpenModelica to pull the graphics annotations out of a model, so that I can render them as SVG.

However, when I pull the graphics for an icon, for example:

OMPython.execute("getIconAnnotation(Modelica.Electrical.Analog.Basic
.Ground)")

I get something like this (pretty-printed):

{'SET1': {'Set1': [-100.0, -100.0, 100.0, 100.0, True, 0.1, 2.0, 2.0]},

'SET2': {'Elements': {'Line1': {'Properties': {'Set1': [0.0, 0.0],

'Set2': [0, 0, 255],
'Set3': ['Arrow.None',

'Arrow.None'],

'Subset1': {'Set1': [-60,

50],

'Set2': [60,

50]},

'Values': [True,

0,
'LinePattern.Solid',
0.25,
3,
'Smooth.None']}},

[ ... more Line elements deleted ...]

Now, just for comparison, pulling it via OMShell-terminal looks like

{-100.0,-100.0,100.0,100.0,true,0.1,2.0,2.0,{Line(true, {0.0, 0.0}, 0, {{-60, 50}, {60, 50}}, {0, 0, 255}, LinePattern.Solid, 0.25, {Arrow.None, Arrow.None}, 3, Smooth.None), [... more Line elements deleted ...]

The additional and pointless key-value layers are simply a design flaw and an annoyance, but mapping ordered lists into unordered sets of name-value pairs is a bug. Take SET2:Elements:Line1:Properties:Subset1,
for instance. Apparently a Line can have many points (the Modelica spec is unclear on this), and they are given in order in the annotation.
However, the order in the Python value is only given by a properly constructed sort of the keys of that dict, and the default sort will not produce the correct results for sufficiently large sets of points ('Set10' will sort before 'Set2').

Let me suggest that all {} Modelica arrays be turned into Python lists, and that typed 'objects' (like Line) be turned into Python tuples giving the object type name ('Line'), and a list of values. So in that mapping, we'd see

{-100.0,-100.0,100.0,100.0,true,0.1,2.0,2.0,{Line(true, {0.0, 0.0}, 0,
{{-60, 50}, {60, 50}}, {0, 0, 255}, LinePattern.Solid, 0.25,
{Arrow.None, Arrow.None}, 3, Smooth.None), ...

become

[-100.0,-100.0,100.0,100.0,true,0.1,2.0,2.0,

('Line', [true, [0.0, 0.0], 0,
-60, 50], [60, 50?, [0, 0, 255], 'LinePattern.Solid', 0.25,
['Arrow.None', 'Arrow.None'], 3, 'Smooth.None'), ...

I had pointed out this bug a long time ago to Anand (main developer of OMPython) but perhaps he didn't get time to fix it. It's not just that the order gets wrong also I noticed some values missing in some scenarios but I don't remember now which scenarios.

I like what Bill suggested but it will be a lot of work because we are taking everything as strings and then making them python types manually. Instead of doing this manual transformations for each of the result its way better that we should use CORBA correctly. AFAIK CORBA has the capability to convert the datatypes of one language to another. All we have to do is to write a correct IDL file.

It's a shame we're not actually using the cumbersome CORBA system that's somewhat pointlessly built into the Python interface. If the IDL was fleshed out with the various method calls and data types that go across it, we could use it to generate network API documentation, and coherent APIs in Python and other languages. 'Arrow' would actually be an enumeration, and 'Arrow.None' would be a real Python value.

Bill

I will be very happy if this happens. It will even makes thing a lot better for OMEdit.

One more bug:

Bill: I find that running a Python program which invokes OMPython results in
an omc server *still running* after the Python program exits. There
should be an "atexit" hook there to shut down the server.

To make matters worse, if you try to do OMPython.execute('quit()'), the
module calls sys.exit(1) itself, a major no-no for a library module.
Just mark it as 'omc not running', and re-start omc if the user tries to
use it again.

Bill

comment:2 Changed 11 years ago by adeas31

  • Cc janssen@… added
Note: See TracTickets for help on using tickets.