关于 alterlab-medchem
alterlab-medchem 是使用 medchem Python 库筛选和排序药物发现候选分子的技能,适用于化合物初筛和先导优化,结合药物化学规则、结构警示、化学基团检测、复杂度指标及查询 DSL。
主要功能
- 01应用药物相似性规则筛选分子
- 02按结构警示目录过滤分子
- 03检测预定义化学基团
- 04评估分子复杂度
- 05用查询 DSL 组合筛选条件
适用场景
- 01初筛化合物库
- 02剔除带有指定结构警示的分子
- 03在先导优化中排序候选物
- 04查找含目标化学基团的分子
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ alterlab-ieu/ alterlab-academic-skills --skill alterlab-medchem安装后在 Claude Code 中输入/alterlab-medchem确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
evals/evals.jsonreferences/api_guide.mdrules_catalog.mdscripts/filter_molecules.py详细介绍
Medchem
概述
Medchem(datamol-io/medchem)是一个用于药物发现工作流中分子筛选和优先级排序的 Python 库,涵盖药物化学规则、结构警示(ChEMBL/NIBR/PAINS)、化学基团检测、复杂度指标和查询 DSL。规则和筛选器是特定情境下的指导原则,并非绝对真理——请结合领域专业知识使用。
已根据 medchem==2.1.0 验证(截至 2026-09 的当前版本;Python ≥ 3.11,RDKit 2026.03)。 下文中的 API 名称均已针对该版本核实;早期文档和博客文章描述的是不同的 API。
何时使用此技能
以下情况应使用此技能:
- 将药物相似性规则(Lipinski、Veber 等)应用于化合物库
- 按结构警示或 PAINS 模式筛选分子
- 为先导化合物优化确定化合物的优先级
- 评估化合物质量和药物化学性质
- 检测反应性或有问题的官能团
- 计算分子复杂度指标
不适用的情况
| 场景 | 改用 |
|---|---|
| 仅计算描述符(MW、cLogP、TPSA、HBD/HBA)或标准化结构,不进行规则/警示筛选 | alterlab-datamol |
| 在精选目录之外编写自定义 SMARTS 查询或子结构逻辑 | alterlab-rdkit |
| 获取带有 scaffold 划分的标记毒性/ADMET 基准数据集(例如 hERG、AMES) | alterlab-pytdc |
| 检索化合物或靶点的实测生物活性(IC50/Ki) | alterlab-chembl |
安装
uv pip install medchem # PyPI; pulls rdkit + datamol
有两项功能需要 PyPI 无法提供的额外原生依赖:
- Lilly 惩罚项(
lilly_demerit_filter)会调用已编译的 Lilly MedChem Rules 工具。自 medchem 2.1 起,medchem install-lilly会下载校验和固定的上游版本(2.1.0),并将其构建在当前 Python 环境旁边——此操作需要make、C++ 编译器和 zlib(运行回归测试还需要 Ruby,或传入--no-test),且不支持原生 Windows(请使用 WSL)。旧版 conda-forgelilly-medchem-rules1.0.1 构建已过时。若没有这些工具,调用会引发ImportError。2.1 还更改了 Lilly 默认原子计数限制(软限制 25 / 硬限制 40 / 最低 7;之前为 30 / 50 / 1)。 - ChemAxon 规则(
rule_of_chemaxon_druglikeness)需要已获许可的 ChemAxon 安装。
其余所有功能(RuleFilters、CommonAlerts、NIBR、复杂度、基团、查询)仅需 PyPI wheel 即可使用。
核心功能
medchem 中通用的约定。 筛选器接收
mols(SMILES 字符串或 RDKit 分子的序列),默认使用n_jobs=-1(全部核心),并接受progress=True。medchem.structural/medchem.rules筛选器类会返回一个 pandas DataFrame(每个输入分子一行);medchem.functional.*辅助函数会返回一个 NumPy 布尔数组,其中True表示分子通过筛选/予以保留。请通过mc.rules.RuleFilters.list_available_rules()和mc.structural.CommonAlertsFilters.list_default_available_alerts()获取规范的规则和警示名称,不要猜测。
1. 药物化学规则 — medchem.rules
单条规则 — medchem.rules.basic_rules.* 函数接受一个 mol(SMILES 或 RDKit),并返回普通的 bool:
import medchem as mc
smi = "CC(=O)OC1=CC=CC=C1C(=O)O" # aspirin
mc.rules.basic_rules.rule_of_five(smi) # -> True
mc.rules.basic_rules.rule_of_veber(smi) # -> True
mc.rules.basic_rules.rule_of_cns(smi)
可用规则(通过 mc.rules.RuleFilters.list_available_rules() 获取完整列表):rule_of_five、rule_of_five_beyond、rule_of_four、rule_of_three、rule_of_three_extended、rule_of_two、rule_of_ghose、rule_of_veber、rule_of_reos、rule_of_egan、rule_of_pfizer_3_75、rule_of_gsk_4_400、rule_of_oprea、rule_of_xu、rule_of_cns、rule_of_respiratory、rule_of_zinc、rule_of_leadlike_soft、rule_of_druglike_soft、rule_of_generative_design、rule_of_generative_design_strict、rule_of_chemaxon_druglikeness(需要 ChemAxon)。
没有
rule_of_drug、rule_of_leadlike_strict、golden_triangle或pains_filter函数(已在 2.1.0 中检查)。PAINS 属于警报系统(HASALERT("pains")或CommonAlertsFilters(alerts_set=["PAINS"]))。对于先导化合物相似性,请使用rule_of_leadlike_soft或rule_of_oprea。
多条规则 — RuleFilters 返回一个包含 mol、pass_all、pass_any 列,以及每条规则对应的一个布尔列的 DataFrame:
import datamol as dm
import medchem as mc
mols = [dm.to_mol(s) for s in smiles_list]
rfilter = mc.rules.RuleFilters(rule_list=["rule_of_five", "rule_of_veber", "rule_of_cns"])
df = rfilter(mols=mols, n_jobs=-1, progress=True)
# df["pass_all"] -> bool per molecule; df["rule_of_five"] -> per-rule bool
clean = [m for m, ok in zip(mols, df["pass_all"]) if ok]
属性范围 — 没有一体化的“Constraints(mw_range=...)”对象(参见第 7 节的说明)。可使用 mc.rules.in_range,根据 mc.rules.list_descriptors() 中的描述符名称(mw、clogp、tpsa、n_lipinski_hbd、n_lipinski_hba、n_rotatable_bonds、n_rings 等)自定义属性阈值,或使用查询 DSL(HASPROP,见第 8 节)。
2. 结构警报筛选器 — medchem.structural
medchem.structural 提供两个筛选器类:CommonAlertsFilters 和 NIBRFilters。(Lilly demerits 通过 medchem.functional 调用,见第 3 节;其类位于 medchem.structural.lilly_demerits 下,且需要外部二进制文件。)
常见警报 — 来自 ChEMBL 的精选警报集(Glaxo、Dundee、BMS、PAINS、SureChEMBL 等)。返回包含 mol、pass_filter(bool)、status(ok/exclude)、reasons(匹配的警报名称,以 ; 连接)的 DataFrame:
import medchem as mc
caf = mc.structural.CommonAlertsFilters() # all default sets
caf_pains = mc.structural.CommonAlertsFilters(alerts_set=["PAINS"]) # PAINS only
df = caf(mols=mol_list, n_jobs=-1, progress=True)
clean = df[df["pass_filter"]]
# discover sets: mc.structural.CommonAlertsFilters.list_default_available_alerts()
NIBR 筛选器 — Novartis 筛选器集。返回包含 mol、pass_filter、severity、status、reasons 的 DataFrame:
nibr = mc.structural.NIBRFilters()
df = nibr(mols=mol_list, n_jobs=-1)
3. 函数式 API — medchem.functional
单次调用的辅助函数,返回 NumPy 布尔数组(True = 保留)。传入 return_idx=True 可改为获取通过筛选的 mol 的索引:
import medchem as mc
mc.functional.rules_filter(mol_list, rules=["rule_of_five", "rule_of_veber"], n_jobs=-1)
mc.functional.alert_filter(mol_list, alerts=["pains"], n_jobs=-1) # alert names are lowercase here
mc.functional.nibr_filter(mol_list, max_severity=10, n_jobs=-1)
mc.functional.complexity_filter(mol_list, complexity_metric="bertz", limit="99", n_jobs=-1)
mc.functional.chemical_group_filter(mol_list, chemical_group=mc.groups.ChemicalGroup(groups=["hinge_binders"]))
Lilly demerits — 需要 Lilly 工具(medchem install-lilly,参见安装);如果缺少该工具,会引发 ImportError。超过 max_demerits(默认值为 160)的分子将被拒绝:
keep = mc.functional.lilly_demerit_filter(mol_list, max_demerits=160, n_jobs=-1) # NumPy bool array
4. 化学基团检测 — medchem.groups
ChemicalGroup 用于匹配精选的基团目录。使用 mc.groups.list_default_chemical_groups() 列出有效的目录名称(例如 hinge_binders、electrophilic_warheads_for_kinases、common_warhead_covalent_inhibitors、privileged_kinase_inhibitor_scaffolds、aggregator)。查询 DSL 的 HASGROUP 所用的每个 mol 的官能团名称来自 mc.groups.list_functional_group_names()。
import medchem as mc
group = mc.groups.ChemicalGroup(groups=["hinge_binders"])
group.has_match(mol) # bool for one mol
group.get_matches(mol) # detailed matches
# batch: mc.functional.chemical_group_filter(mols, chemical_group=group)
phosphate_binders、michael_acceptors和reactive_groups不是默认目录名称。对于反应性/亲电基团,可使用electrophilic_warheads_for_kinases/common_warhead_covalent_inhibitors、警报筛选器(第 2 节),或自定义 SMARTS 目录(mc.catalogs.catalog_from_smarts)。
5. 命名目录 — medchem.catalogs
import medchem as mc
mc.catalogs.list_named_catalogs() # available catalog names
cat = mc.catalogs.NamedCatalogs.pains() # e.g. a PAINS RDKit FilterCatalog
mc.catalogs.catalog_from_smarts(...) # build a catalog from custom SMARTS
6. 分子复杂度 — medchem.complexity
ComplexityFilter 会标记复杂度超过参考集(默认为 ZINC)百分位阈值的分子。它按分子调用,并返回布尔值(True = 在限制范围内/保留)。指标:bertz、whitlock(WhitlockCT)、barone(BaroneCT)、smcm(SMCM)、twc(TWC),以及 sas/qed/clogp。2.1 版新增:mc.complexity.SPS(mol)(标准化的 SpacialScore,Krzyzanowski 等人发表于 J. Med. Chem. 2023);作为 ComplexityFilter 指标("spacialscore")时,需要提供自己的 threshold_stats_file。
import medchem as mc
cflt = mc.complexity.ComplexityFilter(limit="99", complexity_metric="bertz")
keep = [cflt(m) for m in mol_list]
# or batch: mc.functional.complexity_filter(mol_list, complexity_metric="bertz", limit="99")
没有
mc.complexity.calculate_complexity(...);ComplexityFilter接受limit/complexity_metric/threshold_stats_file,而不是max_complexity。如需原始分数,请直接使用指标类(mc.complexity.TWC等)。
7. 子结构约束 — medchem.constraints
mc.constraints.Constraints(core, constraint_fns, prop_name="query") 会对查询核心周围的子结构/R 基团约束进行强制校验(通过 has_match/validate)——它不是物理化学属性范围筛选器。对于 MW/logP/TPSA 范围,请使用 RuleFilters + in_range(第 1 节)或查询 DSL HASPROP(第 8 节)。
8. 查询 DSL — medchem.query
QueryFilter 会根据规则、属性、警示和分组计算布尔表达式。运算符:AND、OR、NOT、比较运算 < > <= >= == !=。基本表达式:MATCHRULE("...")、HASPROP("<descriptor>" < value)、HASALERT("<lowercase set>")、HASGROUP("...")、HASSUBSTRUCTURE/HASSUPERSTRUCTURE、LIKE。
import medchem as mc
qf = mc.query.QueryFilter('MATCHRULE("rule_of_five") AND HASPROP("mw" < 500) AND NOT HASALERT("pains")')
keep = qf(mol_list, n_jobs=-1) # NumPy bool array
语法是上述结构化 DSL——不是
"rule_of_five AND NOT common_alerts"这样的自由文本。没有mc.query.parse();请构造mc.query.QueryFilter(query_string)并将其用于 mols。HASALERT中的警示名称需使用小写(pains、tox、nih等)。
工作流模式
模式 1:化合物库初筛
筛选大型集合,找出类药候选分子,并剔除所有带有结构警示的分子。
import datamol as dm
import medchem as mc
import pandas as pd
df = pd.read_csv("compounds.csv")
mols = [dm.to_mol(smi) for smi in df["smiles"]]
# Rule filter -> DataFrame with pass_all + per-rule columns
rule_df = mc.rules.RuleFilters(rule_list=["rule_of_five", "rule_of_veber"])(
mols=mols, n_jobs=-1, progress=True
)
# Structural alerts -> DataFrame with pass_filter (True = clean)
alert_df = mc.structural.CommonAlertsFilters()(mols=mols, n_jobs=-1, progress=True)
df["passes_rules"] = rule_df["pass_all"].to_numpy()
df["no_alerts"] = alert_df["pass_filter"].to_numpy()
df["drug_like"] = df["passes_rules"] & df["no_alerts"]
df[df["drug_like"]].to_csv("filtered_compounds.csv", index=False)
模式 2:先导化合物优化筛选
叠加更严格的筛选条件,只保留通过每个阶段的分子。所有 functional.* 辅助函数都会返回对齐的 NumPy 布尔数组,因此求交集非常简单。
import numpy as np
import medchem as mc
f = mc.functional
keep = (
f.rules_filter(candidate_mols, rules=["rule_of_oprea"], n_jobs=-1)
& f.nibr_filter(candidate_mols, n_jobs=-1)
& f.complexity_filter(candidate_mols, complexity_metric="bertz", limit="99", n_jobs=-1)
)
# Add lilly_demerit_filter(...) too if the Lilly binaries are installed.
survivors = [m for m, ok in zip(candidate_mols, keep) if ok]
模式 3:识别特定化学基团
标记含有目标骨架/基序的分子(使用 mc.groups.list_default_chemical_groups() 验证名称)。
import medchem as mc
group = mc.groups.ChemicalGroup(groups=["hinge_binders"])
keep = mc.functional.chemical_group_filter(mol_list, chemical_group=group)
with_group = [m for m, ok in zip(mol_list, keep) if ok]
最佳实践
-
结合具体背景:不要盲目应用筛选条件。了解生物靶点和化学空间。
-
组合多种筛选条件:结合使用规则、结构警示和领域知识,以便做出更好的判断。
-
使用并行处理:对于大型数据集(>1000 个分子),始终使用
n_jobs=-1进行并行处理。 -
迭代优化:从宽泛的筛选条件(Ro5)开始,再根据需要应用更具体的标准(CNS、先导类)。
-
记录筛选决策:记录哪些分子被筛除及其原因,以确保结果可复现。
-
验证结果:请记住,上市药物往往无法通过标准筛选;应将这些筛选条件视为指导原则,而非绝对规则。
-
考虑前药:设计为前药的分子可能会有意违反标准药物化学规则。
资源
references/api_guide.md
全面的 API 参考,涵盖所有 medchem 模块,并详细介绍函数签名、参数和返回类型。
references/rules_catalog.md
可用规则、筛选器和警示的完整目录,包含说明、阈值和文献参考。
scripts/filter_molecules.py
批量筛选命令行工具。支持 CSV/TSV、SDF 和纯 SMILES .txt 输入,可配置筛选组合,并生成摘要报告。
用法:
uv run python scripts/filter_molecules.py input.csv \
--rules rule_of_five,rule_of_cns --nibr --output filtered.csv
标志是单独的开关(--nibr、--common-alerts、--lilly、--pains),而不是 --alerts <name>。--lilly 需要 Lilly 工具(medchem install-lilly)。
文档
官方文档:https://medchem-docs.datamol.io/ GitHub 仓库:https://github.com/datamol-io/medchem
AlterLab Academic Skills 套件的一部分。