mcpField
R
rowan

rowan

github.com/jaechang-hits其他38467 次安装1 周前更新
代码仓库

关于 rowan

rowan 是用于云端量子化学计算的 Python SDK,面向处理分子结构的研究人员和开发者。它负责作业执行与存储,并返回能量、几何结构及电子性质,无需本地安装量子化学软件。

主要功能

  1. 01DFT 与半经验计算
  2. 02几何优化和构象搜索
  3. 03扭转能量扫描
  4. 04单点分子性质计算
  5. 05批量提交作业并获取结果

适用场景

  1. 01优化候选分子几何结构
  2. 02按能量对构象排序
  3. 03比较扭转能量曲线
  4. 04计算电荷及 HOMO/LUMO 能级

安装

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

$npx skills add https://github.com/jaechang-hits/sciagent-skills --skill rowan

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

详细介绍

rowan

概述

Rowan 是一个云端量子化学平台,通过 Python SDK(rowan)提供 DFT 和半经验计算。通过 Python 脚本或 Jupyter 笔记本提交计算(几何优化、构象生成、扭转扫描、单点能),并检索结果——能量、几何结构、部分电荷、前线轨道能量——而无需管理 Gaussian、ORCA 或 Psi4 安装。Rowan 负责作业排队、执行和存储。学术研究和探索性用途可使用免费套餐。

适用场景

  • 小分子几何优化:使用 DFT 为候选药物、片段或构建单元获取准确的平衡几何结构。
  • 构象生成与能量排序:生成并优化多个构象,找出能量最低的构象,用于对接或性质预测。
  • 扭转势能扫描:绘制可旋转键的能量分布,以了解构象偏好。
  • 量子力学性质计算:计算偶极矩、部分电荷(Mulliken、ESP)、HOMO/LUMO 能量和静电势面。
  • 对接前能量最小化:在将配体几何结构输入基于结构的对接工具(DiffDock、AutoDock Vina)前进行优化。
  • 比较异构体稳定性:计算互变异构体、立体异构体或构造异构体的相对能量。
  • 对于大规模构象筛选(>1000 个分子),请使用 RDKit 的 ETKDGv3 + MMFF(力场级别,无云端费用)。
  • 对于蛋白质规模的量子力学/分子力学(QM/MM),需要 ORCA + CP2K 等专用软件包。

先决条件

pip install rowan

# Set API key (add to .bashrc or .env)
export ROWAN_API_KEY="your_api_key_here"

快速入门

import rowan

# Authenticate (uses ROWAN_API_KEY environment variable automatically)
client = rowan.RowanClient()

# Run geometry optimization of aspirin at GFN2-xTB level
job = client.compute(
    smiles="CC(=O)Oc1ccccc1C(=O)O",
    method="gfn2-xtb",
    tasks=["optimize"],
)
print(f"Job ID: {job.id}, Status: {job.status}")

# Wait for completion and retrieve energy
result = client.wait(job.id)
print(f"Energy: {result.energy:.6f} Hartree")
print(f"Optimized geometry atoms: {len(result.geometry.atoms)}")

核心 API

模块 1:客户端初始化与身份验证
import rowan
import os

# Option 1: automatic (reads ROWAN_API_KEY env variable)
client = rowan.RowanClient()

# Option 2: explicit key
client = rowan.RowanClient(api_key=os.environ["ROWAN_API_KEY"])

print(f"Authenticated as: {client.user.email}")
print(f"Organization: {client.user.organization}")
模块 2:几何优化

将分子几何结构优化到最近的局部极小值。

import rowan

client = rowan.RowanClient()

