关于 rowan
rowan 是用于云端量子化学计算的 Python SDK,面向处理分子结构的研究人员和开发者。它负责作业执行与存储,并返回能量、几何结构及电子性质,无需本地安装量子化学软件。
主要功能
- 01DFT 与半经验计算
- 02几何优化和构象搜索
- 03扭转能量扫描
- 04单点分子性质计算
- 05批量提交作业并获取结果
适用场景
- 01优化候选分子几何结构
- 02按能量对构象排序
- 03比较扭转能量曲线
- 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 等专用软件包。
先决条件
- Python 软件包:
rowan(官方 Python SDK) - 账户:在 https://rowan.chem.ucla.edu/(学术用途)或 https://rowanquantum.com/ 注册免费账户
- API 密钥:创建账户后设置
ROWAN_API_KEY环境变量 - 数据要求:分子结构需为 SMILES 字符串或 XYZ 坐标块
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)
关键参数
| 参数 | 模块 | 默认值 | 范围 / 选项 | 作用 |
|---|---|---|---|---|
method | compute | 必填 | "gfn2-xtb"、"b3lyp"、"wb97x-d"、"mp2" | QC 方法;xTB 速度最快,DFT 精度高,MP2 用于计算相关能 |
basis_set | compute(DFT) | 取决于方法 | "6-31g*"、"6-311+g**"、"def2-svp"、"def2-tzvp" | 基组;基组越大,精度越高、速度越慢 |
tasks | compute | 必填 | ["optimize"]、["single_point"]、["conformers"]、["torsion_scan"] | 要执行的计算 |
n_conformers | conformers 任务 | 10 | 1–100 | 要生成并优化的构象数量 |
n_scan_points | torsion_scan | 36 | 12–72 | 二面角扫描点数(360/n 为步长) |
solvent | compute | None | "water"、"dmso"、"methanol" 等 | 隐式 SMD 溶剂化模型 |
torsion_atoms | torsion_scan | 必填 | 4 个原子索引的列表 | 定义扫描所用的二面角 |
最佳实践
-
使用 GFN2-xTB 进行筛选,使用 DFT 进行最终表征:xTB 比 DFT 快 100–1000 倍,足以用于构象排序和几何结构探索。对于准确的能量、HOMO/LUMO 能隙和可发表的结果,请改用 B3LYP 或 wB97X-D。
-
计算性质前务必优化几何结构:在未弛豫的几何结构上进行单点计算(例如从 SMILES 三维嵌入得到的结构),会导致能量和电子性质不可靠。请先运行
tasks=["optimize"]。 -
为具有生物学相关性的分子设置
solvent:对于带电或高极性分子,气相能量与溶液相能量通常差异很大。在水相条件下评估候选药物时,请使用solvent="water"。 -
轮询长时间 DFT 计算的作业状态:在长时间运行的批处理工作流中,可使用带超时的
client.wait(),或通过client.get_job(job_id).status进行轮询,以避免阻塞。 -
将优化后的几何结构导出为 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— 总电子能量,单位为 Hartreeresult.geometry— 优化后的三维几何结构(原子 + 坐标)result.dipole_moment— 偶极矩标量,单位为 Debyeresult.homo_energy、result.lumo_energy— 前线轨道能量,单位为 eVresult.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 SMILES | SMILES 字符串格式错误 | 提交前使用 RDKit 的 Chem.MolFromSmiles(smiles) 进行验证 |
| 优化后能量较高 | 几何结构陷入局部极小值 | 使用 tasks=["conformers"] 生成多个构象,并选择能量最低的构象 |
缺少 result.homo_energy | 未请求轨道计算 | 将 "orbitals" 添加到 tasks 列表中 |
参考资料
- Rowan 文档 — 官方 SDK 和 API 参考
- Rowan Python SDK(GitHub) — 源代码和示例
- GFN2-xTB 论文:Bannwarth 等人(2019),J. Chem. Theory Comput. — Rowan 使用的 xTB 半经验方法
- B3LYP 泛函参考文献:Becke(1993),J. Chem. Phys. — 奠基性的 DFT 方法