mcpField
O
openbabel

openbabel

github.com/tondevrel数据与数据库2452 次安装38 周前更新
代码仓库

关于 openbabel

Open Babel 是用于化学数据互操作的工具集,适合需要处理分子文件的研究人员;它支持多种格式转换、3D 结构生成、子结构搜索及批量分子处理,并提供 Python 接口 Pybel。

主要功能

  1. 01转换多种分子文件格式
  2. 02从 SMILES 生成 3D 坐标
  3. 03使用 SMARTS 搜索子结构
  4. 04添加氢并准备对接配体
  5. 05计算指纹与 Tanimoto 相似度
  6. 06迭代处理大型分子文件

适用场景

  1. 01在 SDF、PDB 等格式间转换
  2. 02为分子生成并优化 3D 结构
  3. 03按 SMARTS 筛选化合物
  4. 04批量处理大型化学数据库

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/tondevrel/scientific-agent-skills --skill openbabel

安装后在 Claude Code 中输入/openbabel确认已加载。

详细介绍

Open Babel——通用化学转换器

Open Babel(及其 Python 封装 pybel)是实现化学数据互操作的必备工具。研究人员可以借助它在 SMILES、PDB、SDF、CIF 和 Gaussian 输入/输出等格式之间无缝转换数据。

使用场景

  • 在不同格式之间转换化学文件(例如,将 SDF 转换为 PDB)。
  • 根据 2D 结构或 SMILES 生成 3D 坐标。
  • 使用 SMARTS 模式搜索子结构。
  • 快速准备分子对接(例如,添加氢原子、计算电荷)。
  • 执行基本的力场最小化(UFF、GAFF、MMFF94)。
  • 计算分子指纹和 Tanimoto 系数。
  • 批量处理大型化学数据库(数百万个分子)。

参考文档

官方文档:https://openbabel.org/docs/dev/
Python API(Pybel):https://openbabel.org/docs/dev/UseTheLibrary/Python_Pybel.html
搜索模式:openbabel.OBMol、pybel.readfile、pybel.readstring、mol.make3D

核心原则

OB 与 Pybel
  • OpenBabel(SWIG):底层接口,可直接访问 C++ 类(OBMol、OBAtom)。使用复杂,但功能最强大。
  • Pybel:高层“封装”,采用更符合 Python 风格的写法。推荐用于 90% 的任务。
转换引擎

Open Babel 以管道方式工作:输入格式 -> 内部 OBMol -> 输出格式。你可以在转换过程中直接添加过滤器和变换操作(去除盐、添加氢原子)。

快速参考

安装
# Recommended via conda/mamba
conda install -c conda-forge openbabel
标准导入
from openbabel import openbabel as ob
from openbabel import pybel
基本模式 - 格式转换
from openbabel import pybel

# 1. Read molecule (from string or file)
mol = pybel.readstring("smi", "CC(=O)Oc1ccccc1C(=O)O") # Aspirin

# 2. Add metadata
mol.title = "Aspirin_001"

# 3. Write to a different format
output_pdb = mol.write("pdb")
# Or write to file
# mol.write("sdf", "aspirin.sdf", overwrite=True)

关键规则

✅ 应该做
  • 使用 Pybel 简化操作 - 它负责内存管理,并提供便捷的分子属性访问方式。
  • 为 3D 结构添加氢原子 - 生成 3D 坐标前,始终调用 mol.OBMol.AddHydrogens() 或 mol.addh()。
  • 使用 SMARTS 搜索子结构 - 这是查找官能团最可靠的方法。
  • 批量处理 - 使用 pybel.readfile,不要将分子全部读入列表,以节省内存。
  • 检查几何结构是否有效 - 生成 3D 结构后,检查能量是否合理。
  • 关闭文件迭代器 - 使用 list(pybel.readfile(...)) 或正确迭代,以确保妥善管理文件句柄。
❌ 不应该做
  • 混用 RDKit 和 Open Babel 对象 - 两者不兼容。要在它们之间传递数据,请转换为 SMILES/SDF。
  • 忽略错误 - Open Babel 不会主动提示错误;请检查生成的分子是否为 None。
  • 忽略立体化学信息 - 不带 @ 或 / 的 SMILES 在转换过程中会丢失立体中心信息。
  • 用于复杂描述符计算 - 对于高级 QSAR,通常更推荐 RDKit;Open Babel 最适合格式转换和 3D 处理。

反模式(绝不可做)

from openbabel import pybel

# ❌ BAD: Loading millions of molecules into a list
# mols = list(pybel.readfile("sdf", "huge_database.sdf")) # Crashes RAM

# ✅ GOOD: Iterator-based processing
for mol in pybel.readfile("sdf", "huge_database.sdf"):
    # process one by one
    pass

# ❌ BAD: Generating 3D without hydrogens
mol = pybel.readstring("smi", "C1CCCCC1")
mol.make3D() # ❌ Resulting structure will be distorted/incorrect

# ✅ GOOD: Add H first
mol = pybel.readstring("smi", "C1CCCCC1")
mol.addh()
mol.make3D()
mol.optimize("mmff94")

# ❌ BAD: Manual string manipulation to change format
# pdb_str = sdf_str.replace(...) # ❌ Never works reliably

使用分子(pybel)

属性和原子
mol = pybel.readstring("smi", "c1ccccc1O") # Phenol

print(f"Formula: {mol.formula}")
print(f"Weight: {mol.molwt:.2f}")

# Iterate over atoms
for atom in mol.atoms:
    print(f"Atom: {atom.type}, Coords: {atom.coords}")

