第3章 常用化学信息学工具与库
做SMILES清洗,光靠正则和字符串操作可不够。你得懂点专业的化学信息学工具。这一章,我把自己平时用得最多的四个家伙拎出来,挨个讲讲优缺点和坑。你看完就知道什么场景该用什么,心里也有个底。
3.1 RDKit —— 你的SMILES瑞士军刀
RDKit,说白了,是开源界做化学信息学绕不过去的核心库。我几乎每个清洗脚本都离不开它。
它最拿手的几件事:
- 读写SMILES:
Chem.MolFromSmiles和Chem.MolToSmiles。注意,它默认会做凯库勒化,生成规范SMILES。 - 分子标准化:比如去除氢原子、处理同位素、检查化合价。
- 指纹与子结构搜索:用来过滤不需要的片段。
- 计算描述符:分子量、LogP、氢键供体/受体数量等,可以用来做验证。
安装很简单,用 pip 直接装:
pip install rdkit
我有一个项目,需要清洗百万级SMILES。踩过一个坑:MolFromSmiles 对某些含括号的特殊符号会报错,返回 None。那时我加了个 try-except 把这部分行记录下来,再人工修正。嗯,所以用RDKit一定要养成检查返回值的习惯。
RDKit 常用清洗代码片段
from rdkit import Chem
def clean_smiles(smiles):
mol = Chem.MolFromSmiles(smiles)
if mol is None:
return None
# 去除氢原子,得到“规范”SMILES
canonical = Chem.MolToSmiles(mol, canonical=True)
return canonical
RDKit 的 SMILES 规范不是唯一的。如果你需要跟其他工具对比,建议统一用 RDKit 的规范作为内部标准,再做一次标准化。
3.2 Open Babel —— 格式转换的“万能胶”
Open Babel,我把它叫做“格式转换的老黄牛”。它支持上百种化学文件格式,SDF、MOL、SMILES、InChI……只要你能想到的,它基本都能读能写。
主要用途:
- 把 SDF 批处理转换成 SMILES 文件。
- 把 SMILES 转换为 InChI 或 InChIKey 做交叉验证。
- 在命令行下一条命令搞定批量转换,不需要写代码。
我最常用的是它的命令行模式:
obabel input.sdf -O output.smi --gen2d
这条命令会自动生成2D坐标,同时算出规范SMILES。不过注意,Open Babel 的规范算法和 RDKit 不完全一致,同一个分子可能会得到两个不同的 “规范” SMILES。所以别把它俩的输出直接拿来当 key 做去重。我一开始没注意,导致数据库里出现大量“重复”数据,排查了半天……
别拿 Open Babel 的规范 SMILES 跟 RDKit 的直接比。如果一定要比,先统一用一个工具做规范化,或者用 InChIKey 作为唯一标识。
3.3 ChemAxon —— 专业级的商业解决方案
ChemAxon(主要是 JChem 库)是商业软件,有免费学术许可。它的强项是化学结构标准化、手性处理、互变异构体识别。说实话,在处理含立体化学的 SMILES 时,RDKit 和 Open Babel 有时会“含糊”,ChemAxon 的算法更精细。
我个人习惯在管线中这样用:
- 先用 RDKit 做基础清洗(修复价态、去除不合法原子)。
- 再传给 ChemAxon 做手性标记和互变异构体标准化。
- 最后用 ChemAxon 的
Standardizer功能,按照我定义的规则(比如去掉某些保护基)做最终规范化。
安装 ChemAxon 的 Python 接口需要先下载 JChem 套件,然后配置环境变量:
export JAVA_HOME=/path/to/java
export CHEMAXON_HOME=/path/to/jchem
pip install chemaxon-python
ChemAxon 标准化示例
from chemaxon import standardizer
def standardize_with_rules(smiles):
mol = standardizer.standardize(smiles)
return mol.toFormat('smiles')
如果你们公司预算够,或者你是学生申请免费许可,ChemAxon 在清洗管线中真的能省很多事,尤其是处理互变异构体时。我曾经在一个药物筛选项目里,用 ChemAxon 把 20% 的“假阳性”结构纠正了过来。
3.4 PubChemPy —— 从外部数据库验证SMILES
PubChemPy 是一个轻量级的 Python 包,用来访问 PubChem 数据库。它的核心作用:帮你查一下某个 SMILES 是不是真的存在,或者它的标准名是什么。
常用场景:
- 对可疑的 SMILES 进行“交叉验证”——用这个 SMILES 去 PubChem 检索 CID,看能否匹配到已注册化合物。
- 批量获取化合物的官方 InChIKey 或规范名称,用来做后续的同一性比较。
- 当 SMILES 格式不规范时,尝试用 PubChem 的标准化接口返回一个官方版本。
安装:
pip install pubchempy
一个简单例子:
import pubchempy as pcp
def get_standard_smiles_from_pubchem(smiles):
try:
results = pcp.get_compounds(smiles, 'smiles')
if results:
return results[0].canonical_smiles
except:
return None
return None
PubChemPy 依赖网络,而且有调用频率限制(大约每秒5次)。大批量清洗时,建议先缓存结果,或者用本地数据库镜像。我有个同事没注意这个,跑了一晚上被服务器封了IP……
3.5 工具对比一览
四个工具各有侧重,我整理了一张表,方便你对照选择:
| 工具 | 许可证 | 语言/接口 | 核心能力 | 我推荐的应用场景 |
|---|---|---|---|---|
| RDKit | BSD(开源) | C++底层 / Python | SMILES解析、指纹、描述符、子结构 | 基础清洗、标准化、批量计算 |
| Open Babel | GPL(开源) | C++ / Python / 命令行 | 格式转换、2D坐标、SMILES生成 | 不同格式间的互转、快速批量SMILES导出 |
| ChemAxon | 商业(有免费学术版) | Java / Python | 手性、互变异构体、高级标准化 | 立体化学处理、规则驱动清洗 |
| PubChemPy | MIT(开源) | Python | 查询PubChem、获取官方SMILES/InChIKey | 外部验证、数据补充 |
3.6 我的建议:如何组合使用
说真的,没有哪个工具能包打天下。我通常这样搭:
- 第一道关:RDKit —— 读入所有SMILES,用
MolFromSmiles过滤掉无法解析的,生成规范SMILES。 - 第二道关:Open Babel —— 如果源数据是 SDF 等文件,或者需要转成 InChI,用它一次性转。
- 第三道关:ChemAxon —— 对已知手性中心做标记,处理互变异构体。
- 第四道关:PubChemPy —— 抽检可疑SMILES(比如含稀有元素或异常长度),用PubChem做校验。
当然,如果你的数据量不大,只靠 RDKit 加一些手写规则也能跑起来。但我建议从一开始就搭好管线,后面扩展时不用返工。你想想看,清洗工作最怕的就是重复劳动。
如果你用的是 Python,我推荐在项目里统一用 RDKit 处理过的 SMILES 作为“内部格式”。其他工具生成的结果只用于交叉验证,不直接修改内部库。