055

化学信息学工具栈:RDKit、OpenBabel、Datamol 如何配合使用

RDKit、OpenBabel 与 Datamol 各有分工。这篇给出一个务实的化学信息学工具栈与配合方式。

化学信息学的工具很多,但一个项目实际需要的核心工具并不多。这篇给出一个务实的最小工具栈,以及各工具的分工与配合方式。

核心三件套的分工

工具 定位 最擅长
RDKit 事实标准 分子处理、指纹、描述符、子结构、构象
OpenBabel 格式转换器 罕见格式的支持(CIF、CML 等)
Datamol RDKit 的便利封装 并行处理、常用流程的简化

基本原则:能用 RDKit 就用 RDKit。它的化学正确性最有保障、社区最大、文档最全。OpenBabel 只在需要罕见格式时用(见 037《ECFP 指纹详解》 的格式转换讨论)。

Datamol:值得了解的封装

pip install datamol

import datamol as dm

# ---- 简化的常用操作 ----
mol = dm.to_mol("CC(=O)Nc1ccc(O)cc1")

# 标准化(一行完成 RDKit 需要几步的操作)
mol = dm.sanitize_mol(mol)
mol = dm.standardize_mol(mol, disconnect_metals=True,
                        normalize=True, reionize=True,
                        uncharge=True)
smiles = dm.to_smiles(mol)

# ---- 【并行处理:Datamol 最有价值的功能】 ----
def process(smi):
    m = dm.to_mol(smi)
    if m is None:
        return None
    m = dm.standardize_mol(m)
    return dm.to_smiles(m)

results = dm.parallelized(
    process, smiles_list,
    n_jobs=8,
    progress=True,           # 【自带进度条】
    scheduler="processes",
)

# ---- 描述符批量计算 ----
df = dm.descriptors.batch_compute_many_descriptors(mols, n_jobs=8)

# ---- 便利的 IO ----
df = dm.read_sdf("molecules.sdf", as_df=True)
dm.to_sdf(mols, "output.sdf")
df = dm.read_csv("data.csv", smiles_column="smiles")

# ---- 可视化 ----
dm.to_image(mols[:12], n_cols=4, legends=names[:12])

# ---- 骨架与片段 ----
scaffold = dm.to_scaffold_murcko(mol)
frags = dm.fragment.brics(mol)

# 【Datamol 的价值】:
#   1) 【并行 + 进度条】—— 处理大数据时很实用
#   2) 常用流程的合理默认值
#   3) 与 pandas 的良好集成
#
# 【要注意的】:
#   它封装了 RDKit,出问题时可能需要
#   深入到 RDKit 层面排查
#   → 【理解底层的 RDKit 仍然必要】

一个务实的最小工具栈

# 【核心(几乎每个项目都需要)】
#
#   rdkit                化学信息学基础(见 013)
#   pandas, numpy        数据处理
#   scikit-learn         传统机器学习
#   lightgbm             【梯度提升——最实用的基线】
#   matplotlib/seaborn   可视化
#
# 【常用(按需)】
#
#   datamol              并行与流程简化
#   mols2grid            【交互式分子表格】(见 217)
#   chembl_webresource_client   ChEMBL 数据获取(见 226)
#   openbabel            罕见格式转换
#
# 【深度学习(如果需要)】
#
#   torch                
#   torch_geometric      GNN(见 176)
#   chemprop             【分子图模型的成熟实现】(见 131)
#   transformers         预训练模型(见 025)
#
# 【结构相关(如果做结构基工作)】
#
#   pdbfixer + meeko     结构准备(见 105、106)
#   vina / gnina         对接(见 017、016)
#   openmm               MD(见 015)
#   mdanalysis           轨迹分析(见 129)
#   prolif / plip        相互作用(见 109、108)
#   pymol-open-source    可视化(见 110)
#   py3Dmol              Notebook 中的三维展示(见 111)
#
# 【工程(团队协作时)】
#
#   conda/mamba          环境管理
#   mlflow               实验跟踪
#   dvc                  数据版本管理
#
# 【这个栈能覆盖 80% 以上的常见需求】
# → 【不要一开始就装太多】

