# pyidlrpc¶

A library to call IDL (Interactive Data Language) from python. Allows trasparent wrapping of IDL routines and objects as well as arbitrary execution of IDL code.

pyidlrpc requires a licenced installation of IDL and works by connecting with an idlrpc server. Data is transfered back and forth using the idlrpc API distrbuted with IDL.

All standard IDL and python/numpy datatypes are supported, and pyidlrpc transparently handles translating between equivilent datatypes. This includes translation between IDL structures and python dictionaries.

pyidlrpc is hosted at:
https://bitbucket.org/amicitas/pyidlrpc
Documentation can be found at:
http://amicitas.bitbucket.org/pyidlrpc

pyidlrpc was written by Novimir A. Pablant, and is released under an MIT licence.

## Dependencies¶

• IDL (8.0)
• python (2.7, 3.0 or later)
• numpy
• psutil
• cython

pyidlrpc requires a licenced installation of IDL. Currently only IDL 8.0 or later is spported due to the additon of the HASH and LIST types. Older versions may be compatible but are untested.

pyidlrpc is currently only supported on linux and OS X. It should also work fine on windows, but the setup.py script has not been setup to find the IDL installation directory. If you want to give this a try on windows, just add the appropriate directories to setup.py. (If it works submit a pull reqeust so that I can update the public package.)

## Installation¶

pyidlrpc can be installed using the following command:

python setup.py install

For more control over the installation, all standard distutils commands are available. If setuputils is installed, then the extended commands will also work.

If a full installation is not desired, the pyidlrpc module can be built in place using:

python setup.py build_ext --inplace

This will build pyidlrpc in place and create the pyidlrpc.so shared library which can then be imported from python.

Warning:
On Mac OS X the setup script will change the installation name of the libidl_rpc.dylib library to @rpath/libidl_rpc.dylib.

## examples¶

Here are a few simple examples. A full set of examples and tutorials is included in the documentation.

### starting the idlrpc server¶

For any of the examples below it is recommended than an idlrpc server be started in a separate terminal window:

idlrpc


This step is not strictly necessary as a server will be started automatically if needed. However, pyidlrpc currenly leaves the idlrpc server running in the background, which eventually has to be manually killed. This behavior will be fixed in the next version.

### executing idl code¶

Here is a simple example for executing arbitrary IDL code from python:

# Import pyidlrpc.
import pyidlrpc as idl

# Execute a command in IDL.
# This will print 'Hello mom!' in the idlrpc window.
idl.execute("PRINT, 'Hello mom!'")


As a more complex example, we will now send some data back and forth between IDL and python.

import numpy as np
import pyidlrpc as idl

# Create a numpy array in python.
py_array = np.random.normal(size=1000)

# Copy this data to IDL.
idl.setVariable('idl_array', py_array)

# Calculate the standard devation and the mean in IDL.
idl.execute('idl_stddev = STDDEV(idl_array)')
idl.execute('idl_mean = MEAN(idl_array)')

# Copy the results back to python.
py_stddev = idl.getVariable('idl_stddev')
py_mean = idl.getVariable('idl_mean')

# Print out the results.
print('Mean: {}, StdDev: {}'.format(py_mean, py_stddev))


### calling functions and procedures¶

In the examples above we used just the most basic pyidlrpc commands to control an IDL session and pass data between IDL and python. In these next examples we use the pyidlrpc wrapping routines to do simplify the code in the previous example significantly.

import numpy as np
import pyidlrpc as idl

# Create a numpy array in python.
py_array = np.random.normal(size=1000)

# Calculate the standard devication and mean using IDL.
py_stddev = idl.callFunction('STDDEV', [py_array])
py_mean = idl.callFunction('MEAN', [py_array])

# Print out the results.
print('Mean: {}, StdDev: {}'.format(py_mean, py_stddev))


### wraping functions and procedures¶

Wrapping functions or procedures looks very similar to the example above. Let say we want to wrap the IDL STDDEV and MEAN functions in python module name idlmath.

# idlmath.py

import pyidlrpc as idl

def stddev(*args, **kwargs):
return idl.callFunction('STDDEV', args, kwargs)

def mean(*args, **kwargs):
return idl.callFunction('MEAN', args, kwargs)


That’s all there is to it. Now we can call these functions as though they were native python funcitons.

import numpy as np
import idlmath

array = np.random.normal(size=1000)

# Here we transparently call the wrapped IDL functions.
mean = idlmath.mean(array)
stddev = idlmath.stddev(array)


### wrapping objects¶

pyidlrpc also has the ability to fully wrap IDL objects.

Python wrapping objects should all inherit from PyIDLObject. Here is an example of wrapping a hypothetical Gaussian object.

# _IdlGaussan.py

from pyidlrpc import PyIDLObject

class IdlGaussian(PyIDLObject):

# Define the the IDL command needed to create the object.
_creation_command = "OBJ_NEW"
_creation_params = ['GAUSSIAN']
_creation_keywords = None

def evaluate(self, *args, **kwargs):
return, self.callMethodFunction('EVALUATE', args, kwargs)

def setParam(self, *args, **kwargs):
return, self.callMethodPro('SET_PARAM', args, kwargs)

def getParam(self, *args, **kwargs):
return, self.callMethodFunction('GET_PARAM', args, kwargs)