# Get data as a dictionary
data = mol.data # Access SDF tags/metadata
子结构搜索(SMARTS)
# Search for carboxylic acid group
smarts = pybel.Smarts("C(=O)[OH]")
mol = pybel.readstring("smi", "CC(=O)O") # Acetic acid

if smarts.findall(mol):
    print("Molecule contains a carboxylic acid!")

3D 结构和力场

生成和优化
mol = pybel.readstring("smi", "CN1C=NC2=C1C(=O)N(C(=O)N2C)C") # Caffeine

# 1. Prepare for 3D
mol.addh()

# 2. Generate initial 3D (Distance Geometry)
mol.make3D(forcefield='mmff94', steps=50)

# 3. Fine-tune with a local optimizer
# Options: uff, gaff, mmff94, ghemical
mol.optimize(forcefield='mmff94', steps=500)

print(f"3D Energy: {mol.energy:.2f} kJ/mol")

进阶:底层 Open Babel API

直接操作 OBMol
from openbabel import openbabel as ob

# Access the internal OBMol object from a pybel molecule
obmol = mol.OBMol

# Manual atom addition
new_atom = obmol.NewAtom()
new_atom.SetAtomicNum(6) # Carbon
new_atom.SetVector(1.0, 1.0, 1.0)

# Bond information
for i in range(obmol.NumBonds()):
    bond = obmol.GetBond(i)
    print(f"Bond between {bond.GetBeginAtomIdx()} and {bond.GetEndAtomIdx()}")
描述符计算
# Fingerprints
# Standard types: FP2 (path-based), FP3 (SMARTS patterns), FP4 (functional groups)
fps = mol.calcfp("FP2")
print(f"Fingerprint bits: {fps.bits}")

# Similarity
mol2 = pybel.readstring("smi", "c1ccccc1")
fps2 = mol2.calcfp("FP2")
similarity = fps | fps2 # Tanimoto coefficient

实用工作流

1. 高通量格式转换器
def batch_convert(input_file, in_fmt, output_file, out_fmt, add_h=False):
    """Converts large files with optional hydrogen addition."""
    writer = pybel.Outputfile(out_fmt, output_file, overwrite=True)
    
    for mol in pybel.readfile(in_fmt, input_file):
        if add_h:
            mol.addh()
        writer.write(mol)
    
    writer.close()

# batch_convert("library.smi", "smi", "library.sdf", "sdf", add_h=True)
2. 准备对接用配体(PDBQT)
def prepare_ligand(smi_str, output_name):
    """Basic prep for AutoDock Vina."""
    mol = pybel.readstring("smi", smi_str)
    mol.addh()
    mol.make3D()
    mol.optimize("gaff")
    
    # Open Babel has a dedicated pdbqt format
    mol.write("pdbqt", f"{output_name}.pdbqt", overwrite=True)
3. 去除盐(化学清理)
def strip_salts(mol):
    """Removes smaller fragments (salts/solvents) from a molecule."""
    if len(mol.reversesmi.split(".")) > 1:
        # Get the largest fragment by number of atoms
        fragments = mol.OBMol.Separate()
        largest = max(fragments, key=lambda x: x.NumAtoms())
        return pybel.Molecule(largest)
    return mol

性能优化

使用 FP2 快速搜索

在数百万个分子中执行耗时的 3D 或 SMARTS 匹配之前,先使用指纹筛选(Tanimoto)过滤候选分子。

使用 OBConversion 提高原始速度

如果只需转换格式而无需操作原子,使用原始 OBConversion 类比创建 pybel.Molecule 对象更快。

obconv = ob.OBConversion()
obconv.SetInAndOutFormats("smi", "sdf")
obconv.ConvertFile("in.smi", "out.sdf")

常见问题与解决方案

SMILES 产生的“空分子”
# ❌ Problem: pybel.readstring("smi", "invalid_smiles") returns a blank molecule
# ✅ Solution: Always check for atom count
mol = pybel.readstring("smi", some_input)
if len(mol.atoms) == 0:
    print("Error: Invalid molecule data")
力场的路径问题

在某些系统上,Open Babel 无法找到其数据文件(力场参数)。

# ✅ Solution: Manually set BABEL_DATADIR if needed
import os
# os.environ['BABEL_DATADIR'] = '/path/to/openbabel/data'
3D 手性反转

有时,如果输入的 SMILES 不够明确,make3D 可能会反转一个立体中心。

# ✅ Solution: Use 'gen3d' operation instead of simple make3D
# which is more robust for preserving stereochemistry.
obconv = ob.OBConversion()
obconv.AddOption("gen3d", ob.OBConversion.GENOPTIONS)

最佳实践

  1. 生成 3D 结构前始终添加氢原子——不含氢原子的结构会不正确。
  2. 处理大文件时使用迭代器——不要将整个数据库加载到内存中。
  3. 读取后验证分子——检查原子数和基本属性。
  4. 使用合适的力场——有机分子使用 MMFF94,通用场景使用 UFF,类药物分子使用 GAFF。
  5. 保留立体化学信息——必要时使用包含 @ 和 / 的显式 SMILES 表示法。
  6. 使用指纹进行相似性比较——执行开销较大的操作前,使用 Tanimoto 系数进行筛选。
  7. 显式关闭文件写入器——使用上下文管理器或 .close() 确保数据已写入。
  8. 优化后检查能量——不合理的能量值表明几何结构存在问题。

Open Babel 是化学世界的“黏合剂”。虽然它没有 RDKit 那样精妙的 2D 渲染功能,也没有 PySCF 那样的高级数学能力,但它能处理任何格式并生成 3D 起始结构,因此是每位计算化学家工具箱中的必备工具。

评论

支持 Markdown