RDKit FragmentMatcher 模块详解:基于 SMARTS 的片段命中与排除匹配

发布时间:2026/10/14 15:36:57
RDKit FragmentMatcher 模块详解:基于 SMARTS 的片段命中与排除匹配
科学计算科研机器学习【免费下载链接】rdkitThe official sources for the RDKit library项目地址https://gitcode.com/gh_mirrors/rd/rdkit点击查看免费下载rdkit.Chem.FragmentMatcher是 RDKit Python 层提供的一个轻量级 API用于对分子做片段命中 排除片段的复合结构匹配先用一个 SMARTS 图案作为命中条件on-pattern再叠加若干 SMARTS 排除图案exclusion patterns快速判断某分子是否含有目标片段且不含有被禁止的结构。读完本文你可以掌握FragmentMatcher的全部方法语义、边界行为与底层调用链并能将其用于官能团检测、数据集过滤等实际场景。模块定位与文档组织方式在 RDKit 的文档体系中rdkit.Chem.FragmentMatcher的 API 参考页由 Sphinx 的automodule指令直接从模块源码生成。文档入口文件 Docs/Book/source/rdkit.Chem.FragmentMatcher.rst 的全部内容就是.. automodule:: rdkit.Chem.FragmentMatcher :members: :undoc-members: :show-inheritance:也就是说渲染出的页面内容 模块 docstring 全部成员签名。模块真正的文档正文是 rdkit/Chem/FragmentMatcher.py 开头那段包含 doctest 的 docstring第 10~46 行它同时也是模块的自动化测试。该页面在 rdkit.Chem 包目录 的 Submodules toctree 中注册第 46 行。模块 docstring 中的完整用法doctest 即文档模块 docstring 给出了FragmentMatcher的最小使用契约以下示例全部来自源码原样保留注意 doctest 中Chem依赖模块级from rdkit import Chem导入1. 构造命中图案。如果你想匹配含CO羰基的分子from rdkit.Chem import FragmentMatcher p FragmentMatcher() p.Init(CO)2. 判断分子是否命中from rdkit import Chem mol Chem.MolFromSmiles(CC(O)O) # 乙酸 p.HasMatch(mol) # 1命中 p.HasMatch(Chem.MolFromSmiles(CC(C)C)) # 0异丁烷无羰基3. 获取匹配的原子索引len(p.GetMatches(Chem.MolFromSmiles(CCO))) # 1乙醛只有 1 个 CO len(p.GetMatches(Chem.MolFromSmiles(OCCO))) # 2乙二醛有两个 CO4. 添加排除片段SMARTS。加上苯环排除后任何含苯环的分子一律判负p.AddExclusion(c1ccccc1) p.HasMatch(Chem.MolFromSmiles(CCO)) # 1 p.HasMatch(Chem.MolFromSmiles(c1ccccc1CCO)) # 0苯乙醛被排除方法逐一解析结合源码实现FragmentMatcher类定义在 rdkit/Chem/FragmentMatcher.py整个类只有约 40 行内部状态只有两个字段self._onPatt命中图案Chem.MolFromSmarts解析后的 query mol初始为Noneself._offPatts排除图案列表初始为空列表。方法源码位置行为未调用Init时的返回值Init(sma)L59-L60用 SMARTS 字符串设置/替换唯一的命中图案—AddExclusion(sma)L56-L57追加一个排除图案可多次调用累积生效—HasMatch(mol)L68-L78返回1或0int不是 bool0GetMatch(mol)L80-L83返回第一个匹配的原子索引元组NoneGetMatches(mol, uniquifyTrue)L85-L88返回全部匹配元组列表支持去重NoneGetBond(idx)L90-L93返回命中图案中指定索引的 bond便于做按图案内 atom map 提取原子式的解析NoneGetSMARTS()L62-L63占位实现函数体为pass返回NoneNoneGetExclusionSMARTS()L65-L66占位实现函数体为pass返回NoneNone需要特别说明的源码事实Init是替换语义self._onPatt Chem.MolFromSmarts(sma)直接赋值重复调用Init会覆盖此前的命中图案而AddExclusion是append语义排除图案持续累积。GetSMARTS/GetExclusionSMARTS尚未实现两者函数体均为pass。如果需要在序列化后恢复 SMARTS 原文应自行保存构造时传入的字符串而不能依赖这两个方法。GetMatches的uniquify参数原样透传给mol.GetSubstructMatches(query, uniquifyuniquify)默认True即对同一组原子索引的不同排列只保留一个匹配关闭去重后对对称图案会得到更多条目。匹配判定逻辑与两个关键细节判定顺序先命中、后排除HasMatch的完整判定逻辑L68-L78def HasMatch(self, mol): if self._onPatt is None: return 0 t mol.HasSubstructMatch(self._onPatt) if not t: return 0 else: for patt in self._offPatts: if mol.HasSubstructMatch(patt): return 0 return 1从源码结构看匹配是短路式的命中图案不匹配立即返回 0不必检查排除图案只有命中图案匹配成功后才会逐个检查排除图案任一排除图案命中即整体判 0。细节一排除图案作用于整个分子而非匹配区域值得注意的实现细节是排除图案的mol.HasSubstructMatch(patt)是针对整张分子图执行的第 75~77 行而不是只检查命中片段内部。换句话说AddExclusion的语义是只要分子的任何位置出现该结构就整体否决而不是命中片段的邻域内不得出现该结构。对苯环排除的例子苯乙醛判 0来说两者等价但如果排除图案恰好就是命中图案的子结构、或者你期望做片段局部排除就要清楚FragmentMatcher不提供局部排除——这种更细粒度的需求需要用mol.GetSubstructMatches拿到匹配后再逐匹配手工判断。细节二未Init时的安全退化四个查询方法HasMatch/GetMatch/GetMatches/GetBond开头都有if self._onPatt is None守卫分别返回0或None。这意味着空匹配器永远不会抛异常可以安全地用于条件式启用的过滤管道中——这一点从源码可以直接确认无需额外防御。底层调用链FragmentMatcher本身不做图匹配真正的子结构匹配委托给 C 核心ROMol的查询 APImol.HasSubstructMatch(query)/mol.GetSubstructMatch(query)/mol.GetSubstructMatches(query, uniquify...)绑定自 C 的RWMol::HasSubstructMatch等成员Python 侧的包装实现可见 Code/GraphMol/Wrap/substructmethods.h其中GetSubstructMatches的uniquify参数默认true与 Python 层暴露的行为一致。因此FragmentMatcher的开销模型是Init时做一次 SMARTS 解析MolFromSmarts会产生解析告警日志若字符串非法每次HasMatch最多执行 1 N 次子结构查询N 为排除图案数每次GetMatches执行 1 次子结构查询。测试集成docstring 如何成为回归测试这个模块的 docstring 不只是文档还是被纳入正式测试套件的 doctest模块内自测文件末尾的 doctest boilerplateL100-L109允许直接python rdkit/Chem/FragmentMatcher.py运行_test()调用doctest.testmod(sys.modules[__main__])并把失败数作为退出码。pytest 注册rdkit/Chem/UnitTestDocTestsChem.py 在load_tests中执行tests.addTests(doctest.DocTestSuite(FragmentMatcher, optionflagsdoctest.ELLIPSIS))第 15 行使上述 docstring 示例随整个 Chem 测试套件一起回归。运行配置rdkit/pytest.ini 中python_files UnitTest*.py且addopts包含--doctest-modules并配置了doctest_optionflags ELLIPSIS NORMALIZE_WHITESPACE套件级入口脚本为 Scripts/run_python_tests.py。这也解释了为什么 docstring 里的示例返回值写的是1/0而不是True/False——它们必须与HasMatch的实际 int 返回严格一致否则 CI 中的 doctest 会失败。实用建议与边界情况返回类型差异HasMatch返回 int0/1可直接参与计数如sum(matcher.HasMatch(m) for m in mols)GetMatch返回单个元组或NoneGetMatches返回元组列表或None。注意GetMatches在未Init时返回None而非空列表调用处应做判空。SMARTS 而非 SMILESInit与AddExclusion都用Chem.MolFromSmarts解析所以可以写通配原子[#6]、[CX3]、环成员、方向性基团等 SMARTS 语法写成普通 SMILES 时行为等价于将其解释为 SMARTS。图案原子映射拿到匹配后想按图案中的第 i 个原子提取分子中的对应原子GetBond(idx)提供了按图案索引取 bond 的能力配合匹配元组中的图案侧索引即可定位这是该 API 相比裸调HasSubstructMatch的少量但真实的便利性差异。适用场景该模块适合有官能团且无某结构这类二元条件过滤例如含有酮羰基C(O)且不含芳香环的候选集筛选。对于需要多图案同时命中、条件组合AND/OR/NOT 嵌套或基于匹配位置的后续处理应直接使用rdkit.Chem的原生子结构查询接口FragmentMatcher的价值在于把on 若干 off这一常见模式封装成了状态化的对象。参考文件索引内容路径模块源码类实现与 doctestrdkit/Chem/FragmentMatcher.pySphinx 文档页Docs/Book/source/rdkit.Chem.FragmentMatcher.rstrdkit.Chem 包目录页面注册处Docs/Book/source/rdkit.Chem.rstdoctest 回归注册rdkit/Chem/UnitTestDocTestsChem.pypytest doctest 配置rdkit/pytest.iniPython 测试套件入口Scripts/run_python_tests.pyC 子结构查询 Python 包装Code/GraphMol/Wrap/substructmethods.h赞分享科学计算科研机器学习【免费下载链接】rdkitThe official sources for the RDKit library项目地址https://gitcode.com/gh_mirrors/rd/rdkit点击查看免费下载相关推荐RDKit rdkit.Chem.Fraggle 包解析基于片段化与 Tversky 相似度的分子检索算法RDKit rdkit.Chem.Fraggle 包解析基于片段化与 Tversky 相似度的分子检索算法 本文以 RDKit 官方文档树中的 rdkit.C科学计算科研机器学习Wireit glob模式完全指南文件匹配语法与排除规则详解Wireit glob模式完全指南文件匹配语法与排除规则详解 Wireit 是一款强大的 npm/pnpm/yarn 脚本升级工具它通过智能的 glob 模构建工具开发工具Kubernetes Python Client 详解V1GroupSubject 模型与基于用户组的请求匹配Kubernetes Python Client 详解V1GroupSubject 模型与基于用户组的请求匹配 导读 本文基于官方 Python 客户端库k后端云原生容器编排创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考