# GFN2-xTB semiempirical (fast, good for conformer screening)
job_xtb = client.compute(
    smiles="CCc1ccc(cc1)NC(=O)C",    # paracetamol
    method="gfn2-xtb",
    tasks=["optimize"],
)
result_xtb = client.wait(job_xtb.id)
print(f"xTB optimized energy: {result_xtb.energy:.6f} Hartree")
print(f"Geometry: {len(result_xtb.geometry.atoms)} atoms")
# DFT optimization: B3LYP/6-31G* (accurate, slower)
job_dft = client.compute(
    smiles="CCc1ccc(cc1)NC(=O)C",
    method="b3lyp",
    basis_set="6-31g*",
    tasks=["optimize"],
    solvent="water",               # implicit solvent (SMD model)
)
result_dft = client.wait(job_dft.id)
print(f"B3LYP/6-31G* energy (water): {result_dft.energy:.6f} Hartree")
print(f"Dipole moment: {result_dft.dipole_moment:.3f} Debye")
模块 3:构象生成

生成多个 3D 构象并按能量排序。

import rowan
import pandas as pd

client = rowan.RowanClient()

# Generate and optimize 10 conformers at GFN2-xTB level
job = client.compute(
    smiles="CC(C)CC1=CC=C(C=C1)C(C)C(=O)O",  # ibuprofen
    method="gfn2-xtb",
    tasks=["conformers"],
    n_conformers=10,
)
result = client.wait(job.id)

# Rank conformers by relative energy
conformers = result.conformers
df = pd.DataFrame([
    {"conformer_id": i,
     "energy_hartree":    c.energy,
     "rel_energy_kcal":   (c.energy - min(c2.energy for c2 in conformers)) * 627.509}
    for i, c in enumerate(conformers)
]).sort_values("rel_energy_kcal")

print(df.to_string(index=False))
print(f"\nLowest energy conformer ID: {df.iloc[0]['conformer_id']}")
模块 4:扭转扫描

绘制能量随二面角变化的关系。

import rowan
import numpy as np
import matplotlib.pyplot as plt

client = rowan.RowanClient()

# Scan the C-C=C-C dihedral of butene
job = client.compute(
    smiles="CC=CC",             # but-2-ene
    method="gfn2-xtb",
    tasks=["torsion_scan"],
    torsion_atoms=[0, 1, 2, 3],  # atom indices defining dihedral
    n_scan_points=36,             # 36 points = 10-degree steps
)
result = client.wait(job.id)

angles  = [point.angle  for point in result.torsion_scan]
energies = [point.energy for point in result.torsion_scan]
rel_e = [(e - min(energies)) * 627.509 for e in energies]  # convert to kcal/mol

fig, ax = plt.subplots(figsize=(7, 4))
ax.plot(angles, rel_e, "o-", color="steelblue")
ax.set_xlabel("Dihedral angle (degrees)")
ax.set_ylabel("Relative energy (kcal/mol)")
ax.set_title("Torsional potential: but-2-ene C-C=C-C dihedral")
plt.tight_layout()
plt.savefig("torsion_scan.png", dpi=150)
print("Torsion scan saved -> torsion_scan.png")
模块 5:单点性质

在固定几何结构下计算电子性质(HOMO/LUMO、部分电荷、ESP)。

import rowan

client = rowan.RowanClient()

# Single-point DFT: get frontier orbital energies and partial charges
job = client.compute(
    smiles="c1ccccc1N",          # aniline
    method="b3lyp",
    basis_set="6-311+g**",
    tasks=["single_point", "partial_charges", "orbitals"],
)
result = client.wait(job.id)

print(f"HOMO energy: {result.homo_energy:.4f} eV")
print(f"LUMO energy: {result.lumo_energy:.4f} eV")
print(f"HOMO-LUMO gap: {result.lumo_energy - result.homo_energy:.4f} eV")
print(f"Dipole moment: {result.dipole_moment:.3f} Debye")

# Partial charges (Mulliken)
for i, (atom, charge) in enumerate(zip(result.geometry.atoms, result.partial_charges)):
    print(f"  Atom {i} ({atom.symbol}): {charge:+.4f} e")
模块 6:批量提交作业

并发提交多个分子的计算任务。

import rowan
import pandas as pd
from concurrent.futures import ThreadPoolExecutor, as_completed

client = rowan.RowanClient()

