pymolをimportしようとする話の続きの話
PyMOLのjupyter notebookからのimportに失敗したことについて記事を書いたところ、早速twitterで解決方法を教えていただきました。 @kira_kira_worldさん、@Ag_smith先生ありがとうございました!
- 解決策に入る前に・・・pythonのバージョンについて
- 解決策1)シンボリックリンクの作成
- 解決策2)インストール方法を変える(Anaconda CloudのSchrödinger社のチャンネルを利用)
- _cmdはどこからきたのか?
- まとめ
解決策に入る前に・・・pythonのバージョンについて
先の記事を書いた時点では気づいていなかったのですがどうもpythonのバージョンに原因があったようです。
- Homebrew > pyenv > Anaconda(複数の仮想環境)
みたいな感じになっています。(たぶん)
で、全体(pyenv global
)はPython 3.70となっています。
この状態でhomebrewからPyMOLをインストールしたためか、importしようとしたPyMOLは以下のディレクトリ
「/usr/local/Cellar/pymol/2.3.0/libexec/lib/python3.7/site-packages」
を呼びに行っていました(先の記事でpathを通した所)。
如何にもpython3.7に紐づいていそうな場所です。
また、別の話として、色々とソフトウェアをインストールするためにAnacondaで複数の仮想環境を作成し、 jupyter notebookのカーネルに追加、切り替えつつ使おうとしています。どうやらここに問題がありそうでした。
先の記事で使用した仮想環境(カーネル)のpythonのバージョンを確認したところPython 3.6.10となっていました。
そこで別のPython 3.70の仮想環境に切り替えたところ、エラーは出ずにimport pymol
することができました。(pathを通す必要はありました)
おそらくPythonのバージョンをきちんと合わせておけば問題なく使用できるのではないでしょうか? また確認不足で誤情報を垂れ流してしまった。。。すみません。
解決策1)シンボリックリンクの作成
ではでは、教えていただいた方法をご紹介したいと思います!
まずは@Ag_smith先生に教えていただいた方法です。
先の記事では怪しげなファイル「_cmd.cpython-37m-darwin.so」をコピペして「_cmd.so」に名前を変えるという荒技を行いました。 これだと思わぬ不具合を起こす可能性があるということで、こういう場合はシンボリックリンクを作成すれば良いそうです。
シンボリックリンクはUNIX系のOS(MacやLinux)で、Windowsのショートカットに相当するものだそうです。*1*2
つまり「_cmd.cpython-37m-darwin.so」のシンボリックリンクとして「_cmd.so」を作成しておけば、
import pymol
はシンボリックリンクを中継として本体のファイルに辿りつくことができる、ということのようです。
作成方法は簡単で、ターミナルで以下を実行すればOKです。
# シンボリックリンクを作成したいファイルが入っているディレクトリに移動 cd /usr/local/Cellar/pymol/2.3.0/libexec/lib/python3.7/site-packages/pymol # 「ln -s 本体のファイル リンクの名前」でシンボリックリンクを作成 ln -s _cmd.cpython-37m-darwin.so _cmd.so
できました!
- lnコマンドはリンクを登録するコマンド
- -sはシンボリックリンクを作成するオプション
だそうです。「種類:エイリアス」となっていますがエイリアスとシンボリックリンクは微妙に機能が違うらしい・・・。
このあとjupyter notebookで(エラーの出ていたpython 3.6の仮想環境でも)import pymol
できることを確認しました。
スマート!
解決策2)インストール方法を変える(Anaconda CloudのSchrödinger社のチャンネルを利用)
さて、もう一つの解決方法は@kira_kira_worldさんに教えていただいたもので、 condaでSchrödinger社のチャンネルからPyMOLをインストールするというものです。
1行でOK!
conda install -c schrodinger pymol
ですが注意点があります。こちらはSchrödinger社が配布しているものだということです。
Wikipediaによると、 もともとPyMOLはWarren L. DeLano氏により開発されたオープンソースのソフトウェアで、 現在はSchrödinger社によって商品化されているとのことです。 ですので、上記の方法で入手可能なPyMOLはライセンスに注意が必要そうです。
私はライセンス等に詳しくなく判断ができないので、以下手に入る情報を共有させていただきます。(←コンプライアンスを意識した発言)
まずはSchrödinger社のPyMOLのページ。
2020年03月20日現在、こちらではPyMOL 2.3のダウンロードが可能です(Python 3.7を含むそう)。
Windows、macOS、Linuxそれぞれのインストーラ、および上記のAnaconda Channelを利用する方法が提供されています。
また、ライセンスの購入方法についてもリンクがあります。
さらにスクロールしていくとOpen-Source Philosophyの文字が・・・
Schrödinger社が商用として維持、開発しているものの、元々のDelano氏の意向を引き続き大枠をオープンソースプロジェクトとしているようです。
したがってほとんどのソースコードはGitHub上で公開されています。ページのリンクはこちら。
Homebrew経由でインストールを行った際にも、ソースコードは上記のGithubから取得しているようです。 @Ag_smith先生の記事に記載されていて、 GitHubのHomebrewのFomulraでも取得先URLを確認できます。
では、Schrödinger社コンパイル済みのものをインストールした場合どうなるのでしょうか?試してみます。
テストのための仮想環境を作成し、condaで取得します。ちなみにAnaconda CloudのPyMolページはこちら。
# pythonのバージョンを指定して仮想環境pymoltestを作成 conda create -n pymoltest python=3.7 # 仮想環境をactivate conda activate pymoltest # PyMOLをインストール conda install -c schrodinger pymol # PyMOLを起動 pymol
無事PyMOLのウインドウが立ち上がりました!
ただしHomebrew経由のインストールとは明確な違いが!
同時にActivationのウィンドウが立ち上がります。
「オフィシャル版なのでライセンスを持っているならactivationしてくださいね」ということのようです。
ライセンスがない場合、評価版として30日間使用することができるようです(skip activation)。
評価期間がすぎると「ウィンドウにNo License Fileの表示がされ使えなくなる機能がある」、とのことですが もうすでにNo License Fileの文字が見えますし、30日すぎるとどうなるのかはまだわかりません。
ちなみに学生であればライセンスは無料で取得することができるそうです。が、私はとうに学生ではなくなってしまったのでとりあえずskip activationで先に進めたいと思います。
さて、こちらのPyMOLがjupyter notebookでimportできるか検証したいと思います。 まず準備としてcondaの仮想環境をjupyter notebookに認識させます。
# 以下ターミナルで実行 # jupyter notebookのカーネルに仮想環境を追加 python -m ipykernel install --user --name pymoltest # 一旦、仮想環境を抜けます conda deactivate
また、インストールしたPyMOLの場所を確認するため、PyMOLのコマンド枠で以下を打ち込みます。
import sys print(sys.path)
今回、それっぽいpathは「'/Users/XXXXX/.pyenv/versions/anaconda3-5.3.1/envs/pymoltest/lib/python3.7/site-packages'」でした(XXXXXは実際にはユーザーアカウント名ですが恥ずかしいので隠しています)。 condaの仮想環境pymoltestの中に入っていることがわかりやすいですね。
準備できたのでjupyter notebookを起動、新しいnotebookを作成してChange kernelでkernelをpymoltestに切り替えます。
前回同様、pathを通してpymolをimportしてみます。
import sys sys.path.append('/Users/XXXXX/.pyenv/versions/anaconda3-5.3.1/envs/pymoltest/lib/python3.7/site-packages') # XXXXXは実際にはユーザーアカウント名 import pymol # importしたpymolのpathを確認 print(pymol.__path__)
無事importすることができました!! PATHも指定したものとなっていました!
ちなみにpython 3.6の仮想環境のkernelで上記を実行したところ、前回記事同様に「モジュールpymol._cmdが見つからない」というエラーがでてimportできませんでした。 やはりバージョンの確認が大事そうですね。
何はともあれconda
経由でもPyMolのインストールとCUIの利用が可能であることが確認できました!
目的は達成できたので、とりあえずオープンソース版での利用することとして仮想環境ごと削除しておきます。
# 以下ターミナルで実行 # jupyter notebookのカーネルからアンインストールしておく jupyter kernelspec uninstall pymoltest # condaの仮想環境を削除 conda remove -n pymoltest --all
ターミナルを一度落としてから再度立ち上げpymol
を実行することでオープンソース版のPyMOLが立ち上がることを確認できました。
_cmdはどこからきたのか?
さて、jupyter notebookからPyMOLをimportする際の不具合は
- Pythonのversion違いである可能性がある
こと、解決策として
- シンボリックリンクの作成
- Schrödinger社配布版の利用
があることまでわかりました。
で、今回importエラーとなった「pymol._cmd」とは何者か?もう少し調べてみたいと思います。
Github Open-Source PyMOL上でオープンソースのソースコードを確認してみましたが、 ディレクトリmodules/pymolの中にcmd.pyはあるものの_cmdに相当するものはありませんでした。
ビルド(?)する際に作成されたのかな?ということでsetup.pyの中身を確認したところ以下のコードに行き当たりました。
from distutils.core import setup, Extension # ~ 中略 ~ ext_modules += [ Extension("pymol._cmd", get_sources(pymol_src_dirs), include_dirs = inc_dirs, libraries = libs, library_dirs = lib_dirs, define_macros = def_macros, extra_link_args = ext_link_args, extra_compile_args = ext_comp_args, extra_objects = ext_objects, ), # ~以下略~
distutils
はPythonのモジュール配布のためのユーティリティで *3、Extensionは「C/C++拡張モジュールをセットアップスクリプトで表すために使われ」るそうです*4。
Extensionの説明と引数(argument
)の内容からソースコードからビルドに伴って作成されたC/C++関連のファイルということがなんとなくぼんやりとわかりました。
これを踏まえて「_cmd.cpython-37m-darwin.so」というファイル名を再度眺めてみます。
前回邪魔なのではと削除してしまった「cpython-37m-darwin」の部分ですが、こちらはCythonでコンパイルする際に追加される接尾辞(suffix)のようです*5。 CythonはPythonの「処理速度が遅い」という問題を解決するためにC/C++に変換するもの(????)で*6、 また、darwinはmacOS(Mac OS X)のベースとなっているオープンソースのオペレーティングシステムDarwinのことのようです*7。
なんとなくですがMacでpython 3.7でC/C++関連のコンパイルを行うことで作成されたファイルという感じでしょうか?(・・・浅い理解)
python 3.7に紐づいているからpython 3.6の仮想環境ではうまく動かなかったのかもしれませんね!(平然と誤情報を垂れ流すよ!!)
まとめ
以上、前回に引き続きPyMOLのCUIを利用するための方法についてでした。 適当な記事を書くとすぐに解決策が教えていただけるのでオープンソースのコミュニティに感謝感謝です。ありがとうございました!!
今回も適当調べで誤情報多そうなのでご指摘いただければ幸いです。ではでは!