このページの内容はLinux版の IDL + Python を前提としているため、他のOSでは異なる場合があります。
Python Bridge を用いることで、IDLでPythonのコードを実行 (IDL to Python Bridge)、PythonでIDLのコードを実行 (Python to IDL Bridge)し、データをやりとりすることができる。具体的な使用方法は公式マニュアルを参照。
対応するPythonのバージョンは次の通り。
| Python 2.7 | 3.4 | 3.5 | 3.6 | 3.7 | 3.8 | 3.9 | 3.10 | 3.11 | 3.12 | |
|---|---|---|---|---|---|---|---|---|---|---|
| IDL 9.0 | No | No | No | No | No | Yes | Yes | Yes | Yes | No | 
| IDL 8.9 | No | No | No | No | No | Yes | Yes | Yes | No | No | 
| IDL 8.8.2, 8.8.3 | No | No | No | No | Yes | Yes | Yes | Yes | No | No | 
| IDL 8.8.1 | No | No | No | Yes | Yes | Yes | Yes | No | No | No | 
| IDL 8.8 | No | No | No | Yes | Yes | Yes | No | No | No | No | 
| IDL 8.7.1–8.7.3 | Yes | No | Yes | Yes | No | No | No | No | No | No | 
| IDL 8.6.1, 8.7 | Yes | Yes | Yes | Yes | No | No | No | No | No | No | 
| IDL 8.5.2, 8.6 | Yes | Yes | Yes | No | No | No | No | No | No | No | 
| IDL 8.5, 8.5.1 | Yes | Yes | No | No | No | No | No | No | No | No | 
IDLから Python のコードを実行するために必要な条件:
python コマンドで起動される Python のバージョンは python --version として確認できる。python コマンドが定義されていなかったり、python コマンドで古いバージョンの Python が起動してしまう環境の場合、
などの方法で、目的の Python が起動するようにする。
IDLがlibpythonX.X.so を見つけられない場合には、libpythonX.X.so が置かれているパスをLD_LIBRARY_PATH環境変数に追加する必要がある。
RHEL/CentOS 7 の SCL (Software Collection) で提供される Python にはバージョン番号のsuffixが付加されていないライブラリ libpythonX.X.so が存在しないため、シンボリックリンクを張っておく必要がある。
ln -s libpython3.6m.so /opt/rh/rh-python36/root/lib64/libpython3.6m.so.1.0ln -s libpython3.8.so.rh-python38-1.0 /opt/rh/rh-python38/root/lib64/libpython3.8.so.1.0IDLに添付されているいくつかの共有ライブラリのバージョンと、Pythonや拡張モジュールが要求する共有ライブラリのバージョンに互換性がない場合には、LD_LIBRARY_PATH環境変数内でのディレクトリの順番を調整したり、Python開始時にLD_PRELOAD環境変数でOS標準のライブラリを指定する必要があるかもしれない。特に libstdc++.so.6 や libfreetype.so.6 などで問題が発生する可能性がある。
PythonからIDLのコードを実行するために必要な条件:
Python がモジュールを検索するパスを追加するには、Python 起動前ならPYTHONPATH環境変数で、Python 起動後なら sys.path.append を使う。
共有ライブラリの探索パスを追加するには LD_LIBRARY_PATH環境変数を用いる。
IDLに添付されているいくつかの共有ライブラリのバージョンと、Pythonや拡張モジュールが要求する共有ライブラリのバージョンに互換性がない場合には、LD_LIBRARY_PATH環境変数内でのディレクトリの順番を調整したり、Python開始時にLD_PRELOAD環境変数でOS標準のライブラリを指定する必要があるかもしれない。特に libstdc++.so.6 や libfreetype.so.6 などで問題が発生する可能性がある。
matplotlib のカラーマップを IDL で使う方法とIDL のカラーテーブルを matplotlib で使う方法については別ページを参照。
SciPy の scipy.io.readsav 関数を用いることで、IDLで作成されたsaveファイル(XDR: eXternal Data Representation 形式)をPythonで読み込むことができる。
例えば、次のようなsaveファイルを作成する。
; IDLIDL> a = dindgen(5)IDL> b = complex(1, 2)IDL> c = 'string'IDL> save, a, b, c, file = 'test1.sav'readsave() は辞書(dict)を返すので、keys() で各要素のキー(=IDLでの変数名)を取得できる。
# Python>>> import scipy.io as sio>>> sav_data = sio.readsav('test1.sav')>>> sav_data.keys()dict_keys(['a', 'b', 'c'])各要素のキー(=IDLでの変数名)がわかれば、値を取得できる。IDLの数値型は、NumPy の対応する型になる。例: LONG=>numpy.int32, DOUBLE=>numpy.float64, DCOMPLEX=>numpy.complex128。IDLの文字列はバイト列 (bytes)になるので、decode() で文字列を得る。
# Python>>> sav_data['a']array([0., 1., 2., 3., 4.])>>> sav_data['b'](1+2j)>>> sav_data['c']b'string'>>> sav_data['c'].decode()'string'IDLの構造体は構造化配列 (numpy.recarray)になる。
; IDLIDL> a = {key1: [1, 2, 3], key2: 'string'}IDL> b = [a, {key1: [4, 5, 6], key2: 'string2'}]IDL> save, a, b, file = 'test2.sav'# Python>>> import scipy.io as sio>>> sav_data2 = sio.readsav('test2.sav')>>> sav_data2['a']rec.array([(array([1, 2, 3], dtype=int16), b'string')],
        dtype=[(('key1', 'KEY1'), 'O'), (('key2', 'KEY2'), 'O')])>>> sav_data2['a'].key1[0]array([1, 2, 3], dtype=int16)>>> sav_data2['a'].key2[0]b'string'>>> sav_data2['b']rec.array([(array([1, 2, 3], dtype=int16), b'string'),
           (array([4, 5, 6], dtype=int16), b'string2')],
          dtype=[(('key1', 'KEY1'), 'O'), (('key2', 'KEY2'), 'O')])>>> sav_data2['b'].key1[1]array([4, 5, 6], dtype=int16)>>> sav_data2['b'].key2[1]b'string2'LIST, HASH, ORDEREDHASH, DICTIONARY, BIGINTEGERなどのオブジェクトも構造化配列 (numpy.recarray)になる。LIST, HASH, ORDEREDHASH, DICTIONARY では _SR_PTR にキーと値が格納されている。以下は HASH の例。
