第三章:立体化学、同位素与电荷表示
这一章我们聊聊 SMILES 里三个容易翻车的细节——立体化学、同位素和电荷。这三个东西看着不起眼,但一旦写错,下游的分子检索、性质预测全部跑偏。我在项目里见过不止一次,因为手性标记错了一个符号,整个虚拟筛选的结果全废。
3.1 立体化学:手性中心的标记
SMILES 用一套“方向”标记来表达分子的三维信息。具体怎么做的?其实很简单——顺着 SMILES 字符串爬一遍,每个手性原子周围,系统会记录它的邻居方向,然后用一个@或者@@来区分两种对映体。
3.1.1 基本规则
对于四面体手性中心,SMILES 用@表示反时针(counter‑clockwise),用@@表示顺时针(clockwise)。这个方向是相对于 SMILES 字符串中原子出现顺序的,不是绝对 R/S。所以你写的时候必须保证输入顺序一致,不然解析结果会反。
# 正确定义(R)-2-丁醇
C[C@H](O)CC
# 正确定义(S)-2-丁醇
C[C@@H](O)CC
3.1.2 顺反异构:双键与环
双键的顺反用/和\表示。这两个符号插在双键两边,表示取代基的相对空间位置。举个例子:
# (E)-2-丁烯
C/C=C/C
# (Z)-2-丁烯
C/C=C\C
需要注意,SMILES 里/和\是方向键,不是斜杠或反斜杠字符。我曾经在写脚本时不小心把/写成普通的/,解析器直接报错,白白浪费了一上午。
/或\,否则解析器会认为没有立体信息。
3.2 同位素:原子质量的标记
同位素表示用数字前缀,放在元素符号前面,方括号内。比如碳‑13 写成[13C],氘写成[2H]。这个规则很直观,但有几个容易踩的坑:
- 同位素数字必须紧贴元素符号,不能有空格。
- 当原子同时有同位素和电荷时,顺序是:同位素 → 元素符号 → 电荷。例如:
[13CH3+]。 - 对于没有指定同位素的原子(最常见的自然丰度),可以不加前缀,默认就是最丰同位素。
[13C],有些用了[C],它们的化学性质相同,但 SMILES 字符串不同。在做去重或批次比较时,必须统一规则:要么全部保留同位素标记,要么全部标准化为默认同位素。
我遇到过这样一个场景:一批输入文件里,同一个化合物一半写了[13CH3]一半写了C,导致关联表连接失败。现在我在预处理阶段都会加一个规则:将所有[12C](如果是显式写出的)先替换成C,再统一同位素格式。
3.3 电荷:正负号的写法
电荷用方括号内的+和-表示,紧跟在元素符号后面。多个电荷用数字指定,比如[Fe+3]、[SO4-2]。注意:+和-的位置不能颠倒,数字不能放在符号前面。
# 正确示例
[Na+] # 钠离子
[Ca+2] # 钙离子
[OH-] # 氢氧根离子
# 常见错误(会解析失败或得到错误结构)
[Na1+] # 多余数字1,实际上应该写成[Na+]
[Ca++] # 废弃写法,尽量用[Ca+2]
[Ca++]这种旧格式统一转成[Ca+2]。我写过一个脚本,专门处理七种常见的“歧义电荷写法”,能减少 90% 的解析异常。3.4 三者组合时的书写顺序
当同一个原子同时需要立体化学、同位素和电荷时,SMILES 要求按固定顺序书写:
- 同位素(可选)
- 元素符号(必需)
- 立体化学标记(可选,仅限手性)
- 电荷(可选)
- 氢原子数量(可选,通常用于显式氢)
举个例子,一个氘代的手性铵离子:[2NH3+] —— 同位素2,元素N,氢数3,电荷+。注意这里没有手性标记,因为氮是四级铵,不是手性中心。如果是一个手性碳,比如[13C@H],就变成了:同位素→元素→立体标记→氢→电荷(本例无电荷)。
[C@13H],解析器直接报错,因为@后面不能接数字。规范是死的,写代码的时候一定要按规矩来。
3.5 知识结构一览
下面这张图把本章的核心关系梳理清楚了:
3.6 常用工具与自动化检查
手动检查成千上万的 SMILES 不现实。我这里推荐两个做法:
- RDKit 标准化:调用
Chem.MolToSmiles(mol, isomericSmiles=True)可以标准输出带立体信息的 SMILES。如果是同位素/电荷,MolFromSmiles解析后再输出就能自动修复格式错误。 - 正则表达式预检:脚本里跑一遍正则,检查是否有
[C@@]后面跟了数字、[Fe2]没有电荷符号之类的问题。
import re
import sys
def check_smiles_format(smiles):
# 检查立体标记是否放在正确位置
if re.search(r'\[[A-Za-z]+@[0-9]', smiles):
print(f"错误:立体标记后不应直接跟数字: {smiles}")
return False
# 检查电荷是否用了旧式写法
if re.search(r'\[[A-Za-z]+\+\+', smiles):
print(f"警告:建议使用数字电荷如 [Ca+2]: {smiles}")
return True
好了,第三章就聊这些。立体化学、同位素、电荷是 SMILES 批次一致性检查中最容易出问题的三个点——往后几章我们会看到它们怎么影响到实际的数据比对和搜索。