环境管理:容易被忽略但很重要

# environment.yml
#
# name: chem
# channels:
#   - conda-forge
# dependencies:
#   - python=3.11
#   - rdkit=2024.03.5        # 【锁定版本】
#   - pandas=2.2.*
#   - numpy=1.26.*
#   - scikit-learn=1.5.*
#   - lightgbm=4.5.*
#   - jupyterlab
#   - pip
#   - pip:
#     - datamol==0.12.*
#     - mols2grid==2.0.*

# 【为什么要锁定版本】:
#   1) 【RDKit 不同版本的行为可能不同】
#      如:芳香性感知、标准化的默认选项
#      → 结果不可复现
#   2) 依赖冲突
#   3) 【团队成员的环境一致】
#
# 【推荐用 mamba 而非 conda】:
#   解析速度快得多
#   mamba env create -f environment.yml
#
# 【记录环境】:
#   conda env export --no-builds > environment.lock.yml
#   → 【与代码一起版本管理】

工具选择的常见判断

任务 推荐 不推荐
SMILES → 三维构象 RDKit ETKDG(见 049《构象生成入门》 OpenBabel --gen3d
分子标准化 RDKit MolStandardize(见 046《分子标准化》
质子化态 Dimorphite-DL OpenBabel -p
格式转换(常见格式) RDKit
格式转换(罕见格式) OpenBabel
转 PDBQT Meeko(见 106《Meeko》 OpenBabel
PDB 中恢复配体键级 RDKit + 模板 直接推断
大批量并行处理 Datamol 或 multiprocessing 单线程循环
分子性质预测基线 ECFP + LightGBM(见 131《Chemprop / D-MPNN 论文精读》 直接上深度模型

一个可复用的项目模板

# 【推荐的项目结构】
#
# project/
#   environment.yml           # 环境定义
#   data/
#     raw/                    # 【原始数据,只读】
#     processed/              # 处理后的数据
#   src/
#     data.py                 # 数据加载与清洗
#     features.py             # 特征计算
#     models.py               # 模型定义
#     evaluate.py             # 【评测(含划分逻辑)】
#   notebooks/                # 探索性分析
#   scripts/                  # 可复现的流程脚本
#   results/
#   README.md
#
# 【几个关键的工程实践】:
#
# 1) 【原始数据只读】
#    所有处理都生成新文件
#    → 出问题能回溯
#
# 2) 【清洗流程写成脚本,不要在 Notebook 里手工做】
#    → 可复现
#
# 3) 【固定随机种子并记录】
#    数据划分、模型训练、构象生成
#
# 4) 【评测逻辑单独成模块】
#    → 保证所有模型用同样的划分与指标
#    → 【避免「不小心用了不同的划分」这类错误】
#
# 5) 【记录每次实验的配置与结果】
#    最简单的做法:一个 CSV 追加记录
#    正式一点:MLflow / Weights & Biases
#
# 6) 【缓存昂贵的计算】
#    指纹、描述符、构象算一次存起来

import functools
import hashlib
import pickle
import os

def disk_cache(cache_dir="cache"):
    """简单的磁盘缓存装饰器"""
    os.makedirs(cache_dir, exist_ok=True)
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            key = hashlib.md5(
                repr((func.__name__, args, sorted(kwargs.items()))
                     ).encode()).hexdigest()
            path = os.path.join(cache_dir, f"{key}.pkl")
            if os.path.exists(path):
                with open(path, "rb") as f:
                    return pickle.load(f)
            result = func(*args, **kwargs)
            with open(path, "wb") as f:
                pickle.dump(result, f)
            return result
        return wrapper
    return decorator

@disk_cache()
def compute_fingerprints(smiles_tuple):
    ...

关键要点

  • 能用 RDKit 就用 RDKit——化学正确性最有保障;OpenBabel 只用于罕见格式;
  • Datamol 的核心价值是并行处理与进度条,但理解底层 RDKit 仍然必要;
  • 必须锁定版本——RDKit 不同版本的芳香性感知与标准化默认值可能不同;
  • 评测逻辑单独成模块,保证所有模型用同样的划分与指标。

延伸资源