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.
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).