0

I have a .mat file which I load using scipy:

from oct2py import octave
import scipy.io as spio
matPath = "path/to/file.mat"
matFile = spio.loadmat(matPath)

I get a numpy array which I want to pass to octave function using oct2py, like that:

aMatStruct = matFile["aMatStruct"]
result = octave.aMatFunction(aMatStruct)

But I get the following error:

oct2py.utils.Oct2PyError: Datatype not supported

It seems it's due to the array dtype, which looks like: [('x', 'O'), ('y', 'O'), ('z', 'O')]

So I thought about changing it to 'S', 'U', or something that's supported.

  1. How can it be done?
  2. I couldn't find a supported dtype in the otc2py documentation. Any help on that?
  3. Is there a way to load the .mat file with another (supported) dtype? I looked here but couldn't find anything useful.

Note that inside aMatFunction it uses aMatStruct like that: x = aMatStruct.x.

Suever
  • 64,497
  • 14
  • 82
  • 101
galah92
  • 3,621
  • 2
  • 29
  • 55
  • can you upload a copy of your matfile and specify the exact octave function that fails? – Tasos Papastylianou Sep 08 '16 at 09:00
  • The 'O' means 'object'. The array has 3 fields. What did the srray look like on the matlab source, cells, structure? What does the oct function expect? – hpaulj Sep 08 '16 at 11:52

2 Answers2

0

Found a workaround!

I used the following script, which reconstructs python dictionaries from the loaded struct, which oct2py2 in turn interpret as matlab structs.

Community
  • 1
  • 1
galah92
  • 3,621
  • 2
  • 29
  • 55
0

I was going to suggest converting the resulting array to a valid dictionary but you beat me to it so I won't code it :p

However, the other, simpler solution I was going to suggest is that, since you're only using the struct within octave, you could just load it into its workspace and evaluate directly. i.e. the following works for me:

>>> octave.load("MyFile.mat")
>>> octave.eval("fieldnames(S)")
ans = 
{
  [1,1] = name
  [2,1] = age
}
[u'name', u'age']

EDIT eh screw it, here's the python solution; I'd started it anyway :p

>>> from oct2py import octave
>>> from scipy.io import loadmat
>>> F = loadmat("/home/tasos/Desktop/MyFile.mat")
>>> M = F["S"] # the name of the struct variable I saved in the mat file
>>> M = M[0][0]
>>> D = {M.dtype.names[i]:M[i][0] for i in range(len(M))}
>>> out = octave.fieldnames(D); out
[u'age', u'name']
Tasos Papastylianou
  • 21,371
  • 2
  • 28
  • 57
  • 1
    Not a generic solution (I have to know the struct fields), but really simple one! – galah92 Sep 08 '16 at 10:28
  • Well, of course, hahah! You didn't give any detail whatsoever; you just said "a function" on "a struct", so I just improvised with an example :p Adapt as necessary :) (having said that, that's exactly what the `fieldnames` function does, it gives you the names of a struct's fields! \o/ ) – Tasos Papastylianou Sep 08 '16 at 10:32