3. 化合物数据标准化

虚拟筛选库的质量,往往在“标准化”这一步就被决定。不同来源的化合物文件(SDF、MOL、SMILES、CSV)在进入筛选流程前,必须先被解析成统一的分子表示,再经过一系列结构清理与状态归一化,才能保证后续指纹计算、相似性搜索、对接和药效团建模面对的是同一套化学语义。本节围绕结构解析、去盐、去溶剂、互变异构体标准化、电荷与质子化状态处理,以及标准化工具与流程展开。

一、结构解析:从文件到分子对象

结构解析的目标是把外部文件中的原子、键、坐标、电荷和立体信息读入内存,形成可操作的分子对象。常见输入包括 SDF/MOL(含连接表与坐标)、SMILES(含隐式氢与立体标记)、InChI(标准化字符串)以及 CSV 中的 SMILES 列。解析时最容易被忽略的是立体化学与芳香性:SDF 中的楔形键、SMILES 中的 @/@@、以及芳香环的 Kekulé 与芳香化表示,都会影响后续去重与匹配。

以 RDKit 为例,解析 SDF 时通常需要显式指定是否保留氢、是否做 sanitize:

from rdkit import Chem
suppl = Chem.SDMolSupplier('raw.sdf', removeHs=False, sanitize=True)
mols = [m for m in suppl if m is not None]

若 sanitize=True 失败,分子会被丢弃或返回 None,常见原因是价键异常、芳香性无法感知或金属配位未处理。此时应先记录失败 ID,再决定是修正原始文件还是放宽解析条件,而不是直接忽略。

二、去盐与去溶剂:只保留主成分

商业库和文献库中大量化合物以盐、水合物或溶剂化形式存在,例如盐酸盐、钠盐、三氟乙酸盐(TFA)、二甲基亚砜(DMSO)加合物。虚拟筛选通常只关心主成分(parent),因此需要去盐、去溶剂、去小分子碎片。

判断“谁是主成分”不能只看原子数。常用策略是:按共价片段拆分后,保留最大有机片段;若存在多个相近片段,则结合电荷、分子量、是否含金属、是否为常见反离子(Cl⁻、Na⁺、K⁺、TFA⁻、NH₄⁺)来判定。RDKit 中可用 rdMolStandardize 的 LargestFragmentChooser 或 FragmentParent:

from rdkit.Chem.MolStandardize import rdMolStandardize
lc = rdMolStandardize.LargestFragmentChooser()
parent = lc.choose(mol)

需要注意:去盐后应重新计算电荷与氢原子数,否则会出现“主成分带净电荷”或“氢数不匹配”的问题。对于共价抑制剂或金属配合物,去盐规则要谨慎,避免把真正的主成分当作反离子删除。

三、互变异构体标准化:统一到同一“化学身份”

互变异构体(tautomer)是同一分子的不同质子迁移形式,例如酮–烯醇、酰胺–亚胺醇、咪唑环上的 N–H 迁移。它们在二维结构上不同,但在许多筛选场景中应被视为同一化合物。若不统一,去重会失败,相似性计算也会出现偏差。

互变异构体标准化的核心是打分与选择:对每个互变异构体计算稳定性分数,选取得分最高者作为规范形式。RDKit 提供 TautomerEnumerator,可设置最大互变异构体数、是否允许某些规则:

te = rdMolStandardize.TautomerEnumerator()
te.SetMaxTautomers(1000)
canon = te.Canonicalize(mol)

实际项目中,建议先做互变异构体枚举,再对每个互变异构体做去盐与电荷归一化,最后统一选择规范形式。对于含多个可解离基团的分子,互变异构与质子化状态会相互影响,顺序上通常先处理互变异构,再处理质子化。

四、电荷与质子化状态处理

生理条件(pH ≈ 7.4)下,羧酸、胺、咪唑等基团会以特定离子形式存在。虚拟筛选库若混用中性形式与离子形式,会导致电荷分布、氢键供受体数量和 logP 估计不一致。因此需要明确目标状态:是统一为中性形式,还是统一为生理 pH 下的主要微状态(microstate)。

