Python Mlab - cannot import name find_available_releases

I am new to Python. I am trying to run MATLAB from within Python using the mlab package. I followed the guide on the website and I entered it on the Python command line:

from mlab.releases import latest_release 

I got an error:

 cannot import name find_available_releases 

It seems that in matlabcom.py there was no find_available_releases function.

Can I find out if anyone knows how to resolve this? Thanks!

PS: I am using Windows 7, MATLAB 2012a and Python 2.7

+8
python windows matlab matlab-deployment mlab python-mlab
source share
2 answers

I skipped the code and I don’t think that all the README file and its documentation correspond to what is actually implemented. Most likely, it is copied from the original mlabwrap project.

This is confusing because mlabwrap is implemented using the C extension module to interact with the MATLAB Engine API . However, the mlab code seems to have replaced this part with a pure Python implementation as the MATLAB-bridge backend. It comes from the Dana Pe'er Lab and uses two different methods for interacting with MATLAB depending on the platform ( COM / ActiveX on Windows and pipe on Linux / Mac).


Now that we understand how the backend runs, you can start looking at the import error.

Note: part of the Linux / Mac code tries to find the MATLAB executable in some hard coded places and allows you to choose between different versions.

However, you are working on Windows, and the code does not actually implement any way to choose between MATLAB releases for this platform (therefore, all methods such as discover_location and find_available_releases are useless on Windows). In the end, the COM object is created as :

 self.client = win32com.client.Dispatch('matlab.application') 

As described here , ProgID matlab.application is version independent and will simply use everything that was registered as the default MATLAB server. We can explicitly indicate which version of MATLAB we want (provided that you have several installations), for example matlab.application.8.3 will choose MATLAB R2014a.

So, in order to fix the code, IMO the easiest way would be to get rid of all this logic regarding several versions of MATLAB (the Windows part of the code ) and just create the COM MATLAB object as it is. I did not try to do this, but I do not think it is too important ... Good luck!


EDIT:

I download a module and I managed to get it working on Windows (I use Python 2.7.6 and MATLAB R2014a). Here are the changes:

 $ git diff diff --git a/src/mlab/matlabcom.py b/src/mlab/matlabcom.py index 93f075c..da1c6fa 100644 --- a/src/mlab/matlabcom.py +++ b/src/mlab/matlabcom.py @@ -21,6 +21,11 @@ except: print 'win32com in missing, please install it' raise +def find_available_releases(): + # report we have all versions + return [('R%d%s' % (y,v), '') + for y in range(2006,2015) for v in ('a','b')] + def discover_location(matlab_release): pass @@ -62,7 +67,7 @@ class MatlabCom(object): """ self._check_open() try: - self.eval('quit();') + pass #self.eval('quit();') except: pass del self.client diff --git a/src/mlab/mlabraw.py b/src/mlab/mlabraw.py index 3471362..16e0e2b 100644 --- a/src/mlab/mlabraw.py +++ b/src/mlab/mlabraw.py @@ -42,6 +42,7 @@ def open(): if is_win: ret = MatlabConnection() ret.open() + return ret else: if settings.MATLAB_PATH != 'guess': matlab_path = settings.MATLAB_PATH + '/bin/matlab' diff --git a/src/mlab/releases.py b/src/mlab/releases.py index d792b12..9d6cf5d 100644 --- a/src/mlab/releases.py +++ b/src/mlab/releases.py @@ -88,7 +88,7 @@ class MatlabVersions(dict): # Make it a module sys.modules['mlab.releases.' + matlab_release] = instance sys.modules['matlab'] = instance - return MlabWrap() + return instance def pick_latest_release(self): return get_latest_release(self._available_releases) 

First I added the missing find_available_releases function. I made it say that all versions of MATLAB are available (as I explained above, this does not really matter because of how the COM object is created). It is even better to fix the detection of installed / registered versions of MATLAB using the Windows registry (check the keys HKCR\Matlab.Application.XY and follow their CLSID in HKCR\CLSID ). So you can really pick and choose the version to run.

I also fixed two unrelated errors (one of which the author forgot the value of the returned function, and the other unnecessarily created a wrapper object twice).

Note. During testing, it may be faster to NOT start / shut down the MATLAB instance with every script call. This is why I commented on self.eval('quit();') in the close function. This way you can start MATLAB with matlab.exe -automation (do it only once) and then reuse the session without closing it. Just start the process when you're done :)

Here is a Python example for testing a module (I also show a comparison with NumPy / SciPy / Matplotlib):

test_mlab.py

 # could be anything from: latest_release, R2014b, ..., R2006a # makes no difference :) from mlab.releases import R2014a as matlab # show MATLAB version print "MATLAB version: ", matlab.version() print matlab.matlabroot() # compute SVD of a NumPy array import numpy as np A = np.random.rand(5, 5) U, S, V = matlab.svd(A, nout=3) print "S = \n", matlab.diag(S) # compare MATLAB SVD against Scipy SVD U, S, V = np.linalg.svd(A) print S # 3d plot in MATLAB X, Y, Z = matlab.peaks(nout=3) matlab.figure(1) matlab.surf(X, Y, Z) matlab.title('Peaks') matlab.xlabel('X') matlab.ylabel('Y') matlab.zlabel('Z') # compare against matplotlib surface plot from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt fig = plt.figure() ax = fig.gca(projection='3d') ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='jet') ax.view_init(30.0, 232.5) plt.title('Peaks') plt.xlabel('X') plt.ylabel('Y') ax.set_zlabel('Z') plt.show() 

Here is the result I get:

 C:\>python test_mlab.py MATLAB version: 8.3.0.532 (R2014a) C:\Program Files\MATLAB\R2014a S = [[ 2.41632007] [ 0.78527851] [ 0.44582117] [ 0.29086795] [ 0.00552422]] [ 2.41632007 0.78527851 0.44582117 0.29086795 0.00552422] 

matlab_peaks_surfmatplotlib_peaks_surf


EDIT2:

The above changes have been accepted and merged into mlab .

+6
source share

You are right that find_available_releases () is not written. 2 ways to work with it

  • Check the code in linux and work on it (you work on windows!)
  • Change the code below

Add the following function to matlabcom.py, as in matlabpipe.py

 def find_available_releases(): global _RELEASES if not _RELEASES: _RELEASES = list(_list_releases()) return _RELEASES 

If you see the mlabraw.py file, the following code will give you a clear idea of ​​why I say this!

 import sys is_win = 'win' in sys.platform if is_win: from matlabcom import MatlabCom as MatlabConnection from matlabcom import MatlabError as error from matlabcom import discover_location, find_available_releases from matlabcom import WindowsMatlabReleaseNotFound as MatlabReleaseNotFound else: from matlabpipe import MatlabPipe as MatlabConnection from matlabpipe import MatlabError as error from matlabpipe import discover_location, find_available_releases from matlabpipe import UnixMatlabReleaseNotFound as MatlabReleaseNotFound 
+1
source share

All Articles