smiles_list = [
    ("aspirin",      "CC(=O)Oc1ccccc1C(=O)O"),
    ("caffeine",     "Cn1cnc2c1c(=O)n(c(=O)n2C)C"),
    ("paracetamol",  "CC(=O)Nc1ccc(O)cc1"),
    ("ibuprofen",    "CC(C)Cc1ccc(cc1)C(C)C(=O)O"),
]

def submit_and_wait(name, smiles):
    job = client.compute(smiles=smiles, method="gfn2-xtb", tasks=["optimize"])
    result = client.wait(job.id)
    return {"name": name, "smiles": smiles, "energy": result.energy}

results = []
with ThreadPoolExecutor(max_workers=4) as executor:
    futures = {executor.submit(submit_and_wait, n, s): n for n, s in smiles_list}
    for future in as_completed(futures):
        results.append(future.result())

df = pd.DataFrame(results)
df.to_csv("batch_energies.csv", index=False)
print(df)

关键参数

参数模块默认值范围 / 选项作用
methodcompute必填"gfn2-xtb"、"b3lyp"、"wb97x-d"、"mp2"QC 方法;xTB 速度最快,DFT 精度高,MP2 用于计算相关能
basis_setcompute(DFT)取决于方法"6-31g*"、"6-311+g**"、"def2-svp"、"def2-tzvp"基组;基组越大,精度越高、速度越慢
taskscompute必填["optimize"]、["single_point"]、["conformers"]、["torsion_scan"]要执行的计算
n_conformersconformers 任务101–100要生成并优化的构象数量
n_scan_pointstorsion_scan3612–72二面角扫描点数(360/n 为步长)
solventcomputeNone"water"、"dmso"、"methanol" 等隐式 SMD 溶剂化模型
torsion_atomstorsion_scan必填4 个原子索引的列表定义扫描所用的二面角

最佳实践

  1. 使用 GFN2-xTB 进行筛选,使用 DFT 进行最终表征:xTB 比 DFT 快 100–1000 倍,足以用于构象排序和几何结构探索。对于准确的能量、HOMO/LUMO 能隙和可发表的结果,请改用 B3LYP 或 wB97X-D。

  2. 计算性质前务必优化几何结构:在未弛豫的几何结构上进行单点计算(例如从 SMILES 三维嵌入得到的结构),会导致能量和电子性质不可靠。请先运行 tasks=["optimize"]。

  3. 为具有生物学相关性的分子设置 solvent:对于带电或高极性分子,气相能量与溶液相能量通常差异很大。在水相条件下评估候选药物时,请使用 solvent="water"。

  4. 轮询长时间 DFT 计算的作业状态:在长时间运行的批处理工作流中,可使用带超时的 client.wait(),或通过 client.get_job(job_id).status 进行轮询,以避免阻塞。

  5. 将优化后的几何结构导出为 XYZ 以便复用:保存优化后的几何结构,这样对同一结构进行不同的性质计算时,就不必重新运行耗时的 DFT 作业。

    with open("optimized.xyz", "w") as f:
        f.write(result.geometry.to_xyz())
    

常见工作流

工作流 1:构象搜索与性质计算

目标:找到候选药物的最低能量构象,并计算其电子性质。

import rowan
import pandas as pd

client = rowan.RowanClient()
smiles = "CC(C)Cc1ccc(cc1)C(C)C(=O)O"   # ibuprofen

# Step 1: Generate and rank conformers at fast xTB level
conf_job = client.compute(
    smiles=smiles, method="gfn2-xtb", tasks=["conformers"], n_conformers=20
)
conf_result = client.wait(conf_job.id)
lowest_conf = min(conf_result.conformers, key=lambda c: c.energy)
print(f"Lowest conformer energy: {lowest_conf.energy:.6f} Hartree")

# Step 2: Refine with DFT and compute properties
dft_job = client.compute(
    xyz=lowest_conf.to_xyz(),      # use optimized xTB geometry as DFT start
    method="b3lyp",
    basis_set="6-31g*",
    tasks=["optimize", "partial_charges", "orbitals"],
    solvent="water",
)
dft_result = client.wait(dft_job.id)