常见做法是:

  • 对羧酸、磺酸、四氮唑等强酸,去质子化为负离子;
  • 对脂肪胺、胍、脒等强碱,质子化为正离子;
  • 对咪唑、吡啶等弱碱,根据目标 pH 与 pKa 判断是否质子化;
  • 对两性离子(zwitterion),保留其净电荷为 0 但内部带正负电荷的形式,或统一转为中性形式,需在库内保持一致。

RDKit 中可用 Uncharger 做去电荷,或用 rdMolStandardize 的 ChargeParent 选择电荷形式。若需要更精细的 pKa 驱动质子化,可结合 Dimorphite-DL 或 OpenBabel 的 --partialcharge 与 pH 模型。无论采用哪种工具,都应在库级别记录“标准化版本”和“目标 pH”,保证可追溯。

五、标准化工具与流程

标准化不是单步操作,而是一条可复现的流水线。推荐顺序为:解析 → 去盐/去溶剂 → 互变异构体标准化 → 电荷/质子化归一化 → 去重 → 输出。每一步都应记录输入输出数量与失败原因。

常用工具包括:RDKit(rdMolStandardize)、OpenBabel、Indigo、ChemAxon Standardizer、MolVS(已并入 RDKit)。其中 RDKit 因开源、可脚本化、与后续指纹/对接工具衔接好,成为多数虚拟筛选流程的首选。

建议在标准化流程中固定随机种子与参数版本,并把每一步的分子数、失败 ID、警告信息写入日志。这样当筛选结果异常时,可以快速定位是解析、去盐还是互变异构环节引入的问题。
化合物数据标准化流水线 解析 → 去盐/去溶剂 → 互变异构体标准化 → 电荷/质子化归一化 → 去重 → 输出 ① 结构解析 SDF / SMILES / InChI 立体 + 芳香性 ② 去盐/去溶剂 最大有机片段 反离子 / 溶剂去除 ③ 互变异构体 枚举 + 打分 选规范形式 ④ 电荷/质子化 pH 7.4 微状态 去电荷 / 加质子 ⑤ 去重/输出 InChIKey / 规范SMILES 日志 + 版本 互变异构体标准化示例 酮式(更稳定,得分高) 烯醇式(能量较高,通常不选) 规则:枚举 → 打分 → 取最高分 参数:MaxTautomers=1000 电荷/质子化处理示例 羧酸 —COOH → —COO⁻(pH 7.4) 脂肪胺 —NH₂ → —NH₃⁺ 两性离子:净电荷 0,内部正负分离 工具:Uncharger / ChargeParent / Dimorphite-DL 标准化日志与失败处理(示例字段) 输入分子数:10000 | 解析失败:37 | 去盐后:9820 | 互变异构体标准化后:9805 电荷归一化后:9790 | 去重后:9650 | 最终输出:9650 失败原因:价键异常 12 | 芳香性感知失败 9 | 金属配位未处理 16

标准化完成后,建议用 InChIKey 或规范 SMILES 做去重,并保留原始 ID 与标准化版本的映射。这样在后续筛选命中时,可以回溯到原始化合物记录,避免“同一分子多个 ID”造成的重复计数。对于大规模库,标准化流程应尽量批处理并并行化,同时把每一步的失败分子单独输出,便于人工复核。

不要在没有记录的情况下直接丢弃解析失败的分子。很多失败源于原始文件格式问题,修正后可以重新纳入库;直接丢弃会造成库覆盖度下降,且难以复现。

总结来说,化合物数据标准化的核心是“统一语义”:让同一化学结构在不同来源、不同文件格式、不同质子化状态下,最终收敛到同一个规范表示。结构解析保证读得进来,去盐去溶剂保证主成分正确,互变异构体标准化保证化学身份一致,电荷与质子化处理保证生理相关性,工具与流程保证可复现。只有这五步都做到位,虚拟筛选库才具备可靠的下游计算基础。