PyMOLをJupyter Notebookと連携させる方法について
前回の記事で、PyMOLのスクリプト機能を利用して3D PSAを求めました。『PyMOL=生物学向けの描画ソフト』と思い込んでいたのですが、まだまだ便利な機能がたくさんあって、化学方面にも応用できそうです。
素敵なPyMOLですが、プログラミングができない私にとってコマンドラインでの操作はとっつきづらいです。コマンドと一緒にコメントや出力結果を残しやすいJupyter notebookで使えた方が後でたどりやすいのになー、と、いうことでJupyterから使う方法を調べました。
PyMOL WikiにJupyterという、そのものな項目があったので記載の方法を試していきたいと思います。ほぼそのままです。
検証する操作の確認
Jupyter notebookを試す前に、検証で行う操作を念のためPyMolアプリのGUIで確認します。
アミノ酸残基はBuild
メニューのResidue
から選択して作成することができます。コマンドラインでfragment ala
とするか、cmd.fragment('ala')
としてもOKです。
画像の保存はFile
メニューのExport Image As
あるいは右上のDraw/Ray
パネルからできます。コマンドラインで行うには、png test
とすると作業ディレクトリの中に「test.png」として保存できます。cmd.png('test')
でもOKです。
詳しい使い方はPyMol Bookが日本語でわかりやすいです。なお、cmd
はPyMOL Python APIを使うためのモジュールで、PyMol上のコマンドラインを使うのであればわざわざ使わなくても良いと思いますが、以降の内容との関係するので併記しました。
JupyterからPyMOL
では本題、Jupyter notebookからPyMOLを利用する方法です。PyMol Wikiには大きく2つ、直接PyMOL APIを使う方法と、サードパーティーのライブラリを使う方法が書かれています。それぞれ制限があるようです。
概要はこんな感じです。
直接PyMOL APIを使う
同じスレッド
まず、同じスレッドで使う方法です。こちらはGUIの画面をみることはできません(headless)。
操作は簡単。Jupyter notebookを起動し、PyMOLのモジュールを読み込むだけです。
# cmd モジュールのインポート from pymol import cmd # アラニンを構築し、拡大した後に画像を保存 cmd.fragment('ala') cmd.orient() cmd.png('./test.png', ray=1)
「PyMOL not running, entering library mode (experimental)」とかいう出力がでてきますが問題なく使えます。PyMOL WikiのLaunching From a Scriptによると、PyMol 2.1から、cmd
を使うと自動的にメインスレッドでバックエンドプロセスをGUI無しで起動するらしいので、その関係だと思います。*1
さて、上記で無事「test.png」が作成されたので中身を確認してみます。
from IPython.display import Image Image(filename='./test.png')
うまくいきました!
非同期スレッド
次に、非同期スレッド(asynchronous thread)で使う方法です。こちらはGUIが使えます。
が、残念ながらmacOSではこの操作を行えません(GitHub Issue)。
コマンドだけコピペしておきます。
# PyMOLウィンドウを開く import sys import pymol _stdouterr = sys.stdout, sys.stderr pymol.finish_launching(['pymol', '-q']) sys.stdout, sys.stderr = _stdouterr # PyMOLウィンドウにアラニンを読み込む from pymol import cmd cmd.fragment('ala')
コマンドラインモード
PyMOL Wikiから外れますが、コマンドラインモードであればMacでもJupyterからPyMOLを立ち上げることができます。起動のオプション-c
を使うと、GUIなしのコマンドラインのみのモードとなり、バッチプロセスに使うことができます(PyMOLWiki Command Line Options)。
import pymol # PyMolをコマンドラインモードで立ち上げる pymol.pymol_argv = ['pymol','-c'] pymol.finish_launching() # Detected 4 CPU cores. Enabled multithreaded rendering.
ターミナルにPyMOL起動時のバージョン情報が表示され、起動がうまくいったことがわかります。オプション-q
をつければこの表示が出ないようにすることもできます(quietモード)。
注意点として、このPyMOLの立ち上げ方はCPUを100%使うらしいです*2。Macが悲鳴をあげるので不要であればcmd.quit()
で終了しておいた方が良さそうです。
# コマンドラインモードのPyMOLを終了
cmd.quit()
RPCコミュニケーション
つづいて、Jupyter notebookとは別に立ち上げたPyMol(スタンドアローン)をRPCコミュニケーションで操作する方法です。RPC(Remote procedure call、遠隔手続き呼び出し)は「プログラムから別のアドレス空間にあるサブルーチンや手続きを実行することを可能にする技術」で、「遠隔相互作用の詳細を明示的にコーディングする必要がない」そうです(Wikipedia 遠隔手続き呼び出し)。・・・よくわかりません。
まず、pymol -R
で立ち上げておきます。-R
オプションはRPCサーバーを立ち上げるためのオプションです。
pymol -R # xml-rpc server running on host localhost, port 9123
PyMOL GUIアプリが立ち上がりますが、上記のように表示され、xml-rpc server
がlocalhostのポート番号9123で起動していることがわかります。
このRPCサーバーにJupyter notebookからアクセスするにはPythonのxmlrpc.clientモジュールを使えば良いそうです。
# Jupyter notebookからPyMOL にRPCコミュニケーション import xmlrpc.client as xmlrpclib cmd = xmlrpclib.ServerProxy('http://localhost:9123') cmd.fragment('ala')
以上を実行すると、PyMOLのGUIウィンドウにアラニンが読み込まれます。
xmlrpc.client.ServerProxy()
でRPCコミュニケーションを管理するためのオブジェクトを生成し、これにPyMOL Python APIを扱うためのモジュールcmd
と同じ名前をつけておくことで、APIを扱う感覚で外部のPyMolを操作ができているようです。・・たぶん。
以上が、直接PyMol APIを使う方法です。
サードパーティーライブラリ
つづいてサードパーティーのライブラリを使った方法についてです。ライブラリとしてIPyMOLとRDKitが言及されていますがPyMOL Wikiには詳細は書かれていません。
ライブラリの説明やGitHubをたよりに試してみましょう。
IPyMOL
まずIPyMOLです。IPythonからPyMolのセッションを制御するためのライブラリで、こちらもRPCコミュニケーションを利用します(MITライセンス)。
「Jupyter Notebookできちんと見せたい時や、PyMOLスクリプトのプロトタイプを簡便に作成したい時に理想的なツール」とのことなので、今回の目的にまさにぴったりなライブラリです。
pipでインストール可能(ipymol - PyPI)ですが、古いバージョンらしく不具合があるらしいです(GitHub issue #21)。GitHubバージョンは修正されているらしいので、直接インストールしてみます。
pip install git+https://github.com/cxhernandez/ipymol.git
IPyMOLでは、さきと同様に、あらかじめpymol -R
で立ち上げておいたPyMOLに接続できますが、IPyMolからstart()
でPyMOL RPCサーバーを起動することもできます。閉じる時はstop()
です。
from ipymol import viewer as pymol pymol.start()
PyMOLのGUIが立ち上がりました!今回は「xml-rpc server running on host localhost, port 9124」と出たので、ポート番号が先とは異なるようです。
アラニンを読み込むには以下のようにします。
pymol.fragment('ala')
display()
を使うことでPyMOL GUIのディスプレイをJupyter Notebook上に描画することができます。
pymol.display()
IPyMolで利用可能なAPIは以下を打ち込むと確認できます。出力は多いので省略します。
print(pymol._server.system.listMethods())
上記のリストに含まれていないコマンドを使いたい時はpymol.do("実行したいコマンド")
とすればOKです。
使い方の実例はこちらのノートブックが参考になります。
終わったらstop()
でウィンドウを閉じられます。
# IPyMOLで立ち上げたPyMOLの終了
pymol.start()
RDKit PyMolモジュール
続いてRDKitからPyMolに RPCコミュニケーションする方法です。Chem.PyMolモジュールを利用すればOKで、化学の新しいカタチさんが「RDKitからPyMOLを利用する」で詳しい使い方をご紹介してくださっています。
参考までにこれまでと同じ処理を確認します。
まず、pymol -R
でXML-RPC サーバーを立ち上げておきます。
RDKitで必要なモジュールをインポートし、MolViewerオブジェクトを作成します。
from rdkit import Chem from rdkit.Chem import PyMol v = PyMol.MolViewer()
MolViewerに含まれていない操作を行うには、sever.do("実行したいコマンド")
とすれば良いそうです。アラニンフラグメントを読み込み、GetPNG()
でJupyter notebook上に描画します。
# アラニンの読み込み v.server.do("fragment ala") # ズーム v.Zoom('ala') # PyMOL GUIの画面をPNGで取得 v.GetPNG()
SaveFile()
を使うことで画像として保存することもできます。
折角ですので、ついでに前回の記事で取り上げた3D PSAのスクリプトを実行してみましょう!
まずDeleteAll()
で一度全て消した後に、LoadFile()
でファイルを読み込みます。「conformer-00.xyz」というxzyファイルを「conf1」という名前のオブジェクトとしてロードしています。
# viewewrのオブジェクトを全て消す v.DeleteAll() # ファイルの読み込み v.LoadFile('./conformer-00.xyz', 'conf1')
別途作成したスクリプト(psa3d.py
)をつかえるように読み込み(run
)、計算を実行します。
# スクリプトの実行 v.server.do('run ./psa3d.py') # 計算の実行 v.server.do('set solvent_radius=1.4; set dot_density=4; set dot_solvent=1; psa3d')
無事計算が実行され、PyMOL上にSA 3D PSAの値「201.973」が表示されました。
以上、サードパーティライブラリの動作も確認できました。
まとめ
以上、PyMOLをJupyter notebookで利用するための方法の紹介でした。ほとんどPyMOL Wikiそのままですが。。。
PyMOLのスクリプトは色々な方が作成、公開してくださっているようなので、Jupyter notebookとうまく連携させればプログラミング苦手な私でももっと活用できるかもしれません。
Jupyter notebookで操作して出力された結果を、PyMOLから受け取ってJupyter Notebookに表示することもしたかったのですが、やり方がよくわかりませんでした。サブプロセス(?)を使えば良いのかもしれませんが私のキャパシティでは無理でした。。。
ではでは。
*1:どういうことかはさっぱりわかりません。。。