第3章 RDKit 入门:安装、分子对象与 SMILES 互转

RDKit 是什么?说白了,它是化学信息学领域最常用的 Python 工具包之一。我从做虚拟筛选项目开始接触它,到现在几乎每个跟小分子打交道的 pipeline 都离不开它。它能帮你把 SMILES 变成实实在在的分子对象,也能反过来把分子对象转回 SMILES,还能计算指纹、生成 3D 构象——嗯,今天我们就把最基础的这部分先捋清楚。

3.1 安装与配置

安装 RDKit 的方式有好几种,我个人的习惯是用 conda 创建虚拟环境再装,这样依赖最干净,不会跟系统里的其他包打架。

先说说最常见的两种方式:

pip 安装

pip install rdkit

如果你用的是常规 Python 环境,这条命令就够了。不过要注意,RDKit 的 pip 包在部分旧平台可能缺少预编译 wheel,第一次装的时候可能会编译一会儿。

conda 安装(我推荐)

conda create -n rdkit_env python=3.10
conda activate rdkit_env
conda install -c conda-forge rdkit

conda-forge 渠道的 RDKit 更新很及时,而且二进制包是预编译好的,装完就能用。我在项目里遇到过好几次 pip 装完 import 报错的情况,换成 conda 就一次过了——你想想看,这种环境问题排查起来真的很费时间,所以一开始就把环境搭稳最划算。

验证安装

from rdkit import Chem
print(Chem.__version__)

如果能正常输出版本号(比如 2024.03.1),就说明装好了。要是报错,先检查是不是在正确的虚拟环境里,再确认 Python 版本是不是 3.8–3.12 之间。

我建议安装完成后立刻跑一下 RDKit 自带的测试集,确保所有模块都正常工作:
python -m rdkit.test

3.2 分子对象创建

RDKit 里最核心的数据结构就是 Mol 对象。你可以把它理解成一个「分子容器」,里面存了原子、键、立体构型、芳香性信息等等。创建 Mol 对象最常用的方式是直接从 SMILES 出发。

从 SMILES 创建

from rdkit import Chem

mol = Chem.MolFromSmiles('CCO')
print(mol)
# 输出: <rdkit.Chem.rdchem.Mol object at 0x...>

一行代码就把乙醇的 SMILES 变成了可操作的分子对象。几乎所有的计算都从这一步开始。

从其他格式创建

输入格式 方法 示例
SMILES MolFromSmiles(smi) Chem.MolFromSmiles('C1=CC=CC=C1')
Mol 文件 MolFromMolFile(path) Chem.MolFromMolFile('ligand.mol')
InChI MolFromInchi(inchi) Chem.MolFromInchi('InChI=1S/C2H6O/c1-2-3/h3H,2H2,1H3')
PDB 文件 MolFromPDBFile(path) Chem.MolFromPDBFile('protein.pdb')

我个人用得最多的是 MolFromSmiles 和 MolFromMolFile,前者适合快速原型,后者适合处理已经画好的分子结构。

3.3 SMILES 与 Mol 互转

这个双向转换是 RDKit 最基础也最常用的操作。说白了就是两条路:SMILES → Mol(读入),Mol → SMILES(写出)。

SMILES → Mol

smiles = 'C1=CC=CC=C1'
mol = Chem.MolFromSmiles(smiles)

if mol is not None:
    print('转换成功')
else:
    print('SMILES 语法错误')

注意返回值可能是 None——如果 SMILES 不合法,RDKit 不会报错,而是返回空。我之前在一个批处理脚本里忘了检查 None,结果下游计算全崩了,排查了半天才找到原因。所以,记得每次都判空。

Mol → SMILES

mol = Chem.MolFromSmiles('CCO')
smiles_out = Chem.MolToSmiles(mol)
print(smiles_out)
# 输出: CCO

这里有个小细节:MolToSmiles 默认输出的是规范 SMILES(canonical SMILES)。同一个分子可能有多种 SMILES 写法,但规范 SMILES 是唯一的。这对于去重、建索引非常有用。

带选项的 SMILES 生成

smiles_with_h = Chem.MolToSmiles(mol, allHsExplicit=True)
print(smiles_with_h)
# 输出: CCO

还可以控制是否保留立体信息、是否输出凯库勒式等等。具体选项可以查 RDKit 文档,我在做数据库标准化时一般用默认参数就够了。

注意:MolFromSmiles 不会自动加氢。如果你想得到带有全部氢原子的结构,需要显式调用 Chem.AddHs(mol)。这在做 3D 构象生成时尤其重要,我刚开始就忘过这一步,生成的 3D 结构少了好多氢。

3.4 常用操作速览

创建完 Mol 对象之后,通常马上就会查它的基本信息。

查看分子属性

mol = Chem.MolFromSmiles('CCO')
print('原子数:', mol.GetNumAtoms())
print('键数:', mol.GetNumBonds())
print('分子量:', Descriptors.MolWt(mol))

遍历原子与键

for atom in mol.GetAtoms():
    print(atom.GetSymbol(), atom.GetAtomicNum())

for bond in mol.GetBonds():
    print(bond.GetBeginAtomIdx(), bond.GetEndAtomIdx(), bond.GetBondType())

这些遍历操作在后续做子结构匹配、原子指纹提取时会频繁出现。刚开始可以多打印几次,看看每个字段的实际值长什么样,心里就有底了。

核心心法:RDKit 里一切计算都从 Mol 对象出发。只要把 SMILES 转成了 Mol,后续的指纹、构象、描述符计算就都水到渠成了。
RDKit 分子处理核心流程 SMILES 字符串 语法校验 RDKit Mol 对象 结构可视化 指纹与属性 3D 构象生成 格式导出 核心流程:输入 → 校验 → 处理 → 输出

3.5 避坑指南

RDKit 入门容易,但有几个坑我当初都踩过,这里列出来你注意一下:

  • SMILES 大小写敏感:Chem.MolFromSmiles('CCO') 正确,但 cco 会返回 None。元素符号首字母大写,这是基本规则。
  • 芳香性感知:RDKit 在读取 SMILES 时会自动做芳香性感知。如果你用凯库勒式(比如 C1=CC=CC=C1),RDKit 会把它识别为芳香性苯环;但如果你明确不想让 RDKit 做芳香性处理,可以用 sanitize=False 参数。
  • 加氢时机:前面提过,MolFromSmiles 默认不加氢。如果你要做 3D 构象优化,一定要先 Chem.AddHs(mol),再调用嵌入函数。我曾经漏掉这一步,生成的构象键长全是错的,折腾了一下午才发现是氢没加上。
一个小习惯:每当你从 SMILES 创建 Mol 对象之后,先打印一下 mol.GetNumAtoms(),确认原子数跟预期一致。这能帮你及早发现 SMILES 解析异常。

嗯,关于 RDKit 入门最核心的部分就这些。安装、创建分子对象、SMILES 与 Mol 互转,这三步是后续所有计算的基石。你只要把这三步练熟,后面的指纹、构象、描述符就都顺了。