🫘

MolSnapperの動作確認

に公開

分子生成系のAIも面白そうだなと思い、とりあえず最近の報告を実装・動作確認してみた。
今回はこちらの報告。 MolSnapper
githubはこちら。 MolSnapper(github)

本記事では、MolSnapper リポジトリをローカルで動かし、PDB ID: 4AG8 のタンパク質・リガンド複合体について

  1. データ準備
  2. 前処理(クリーニング & ポケット抽出)
  3. 分子サンプリング
  4. 評価スコアリング
  5. 上位候補の抽出&SDF マージ(Similarity / QED順)

という一連の流れを、コマンド/スクリプト例つきでまとめます。


1. 環境構築

# MolSnapper リポジトリをクローン
mkdir /usr/local/apps
cd /usr/local/apps
git clone https://github.com/oxpig/MolSnapper.git
cd MolSnapper

# Conda 環境作成
conda env create -f env.yml
conda activate MolSnapper

必要モジュール:

  • Python 3.9.18
  • PyTorch 2.0.1 + CUDA 11.7
  • PyTorch Geometric 2.3.1
  • RDKit 2022.03.5
  • Biopython 1.83
  • pdb-tools ≥2.0 など

2. 生データの準備

# 作業ディレクトリ作成
mkdir -p ~/molsnapper/4AG8_test
cd ~/molsnapper/4AG8_test

# PDB (4AG8) をダウンロード
wget -O 4AG8.pdb https://files.rcsb.org/download/4AG8.pdb

# リガンド三文字コードを確認 (例: LIG)
grep '^HETATM' 4AG8.pdb | awk '{print $4}' | sort | uniq

# リガンドモデル SDF をダウンロード
mkdir -p ligands
wget -O ligands/4AG8_0.sdf https://files.rcsb.org/ligands/download/LIG_model.sdf

構成例:

~/molsnapper/4AG8_test/
├── 4AG8.pdb
└── ligands/
    └── 4AG8_0.sdf

3. 前処理(クリーニング&分割→ポケット抽出)

3.1 クリーニング & ATOM/HETATM 分割

python scripts/clean_and_split.py \
  --in-dir       ~/molsnapper/4AG8_test \
  --proteins-dir ~/molsnapper/4AG8_test/proteins \
  --ligands-dir  ~/molsnapper/4AG8_test/ligands

出力例:

proteins/4AG8_protein.pdb
ligands/4AG8_0.sdf

3.2 ポケット.pkl 生成

python scripts/prepare_single_complex.py \
  --root_dir         ~/molsnapper/4AG8_test \
  --ligand_filename  ligands/4AG8_0.sdf \
  --protein_filename proteins/4AG8_protein.pdb \
  --out_pockets_path ~/molsnapper/4AG8_test/processed_pocket_4AG8.pkl

4. 分子サンプリング

mkdir -p ~/molsnapper/4AG8_test/outputs

python scripts/sample_single_pocket.py \
  --outdir       ~/molsnapper/4AG8_test/outputs \
  --config       configs/sample/sample_MolDiff.yml \
  --device       cuda:0 \
  --batch_size   0 \
  --pocket_path  ~/molsnapper/4AG8_test/processed_pocket_4AG8.pkl \
  --sdf_path     ~/molsnapper/4AG8_test/ligands/4AG8_0.sdf \
  --use_pharma   False \
  --clash_rate   0.1

生成結果はサブディレクトリ内に

0.sdf, 1.sdf, …, *_shifted.sdf

として出力されます。


5. 評価スコアリング

mkdir -p ~/molsnapper/4AG8_test/outputs/eval

python scripts/evaluate.py \
  ~/molsnapper/4AG8_test/outputs/sample_MolDiff_*_SDF \
  --protein_path ~/molsnapper/4AG8_test/4AG8.pdb \
  --reflig_path  ~/molsnapper/4AG8_test/ligands/4AG8_0.sdf \
  --save_path    ~/molsnapper/4AG8_test/outputs/eval

出力:

~/molsnapper/4AG8_test/outputs/eval/eval_all.pt

→ 下記で results.csv に変換

cd ~/molsnapper/4AG8_test/outputs/eval
python - << 'EOF'
import torch, pandas as pd

data = torch.load('eval_all.pt')
df   = pd.DataFrame(data)
chem = pd.json_normalize(df['chem_results'])
df2  = pd.concat([df.drop(columns=['chem_results']), chem], axis=1)
df2['sample'] = df2.index
df2.to_csv('results.csv', index=False)
print(df2.head())
EOF

6. 上位候補抽出&SDFマージ

6.1 Similarity 順トップ5

# ID を取得
cd ~/molsnapper/4AG8_test/outputs/eval
ids=$(python - << 'EOF'
import pandas as pd
df = pd.read_csv('results.csv')
print(" ".join(df.sort_values('similarity', ascending=False).head(5)['sample'].astype(str)))
EOF
)

# マージ
merged=~/molsnapper/4AG8_test/outputs/top5_sim_shifted.sdf
> "$merged"
for id in $ids; do
  cat ~/molsnapper/4AG8_test/outputs/sample_MolDiff_*_SDF/${id}_shifted.sdf \
    >> "$merged"
  echo '$$$$' >> "$merged"
done

# 確認
grep -c '^\$\$\$\$$' "$merged"  # => 5

6.2 QED 順トップ5

# ID を取得
cd ~/molsnapper/4AG8_test/outputs/eval
ids=$(python - << 'EOF'
import pandas as pd
df = pd.read_csv('results.csv')
print(" ".join(df.sort_values('qed', ascending=False).head(5)['sample'].astype(str)))
EOF
)

# マージ
merged=~/molsnapper/4AG8_test/outputs/top5_qed_shifted.sdf
> "$merged"
for id in $ids; do
  cat ~/molsnapper/4AG8_test/outputs/sample_MolDiff_*_SDF/${id}_shifted.sdf \
    >> "$merged"
  echo '$$$$' >> "$merged"
done

# 確認
grep -c '^\$\$\$\$$' "$merged"  # => 5

7. PyMOL で可視化

PyMOLでひと通りloadして生成した構造を見てみます。

pymol
# 受容体
load ~/molsnapper/4AG8_test/4AG8.pdb, receptor

# 入力構造
load ~/molsnapper/4AG8_test/ligands/4AG8_0.sdf, ligand


# Similarity 順トップ5
load ~/molsnapper/4AG8_test/outputs/top5_sim_shifted.sdf, sim_candidates

# QED 順トップ5
load ~/molsnapper/4AG8_test/outputs/top5_qed_shifted.sdf, qed_candidates

実施の途中で気がついたんですが、あくまで入力した分子構造をポケットの中の範囲で変換する方法論だったらしく、全くのde novoっていう感じではありませんでした。
pocket2molDiffSBDDっていうのは低分子の入力なしに分子構造を生成できるっぽいので、次回はそちらにチャレンジしたいです。

Discussion