print(f"B3LYP/6-31G* energy (water): {dft_result.energy:.6f} Hartree")
print(f"HOMO-LUMO gap: {dft_result.lumo_energy - dft_result.homo_energy:.4f} eV")
print(f"Dipole moment: {dft_result.dipole_moment:.3f} Debye")
工作流 2:互变异构体的相对稳定性

目标:比较两种互变异构体的能量,确定哪一种在水中更稳定。

import rowan

client = rowan.RowanClient()

tautomers = {
    "keto":   "CC(=O)CC(=O)C",     # acetylacetone keto form
    "enol":   "CC(=O)C=C(O)C",     # acetylacetone enol form
}

energies = {}
for name, smiles in tautomers.items():
    job = client.compute(
        smiles=smiles,
        method="b3lyp",
        basis_set="6-311+g**",
        tasks=["optimize"],
        solvent="water",
    )
    result = client.wait(job.id)
    energies[name] = result.energy
    print(f"{name}: {result.energy:.6f} Hartree")

delta_e_hartree = energies["enol"] - energies["keto"]
delta_e_kcal    = delta_e_hartree * 627.509
print(f"\nDelta E (enol - keto): {delta_e_kcal:.2f} kcal/mol")
print(f"More stable form: {'enol' if delta_e_kcal < 0 else 'keto'}")

预期输出

  • result.energy — 总电子能量,单位为 Hartree
  • result.geometry — 优化后的三维几何结构(原子 + 坐标)
  • result.dipole_moment — 偶极矩标量,单位为 Debye
  • result.homo_energy、result.lumo_energy — 前线轨道能量,单位为 eV
  • result.partial_charges — 各原子的电荷列表,单位为元电荷
  • result.conformers — 构象对象列表,每个对象包含相应的能量
  • result.torsion_scan — 扫描点列表,包含(角度、能量)

常见用法

用法:快速单点能量计算

适用场景:在一次调用中比较两个构象或反应中间体的相对能量。

import rowan

client = rowan.Client()

smiles_list = ["CC(=O)O", "C(=O)(O)C"]  # Acetic acid, two representations
jobs = []
for smi in smiles_list:
    job = client.compute(
        molecule=rowan.Molecule.from_smiles(smi),
        theory_level="gfn2-xtb",
        task="single_point",
    )
    jobs.append(job)

# Collect energies
for smi, job in zip(smiles_list, jobs):
    result = client.wait(job)
    print(f"{smi}: energy = {result.energy:.6f} Hartree")
用法:检查运行中的作业状态

适用场景:监控长时间运行的优化或构象搜索,而不造成阻塞。

import rowan, time

client = rowan.Client()
job = client.compute(
    molecule=rowan.Molecule.from_smiles("c1ccccc1"),
    theory_level="gfn2-xtb",
    task="optimize",
)
print(f"Job ID: {job.id}")

# Poll every 10 seconds (non-blocking)
for _ in range(30):
    status = client.status(job)
    print(f"Status: {status}")
    if status in ("completed", "failed"):
        break
    time.sleep(10)

result = client.get(job)
print(f"Final energy: {result.energy:.6f} Hartree")

故障排查

问题原因解决方案
AuthenticationError未设置 API 密钥或密钥已过期设置 ROWAN_API_KEY 环境变量;在 rowanquantum.com 重新生成密钥
作业一直处于 queued 状态免费版服务器负载较高等待或升级到付费版;高峰时段免费版可能会排队
出现 SCF not converged 错误DFT 自洽场计算未收敛尝试使用较小的基组;先使用 method="gfn2-xtb" 获取更好的初始几何结构
ValueError: invalid SMILESSMILES 字符串格式错误提交前使用 RDKit 的 Chem.MolFromSmiles(smiles) 进行验证
优化后能量较高几何结构陷入局部极小值使用 tasks=["conformers"] 生成多个构象,并选择能量最低的构象
缺少 result.homo_energy未请求轨道计算将 "orbitals" 添加到 tasks 列表中

参考资料

评论

支持 Markdown