Enables Python scripts that are run inside Icy to communicate with other Python instances outside Icy. This allows the access to CPython-only libraries such as Numpy.
Institution: Institut Pasteur
This plugin provides execnet, a Python module that allows several python instances to communicate. Among its several purposes, it is useful in Icy because it offers a way to use powerful libraries that are only available with CPython and not with Jython, the latter being the heart of the Python scriping engine in Icy. For example, you can use execnet to send images opened in Icy to a script that runs computations with powerful libraries such as Numpy, Scipy or Pandas.
You need a working CPython installation outside of Icy. No particular setup is required in this external Python, apart from installing the libraries you plan to use, such as Numpy or Pandas.
Icy will do some invisible work to setup the remote interpreter. It uses execnet under-the-hood, which is capable of bootstrapping itself, and later on it will send some additional modules to setup standard streams (so that you can print in the remote and see the output in Icy) and provide functions to exchange data.
The following piece of code (source on GitHub) can be executed from the Script Editor:
On line 1, we import the IcyExecnetGateway class, which will do the hard work of launching a remote interpreter.
Lines 4 and 7 show how to launch a remote interpreter and execute some code in it. In this example, we print some text in the remote interpreter, and that text is automatically sent back to Icy and printed in the console of the Script Editor, as shown in the screenshot below:
Transferring data between Icy and the remote interpreter
Send a pure-Python object to the remote, from Icy:
- On Icy side: use gateway.send(object),
- On the remote side: use channel.receive(). channel is a variable automatically available in the remote to exchange data with its parent.
Send a pure-Python object to Icy, from the remote:
- On the remote side: use channel.send(object).
- On Icy side: use gateway.receive().
Transfer an image (of type IcyBufferedImage) to the remote, from Icy:
- On Icy side: convert first the image to a pure-python object using icyexecnetgateway.pack_image(image) and send that object.
- On the remote side: use channel.receive() to receive the image object, import the numpyexecnet module, and use numpyexecnet.unpack_image(packed_image). The result will be a 2D Numpy array.
Transfer a 2D Numpy array to Icy, from the remote:
- On the remote side: import the numpyexecnet module, use numpyexecnet.pack_image(array) to convert the Numpy array to a pure-python object, and send that object.
- On Icy side: use gateway.receive() to receive the array object, and icyexecnetgateway.unpack_image(array) to convert it to an IcyBufferedImage.
- It is not currently possible to send a Sequence as-is to the remote interpreter. Instead, send each image of the sequence to the remote.
- Likewise, it is not possible to send Java objects. If you try, you will get a execnet.DataFormatError, saying that the object cannot be serialized. Be sure to convert them to Python objects (for example a Java ArrayList has to be converted to a Python list).
Example (Icy to Numpy/Matplotlib)
In this example, we send an image (first image, first channel, first z, of the currently active sequence) to the remote interpreter. It is received as a Numpy array, and displayed on the screen with the Matplotlib library (source on GitHub).
Example (Numpy to Icy)
In this example, we generate a random 2D array using Numpy ‘rand’ function. We display this array in matplotlib, and we also sendit to Icy. It is received as an IcyBufferedImage. A sequence is made from this image, and displayed (source on GitHub).
Launching a specific interpreter:
By default, when calling IcyExecnetGateway(), the interpreter that will be launched is the ‘python’ executable that is found on the system path. In some situations, it is desirable to specify another executable (a specific python installation in a virtual environment, or a locally-installed version instead of the system Python in MacOS X). You can specify the desired python executable located at /path/to/python by using: IcyExecnetGateway(python_path=”/path/to/python”).
It is also possible to call an interpreter on a different machine, using execnet specifications. For example, you can call a Python 2.4 interpreter through ssh on a host called wyvern using IcyExecnetGateway(gateway_spec="ssh=wyvern//python=python2.4"). See http://codespeak.net/execnet/basics.html for more details about the specifications.
Coming soon on this page:
- Examples of fancy things to do with Numpy, Scipy, scikit.image, Pandas, Fenics, Matplotlib, etc.