mcpField
D
drug-discovery-pipeline

drug-discovery-pipeline

github.com/nvidia-bionemo其他502253 次安装2 天前更新
代码仓库

关于 drug-discovery-pipeline

drug-discovery-pipeline 是依次使用 GenMol、DiffDock 和 Boltz2 筛选候选药物的技能指南。它涵盖从头发现、基于骨架的先导优化和虚拟筛选,并说明托管及本地 Docker 模式。

主要功能

  1. 01GenMol、DiffDock 和 Boltz2 顺序工作流
  2. 02从头生成分子
  3. 03基于骨架生成类似物
  4. 04分子对接与亲和力预测
  5. 05托管及本地 Docker 模式指南

适用场景

  1. 01针对目标蛋白寻找初始命中分子
  2. 02从已知骨架生成类似物
  3. 03筛选候选分子库
  4. 04结合对接和亲和力结果排序候选物

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/nvidia-bionemo/bionemo-agent-toolkit --skill drug-discovery-pipeline

安装后在 Claude Code 中输入/drug-discovery-pipeline确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

BENCHMARK.md
skill-card.md
skill.oms.sig
evals/
config.yml
evals.json
evals/files/
egfr.pdb

详细介绍

药物发现流程

依次使用三个 BioNeMo NIM,端到端筛选候选药物:

Step 1: GenMol    →  Step 2: DiffDock  →  Step 3: Boltz2
(Generate mols)      (Dock to target)      (Predict affinity)

概述

此流程适用于:

  • 从头发现命中化合物:生成类药分子,并针对目标进行筛选
  • 先导优化:从已知骨架出发,生成改良类似物,然后进行对接和评分
  • 虚拟筛选:对候选分子库进行对接,并根据对接置信度和亲和力进行筛选

开始之前

请与用户确认:

  1. 目标蛋白质:结合靶标的 PDB 文件或序列
  2. 起点:从头生成(无骨架)还是骨架修饰(已知核心)?
  3. 评分方式:类药性(QED)还是亲脂性(LogP)?
  4. API 模式:托管模式还是本地 Docker?

对于本地 Docker,不要假设所有 NIM 都同时运行在 localhost:8000 上。可以一次运行一个容器,并在各步骤之间传递文件和结果;也可以在不同的主机端口上启动各个 NIM,并设置每个步骤对应的 URL。


步骤 1:使用 GenMol 生成分子

GenMol 需要 SAFE 表示法输入(不是原始 SMILES)。请使用 safe-mol 软件包。

import requests, json, os
import safe as sf                          # pip install safe-mol
from pathlib import Path

NGC_API_KEY = os.getenv("NGC_API_KEY")
HOSTED = True

if HOSTED:
    genmol_url = "https://health.api.nvidia.com/v1/biology/nvidia/genmol/generate"
    headers = {"Content-Type": "application/json",
               "Authorization": f"Bearer {NGC_API_KEY}"}
else:
    genmol_url = "http://localhost:8000/generate"
    headers = {"Content-Type": "application/json"}

# De novo generation (no scaffold):
safe_input = "[*{20-30}]"

# Scaffold decoration (known core):
# scaffold_smiles = "c1ccccc1"
# safe_input = sf.encode(scaffold_smiles) + ".[*{5-10}]"

payload = {
    "smiles": safe_input,              # field is named 'smiles' but takes SAFE notation
    "num_molecules": 30,               # request more to compensate for post-generation filtering
    "scoring": "QED",                  # QED or LogP
    "unique": True,
    "temperature": "1.0",             # NOTE: must be string, not float
    "noise": "1.0",                   # NOTE: must be string, not float
}

r = requests.post(genmol_url, headers=headers, json=payload)
r.raise_for_status()
molecules = r.json()["molecules"]
molecules_sorted = sorted(molecules, key=lambda x: x["score"], reverse=True)
top_20 = molecules_sorted[:20]

