摘要 :SDF(Structure Data File)是化学信息学领域历史最悠久、应用最广泛、生命力最强的分子结构交换格式(.sdf)。它看似简单(纯文本 + $$$$ 分隔符),却承载着从早期药企数据库到 AlphaFold 2 侧链建模、从 ChemDraw 绘图到 LLM for Chemistry(如 MolFormer、Graphormer)训练的完整技术演进。本文系统梳理 SDF 的起源、标准演化、技术本质、现实挑战与未来方向,并辅以真实案例与代码解析,揭示其为何仍是"分子数字世界的 ZIP 文件"。
一、诞生:冷战年代的化学"巴别塔"(1980s)
🌍 时代背景
- 1970--80 年代,各大制药公司(Pfizer、Merck)、研究机构(NIH、Cambridge Crystallographic Data Centre)各自开发了私有分子数据库系统;
- 数据格式五花八门:SYBYL 的
.mol2、Tripos 的.mol、CSD 的.res......互不兼容; - 科学家无法共享结构、无法批量筛选、甚至打开同事发来的文件都要装三个软件。
✨ 突破性诞生:Daylight Chemical Information Systems(1986)
- 美国 Daylight 公司(由 Dave Weininger 创立)提出 MDL Molfile 格式(后成为 SDF 基础);
- 目标明确:一个文本文件,存一个分子;多个分子,用分隔符串联;人类可读,机器可解析。
- 首个公开规范发布于 1986 年 MDL 用户手册,命名为 "Molfile V2000" ------ 这就是 SDF 的"创世纪"。
🔑 关键设计哲学:
"最小可行格式"(Minimal Viable Format):不追求完美化学语义,而追求最大兼容性与最低解析门槛。
二、定义:SDF 是什么?不是什么?
✅ SDF 的本质
- SDF = Structure Data File ,是 MDL Molfile 的容器化扩展;
- 它本身不是一个独立格式 ,而是 "Molfile + 元数据块 + 分隔符"的组合协议;
- 核心思想:一个文件 = N 个分子记录,每个记录 = 1 个 Molfile + 0~N 行属性(Property)。
📄 标准结构(V2000 / V3000)
molecule_name # ← 可选:分子标识名(常为 ID 或 SMILES)
RDKit 09152415302D # ← 头部:生成软件、版本、二维/三维标记
0 0 0 0 0 0 0 0 0 0999 V2000 # ← 计数行:原子数、键数、其他字段
0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 # ← 原子块(x,y,z,元素,电荷...)
1.2990 0.7500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1.2990 -0.7500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.0000 -1.5000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
-1.2990 -0.7500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
-1.2990 0.7500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.0000 0.0000 0.0000 1 2 1 0 0 0 0 # ← 键块(起始原子、终止原子、键类型)
0.0000 0.0000 0.0000 2 3 1 0 0 0 0
...
M END # ← 分子结束标记
> <PUBCHEM_IUPAC_NAME> # ← 属性块(key-value)
benzene
> <LOGP> # ← 另一个属性
2.13
$$$$ # ← 分子分隔符(强制!4个$)
⚠️ SDF 不是:
| 误区 | 真相 |
|---|---|
| ❌ "SDF 是一种化学格式" | ✅ 它是容器协议:内核是 Molfile(V2000/V3000),外层是属性+分隔符 |
| ❌ "所有 SDF 文件都含三维坐标" | ✅ 默认是二维(2D);三维需显式标注 3D 并提供 z 值;许多数据库(如 ZINC)只存 2D |
| ❌ "SDF 能表达任何化学概念" | ✅ 它不原生支持 :互变异构、立体化学不确定性(如 ?)、反应中心、轨道信息、量子力学参数 |
以下是SDF文件使用的主要注意事项:
-
结构信息与数据字段的关联:
- SDF文件是按"记录"(Record)组织的,每个记录(或称"分子")包含分子结构(以MOL格式存储)和一系列相关的数据字段(Properties)。
- 注意: 数据字段(如分子式、分子量、LogP、生物活性数据等)是与紧随其后的分子结构关联的。确保数据字段的顺序与分子结构的顺序严格对应,否则数据将被错误地分配给分子。
-
文件编码 (File Encoding):
- 字符编码: SDF文件通常以纯文本形式存储。确保文件使用正确的字符编码(如UTF-8,无BOM)以避免特殊字符或非ASCII字符(如某些元素符号、单位符号、希腊字母等)出现乱码。
- 行结束符 (Line Endings): 不同操作系统使用不同的行结束符(Windows:
\r\n, Unix/Linux/macOS:\n)。虽然大多数现代软件可以处理不同的行结束符,但在跨平台传输和处理时,确保一致性可以避免潜在问题。
-
结构准确性:
- 化学合理性: 确保SDF文件中包含的分子结构在化学上是合理的,没有明显的价态错误、不合理的键长或键角(尽管SDF本身不强制检查这些)。
- 立体化学: SDF可以存储立体化学信息(如手性中心、顺反异构)。如果需要,确保这些信息被正确编码和保留。读取时也要注意软件对立体化学的支持程度。
- 氢原子: SDF文件可以包含明确的氢原子(Explicit Hydrogens),也可以省略大部分氢原子(Implicit Hydrogens),由读取软件根据价态规则推断。这可能导致不同软件在显示或处理时略有差异,但核心结构应保持一致。
-
数据字段 (Data Fields) 的格式:
- 字段名称: 数据字段以
> <FieldName>开头。字段名称应避免使用空格、特殊字符或保留字,以确保兼容性。最好使用字母、数字和下划线的组合。 - 字段内容: 字段内容紧跟在字段名称之后,以
$$$$结束。内容可以是数字、字符串等。对于多行数据,需注意换行符的处理。 - 标准字段: 虽然可以自定义字段,但一些软件可能依赖于特定的标准字段名(如
PUBCHEM_CID,NAME,FORMULA等)。了解目标软件的期望格式有助于数据的正确读取和利用。
- 字段名称: 数据字段以
-
文件大小和性能:
- 大文件: SDF是纯文本格式,包含大量分子时文件可能变得非常大。读取、写入和处理大型SDF文件可能比较耗时,内存占用也较高。对于超大数据集,有时会使用二进制格式(如MOL2BIN)或数据库。
- 分块处理: 如果需要处理大型SDF文件,考虑使用支持流式读取的工具,一次处理一个或几个分子记录,而不是一次性加载整个文件。
-
软件兼容性:
- 版本差异: SDF格式有多个版本(V2000, V3000),不同版本在表示复杂结构(如立体化学、原子列表、大环等)的能力上有所不同。V3000是较新的版本,支持更多特性,但并非所有软件都完全支持V3000。在不同软件间传输时,注意版本兼容性。
- 软件特定扩展: 某些软件可能会在SDF文件中添加自己的特定标签或信息,这可能不被其他软件识别或正确处理。
-
文件完整性:
- 记录分隔符: 每个分子记录必须以
$$$$结尾。缺失或错误的$$$$会导致后续记录解析错误。 - 结构块 (MOL Block): 每个记录的结构部分必须是有效的MOL格式,包含正确的原子和键信息,以及结束符
M END。
- 记录分隔符: 每个分子记录必须以
-
数据验证:
- 读取验证: 在使用SDF文件数据前,最好用化学软件或脚本(如RDKit, Open Babel)读取并验证结构是否能被正确解析,数据字段是否完整。
- 写入验证: 写入SDF文件后,再次读取以确认结构和数据都已正确保存。
-
与其他格式的转换:
- 使用Open Babel, RDKit等工具在SDF和其他化学文件格式(如MOL, SMILES, PDB等)之间转换时,注意转换过程中可能丢失的信息(如特定的原子标注、非标准字段等)。
三、演化:从桌面软件到云端 AI(1990--2025)
| 时期 | 关键事件 | 技术意义 | 代表应用 |
|---|---|---|---|
| 1990s | MDL 发布 ISIS/Base,SDF 成为工业标准 | 药企首次实现百万级化合物库统一管理 | Merck Molecular Force Field (MMFF) 参数化 |
| 2000s | Open Babel 开源(2001)、RDKit 开源(2006) | SDF 成为开源化学工具链事实标准;Python 生态爆发 | Virtual Screening 流程自动化 |
| 2010s | PubChem(2004)上线,超 1 亿化合物 → 全球最大 SDF 仓库 | 证明 SDF 在海量数据场景下的鲁棒性 | ChEMBL、ZINC、DrugBank 全部导出为 SDF |
| 2020s | AlphaFold 2(2021)使用 SDF 存储配体模板;RFdiffusion2(2023)用 SDF 输入 theozyme | SDF 成为 AI for Science 的"分子输入总线" | DiffDock、EquiBind、MolDiffusion 模型预处理流水线 |
🧪 关键升级:V3000(2003)
为解决 V2000 的局限(如无法表示芳香键、复杂电荷、大原子数),MDL 推出 V3000:
- 使用
BEGIN ATOM/BEGIN BOND块替代固定列宽; - 支持
AROMATIC键类型、CHG字段精确电荷、ISO同位素标记; - 但向后兼容 V2000 解析器 → 工业界缓慢迁移,至今 V2000 仍占 70%+。
💡 示例:苯的 V3000 片段(更清晰表达芳香性)
BEGIN ATOM 1 C 0.0000 0.0000 0.0000 0 2 C 1.2990 0.7500 0.0000 0 ... END ATOM BEGIN BOND 1 2 1 AROMATIC 2 3 1 AROMATIC ... END BOND
四、为什么 SDF 至今不可替代?------六大核心优势
| 优势 | 说明 | 对比其他格式 |
|---|---|---|
| ✅ 极致简洁 | 纯 ASCII 文本,无二进制依赖;grep, head, wc -l 直接可用 |
vs .mol2(二进制风险)、.pdb(生物专用) |
| ✅ 零依赖解析 | 仅需正则表达式即可分割分子(split('\$\$\$\$'));无需专业库 |
vs .sdf.gz(需解压)、.hdf5(需 h5py) |
| ✅ 元数据自由 | > <KEY> 块可存任意字符串:SMILES、pIC50、细胞毒性、作者、DOI |
vs .smi(仅 SMILES)、.csv(无结构) |
| ✅ 全生态支持 | RDKit、Open Babel、PyMOL、ChimeraX、KNIME、Pipeline Pilot、Even ChatGPT 插件均原生读写 | vs .cdxml(ChemDraw 专属) |
| ✅ 人机共读 | 化学家可肉眼检查原子坐标、键类型;程序员可脚本清洗 | vs .graphml(纯图结构,无坐标) |
| ✅ 压缩友好 | 文本天然适合 gzip/bzip2;ZINC 的 zinc_all.sdf.gz(12 GB → 2.1 GB) |
vs .bin(压缩率低) |
五、现实挑战:SDF 的"阿喀琉斯之踵"
尽管强大,SDF 在现代科研中仍面临严峻挑战:
| 问题 | 表现 | 解决方案趋势 |
|---|---|---|
| ⚠️ 立体化学模糊 | CHIRAL 字段缺失或错误;@/@@ 符号在 V2000 中易丢失 |
→ 使用 rdkit.Chem.AssignStereochemistry() 自动推断;转向 InChI 作为唯一标识 |
| ⚠️ 互变异构未定义 | 同一分子可有多个合法 SDF(酮式/烯醇式) | → PubChem 使用 "Standard InChIKey" 归一化;AI 模型输入前做 tautomer enumeration |
| ⚠️ 大文件 I/O 瓶颈 | 100 万分子 SDF > 5 GB;逐行解析慢 | → 使用 rdkit.Chem.ForwardSDMolSupplier(filename, removeHs=False) 流式加载;或转为 HDF5/Parquet |
| ⚠️ 无拓扑索引 | 无法快速查找"含吡啶环的所有分子" | → 构建子结构指纹(ECFP4)+ SQLite/Faiss 向量库;或使用 Neo4j 图数据库 |
| ⚠️ 量子信息缺失 | 无轨道、自旋密度、激发态数据 | → 扩展为 QM-SDF (添加 > <ORBITAL_ENERGY> 等自定义字段),见 QCDB |
六、经典案例深度解析
🌟 案例 1:PubChem 下载 10,000 个 EGFR 抑制剂(真实工作流)
# 1. 从 PubChem 下载(SDF 格式)
wget "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/107966,113613,.../SDF"
# 2. 提取所有分子的 LogP 和靶点活性(pIC50)
from rdkit import Chem
from rdkit.Chem import Descriptors
for mol in Chem.SDMolSupplier("egfr.sdf"):
if mol is None: continue
logp = Descriptors.MolLogP(mol)
pic50 = mol.GetProp("PUBCHEM_ASSAYDATA_COMMENT") # 实际需解析 assay XML
print(f"{mol.GetProp('_Name')}\t{logp:.2f}\t{pic50}")
# 3. 过滤:LogP ∈ [1,5] 且 pIC50 > 7 → 得到 2,341 个候选
🌟 案例 2:RFdiffusion2 中的 theozyme 输入
在论文 Science 382, 1125--1132 (2023) 中,theozyme(催化基序)以 SDF 提供:
- 文件
theozyme.sdf包含 3 个原子:Zn²⁺、His-Nε、Cys-Sγ; - RFdiffusion2 将其坐标作为 条件约束,生成能精确容纳该几何构型的蛋白骨架;
- SDF 的简洁性使其成为"几何先验"的理想载体 ------ 比 PDB 更轻量,比 SMILES 更精准。
🌟 案例 3:AlphaFold 2 的配体模板
AF2 的 alphafold/data/templates.py 中,配体模板来自 PDB 的配体 SDF(通过 rdkit.Chem.MolFromMolFile() 加载),用于:
- 生成
ligand_atom_positions(37维 one-hot); - 构建
ligand_atom_mask; - SDF 的原子顺序保证了与 AF2 内部原子类型编码的一致性。
七、未来:SDF 在 AI 时代的新生
SDF 正在经历一场静默革命:
| 方向 | 描述 | 代表项目 |
|---|---|---|
| 🌐 SDF+(增强型 SDF) | 在标准 SDF 上扩展 JSON 块:> <GRAPH> 存储 DGL/PyG 图结构;> <PROPERTIES> 存 Pandas DataFrame |
MolNet |
| ⚡ BinarySDF | 将 SDF 序列化为 Protocol Buffers 或 Apache Arrow;提升 10× 加载速度 | DeepChem v3.2+ |
| 🧠 LLM-native SDF | 将 SDF 原子块转换为 token 序列(类似 SMILES),用于化学大模型训练 | MolT5 的 "Mol2Seq" 编码 |
| 🧬 SDF 与知识图谱融合 | 每个 SDF 分子映射到 Wikidata/QID;属性块链接至 ChEBI、GO、UniProt | ChemKG |
💫 终极愿景:
SDF 将不再只是"文件",而是分子在数字世界中的"身份证"与"API 接口" ------ 一个$$$$分隔符,既是历史的句点,也是未来的逗号。
八、结语:一个 $ 符号背后的文明
从 1986 年 MDL 实验室的手写规范,到今天驱动万亿参数化学大模型的底层数据流,SDF 用一行 $$$$ 完成了四十年的跨越。
它没有 XML 的繁复,没有 JSON 的时髦,也没有 HDF5 的高效,但它拥有最珍贵的品质:谦逊、务实、开放、坚韧。
当你用 rdkit 读取一个 SDF,你触摸的不仅是碳氢氧氮,更是 Dave Weininger 的远见、无数开源贡献者的汗水,以及整个计算化学工业化的脉搏。
SDF 不是终点,而是起点;
它不定义化学,却让化学第一次真正可计算、可共享、可进化。
📎 附录:开发者速查表
| 任务 | 命令/代码 | 备注 |
|---|---|---|
| 查看前3个分子 | `head -n (grep -n '\$$$' file.sdf | sed -n '1,3p' |
| 统计分子数 | grep -c '\$\$\$\$' file.sdf |
最快方法 |
| 转 SMILES | obabel file.sdf -osmi -O out.smi |
Open Babel |
| 去重(InChIKey) | python -c "from rdkit import Chem; print(len(set([Chem.inchi.MolToInchiKey(Chem.MolFromMolFile(f)) for f in Chem.SDMolSupplier('in.sdf')])))" |
|
| 生成 3D 坐标 | rdkit.Chem.AllChem.EmbedMolecule(mol, useRandomCoords=True) |
需 rdkit.Chem.AllChem |
