SMILES 中的立体化学:手性表示与解析

立体化学,说白了就是处理分子在三维空间里的“手性”问题。你想想看,两个分子原子构成完全一样,但镜像重叠不上——就像左手和右手。这在药物分子里太重要了,有时候一个手性中心错了,药效天差地别。

SMILES 怎么表示这种空间信息呢?核心就是 @ 和 @@ 这两个符号。我刚开始接触时也绕晕过,实际做项目才发现,搞不懂这个,分子描述符提取的结果全是错的。

SMILES 立体化学表示体系 立体化学核心概念 手性中心 @ 与 @@ 表示 假不对称中心 @? 与 @@? Z/E 异构 双键方向标记 CIP 规则 R/S 标记 空间取向 楔形/虚线键 顺反标记 Cis/Trans 示例: [C@@H] 示例: [C@?H] 示例: C/C=C/C 应用: 药物分子手性、天然产物解析、反应立体选择性分析

手性中心的 SMILES 表示

手性中心是分子中存在四个不同取代基的碳原子。SMILES 用 @ 和 @@ 来标记原子的手性方向。这两个符号表示的是从原子出发连接各取代基的 二维排列顺序,而不是三维坐标本身。

关键理解:@ 表示逆时针方向,@@ 表示顺时针方向。但这只是SMILES内部的约定,真正的 R/S 构型还需要通过 CIP 规则重新推导。

我举个例子。丙氨酸的 S 构型可以写成 N[C@@H](C)C(=O)O。这里 [C@@H] 就是说:这个碳原子是手性中心,周围的四个连接 @ 符号在决定排列顺序。为什么是四个连接?嗯,这里要注意,SMILES 里原子默认最多三个显式连接,手性中心必须用方括号括起来。

@ 和 @@ 的判定规则

怎么确定一个手性中心该用 @ 还是 @@?我当年学的时候被这个问题卡了好久。后来发现,关键在于理解 视角。

  1. 把碳原子放在中心。
  2. 看向取代基中 在 SMILES 里最后出现的那一个(通常是编号或分支最大那个)。
  3. 从视角看去,其他三个取代基的排列顺序如果是 顺时针,则用 @@;如果是 逆时针,则用 @。
我个人的小技巧:写一个手性中心时,先确定哪个基团是“朝屏幕外的”,再画其他三个基团的相对位置。如果搞反了,解析出的构型就会镜像翻转。我在项目中就踩过这个坑。

来看几个经典例子:

# L-丙氨酸(S构型)
N[C@@H](C)C(=O)O

# D-丙氨酸(R构型)
N[C@H](C)C(=O)O

# 手性环丁烷
C1[C@H](C)C[C@H]1C

假不对称中心

假不对称中心是个比较 tricky 的概念。它指的是一个碳原子连接了两个完全相同的基础结构,但两个结构之间的立体化学不同。比如内消旋酒石酸。

SMILES 用 @? 和 @@? 来表示假不对称中心。那个问号就是提示:这个中心不是真正的手性,只是在特定构型下表现出局部的不对称性。

# 假不对称中心的例子
O=C(O)[C@?H](O)[C@@?H](O)C(=O)O
我曾经犯过的错:在处理假不对称中心时,如果直接按普通手性中心解析,得到的描述符是错的。必须检查两个邻接基团的立体化学是否一个 R 一个 S。只有这种情况下,假不对称中心才有意义。

Z/E 异构的表示

双键的顺反异构也用 SMILES 来表示。用的是 / 和 \ 这两个字符。它们分别表示双键一侧的取代基处于 向上 或 向下 的位置。

比如 C/C=C/C 表示两个甲基在双键对侧(E构型),而 C/C=C\C 表示两个甲基在同侧(Z构型)。

# Z构型(顺式)
CC/C=C\C

# E构型(反式)
CC/C=C/C

# 复杂一点的例子
C/C(=C/C=C/C)/C(=O)O

我建议你在处理 Z/E 异构时,一定先确认双键两端的取代基优先级。Z/E 命名和 CIS/TRANS 不一定对应,尤其在复杂的天然产物里。我做过一个萜类化合物项目,就因为搞混了 Z/E 标记,导致后续描述符全错。那次教训很深刻。

用 RdKit 解析立体化学

实战环节。我们用 RdKit 来解析一个分子的立体化学信息。这段代码会显示每个原子的手性标记。

from rdkit import Chem
from rdkit.Chem import Descriptors

smiles = "N[C@@H](C)C(=O)O"
mol = Chem.MolFromSmiles(smiles)

# 获取手性中心信息
for atom in mol.GetAtoms():
    if atom.GetChiralTag() != Chem.ChiralType.CHI_UNSPECIFIED:
        chiral_type = atom.GetChiralTag()
        center_idx = atom.GetIdx()
        neighbors = [n.GetIdx() for n in atom.GetNeighbors()]
        print(f"手性中心在原子 {center_idx}")
        print(f"手性标记: {chiral_type}")
        print(f"邻接原子: {neighbors}")

# 输出 CIP 优先级
from rdkit.Chem import rdMolDescriptors
cip_map = rdMolDescriptors.FindMolChiralCenters(mol, includeUnassigned=True)
print("\nCIP 标记:", cip_map)
注意:RdKit 的 FindMolChiralCenters 默认会忽略假不对称中心。要处理它们,需要设置 includeUnassigned=True 参数。我在处理内消旋化合物时就吃过这个亏。

常见问题与避坑指南

问题 原因 解决方法
手性中心无法正确识别 原子未用方括号括起来,或连接顺序不对 确保手性原子被 [ ] 包围,检查分支顺序
@ 和 @@ 搞反 视角选择错误,后出现基团判定错误 将三维结构画出来再映射回 SMILES
假不对称中心解析失败 RdKit 默认只处理真手性 使用 includeUnassigned=True 参数
Z/E 表示与预期不符 双键两端取代基排列顺序理解错误 先画出结构,用 / 和 \ 标记方向再转 SMILES

我个人习惯是,遇到手性分子,先用三维软件画出结构,确认每个手性中心的取向,再写 SMILES 字符串。这样做可以避免很多低级错误。毕竟,一个字母之差,分子的性质可能天差地别。

总结一下关键点

  • @ / @@ 标记的是二维排列顺序,不是三维坐标。
  • 手性原子必须用方括号括起来,否则会被当成普通原子。
  • 假不对称中心用 @? / @@? 表示,解析时需特别对待。
  • Z/E 异构用 / 和 \ 表示,关注的是取代基在双键两侧的上下关系。
  • RdKit 解析时要注意参数设置,特别是假不对称中心。

掌握这些,你就能在 SMILES 层面完整描述分子的立体化学信息了。这是后续计算分子描述符、构象分析的基础。搞不定这一块,后面的所有工作都是空中楼阁。