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

動作検証をするために、次のように実験を進める:

  1. ターゲット分子 Nirmatrelvir のみをフラグメントにし、分子を幾つか出力する。

  2. ターゲット分子を含む材料候補を similarity-mcts で選び、分子を幾つか出力する。

  3. 両者の 差集合を 得る。

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 に戻ろう。上記のファイルを開き、以下のようにメニューを辿る:

  1. File ‣ Fetch Structure by ID ‣ PDB(mmCIF) ‣ 7tll

  2. File ‣ Open ‣ ligand.pdbqt ‣ file type PDB

  3. Tools ‣ Surface/Binding Analysis ‣ AutoDock Vina

我々の Output fileall だ。ReceptorLigand を指定しよう。Resize search volume using をマウス操作の為にチェックする。上記のコマンドで得た vina のパスを Executable location に書く。

私の場合、 binding site をマウスで指定すると、 Presets メニューで切り替えるまで枠が表示されない。実験結果を後程、再確認したければ all.receptor.pdb を開き、次のようにする:

  1. Tools ‣ Surface/Binding Analysis ‣ ViewDock ‣ all.pdbqt

  2. Move ‣ Play

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 で確認しよう:

  1. Presets ‣ Interactive 1 (ribbons)chimera のメニューで辿る。

  2. カーソルを binding site 上の receptor の active site amino acid に合わせると、その位置が表示される。

  3. chimeraTools ‣ Sequence ‣ Sequence を辿り、ヌクレオチドやアミノ酸の sequence alignment を表示し、 fast format で保存する。

  4. 活性部位のアミノ酸を確認したいならば、配列上のその場所で右クリックする。

鋳型から鋳物を鋳造すれば、元の鋳型に合うはずだ。私が smiles.csv [3] にアミノ酸とヌクレオチドを追加した理由でもある。Docking simulation における binding site と ligand の関係も同様だと言えるかどうか、以下の方法で実験する:

  1. 該当箇所を rdkit で smiles に変換する。範囲は Phe140 から Glu166 迄だ。

  2. その 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']
  1. 出力された分子から、ドッキング・シミュレーションで好成績となった分子を選ぶ。勿論、選択肢の中での好成績だが。

  2. その分子をターゲットに 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をインポートするので、この文書と出力が若干異なる。

  • 絡み合ったスパゲッティコードを解く。

参照

参考文献