; IDLIDL> a = HASH('key1', 1, 'key2', [2., 3.], 'key3', 'string')IDL> save, a, file = 'test3.sav'# Python>>> import scipy.io as sio>>> sav_data3 = sio.readsav('test3.sav')>>> sav_data3['a']rec.array([(0, None, 0, 0, 0, 0, 0, 0, None, 0, 32908864, array([array([b'key3', b'key2', b'key1'], dtype=object),
                  array([b'string', array([2., 3.], dtype=float32), 1], dtype=object)],
                 dtype=object), 0)],
          dtype=[(('idl_object_top', 'IDL_OBJECT_TOP'), '>i8'), (('__obj__', '__OBJ__'), 'O'), (('idl_object_bottom', 'IDL_OBJECT_BOTTOM'), '>i8'), (('table_bits', 'TABLE_BITS'), '>u4'), (('table_size', 'TABLE_SIZE'), '>u4'), (('table_count', 'TABLE_COUNT'), '>u4'), (('table_remove', 'TABLE_REMOVE'), '>u4'), (('table_foreach', 'TABLE_FOREACH'), '>u4'), (('table_data', 'TABLE_DATA'), 'O'), (('flags', 'FLAGS'), '>u4'), (('_hashhandle', '_HASHHANDLE'), '>i8'), (('_sr_ptr', '_SR_PTR'), 'O'), (('idl_hashversion', 'IDL_HASHVERSION'), '>i2')])>>> sav_data3['a']._sr_ptr[0][0]array([b'key3', b'key2', b'key1'], dtype=object)>>> sav_data3['a']._sr_ptr[0][1]array([b'string', array([2., 3.], dtype=float32), 1], dtype=object)>>> # DICT に変換する>>> {k.decode(): v for k, v in zip(sav_data3['a']._sr_ptr[0][0], sav_data3['a']._sr_ptr[0][1])}{'key3': b'string', 'key2': array([2., 3.], dtype=float32), 'key1': 1}BigInteger の場合、PDIGITS に下位の桁から32bitごとに区切られた値の配列が、負数のとき ISNEGATIVE に1が入っている。Python 3のint型は 2**63 を超える数も扱うことができる。
; IDLIDL> a = BigInteger('-123456789012345678901234567890')IDL> save, a, file = 'test4.sav'# Python>>> import scipy.io as sio>>> sav_data4 = sio.readsav('test4.sav')>>> sav_data4['a']rec.array([(0, None, 0, 1, 0, 0, array([1312754386, 3279151342, 2397638646, 1], dtype=uint32))],
     dtype=[(('idl_object_top', 'IDL_OBJECT_TOP'), '>i8'), (('__obj__', '__OBJ__'), 'O'), (('idl_object_bottom', 'IDL_OBJECT_BOTTOM'), '>i8'), (('isnegative', 'ISNEGATIVE'), 'u1'), (('isinfinite', 'ISINFINITE'), 'u1'), (('isnan', 'ISNAN'), 'u1'), (('pdigits', 'PDIGITS'), 'O')])>>> a = 0>>> for x in reversed(sav_data4['a'].pdigits[0]):...   a = (a << 32) + int(x)... >>> if sav_data4['a'].isnegative[0] == 1:...   a = -a... >>> a-123456789012345678901234567890