print(f"Generated {len(molecules)} valid molecules (requested 30)")
print("Top 5 by QED score:")
for m in top_20[:5]:
    print(f"  {m['smiles'][:50]}  score={m['score']:.4f}")

步骤 2:使用 DiffDock 对接分子

准备蛋白质,并对每个候选分子进行对接:

# Load protein (ATOM records only)
receptor_pdb_raw = Path("target.pdb").read_text()
receptor_pdb = "\n".join(line for line in receptor_pdb_raw.splitlines()
                          if line.startswith("ATOM"))

if HOSTED:
    diffdock_url = "https://health.api.nvidia.com/v1/biology/mit/diffdock"
else:
    diffdock_url = "http://localhost:8000/molecular-docking/diffdock/generate"

docking_results = []

for i, mol in enumerate(top_20):
    payload = {
        "protein": receptor_pdb,
        "ligand": mol["smiles"],
        "ligand_file_type": "txt",     # "txt" for SMILES input
        "num_poses": 5,
        "time_divisions": 20,
        "steps": 18,
        "save_trajectory": False,
    }

    r = requests.post(diffdock_url, headers=headers, json=payload)
    r.raise_for_status()
    result = r.json()

    best_conf = result["position_confidence"][0]  # rank 1 pose
    best_pose = result["ligand_positions"][0]

    docking_results.append({
        "smiles": mol["smiles"],
        "qed_score": mol["score"],
        "docking_confidence": best_conf,
        "best_pose_sdf": best_pose,
    })
    print(f"  Mol {i+1:2d}: QED={mol['score']:.3f}  docking_conf={best_conf:.4f}")

# Rank by docking confidence
docking_results.sort(key=lambda x: x["docking_confidence"], reverse=True)
print(f"\nTop 3 by docking confidence:")
for d in docking_results[:3]:
    print(f"  {d['smiles'][:50]}  conf={d['docking_confidence']:.4f}")

步骤 3:使用 Boltz2 预测结合亲和力

针对对接结果排名靠前的候选分子,预测基于结构的结合亲和力:

if HOSTED:
    boltz_url = "https://health.api.nvidia.com/v1/biology/mit/boltz2/predict"
else:
    boltz_url = "http://localhost:8000/biology/mit/boltz2/predict"

# Use the target protein sequence (not PDB)
target_sequence = "<YOUR_TARGET_PROTEIN_SEQUENCE>"

affinity_results = []
for d in docking_results[:5]:  # score top 5 docking hits
    payload = {
        "polymers": [
            {"id": "A", "molecule_type": "protein", "sequence": target_sequence}
        ],
        "ligands": [
            {"id": "L1", "smiles": d["smiles"], "predict_affinity": True}
        ],
        "recycling_steps": 3,
        "sampling_steps": 50,
        "diffusion_samples": 1,
        "output_format": "mmcif",
    }

    r = requests.post(boltz_url, headers=headers, json=payload)
    r.raise_for_status()
    result = r.json()

    aff = result["affinities"]["L1"]
    pic50 = aff["affinity_pic50"][0]
    prob_binding = aff["affinity_probability_binary"][0]

    affinity_results.append({
        **d,
        "pic50": pic50,
        "probability_binding": prob_binding,
    })
    print(f"  {d['smiles'][:40]}  pIC50={pic50:.2f}  P(bind)={prob_binding:.3f}")

# Final ranking by pIC50
affinity_results.sort(key=lambda x: x["pic50"], reverse=True)

结果解读

  • GenMol QED 分数:0–1;>0.5 表示具有类药性
  • DiffDock 置信度:越高,结合姿势预测越可靠
  • Boltz2 pIC50:预测的 -log10(IC50);>6 表示亚微摩尔级,>8 表示效力很强
  • P(bind):二元结合的概率;>0.7 表示很可能结合

快速参考 — 技能依赖项

步骤技能关键端点
分子生成genmol-nim/biology/nvidia/genmol/generate
对接diffdock-nim/molecular-docking/diffdock/generate
亲和力预测boltz2-nim/biology/mit/boltz2/predict

评论

支持 Markdown