magattacaのブログ

日付以外誤報

PyMOLをJupyter Notebookと連携させる方法について

前回の記事で、PyMOLのスクリプト機能を利用して3D PSAを求めました。『PyMOL=生物学向けの描画ソフト』と思い込んでいたのですが、まだまだ便利な機能がたくさんあって、化学方面にも応用できそうです。

素敵なPyMOLですが、プログラミングができない私にとってコマンドラインでの操作はとっつきづらいです。コマンドと一緒にコメントや出力結果を残しやすいJupyter notebookで使えた方が後でたどりやすいのになー、と、いうことでJupyterから使う方法を調べました。

PyMOL WikiJupyterという、そのものな項目があったので記載の方法を試していきたいと思います。ほぼそのままです。

検証する操作の確認

Jupyter notebookを試す前に、検証で行う操作を念のためPyMolアプリのGUIで確認します。

  1. ラニンを読み込む(fragmentcmd.fragment)
  2. 描画を画像(PNG)で保存(pngcmd.png)

アミノ酸残基はBuildメニューのResidueから選択して作成することができます。コマンドラインfragment alaとするか、cmd.fragment('ala')としてもOKです。

f:id:magattaca:20210109154316p:plain

画像の保存はFileメニューのExport Image Asあるいは右上のDraw/Rayパネルからできます。コマンドラインで行うには、png testとすると作業ディレクトリの中に「test.png」として保存できます。cmd.png('test')でもOKです。

f:id:magattaca:20210109154344p:plain

詳しい使い方はPyMol Bookが日本語でわかりやすいです。なお、cmdPyMOL 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 WikiLaunching From a Scriptによると、PyMol 2.1から、cmdを使うと自動的にメインスレッドでバックエンドプロセスをGUI無しで起動するらしいので、その関係だと思います。*1

さて、上記で無事「test.png」が作成されたので中身を確認してみます。

from IPython.display import Image
Image(filename='./test.png')

f:id:magattaca:20210109154444p:plain

うまくいきました!

非同期スレッド

次に、非同期スレッド(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')

Macでこれを実行するとカーネルが死にます。。。

コマンドラインモード

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%使うらしいです*2Macが悲鳴をあげるので不要であれば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 serverlocalhostのポート番号9123で起動していることがわかります。

このRPCサーバーにJupyter notebookからアクセスするにはPythonxmlrpc.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を使う方法です。

サードパーティーライブラリ

つづいてサードパーティーのライブラリを使った方法についてです。ライブラリとしてIPyMOLRDKitが言及されていますが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()

f:id:magattaca:20210109154735p:plain

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 -RXML-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()

f:id:magattaca:20210109154938p:plain

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:どういうことかはさっぱりわかりません。。。

*2:Launching From a Script