Chem-Ant 論文¶
- author:
Akihiro Kuroiwa
- date:
2022/07/08
- abstract:
2019年に
chess-ant
を書き始めたのだが、最初は minimax にこだわり、遅々として作業は進まなかった。2020年にクルーズ船ダイヤモンド・プリンセス号の COVID-19 集団感染があり、いよいよパンデミックが注目され始めた頃、chess-ant
のアルゴリズムを治療薬の開発に役立てようと思い立った。その後、 MCTS solver の論文を読み、性能が向上した。同時に cheminformatics のソフトウェアの使い方も身についていった。SARS-CoV-2 のパンデミックが収束した後も、次なるパンデミックが待ち構えている。我々の技能で社会に貢献しよう。
UCSF Chimera¶
私の古いラップトップ Fujitsu LIFEBOOK AH42/C に UCSF ChimeraX をインストールしようとしたら、次のようなエラーが表示された:
ERROR: ChimeraX requires OpenGL graphics version 3.3.
Your computer graphics driver provided version 2.1
Try updating your graphics driver.
従って、この実験では、 UCSF Chimera を用いる。その利点は、 binding site と呼ばれる結合部位をマウスで指定できることにある。
chmod u+x chimera-alpha-linux_x86_64.bin
./chimera-alpha-linux_x86_64.bin
Ubuntu の ~/.profile
で:
if [ -d "$HOME/.local/bin" ] ; then
PATH="$HOME/.local/bin:$PATH"
fi
私の場合、インストールする場所は2箇所に分かれる:
~/.local/bin/
~/.local/UCSF-Chimera64-2022-05-18/
ターミナルを開いてコマンドラインで chimera を実行するか、デスクトップに出来たアイコンを右クリックし、実行権限を与え、ダブルクリックする。
実験に先立ち、最新リリースの AutoDock Vina installer from GitHub を入手し、マニュアルに沿いインストールする。バイナリーファイル(実行ファイル)の在り処は、次のコマンドで確認できる:
cd ~/.local/bin/
ln -s vina_1.2.3_linux_x86_64 vina
which vina
動作検証をするために、次のように実験を進める:
ターゲット分子 Nirmatrelvir のみをフラグメントにし、分子を幾つか出力する。
ターゲット分子を含む材料候補を similarity-mcts で選び、分子を幾つか出力する。
両者の 差集合を 得る。
similarity-genMols -t "CC1(C2C1C(N(C2)C(=O)C(C(C)(C)C)NC(=O)C(F)(F)F)C(=O)NC(CC3CCNC3=O)C#N)C" -m "CC1(C2C1C(N(C2)C(=O)C(C(C)(C)C)NC(=O)C(F)(F)F)C(=O)NC(CC3CCNC3=O)C#N)C" -b70 -p "gen_smiles" -f "gen1-1.csv"
similarity-mcts -l2 -e3 -r10 -b100 -p "gen_smiles" -f "gen1-2.csv"
実行後、次のように表示されただろう:
Material candidates: {'CC1(C2C1C(N(C2)C(=O)C(C(C)(C)C)NC(=O)C(F)(F)F)C(=O)NC(CC3CCNC3=O)C#N)C', 'CCCC1=NC(=C(N1CC2=CC=C(C=C2)C3=CC=CC=C3C4=NNN=N4)C(=O)O)C(C)(C)O'}
similarity-genMols を実行する際に気をつけることがある。Python ではシングルクォートとダブルクォートを区別しないが、 bash や dash では区別する。更に、コマンドラインでカンマは不要だ:
similarity-genMols -t "CC1(C2C1C(N(C2)C(=O)C(C(C)(C)C)NC(=O)C(F)(F)F)C(=O)NC(CC3CCNC3=O)C#N)C" -m "CC1(C2C1C(N(C2)C(=O)C(C(C)(C)C)NC(=O)C(F)(F)F)C(=O)NC(CC3CCNC3=O)C#N)C" "CCCC1=NC(=C(N1CC2=CC=C(C=C2)C3=CC=CC=C3C4=NNN=N4)C(=O)O)C(C)(C)O" -b100 -f gen1-2.csv
similarity-genMols -t "CC1(C2C1C(N(C2)C(=O)C(C(C)(C)C)NC(=O)C(F)(F)F)C(=O)NC(CC3CCNC3=O)C#N)C" -m "CCCC1=NC(=C(N1CC2=CC=C(C=C2)C3=CC=CC=C3C4=NNN=N4)C(=O)O)C(C)(C)O" -b100 -f gen1-3.csv
import pandas as pd
df1_1 = pd.read_csv("gen_smiles/gen1-1.csv", header=0, index_col=0)
df1_2 = pd.read_csv("gen_smiles/gen1-2.csv", header=0, index_col=0)
df1_3 = pd.read_csv("gen_smiles/gen1-3.csv", header=0, index_col=0)
df1_4 = pd.concat([df1_1, df1_1, df1_2, df1_3, df1_3], axis=0)
df1_4.drop_duplicates(subset="smiles", keep=False, inplace=True)
df1_4.sort_values(["lipinski", "dice_similarity"], inplace=True, ascending=False)
df1_4.reset_index(drop=True).to_csv("gen_smiles/gen1-4.csv")
Ligand file を Open Babel で作成する。gen3.csv
を開き、 similarity-mcts で得た高得点の分子のsmilesを指定しよう。水素原子を付加し、部分電荷を割り当てるのを忘れないように。Ubuntuで:
sudo apt install openbabel
obabel -L
obabel -L charges
obabel -h -c -ican -:"CCCC1C2C(CN1C(=O)C1C3C(CN1C(=O)C(F)(F)F)C3(C)C)C2(C)C" -opdbqt -O ligand.pdbqt --gen3D --partialcharge gasteiger
UCSF Chimera に戻ろう。上記のファイルを開き、以下のようにメニューを辿る:
我々の Output file は all
だ。Receptor と Ligand を指定しよう。Resize search volume using をマウス操作の為にチェックする。上記のコマンドで得た vina のパスを Executable location に書く。
私の場合、 binding site をマウスで指定すると、 Presets メニューで切り替えるまで枠が表示されない。実験結果を後程、再確認したければ all.receptor.pdb
を開き、次のようにする:
AutoDock Vina¶
UCSF Chimera により出力された receptor file を再利用し、コマンドラインであなたが独自に作成した ligand file を実験したいだろう。設定ファイル conf.txt
を用意しよう:
receptor = all.receptor.pdbqt
ligand = ligand.pdbqt
out = all.pdbqt
center_x = -2.68714
center_y = -1.23572
center_z = 13.8821
size_x = 25.747
size_y = 22.6627
size_z = 22.1881
similarity-mcts は今回は Catechin と謎めいた分子 Gnididin [1] を選んだ:
similarity-mcts -l2 -e3 -r10 -b100 -p "gen_smiles" -f "gen2-2.csv"
Material candidates: {'C1C(C(OC2=CC(=CC(=C21)O)O)C3=CC(=C(C=C3)O)O)O', 'CCCCCC=CC=CC(=O)OC1C(C23C4C=C(C(=O)C4(C(C5(C(C2C6C1(OC(O6)(O3)C7=CC=CC=C7)C(=C)C)O5)CO)O)O)C)C'}
gen2-2.csv
:
,smiles,dice_similarity,lipinski
0,C=C(C)C12OC3(CO)OC1C1C4OC4(CO)C(O)C4(O)C(=O)C(C)=CC4C1(O3)C(C)C2CO,0.19672131147540983,1.0
残念ながら、この分子は Gnididin のみで生成されたフラグメントにより出来る。
obabel -h -c -ican -:"C=C(C)C12OC3(CO)OC1C1C4OC4(CO)C(O)C4(O)C(=O)C(C)=CC4C1(O3)C(C)C2CO" -opdbqt -O ligand.pdbqt --gen3D --partialcharge gasteiger
AutoDock Vina を実行する:
vina --config conf.txt
mode | affinity | dist from best mode
| (kcal/mol) | rmsd l.b.| rmsd u.b.
-----+------------+----------+----------
1 -8.765 0 0
2 -8.31 1.82 6.828
3 -8.252 2.441 4.152
4 -8.086 1.664 7.041
5 -7.85 2.301 7.148
6 -7.825 1.726 6.693
7 -7.797 3.008 6.184
8 -7.412 2.183 7.011
9 -7.339 2.426 4.168
鋳型と鋳物¶
参照した論文に書かれているアミノ酸相互作用は [2] PDB ID: 6LU7 に基づく。一方、我々の実験は the SARS-CoV-2 Mpro Omicron P132H に基づいており、 PDB ID: 7TLL を使用する。Active site amino acid の冒頭3文字はアミノ酸の略号で、残りは配列上の位置を示す。UCSF Chimera で確認しよう:
と chimera のメニューで辿る。
カーソルを binding site 上の receptor の active site amino acid に合わせると、その位置が表示される。
chimera で
を辿り、ヌクレオチドやアミノ酸の sequence alignment を表示し、 fast format で保存する。活性部位のアミノ酸を確認したいならば、配列上のその場所で右クリックする。
鋳型から鋳物を鋳造すれば、元の鋳型に合うはずだ。私が smiles.csv
[3] にアミノ酸とヌクレオチドを追加した理由でもある。Docking simulation における binding site と ligand の関係も同様だと言えるかどうか、以下の方法で実験する:
該当箇所を
rdkit
で smiles に変換する。範囲は Phe140 から Glu166 迄だ。その smiles 文字列は長過ぎるので、 fragments に分解し、幾つかの分子に出力する。
from rdkit import Chem
from rdkit.Chem import BRICS
Chem.MolToSmiles(Chem.MolFromFASTA("FLNGSCGSVGFNIDYDCVSFCYMHHME"))
smiles = 'CC[C@H](C)[C@H](NC(=O)[C@H](CC(N)=O)NC(=O)[C@H](Cc1ccccc1)NC(=O)CNC(=O)[C@@H](NC(=O)[C@H](CO)NC(=O)CNC(=O)[C@H](CS)NC(=O)[C@H](CO)NC(=O)CNC(=O)[C@H](CC(N)=O)NC(=O)[C@H](CC(C)C)NC(=O)[C@@H](N)Cc1ccccc1)C(C)C)C(=O)N[C@@H](CC(=O)O)C(=O)N[C@@H](Cc1ccc(O)cc1)C(=O)N[C@@H](CC(=O)O)C(=O)N[C@@H](CS)C(=O)N[C@H](C(=O)N[C@@H](CO)C(=O)N[C@@H](Cc1ccccc1)C(=O)N[C@@H](CS)C(=O)N[C@@H](Cc1ccc(O)cc1)C(=O)N[C@@H](CCSC)C(=O)N[C@@H](Cc1c[nH]cn1)C(=O)N[C@@H](Cc1c[nH]cn1)C(=O)N[C@@H](CCSC)C(=O)N[C@@H](CCC(=O)O)C(=O)O)C(C)C'
allfrags = set()
allfrags.update(BRICS.BRICSDecompose(Chem.MolFromSmiles(smiles), returnMols=True))
builder = BRICS.BRICSBuild(allfrags)
generated_smiles = []
for i in range(30):
mol = next(builder)
mol.UpdatePropertyCache(strict=True)
generated_smiles.append(Chem.MolToSmiles(mol))
generated_smiles
['CSCC[C@H](SC)C(=O)N[C@@H](CCC(=O)O)C(=O)O', 'CSCC[C@H](SC)C(=O)Nc1c[nH]cn1', 'CSCC[C@H](SC)C(=O)Nc1ccc(O)cc1', 'CSCC[C@H](SC)C(=O)Nc1ccccc1', 'CS[C@@H](CC(C)C)C(=O)Nc1ccc(O)cc1', 'CC(C)C[C@H](N[C@@H](CCC(=O)O)C(=O)O)C(=O)Nc1ccc(O)cc1', 'CC(C)C[C@H](Nc1ccc(O)cc1)C(=O)Nc1ccc(O)cc1', 'CC(C)C[C@H](Nc1ccccc1)C(=O)Nc1ccc(O)cc1', 'CC(C)C[C@H](Nc1c[nH]cn1)C(=O)Nc1ccc(O)cc1', 'CS[C@@H](CC(C)C)C(=O)Nc1c[nH]cn1', 'CS[C@@H](CC(C)C)C(=O)Nc1ccccc1', 'CS[C@@H](CC(C)C)C(=O)N[C@@H](CCC(=O)O)C(=O)O', 'CS[C@@H](CC(=O)O)C(=O)NC(=O)[C@H](CC(C)C)SC', 'CS[C@@H](CC(C)C)C(=O)NC(=O)[C@@H](SC)C(C)C', 'CS[C@@H](CC(N)=O)C(=O)NC(=O)[C@H](CC(C)C)SC', 'CS[C@@H](CC(C)C)C(=O)NC(=O)[C@H](CS)SC', 'CS[C@@H](CC(C)C)C(=O)NC(=O)[C@@H](N)Cc1c[nH]cn1', 'CS[C@@H](CC(C)C)C(=O)NC(=O)[C@@H](N)Cc1ccc(O)cc1', 'CS[C@@H](CC(C)C)C(=O)NC(=O)[C@@H](N)Cc1ccccc1', 'CS[C@@H](CO)C(=O)NC(=O)[C@H](CC(C)C)SC', 'CS[C@@H](CC(C)C)C(=O)NC(=O)[C@H](CC(C)C)SC', 'CC[C@H](C)[C@H](SC)C(=O)NC(=O)[C@H](CC(C)C)SC', 'CSCC(=O)NC(=O)[C@H](CC(C)C)SC', 'CC(C)C[C@H](N[C@@H](CCC(=O)O)C(=O)O)C(=O)Nc1ccccc1', 'CC(C)C[C@H](Nc1c[nH]cn1)C(=O)Nc1ccccc1', 'CC(C)C[C@H](Nc1ccc(O)cc1)C(=O)Nc1ccccc1', 'CC(C)C[C@H](Nc1ccccc1)C(=O)Nc1ccccc1', 'CC(C)C[C@H](Nc1ccc(O)cc1)C(=O)N[C@@H](CCC(=O)O)C(=O)O', 'CC(C)C[C@H](Nc1ccccc1)C(=O)N[C@@H](CCC(=O)O)C(=O)O', 'CC(C)C[C@H](N[C@@H](CCC(=O)O)C(=O)O)C(=O)N[C@@H](CCC(=O)O)C(=O)O']
出力された分子から、ドッキング・シミュレーションで好成績となった分子を選ぶ。勿論、選択肢の中での好成績だが。
その分子をターゲットに similarity-mcts を動かす。
obabel -h -c -ican -:"CC(C)C[C@H](Nc1ccc(O)cc1)C(=O)N[C@@H](CCC(=O)O)C(=O)O" -opdbqt -O ligand.pdbqt --gen3D --partialcharge gasteiger
vina --config conf.txt
mode | affinity | dist from best mode
| (kcal/mol) | rmsd l.b.| rmsd u.b.
-----+------------+----------+----------
1 -7.192 0 0
2 -7.014 2.837 4.843
3 -7.002 1.339 2.292
4 -7.001 2.143 4.417
5 -6.894 1.303 2.67
6 -6.759 2.539 6.62
7 -6.578 2.329 7.121
8 -6.547 3.004 7.767
9 -6.51 1.3 2.908
similarity-mcts -i -l2 -e3 -r10 -b100 -p "gen_smiles" -f "gen3-2.csv" -t "CC(C)C[C@H](Nc1ccc(O)cc1)C(=O)N[C@@H](CCC(=O)O)C(=O)O"
Material candidates: {'CC1CCC2C(C(OC3C24C1CCC(O3)(OO4)C)OC)C', 'C(CCN)CC(C(=O)O)N', 'CC(C)C[C@H](Nc1ccc(O)cc1)C(=O)N[C@@H](CCC(=O)O)C(=O)O'}
,smiles,dice_similarity,lipinski
0,CCNC1CCNC1=O,0.5454545454545454,1.0
1,CC(Nc1ccccc1)C(=O)Oc1ccccc1,0.5269607843137255,1.0
2,COC(=O)[C@H](CC(C)C)Nc1ccc(O)cc1,0.5084427767354597,1.0
3,CC(C)C(=O)OC(=O)C(C)C,0.5078125,1.0
4,O=C1NCCC1Nc1ccc(F)cc1,0.5066162570888468,1.0
5,COC(=O)[C@H](CC(C)C)OC,0.5040983606557377,1.0
6,C(c1nn[nH]n1)c1nn[nH]n1,0.4921875,1.0
7,CCOc1nn[nH]n1,0.4765625,1.0
8,COc1ccc(O)cc1,0.46875,1.0
9,CO[C@@H](CCC(=O)O)C(=O)O,0.4609053497942387,1.0
10,CC(C(=O)N1Cc2ccccc2CC1C(=O)O)N1Cc2ccccc2CC1c1ccccc1,0.4494649227110582,1.0
11,CC(C(=O)N1Cc2ccccc2CC1C(=O)O)N1Cc2ccccc2CC1C(=O)O,0.4436183395291202,1.0
12,c1ccc(C2CC3CCCC3N2c2ccccc2)cc1,0.4426666666666666,1.0
13,COC(=O)[C@H](CC(C)C)NC1OC2OC3(C)CCC4C(C)CCC(C1C)C24OO3,0.43861607142857145,1.0
14,O=C(O)C1Cc2ccccc2CN1c1ccccc1,0.4348387096774193,1.0
15,CC1CCC2C(C)C(Nc3ccc(O)cc3)OC3OC4(C)CCC1C32OO4,0.4311717861205916,1.0
16,CO[C@@H](CC(C)C)C(=O)NC1OC2OC3(C)CCC4C(C)CCC(C1C)C24OO3,0.4242761692650334,1.0
17,CC(C(=O)Oc1ccccc1)N1C(c2ccccc2)CC2CCCC21,0.4230287859824781,1.0
18,CCOc1ccccc1C(=O)O,0.4228971962616822,1.0
19,Cc1cc(NC2CCNC2=O)no1,0.4113924050632911,1.0
短い smiles は無視する:
obabel -h -c -ican -:"CC(C(=O)N1Cc2ccccc2CC1C(=O)O)N1Cc2ccccc2CC1c1ccccc1" -opdbqt -O ligand.pdbqt --gen3D --partialcharge gasteiger
vina --config conf.txt
mode | affinity | dist from best mode
| (kcal/mol) | rmsd l.b.| rmsd u.b.
-----+------------+----------+----------
1 -8.417 0 0
2 -8.302 2.467 6.754
3 -8.003 4.96 7.503
4 -7.624 3.907 6.517
5 -7.506 5.171 7.983
6 -7.485 2.979 5.385
7 -7.433 5.416 9.353
8 -7.375 2.857 5.204
9 -7.296 2.998 5.526
類似性の目標となるターゲット分子そのものが必要な場合は、上記の方法が役立つかも知れない。
課題
MCTS solver を別パッケージにする
ターゲット分子が無くともドッキング・シミュレーションで高得点を取れるシミュレーションは出来るか?
Type bool が 1.0 や 0.0 のように csv file に出力されてしまう。
similarity-ant は遅すぎて実用性に程遠い。
そもそも similarity-mcts は正しく動作しているのか?
Version 0.0.3 の similarity-mcts は MCTS solverをインポートするので、この文書と出力が若干異なる。
絡み合ったスパゲッティコードを解く。