multiscale / muscle3

The third major version of the MUltiScale Coupling Library and Environment
Apache License 2.0
25 stars 13 forks source link

Send a list of data #260

Closed rnouail closed 12 months ago

rnouail commented 12 months ago

Dear developpers,

I try to build a message to send based on a data list composed of two items:

Thank you in advance

Regards

Rémy

LourensVeen commented 12 months ago

I didn't test it, but I think this should work, assuming you have a float in x and a numpy.array in v:

msg = Message(timestamp, data=[x, v])

rnouail commented 12 months ago

Thank you for the answer, however, it is more complicated, because I want to use the piece of code into a matlab function and the proposed solution doesn't work. I did several tests :

voltage=[0:10]';
v0=10;
ip=100;

%Message creation
msg = py.libmuscle.Message(t_cur,py.None,data=[ip, v0]);
%don't Work (Matlab error) Error: Incorrect use of '=' operator. To assign a value to a variable, use '='. To compare
values for equality, use '=='.

msg = py.libmuscle.Message(t_cur,py.None,[ip, v0]); %don't Work (Matlab error)
%don't Work: Error using y.libmuscle.grid.Grid/horzcat Array formation and parentheses-style indexing with objects of class 'py.libmuscle.grid.Grid' is not allowed.  Use objects of class 'py.libmuscle.grid.Grid' only as scalars or use a cell array.

msg = py.libmuscle.Message(t_cur,py.None,{ip, v0}); %Work

msg = py.libmuscle.Message(t_cur,py.None,voltage); %don't Work: Python Error: AttributeError: 'array.array' object has no attribute 'fromstring'

cell_voltage = num2cell(voltage'); %Only horizontal cells work

grid_voltage = py.libmuscle.Grid(cell_voltage); 

msg = py.libmuscle.Message(t_cur,py.None,[ip grid_voltage]);
%don't Work: Error using y.libmuscle.grid.Grid/horzcat Array formation and parentheses-style indexing with objects of class 'py.libmuscle.grid.Grid' is not allowed.  Use objects of class 'py.libmuscle.grid.Grid' only as scalars or use a cell array.

msg = py.libmuscle.Message(t_cur,py.None,grid_voltage); % % error during execution with muscle_manager: Python Error: AttributeError: 'tuple' object has no attribute 'flags'

I'm a little bit out of ideas. In cpp, I use the "data" object to build the data list for the message to send. I don't find how to do the same thing in my matlab-python code. Thank in advance for your help.

Regards

maarten-ic commented 12 months ago

Hi Rémy,

The MATLAB/Python integration is a bit cumbersome and you need to sometimes explicitly create Python objects from your MATLAB data.

  1. Create a Python list from MATLAB
    % msg = py.libmuscle.Message(t_cur,py.None,data=[ip, v0]);
    msg = py.libmuscle.Message(t_cur, t_next, py.list({ip, v0}))
  2. Create a numpy array from MATLAB
    % msg = py.libmuscle.Message(t_cur,py.None,voltage);
    msg = py.libmuscle.Message(t_cur, py.None, py.numpy.asarray(voltage));

Can you try if this solves your problem?

rnouail commented 12 months ago

Hi,

we progress : solution 1 works well to create a list. Thank

solution 2 is not working :

py.numpy.asarray([1 2 3]) Python Error: AttributeError: 'array.array' object has no attribute 'fromstring'

However, if I use a cell instead of the matrix, it works:

py.numpy.asarray({1 2 3})

Is also work for a scalar but it is useless.

py.numpy.asarray(1)

For the cell implemenation, there is a limitation : only horizontal cell is possible.

I ask google to make this numpy array from a matlab matrix but I'm still looking for.

Thank again for your help.

maarten-ic commented 12 months ago

Hi Rémy,

Looks like I made a mistake and you should instead use py.numpy.array(voltage) or py.numpy.ndarray(voltage). See also this support page from MATLAB: https://www.mathworks.com/help/matlab/matlab_external/passing-data-to-python.html#mw_b64f3777-2204-45e9-8ced-f3f363096a49

Hope this helps!

rnouail commented 12 months ago

I understand the issue : On my machine, if I load python 3.9 I've got the following error on matlab :

py.numpy.asarray([1 2 3]) Python Error: AttributeError: 'array.array' object has no attribute 'fromstring'

If I use python 3.7, everything is fine.

I need to reset my environnement with python 3.7 and I try again.

LourensVeen commented 12 months ago

Looks like array.array.fromstring was renamed array.array.frombytes in Python 3.2, and in Python 3.9 the deprecated array.array.fromstring was removed.

Which version of numpy are you running? You should be able to check that from Matlab using py.numpy.__version__. It's possible that you have an old version of NumPy that still uses fromstring, and which therefore doesn't work with Python 3.9.

rnouail commented 12 months ago

py.numpy.version doesn't work on matlab. I try : system('python -m pip show numpy') and I get the version 1.21.5 (with python3.7).

If I load the module python 3.9, I have got the version 1.25.0 for numpy.

LourensVeen commented 12 months ago

Hmm, well those should work as far as I can see, so it's probably not a numpy problem then.

It could be that there's something in the Matlab Python integration that uses fromstring still. There's a (thread at Matlab Central about it)[https://www.mathworks.com/matlabcentral/answers/638735-matlab-numpy-array-attributeerror-array-array-object-has-no-attribute-fromstring]. It refers to a Matlab/Python type compatibility table which is now at https://www.mathworks.com/support/requirements/python-compatibility.html.

Which version of Matlab do you have?

rnouail commented 12 months ago

I use matlab 2020b, but I'm happy to work with python 3.7. So it is not a strong issue for me .

LourensVeen commented 12 months ago

Okay, yes, then it's 2.7, 3.6, 3.7, or 3.8.

Python 3.7 does drop out of upstream support on Thursday. It will continue to work for a while, but with the most recent release of MUSCLE3 we've dropped support for Python 3.6 because it's becoming impossible to install anything on it due to broken metadata on PyPI. Eventually the same will happen with 3.7. If you have a working setup, you may want to run pip freeze and save the resulting list so you can reproduce it later if needed.

rnouail commented 12 months ago

By the way, I'm now able to communicate as I want between Matlab and my cpp agent, so I think we could close the issue. Thank a lot for you help. Regards

LourensVeen commented 12 months ago

Excellent, you're welcome! And thanks to Maarten, who actually solved it! :smile: