Question

I have a .mat file generated from matlab 2012b. It contains a variable with a user-defined matlab class.

When loading the file using scipy.io.loadmat in python 3.3, I get the following:

mat=scipy.io.loadmat('D:\test.mat')
mat
{'__header__': b'MATLAB 5.0 MAT-file, Platform: PCWIN64, Created on: Fri Feb 22 15:26:28 2013', '__function_workspace__': array([[ 0,  1, 73, ...,  0,  0,  0]], dtype=uint8), '__globals__': [], '__version__': '1.0', 'None': MatlabOpaque([ (b'futureDS', b'MCOS', b'cStream', [[3707764736], [2], [1], [1], [1], [1]])], 
      dtype=[('s0', 'O'), ('s1', 'O'), ('s2', 'O'), ('arr', 'O')])}

I am looking to access the "futureDS" object of type "cStream" but seem unable to do so using mat['None']. Calling mat['None'] simple results in:

MatlabOpaque([ (b'futureDS', b'MCOS', b'cStream', [[3707764736], [2], [1], [1], [1], [1]])], 
      dtype=[('s0', 'O'), ('s1', 'O'), ('s2', 'O'), ('arr', 'O')])

I am stuck here. I am new to python and trying to port my old work from matlab. Any help would be appreciated.

Thank you.

Was it helpful?

Solution

Unfortunately, SciPy does not support mat files that contain new-style class objects (those defined with classdef), nor does any third-party mat-file reader as far as I'm aware. That __function_workspace__ element in the returned mat dictionary contains the information you're after in some undocumented and as-yet-not-reverse-engineered way.

The easiest solution is to convert your custom classes into basic struct objects within Matlab before saving them to disk. This can be achieved (albeit with a warning) by simply calling struct(futureDS). It exposes all public and private properties as plain fields, which can be read by any third-party reader worth its salt.

(More technically, Matlab saves these objects with the Matlab Array type id of 17; the official documentation (PDF) only enumerates types up through 15).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top