Access .mat file containing matlab classes in python

Posted on

Problem :

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

When loading the file using in python 3.3, I get the following:'D:test.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.

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

Leave a Reply

Your email address will not be published. Required fields are marked *