SMILES 简介:化学分子线性表示法
做化学信息学的人,每天都得跟分子结构打交道。你想想看,一个有机分子动不动就几十上百个原子,怎么在计算机里存它?画个图?那文件太大了,也不方便搜索。早年我还在药企做数据库的时候,每天要处理几百万个分子,要是都用 MOL 文件存,硬盘早炸了。
后来我遇到了 SMILES——Simplified Molecular Input Line Entry System。说白了,就是把分子结构写成一行字符串。就像给分子起了个“身份证号”,简短、唯一、还能还原成结构。
SMILES 的核心思想:用 ASCII 字符表示原子、化学键、分支和环。一行字符串 = 一个完整的分子。
为什么不能用分子图?
分子图(Graph)虽然直观,但存储和计算成本太高。举个例子:乙醇的分子图包含 9 个原子和 8 条键,存成图结构至少要几百字节。而 SMILES 只需要 3 个字符:CCO。你自己感受一下差别。
我刚开始做分子指纹计算时,读了几万个 MOL 文件,程序卡得跑不动。后来全部转成 SMILES,处理速度提升了 100 倍。嗯,从那时起,我就成了 SMILES 的铁粉。
SMILES 的基本规则
SMILES 的语法其实不复杂,掌握几个核心点就够了。我们来拆开看。
1. 原子表示
- 标准元素符号:直接写元素周期表的符号。比如
C是碳,O是氧,N是氮。 - 特殊原子:带电荷、同位素或配位数的原子,用方括号括起来。比如
[NH4+]表示铵根离子,[13CH3]表示碳-13 同位素的甲基。 - 氢原子:大多数情况下省略。比如
CH3表示甲基,不用写成C加三个H。 - 芳香性原子:用小写字母表示。比如
c1ccccc1就是苯环,中间的c都是芳香碳。
这里有个坑:我当年写 SMILES 时,把氟原子写成了 F 就对了,但氯原子不能写 CL,必须写 Cl。元素符号大小写很敏感,搞错了解析器会报错。
2. 化学键表示
| 键类型 | 符号 | 示例 |
|---|---|---|
| 单键 | - 或不写 | CC(乙烷) |
| 双键 | = | C=C(乙烯) |
| 三键 | # | C#C(乙炔) |
| 芳香键 | : | c1ccccc1(苯环) |
你没看错,单键可以不写。比如乙醇写 CCO,中间的单键直接省略。但有时候写全 C-C-O 也行,只是代码长了点。
3. 分支结构
分支用圆括号 () 表示。比如异丙醇:CC(C)O。括号里的 C 就是挂在中间碳上的甲基分支。你可以想象成:先写骨干,再用括号把支链“挂”上去。
我曾经犯过的错误:写 CC(C)O 想把甲基挂在左边的碳上,结果解析器默认挂到右边的碳上。其实 SMILES 的分支是 挂在前一个原子上的,搞反了结构就错了。
4. 环结构
用数字标记环的起点和终点。比如环己烷:C1CCCCC1。数字 1 表示第一个环的断开处,前后两个 1 连接起来就形成了闭环。多个环用不同的数字,比如萘:c1ccc2ccccc2c1,用了 1 和 2 两个环标签。
小技巧:如果分子里环数很多,建议用 %...% 语法来写两位数的环标签,比如 %10% 表示第 10 个环。否则数字超过 9 就和原子符号混淆了。
5. 电荷与同位素
- 电荷写在方括号里:
[Na+]、[Cl-]、[OH-]。 - 同位素写在元素符号前面:
[18OH2]表示 H218O。 - 配位键/离子键有时用
[Fe+3]等形式表示。
6. 芳香性
芳香碳用小写 c,芳香氮用小写 n,芳香氧用小写 o。比如吡啶:n1ccccc1。芳香键用 : 表示,但绝大多数时候你只用小写原子符号,解析器会自动识别芳香键。
SMILES 到底长什么样?看几个例子
下面是我随手列的几个常见分子的 SMILES,你可以对照结构感受一下。
# 乙醇
CCO
# 苯
c1ccccc1
# 环己烷
C1CCCCC1
# 乙酸(醋酸)
CC(=O)O
# 对硝基苯酚
c1cc(ccc1[N+](=O)[O-])O
# 咖啡因
Cn1c(=O)c2c(ncn2C)n(C)c1=O
注意看乙酸的写法:CC(=O)O。那个 =O 表示双键氧,括号里的 =O 是分支。如果不加括号,写成 CC=O 就成了乙醛,完全不一样。
SMILES 与其他表示法的对比
| 格式 | 优点 | 缺点 |
|---|---|---|
| SMILES | 紧凑、易读、适合文本处理 | 不唯一(同分子有多种写法) |
| Canonical SMILES | 唯一标准形式 | 需要标准化算法 |
| MOL/SDF | 保留原子坐标和键信息 | 文件大,不适合大规模存储 |
| InChI | 标准化强,含立体化学 | 字符串很长,不易读 |
我一般这么选:做数据库用 Canonical SMILES,做可视化用 MOL 文件,做唯一标识用 InChI。SMILES 可读性最好,调试时特别方便。
注意:不是所有分子都能用 SMILES 完美表示。比如多聚体、配位键、部分金属有机化合物,SMILES 的语法会变得很别扭。这时候可以改用 *.MOL 或专用标记方法。
从分子到 SMILES:用 Python 搞定
写 SMILES 当然不用手撸,RDKit 这个库帮你干脏活。下面是我经常用的几行代码:
from rdkit import Chem
# 从 SMILES 读入分子
mol = Chem.MolFromSmiles("CCO")
print(mol.GetNumAtoms()) # 输出 3
# 从分子转 SMILES
smiles = Chem.MolToSmiles(mol)
print(smiles) # 输出 CCO
# 转成 Canonical SMILES(唯一的)
canon_smiles = Chem.MolToSmiles(mol, canonical=True)
print(canon_smiles) # 还是 CCO,因为乙醇本身很简单
你看,三行代码搞定了。但注意:RDKit 的 Canonical SMILES 默认会做一些标准化,比如将芳香性写成小写。如果你要保留原始写法,可以加参数 isomericSmiles=True 或 allBondsExplicit=True。
SMILES 知识体系
下面这张图把 SMILES 的核心元素串了起来。看完这张图,你就能理解它为什么叫“线性表示法”了。
常见避坑指南
- 大小写必须严格:氮元素写
N,不能写n(除非是芳香氮)。溴写Br,不能BR。 - 环数字不能重复使用:一个分子里如果出现两个相同数字,解析器会认为它们必须连在一起。如果你只是巧合写了个
C1C1,那是错误。 - 分支括号紧贴前一个原子:
CC(C)O和C C ( C ) O都是合法的,但前者更规范。不要瞎加空格。 - 芳香性表示要一致:要么都用小写(如
c1ccccc1),要么都用大写加芳香键c1:c:c:c:c:c1。混着用容易出问题。
我的习惯:拿到一个分子后,先用 RDKit 的 MolFromSmiles() 验证一下,再转成 Canonical SMILES。这样能避免手写错误,也保证唯一性。
SMILES 看起来简单,但它是整个化学信息学大厦的砖瓦。你在后面会遇到 SMILES token 化、注意力机制、热力图可视化——所有这些都建立在你能正确读写 SMILES 的基础上。这一章打好了地基,后面你就能盖起高楼了。