From 096361ed50a10f2f48243819b39965d5d1da0460 Mon Sep 17 00:00:00 2001 From: Loach1703 Date: Tue, 25 Aug 2026 16:37:47 +0800 Subject: [PATCH 1/3] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- UserGuide.md | 220 +++++++++++++++++++++++++++++++++++++++++- src/autoVB/nbo/nbo.py | 2 +- 2 files changed, 217 insertions(+), 5 deletions(-) diff --git a/UserGuide.md b/UserGuide.md index 8dc3ccc..94d170b 100644 --- a/UserGuide.md +++ b/UserGuide.md @@ -232,20 +232,232 @@ autovb{xmo2svg=optimized3d,svgbaseline=2} ##### 2.3.5.1 debug 调试模式,会打印更多输出。 -### 3 脚本提交方法 -配置好环境变量后,你可以直接在终端中传入输入文件运行: +## 3 命令行工具 + +安装 `autoVB` 后,以下命令行工具会通过 Python 包的脚本入口提供。可以在终端中使用 `<命令> --help` 查看对应的帮助信息。除特别说明外,命令都应在包含输入文件的工作目录中运行。 + +### 3.1 `autovb` + +`autovb` 是主程序入口,用于从 `.autovb`、Gaussian `.gjf` 或 XMVB `.xmi` 输入文件开始完整的 autoVB 工作流。它可以执行 NBO/GVB 初猜准备、活性空间选择、XMVB 输入文件生成、XMVB 计算、结果解析和绘图等步骤。 + +```bash +autovb [--mem MEM] [--nproc NPROC] +``` + +参数: + +- ``:输入文件路径。 +- `--mem MEM`:覆盖输入文件中的内存设置,例如 `4GB`、`8G` 或 `4000MB`。 +- `--nproc NPROC`:覆盖输入文件中的并行进程数。 + +例如: + +```bash +autovb C6H6.autovb --mem 8GB --nproc 8 +``` + +#### 3.1.1 作业提交 + +配置好环境变量后,可以直接在终端中运行: + ```bash autovb ``` -如果需要同时指定内存和并行核心数(覆盖文件内 `%mem` 与 `%nprocshared`),可以追加参数: + +也可以通过 `--mem` 和 `--nproc` 覆盖输入文件中的 `%mem` 与 `%nprocshared`: + ```bash autovb --mem 8GB --nproc 8 ``` -注意:不要在登录节点运行计算,请将命令写入作业脚本(SLURM/PBS 等)提交。`examples` 目录下包含 `example_slurm.sh`,你可以根据本地软件路径调整并提交: + +正式计算时不要在登录节点运行,建议将命令写入 SLURM/PBS 等作业脚本中提交。`examples` 目录下包含 `example_slurm.sh`,可根据本地软件路径调整后使用: + ```bash sbatch example_slurm.sh ``` +### 3.2 `autovb_nbo` + +`autovb_nbo` 根据 XYZ 坐标文件生成 Gaussian NBO 输入文件。它只负责生成 `.gjf`,不会自动运行 Gaussian 或 NBO;生成后应检查电荷、自旋和计算设置。 + +```bash +autovb_nbo [-c CHARGE] [-s SPIN | -m MULTIPLICITY] +``` + +参数: + +- ``:输入的 `.xyz` 文件。 +- ``:Gaussian 使用的基组,例如 `6-31g*`。 +- `-c`、`--charge`:体系总电荷,默认值为 `0`。 +- `-s`、`--spin`:自旋数,即未成对电子数,默认值为 `0`。 +- `-m`、`--multiplicity`:自旋多重度,与 `--spin` 二选一,默认值为 `1`。 + +输出文件名为与 XYZ 同名的 `.gjf` 文件。例如: + +```bash +autovb_nbo C6H6.xyz 6-31g* +autovb_nbo radical.xyz 6-31g* --charge 0 --multiplicity 2 +``` + +### 3.3 `autovb_xmi` + +`autovb_xmi` 从已有的 Gaussian `.fch`、`.chk` 文件或不带后缀的文件名生成 XMVB `.xmi` 输入文件。它会使用 NBO 结果选择活性空间,并生成 NBO 轨道初猜。 + +```bash +autovb_xmi [options] +``` + +参数: + +- ``:`.fch`、`.chk` 文件,或可以补全为这些文件的 basename。 +- ``:写入 XMVB 输入文件的基组文本。 +- `-t`、`--threshold`:活性空间选择阈值,默认值为 `1.96`。 +- `-nae`、`--active_electron`:显式指定活性电子数,默认值为 `0`,表示不显式指定。 +- `-nao`、`--active_orbital`:显式指定活性轨道数,默认值为 `0`,表示不显式指定。 +- `-aoa`、`-aat`、`--active_orbital_atom`:指定活性轨道涉及的原子编号,可以传入多个整数。 + +例如: + +```bash +autovb_xmi C6H6.fch 6-31g* +autovb_xmi C6H6.fch 6-31g* -nae 6 -nao 6 +autovb_xmi C6H6.fch 6-31g* -aoa 1 3 5 7 9 11 +``` + +默认输出与输入同名的 `.xmi` 文件。 + +### 3.4 `draw_xmo` + +`draw_xmo` 读取 XMVB 的 `.xmo` 文件,解析价键结构并生成 SVG 图像。它适合直接查看 XMVB 输出中的价键结构。 + +```bash +draw_xmo [options] +``` + +参数: + +- `-w`、`--weight {lowdin,cc}`:选择用于排序和绘图的权重表,默认值为 `lowdin`。 +- `-m`、`--max-structures {N,all}`:最多绘制的结构数,默认值为 `20`;使用 `all` 绘制全部结构。 +- `--baseline-index N`:指定用于确定初始电子分布的结构编号,默认使用最高权重结构。 +- `--charge CHARGE`:RDKit 判断键级时使用的总电荷,默认值为 `0`。 +- `--show-hydrogens`:显示氢原子;默认隐藏氢原子。 +- `--write-individual-svgs`:除网格图外,为每个价键结构单独写出 SVG。 +- `-n`、`--structures-per-row N`:网格图每行的结构数,默认值为 `2`。 +- `--hide-atom-labels`:隐藏原子编号。 +- `--hide-lone-pairs`:隐藏孤对电子标记。 + +例如: + +```bash +draw_xmo C6H6_vb.xmo --max-structures 5 --show-hydrogens +``` + +### 3.5 `xmo2svg` + +`xmo2svg` 也是将 `.xmo` 转换为 SVG 的工具,但它使用 `.xmo` 中 `$orb` 部分的原子标签建立分子连接关系。对于过渡态、多个分子片段或需要保留 `$orb` 成键关系的体系,通常优先使用该工具。 + +```bash +xmo2svg [options] +``` + +参数: + +- `-w`、`--weight {lowdin,cc,both}`:选择显示的权重,默认值为 `lowdin`;`both` 同时显示 CC 和 Lowdin 权重。 +- `-m`、`--max-structures {N,all}`:最多绘制的结构数,默认值为 `20`;使用 `all` 绘制全部结构。 +- `--baseline-index N`:指定基准结构编号,默认使用最高权重结构。 +- `--charge CHARGE`:RDKit 判断键级时使用的总电荷,默认值为 `0`。 +- `--projection {rdkit,pca,optimized3d,contact}`:选择原子排布方式,默认值为 `rdkit`。`pca` 和 `optimized3d` 使用输入三维坐标投影,`contact` 适合包含多个分子片段的体系。 +- `--show-hydrogens`:显示氢原子;默认隐藏氢原子。 +- `--no-condensed-hydrogens`:关闭杂原子或孤立碳的紧凑氢原子显示。 +- `--write-individual-svgs`:除网格图外,为每个价键结构单独写出 SVG。 +- `-n`、`--structures-per-row N`:网格图每行的结构数,默认值为 `2`。 +- `--hide-atom-labels`:隐藏原子编号。 +- `--hide-connection-labels`:隐藏结构权重后面的成键原子对和自由基标记。 +- `--hide-lone-pairs`:隐藏孤对电子标记。 + +例如: + +```bash +xmo2svg R24_vb.xmo --projection optimized3d --weight both +xmo2svg mens_vb.xmo --projection contact --hide-connection-labels +``` + +输出 SVG 文件与 `.xmo` 文件同名,扩展名为 `.svg`;使用 `--write-individual-svgs` 时还会输出各结构对应的单独 SVG 文件。 + +### 3.6 `fch2vb` + +`fch2vb` 调用 MOKIT 的 `fch2inp` 将 Gaussian `.fch` 转换为 GAMESS `.inp`,读取其中的轨道信息,并生成只包含初猜轨道和分子坐标的最小 XMVB `.xmi` 文件。该工具不进行活性空间选择,生成的活性电子数和活性轨道数均为 `0`,轨道类型为 `oeo`。 + +```bash +fch2vb [-o OUTPUT] [--basis BASIS] [--norb N] +``` + +参数: + +- ``:Gaussian formatted checkpoint 文件。 +- `-o`、`--output`:输出 `.xmi` 路径,默认与 `.fch` 同名。 +- `--basis`:写入 XMVB `$ctrl` 的基组文本,默认为空。 +- `--norb`:写入初猜的轨道数,默认取占据轨道数,通常为电子数除以 2。 + +例如: + +```bash +fch2vb C4H6.fch --basis cc-pVDZ --norb 15 -o C4H6_guess.xmi +``` + +### 3.7 `xmo2json` + +`xmo2json` 读取 XMVB `.xmo` 文件并生成 JSON 摘要。摘要包含分子信息、`orb` 部分、能量、收敛状态、价键结构和结构权重等结果,便于后续批量统计和数据集处理。 + +```bash +xmo2json [-o OUTPUT] +``` + +参数: + +- ``:输入的 XMVB `.xmo` 文件。 +- `-o`、`--output`:输出 JSON 路径,默认与 `.xmo` 同名,扩展名为 `.json`。 + +例如: + +```bash +xmo2json C6H6_vb.xmo +xmo2json C6H6_vb.xmo -o results/C6H6.json +``` + +### 3.8 `xmo2xmi` + +`xmo2xmi` 读取 `.xmi` 文件,并用同目录下与其同名的 `.orb` 文件替换 XMVB 初猜轨道;其余输入内容保持不变。该工具适用于用一次 XMVB 计算生成的 `.orb` 作为下一次计算初猜的情况。 + +```bash +xmo2xmi [-o OUTPUT] [--method METHOD] [--iscf {2,5,6}] +``` + +参数: + +- ``:输入的 XMVB `.xmi` 文件,同时需要存在同名 `.orb` 文件。 +- `-o`、`--output`:输出 `.xmi` 路径,默认命名为 `<原文件名>_new.xmi`。 +- `--method METHOD`:替换 `$ctrl` 中的计算方法,例如 `vbpt2` 或 `bovb`;默认不修改方法。 +- `--iscf {2,5,6}`:替换 `$ctrl` 中的 `iscf`;默认不修改 `iscf`。 + +例如: + +```bash +xmo2xmi C6H6_vb.xmi +xmo2xmi C6H6_vb.xmi --method bovb --iscf 5 -o C6H6_bovb.xmi +``` + +### 3.10 命令选择建议 + +- 从分子坐标开始进行完整自动计算:使用 `autovb`。 +- 只生成 Gaussian NBO 输入文件:使用 `autovb_nbo`。 +- 已有 `.fch`/`.chk`,只想生成 XMVB `.xmi`:使用 `autovb_xmi`。 +- 已有 `.fch`,只想转换为最小 XMVB 初猜:使用 `fch2vb`。 +- 已有 `.xmo`,需要按普通分子结构绘图:使用 `draw_xmo`。 +- 已有 `.xmo`,需要按 `$orb` 标签或三维投影绘图:使用 `xmo2svg`。 +- 已有 `.xmo`,需要批量提取结果:使用 `xmo2json`。 +- 需要用 `.orb` 替换 `.xmi` 初猜:使用 `xmo2xmi`。 + ## 4 示例 ### 4.1 苯分子的自动计算 diff --git a/src/autoVB/nbo/nbo.py b/src/autoVB/nbo/nbo.py index d71613d..51e8ead 100644 --- a/src/autoVB/nbo/nbo.py +++ b/src/autoVB/nbo/nbo.py @@ -1254,7 +1254,7 @@ def get_xmidata(self) -> 'XMIData': # 生成XMIData对象 from ..io.writers import XMIData xmidata = XMIData( - molecule_name=self.filename, + molecule_name=self.origin_filename, method=method, stru_type=stru_type, int_type=vbsetting.inte, From d7f677c6aa97b77e8f2f3649b440a72c60dd575c Mon Sep 17 00:00:00 2001 From: Loach1703 Date: Tue, 25 Aug 2026 19:31:33 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=E9=87=8D=E6=9E=84=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E8=A1=8C=E5=B7=A5=E5=85=B7=E5=B9=B6=E7=BB=9F=E4=B8=80?= =?UTF-8?q?XMO=E7=BB=98=E5=9B=BE=E5=85=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- UserGuide.md | 88 ++++---- pyproject.toml | 7 +- src/autoVB/cli/draw_xmo.py | 201 +----------------- src/autoVB/cli/nbo.py | 2 +- src/autoVB/cli/xmi.py | 2 +- src/autoVB/cli/xmo2svg.py | 130 ++++------- .../draw_xmo/xmo_drawer_input_converter.py | 25 ++- src/autoVB/io/readers.py | 14 +- src/autoVB/main.py | 86 +------- src/autoVB/vbkit/xmo2svg.py | 156 ++++++++++++++ 10 files changed, 283 insertions(+), 428 deletions(-) create mode 100644 src/autoVB/vbkit/xmo2svg.py diff --git a/UserGuide.md b/UserGuide.md index 94d170b..86a1a46 100644 --- a/UserGuide.md +++ b/UserGuide.md @@ -188,10 +188,10 @@ opt参数,暂未实现 #### 2.3.4 绘图相关 ##### 2.3.4.1 draw_xmo -调用 `draw_xmo` 工具,对 `.xmo` 文件进行解析,生成分子价键结构 `.svg` 图像文件。画出的分子构型仅供参考,可能存在错误。 +`draw_xmo` 是 `xmo2svg` 的别名。必须指定与 `xmo2svg` 相同的投影值,例如 `autovb{draw_xmo=optimized3d}` 等价于 `autovb{xmo2svg=optimized3d}`。画出的分子构型仅供参考,可能存在错误。 ##### 2.3.4.2 xmo2svg -在 XMVB 计算结束后解析 `.xmo` 文件,并生成与 `.xmo` 文件同名的价键结构 `.svg` 图像。使用格式为 `autovb{xmo2svg=投影方式}`。支持以下选项: +在 XMVB 计算结束后解析 `.xmo` 文件,并生成与 `.xmo` 文件同名的价键结构 `.svg` 图像。使用格式为 `autovb{xmo2svg=投影方式}`。`xmo2svg` 是统一的绘图参数,支持以下选项: **不设置(默认值为 `None`)**:不生成 `.svg` 图像。 @@ -211,7 +211,7 @@ autovb{xmo2svg=rdkit,hide_svg_labels} ``` ##### 2.3.4.4 svgweight -选择 `xmo2svg` 图中显示的结构权重,可设为 `cc`、`lowdin` 或 `both`,默认值为 `both`。当设置为 `both` 时,CC 权重和 Lowdin 权重分两行显示,结构仍按 Lowdin 权重选择和排序。例如: +选择 `xmo2svg` 图中显示和排序的结构权重,可设为 `cc`、`lowdin`、`inverse`、`renormalized` 或 `both`,默认值为 `both`。当设置为 `both` 时,CC 权重和 Lowdin 权重分两行显示,结构仍按 Lowdin 权重选择和排序。例如: ```text autovb{xmo2svg=optimized3d,svgweight=both} @@ -276,12 +276,12 @@ autovb --mem 8GB --nproc 8 sbatch example_slurm.sh ``` -### 3.2 `autovb_nbo` +### 3.2 `xyz2nbo` -`autovb_nbo` 根据 XYZ 坐标文件生成 Gaussian NBO 输入文件。它只负责生成 `.gjf`,不会自动运行 Gaussian 或 NBO;生成后应检查电荷、自旋和计算设置。 +`xyz2nbo` 根据 XYZ 坐标文件生成 Gaussian NBO 输入文件。它只负责生成 `.gjf`,不会自动运行 Gaussian 或 NBO;生成后应检查电荷、自旋和计算设置。 ```bash -autovb_nbo [-c CHARGE] [-s SPIN | -m MULTIPLICITY] +xyz2nbo [-c CHARGE] [-s SPIN | -m MULTIPLICITY] ``` 参数: @@ -295,16 +295,16 @@ autovb_nbo [-c CHARGE] [-s SPIN | -m MULTIPLICITY] 输出文件名为与 XYZ 同名的 `.gjf` 文件。例如: ```bash -autovb_nbo C6H6.xyz 6-31g* -autovb_nbo radical.xyz 6-31g* --charge 0 --multiplicity 2 +xyz2nbo C6H6.xyz 6-31g* +xyz2nbo radical.xyz 6-31g* --charge 0 --multiplicity 2 ``` -### 3.3 `autovb_xmi` +### 3.3 `nbo2xmi` -`autovb_xmi` 从已有的 Gaussian `.fch`、`.chk` 文件或不带后缀的文件名生成 XMVB `.xmi` 输入文件。它会使用 NBO 结果选择活性空间,并生成 NBO 轨道初猜。 +`nbo2xmi` 从已有的 Gaussian `.fch`、`.chk` 文件或不带后缀的文件名生成 XMVB `.xmi` 输入文件。它会使用 NBO 结果选择活性空间,并生成 NBO 轨道初猜。 ```bash -autovb_xmi [options] +nbo2xmi [options] ``` 参数: @@ -319,50 +319,25 @@ autovb_xmi [options] 例如: ```bash -autovb_xmi C6H6.fch 6-31g* -autovb_xmi C6H6.fch 6-31g* -nae 6 -nao 6 -autovb_xmi C6H6.fch 6-31g* -aoa 1 3 5 7 9 11 +nbo2xmi C6H6.fch 6-31g* +nbo2xmi C6H6.fch 6-31g* -nae 6 -nao 6 +nbo2xmi C6H6.fch 6-31g* -aoa 1 3 5 7 9 11 ``` 默认输出与输入同名的 `.xmi` 文件。 -### 3.4 `draw_xmo` +### 3.4 `xmo2svg` -`draw_xmo` 读取 XMVB 的 `.xmo` 文件,解析价键结构并生成 SVG 图像。它适合直接查看 XMVB 输出中的价键结构。 +`xmo2svg` 读取 XMVB 的 `.xmo` 文件并生成 SVG 图像。通过 `--connectivity` 选择分子连接关系:默认使用 `.xmo` 中 `$orb` 部分的原子标签,适合过渡态、多个分子片段或需要保留 `$orb` 成键关系的体系;设置为 `rdkit` 时使用 RDKit 推断普通分子键连关系。 ```bash -draw_xmo [options] +xmo2svg [--connectivity {orb,rdkit}] [options] ``` 参数: -- `-w`、`--weight {lowdin,cc}`:选择用于排序和绘图的权重表,默认值为 `lowdin`。 -- `-m`、`--max-structures {N,all}`:最多绘制的结构数,默认值为 `20`;使用 `all` 绘制全部结构。 -- `--baseline-index N`:指定用于确定初始电子分布的结构编号,默认使用最高权重结构。 -- `--charge CHARGE`:RDKit 判断键级时使用的总电荷,默认值为 `0`。 -- `--show-hydrogens`:显示氢原子;默认隐藏氢原子。 -- `--write-individual-svgs`:除网格图外,为每个价键结构单独写出 SVG。 -- `-n`、`--structures-per-row N`:网格图每行的结构数,默认值为 `2`。 -- `--hide-atom-labels`:隐藏原子编号。 -- `--hide-lone-pairs`:隐藏孤对电子标记。 - -例如: - -```bash -draw_xmo C6H6_vb.xmo --max-structures 5 --show-hydrogens -``` - -### 3.5 `xmo2svg` - -`xmo2svg` 也是将 `.xmo` 转换为 SVG 的工具,但它使用 `.xmo` 中 `$orb` 部分的原子标签建立分子连接关系。对于过渡态、多个分子片段或需要保留 `$orb` 成键关系的体系,通常优先使用该工具。 - -```bash -xmo2svg [options] -``` - -参数: - -- `-w`、`--weight {lowdin,cc,both}`:选择显示的权重,默认值为 `lowdin`;`both` 同时显示 CC 和 Lowdin 权重。 +- `--connectivity {orb,rdkit}`:选择连接关系来源,默认值为 `orb`。`orb` 使用 `$orb` 标签,`rdkit` 使用 RDKit 键连推断。 +- `-w`、`--weight {lowdin,cc,inverse,renormalized,both}`:选择显示和排序的权重,默认值为 `lowdin`;`both` 同时显示 CC 和 Lowdin 权重。 - `-m`、`--max-structures {N,all}`:最多绘制的结构数,默认值为 `20`;使用 `all` 绘制全部结构。 - `--baseline-index N`:指定基准结构编号,默认使用最高权重结构。 - `--charge CHARGE`:RDKit 判断键级时使用的总电荷,默认值为 `0`。 @@ -378,18 +353,28 @@ xmo2svg [options] 例如: ```bash +xmo2svg C6H6_vb.xmo --connectivity rdkit xmo2svg R24_vb.xmo --projection optimized3d --weight both xmo2svg mens_vb.xmo --projection contact --hide-connection-labels ``` 输出 SVG 文件与 `.xmo` 文件同名,扩展名为 `.svg`;使用 `--write-individual-svgs` 时还会输出各结构对应的单独 SVG 文件。 -### 3.6 `fch2vb` +`draw_xmo` 是 `xmo2svg` 的别名,所有参数、默认值、连接模式和输出文件名均完全一致: + +```bash +draw_xmo [options] +``` + +### 3.5 `fch2vb` `fch2vb` 调用 MOKIT 的 `fch2inp` 将 Gaussian `.fch` 转换为 GAMESS `.inp`,读取其中的轨道信息,并生成只包含初猜轨道和分子坐标的最小 XMVB `.xmi` 文件。该工具不进行活性空间选择,生成的活性电子数和活性轨道数均为 `0`,轨道类型为 `oeo`。 +`fch2xmi` 是 `fch2vb` 的同功能别名。 + ```bash fch2vb [-o OUTPUT] [--basis BASIS] [--norb N] +fch2xmi [-o OUTPUT] [--basis BASIS] [--norb N] ``` 参数: @@ -405,7 +390,7 @@ fch2vb [-o OUTPUT] [--basis BASIS] [--norb N] fch2vb C4H6.fch --basis cc-pVDZ --norb 15 -o C4H6_guess.xmi ``` -### 3.7 `xmo2json` +### 3.6 `xmo2json` `xmo2json` 读取 XMVB `.xmo` 文件并生成 JSON 摘要。摘要包含分子信息、`orb` 部分、能量、收敛状态、价键结构和结构权重等结果,便于后续批量统计和数据集处理。 @@ -425,7 +410,7 @@ xmo2json C6H6_vb.xmo xmo2json C6H6_vb.xmo -o results/C6H6.json ``` -### 3.8 `xmo2xmi` +### 3.7 `xmo2xmi` `xmo2xmi` 读取 `.xmi` 文件,并用同目录下与其同名的 `.orb` 文件替换 XMVB 初猜轨道;其余输入内容保持不变。该工具适用于用一次 XMVB 计算生成的 `.orb` 作为下一次计算初猜的情况。 @@ -447,14 +432,13 @@ xmo2xmi C6H6_vb.xmi xmo2xmi C6H6_vb.xmi --method bovb --iscf 5 -o C6H6_bovb.xmi ``` -### 3.10 命令选择建议 +### 3.8 命令选择建议 - 从分子坐标开始进行完整自动计算:使用 `autovb`。 -- 只生成 Gaussian NBO 输入文件:使用 `autovb_nbo`。 -- 已有 `.fch`/`.chk`,只想生成 XMVB `.xmi`:使用 `autovb_xmi`。 +- 只生成 Gaussian NBO 输入文件:使用 `xyz2nbo`。 +- 已有 `.fch`/`.chk`,只想生成 XMVB `.xmi`:使用 `nbo2xmi`。 - 已有 `.fch`,只想转换为最小 XMVB 初猜:使用 `fch2vb`。 -- 已有 `.xmo`,需要按普通分子结构绘图:使用 `draw_xmo`。 -- 已有 `.xmo`,需要按 `$orb` 标签或三维投影绘图:使用 `xmo2svg`。 +- 已有 `.xmo`,需要绘图:使用 `xmo2svg`。 - 已有 `.xmo`,需要批量提取结果:使用 `xmo2json`。 - 需要用 `.orb` 替换 `.xmi` 初猜:使用 `xmo2xmi`。 diff --git a/pyproject.toml b/pyproject.toml index 3ecd06b..4462c9d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,12 +17,13 @@ dependencies = [ ] [project.scripts] -autovb_nbo = "autoVB.cli.nbo:autovb_nbo" -autovb_xmi = "autoVB.cli.xmi:autovb_xmi" +xyz2nbo = "autoVB.cli.nbo:autovb_nbo" +nbo2xmi = "autoVB.cli.xmi:autovb_xmi" autovb = "autoVB.cli.autovb:autovb_main" autovb_test = "autoVB.cli.autovb_test:autovb_test" -draw_xmo = "autoVB.cli.draw_xmo:draw_xmo" +draw_xmo = "autoVB.cli.xmo2svg:xmo2svg" fch2vb = "autoVB.cli.fch2vb:fch2vb" +fch2xmi = "autoVB.cli.fch2vb:fch2vb" xmo2json = "autoVB.cli.xmo2json:xmo2json" xmo2xmi = "autoVB.cli.xmo2xmi:xmo2xmi" xmo2svg = "autoVB.cli.xmo2svg:xmo2svg" diff --git a/src/autoVB/cli/draw_xmo.py b/src/autoVB/cli/draw_xmo.py index edf55f9..b8accb0 100644 --- a/src/autoVB/cli/draw_xmo.py +++ b/src/autoVB/cli/draw_xmo.py @@ -1,196 +1,9 @@ -import argparse -from pathlib import Path -import sys +"""Backward-compatible alias for :mod:`autoVB.cli.xmo2svg`.""" -DEFAULT_XMO_MAX_STRUCTURES = 20 -DEFAULT_XMO_WEIGHT_TABLE = "lowdin" -DEFAULT_XMO_ACTIVE_SPACE_COLOR = "#B00000" -DEFAULT_XMO_ACTIVE_SPACE_WIDTH = 3.0 -DEFAULT_XMO_STRUCTURES_PER_ROW = 2 +from .xmo2svg import ( + parse_draw_xmo_max_structures, + parse_draw_xmo_structures_per_row, + xmo2svg, +) - -def parse_draw_xmo_max_structures(value: str) -> int | None: - normalized_value = value.strip().lower() - if normalized_value == "all": - return None - - try: - max_structures = int(normalized_value) - except ValueError as exc: - raise argparse.ArgumentTypeError( - "--max-structures must be a positive integer or 'all'." - ) from exc - if max_structures <= 0: - raise argparse.ArgumentTypeError( - "--max-structures must be a positive integer or 'all'." - ) - return max_structures - - -def parse_draw_xmo_structures_per_row(value: str) -> int: - try: - structures_per_row = int(value) - except ValueError as exc: - raise argparse.ArgumentTypeError( - "--structures-per-row must be a positive integer." - ) from exc - if structures_per_row <= 0: - raise argparse.ArgumentTypeError( - "--structures-per-row must be a positive integer." - ) - return structures_per_row - - -def draw_xmo_file( - xmo_file: str | Path, - *, - weight_table: str = DEFAULT_XMO_WEIGHT_TABLE, - max_structures: int | None = DEFAULT_XMO_MAX_STRUCTURES, - baseline_index: int | None = None, - charge: int = 0, - hide_hydrogens: bool = True, - write_individual_svgs: bool = False, - show_atom_labels: bool = True, - show_lone_pairs: bool = True, - structures_per_row: int = DEFAULT_XMO_STRUCTURES_PER_ROW, -): - from ..draw_xmo.molecule_bond_variant_drawer import MoleculeBondVariantDrawer - from ..draw_xmo.xmo_drawer_input_converter import XmoToDrawerInputConverter - from ..io.xmo_output_parser import XmoParser - from ..utils import constants - - print(f'Draw_XMO version: {constants.VERSION}') - xmo_path = Path(xmo_file) - if not xmo_path.exists(): - raise FileNotFoundError(f"XMO file not found: {xmo_path}") - if not xmo_path.is_file(): - raise ValueError(f"XMO path is not a file: {xmo_path}") - - output_dir = xmo_path.parent - parsed_data = XmoParser(xmo_path).parse() - converter = XmoToDrawerInputConverter( - parsed_data, - output_dir, - hide_hydrogens=hide_hydrogens, - max_structures=max_structures, - baseline_index=baseline_index, - weight_table=weight_table, - ) - drawer_input = converter.convert() - hide_hydrogens = converter.hide_hydrogens - - drawer = MoleculeBondVariantDrawer( - xyz_file=drawer_input.xyz_file, - output_dir=output_dir, - charge=charge, - active_bond_atom=drawer_input.active_bond_atom, - active_space=drawer_input.active_space, - baseline_unpaired_atoms=drawer_input.baseline_unpaired_atoms, - active_space_color=DEFAULT_XMO_ACTIVE_SPACE_COLOR, - active_space_width=DEFAULT_XMO_ACTIVE_SPACE_WIDTH, - color_active_space=True, - show_atom_labels=show_atom_labels, - hide_hydrogens=hide_hydrogens, - show_lone_pairs=show_lone_pairs, - write_individual_svgs=write_individual_svgs, - structures_per_row=structures_per_row, - ) - result = drawer.draw() - - print(f"Read XMO from: {parsed_data.source_file.resolve()}") - print(f"Generated XYZ: {drawer_input.xyz_file.resolve()}") - print(f"Active orbital -> atom: {drawer_input.orbital_to_atom}") - print(f"Weight table: {drawer_input.weight_table}") - print(f"active_bond_atom: {drawer_input.active_bond_atom}") - print(f"Bond perception mode: {drawer.bond_perception_mode}") - print(f"Drawn structures: {len(drawer_input.active_space)}") - print(f"Output directory: {result.output_dir.resolve()}") - for out_file in result.written_files: - print(f" - {out_file.name}") - - return result - - -def draw_xmo(argv=None) -> int: - parser = argparse.ArgumentParser( - prog="draw_xmo", - description="Read an XMO file and generate valence-bond SVG files in the same directory.", - ) - parser.add_argument("xmo_file", help="input .xmo file") - parser.add_argument( - "--weight", - "-w", - choices=("lowdin", "cc"), - default=DEFAULT_XMO_WEIGHT_TABLE, - help=f"weight table to use, default: {DEFAULT_XMO_WEIGHT_TABLE}", - ) - parser.add_argument( - "--max-structures", - "-m", - type=parse_draw_xmo_max_structures, - default=DEFAULT_XMO_MAX_STRUCTURES, - help=( - "maximum number of highest-weight structures to draw; " - f"use all to draw every structure, default: {DEFAULT_XMO_MAX_STRUCTURES}" - ), - ) - parser.add_argument( - "--baseline-index", - type=int, - default=None, - help=( - "structure index used as the initial electron distribution; " - "the highest-weight structure is used by default" - ), - ) - parser.add_argument( - "--charge", - type=int, - default=0, - help="total charge used by RDKit when perceiving bonds from XYZ, default: 0", - ) - parser.add_argument( - "--show-hydrogens", - action="store_true", - help="show hydrogen atoms; hydrogens are hidden by default", - ) - parser.add_argument( - "--write-individual-svgs", - action="store_true", - help="write one SVG per structure in addition to the grid SVG", - ) - parser.add_argument( - "--structures-per-row", - "-n", - type=parse_draw_xmo_structures_per_row, - default=DEFAULT_XMO_STRUCTURES_PER_ROW, - help=( - "number of structures per row in the grid SVG, " - f"default: {DEFAULT_XMO_STRUCTURES_PER_ROW}" - ), - ) - parser.add_argument( - "--hide-atom-labels", - action="store_true", - help="hide atom-number labels", - ) - parser.add_argument( - "--hide-lone-pairs", - action="store_true", - help="hide lone-pair dots", - ) - args = parser.parse_args(argv) - - draw_xmo_file( - args.xmo_file, - weight_table=args.weight, - max_structures=args.max_structures, - baseline_index=args.baseline_index, - charge=args.charge, - hide_hydrogens=not args.show_hydrogens, - write_individual_svgs=args.write_individual_svgs, - show_atom_labels=not args.hide_atom_labels, - show_lone_pairs=not args.hide_lone_pairs, - structures_per_row=args.structures_per_row, - ) - return 0 +draw_xmo = xmo2svg diff --git a/src/autoVB/cli/nbo.py b/src/autoVB/cli/nbo.py index c4addbb..6ac665e 100644 --- a/src/autoVB/cli/nbo.py +++ b/src/autoVB/cli/nbo.py @@ -21,7 +21,7 @@ def autovb_nbo_impl(xyz: Path, basis: str, charge: int, spin: int) -> int: def autovb_nbo(argv=None): - parser = argparse.ArgumentParser(prog="autovb-nbo", description="Generate Gaussian NBO .gjf from .xyz") + parser = argparse.ArgumentParser(prog="xyz2nbo", description="Generate Gaussian NBO .gjf from .xyz") parser.add_argument("xyz", type=Path, help="input .xyz file") parser.add_argument("basis", help="basis set for gjf") parser.add_argument("-c", "--charge", type=int, default=0) diff --git a/src/autoVB/cli/xmi.py b/src/autoVB/cli/xmi.py index 237e292..a7396ca 100644 --- a/src/autoVB/cli/xmi.py +++ b/src/autoVB/cli/xmi.py @@ -32,7 +32,7 @@ def autovb_xmi_impl(name: str, mol: gto.Mole, input_data: autoVBInputData) -> in def autovb_xmi(argv=None): - parser = argparse.ArgumentParser(prog="autovb-xmi", description="Generate XMVB .xmi from .fch/.chk or basename") + parser = argparse.ArgumentParser(prog="nbo2xmi", description="Generate XMVB .xmi from .fch/.chk or basename") parser.add_argument("file", type=Path, help="NBO output .fch/.chk file or basename (without extension)") parser.add_argument("basis", help="basis set override for xmi header") parser.add_argument("--threshold", "-t", type=float, default=1.96, help="threshold for selecting important structures based on cc weight, default 1.96 (corresponding to 95%% cumulative weight)") diff --git a/src/autoVB/cli/xmo2svg.py b/src/autoVB/cli/xmo2svg.py index b02b1ef..2fe5a34 100644 --- a/src/autoVB/cli/xmo2svg.py +++ b/src/autoVB/cli/xmo2svg.py @@ -1,103 +1,47 @@ import argparse from pathlib import Path -from .draw_xmo import ( +from ..vbkit.xmo2svg import ( DEFAULT_XMO_ACTIVE_SPACE_COLOR, DEFAULT_XMO_ACTIVE_SPACE_WIDTH, DEFAULT_XMO_MAX_STRUCTURES, DEFAULT_XMO_STRUCTURES_PER_ROW, DEFAULT_XMO_WEIGHT_TABLE, - parse_draw_xmo_max_structures, - parse_draw_xmo_structures_per_row, + xmo2svg_file, + xmo2svg_report_lines, ) -def xmo2svg_file( - xmo_file: str | Path, - *, - weight_table: str = DEFAULT_XMO_WEIGHT_TABLE, - max_structures: int | None = DEFAULT_XMO_MAX_STRUCTURES, - baseline_index: int | None = None, - charge: int = 0, - hide_hydrogens: bool = True, - write_individual_svgs: bool = False, - show_atom_labels: bool = True, - show_lone_pairs: bool = True, - structures_per_row: int = DEFAULT_XMO_STRUCTURES_PER_ROW, - projection: str = "rdkit", - condense_hydrogens: bool = True, - show_connection_labels: bool = True, -): - """使用 XMO ``$orb`` 标签建立键连并生成价键结构 SVG。""" - from ..draw_xmo.orbital_connectivity_molecule_drawer import ( - OrbitalConnectivityMoleculeDrawer, - ) - from ..draw_xmo.xmo_drawer_input_converter import XmoToDrawerInputConverter - from ..io.xmo_output_parser import XmoParser - from ..utils import constants - - print(f"XMO2SVG version: {constants.VERSION}") - xmo_path = Path(xmo_file) - if not xmo_path.exists(): - raise FileNotFoundError(f"XMO file not found: {xmo_path}") - if not xmo_path.is_file(): - raise ValueError(f"XMO path is not a file: {xmo_path}") +def parse_draw_xmo_max_structures(value: str) -> int | None: + normalized_value = value.strip().lower() + if normalized_value == "all": + return None - output_dir = xmo_path.parent - parsed_data = XmoParser(xmo_path).parse() - converter = XmoToDrawerInputConverter( - parsed_data, - output_dir, - hide_hydrogens=hide_hydrogens, - max_structures=max_structures, - baseline_index=baseline_index, - weight_table=weight_table, - show_connection_labels=show_connection_labels, - ) - drawer_input = converter.convert() - hide_hydrogens = converter.hide_hydrogens + try: + max_structures = int(normalized_value) + except ValueError as exc: + raise argparse.ArgumentTypeError( + "--max-structures must be a positive integer or 'all'." + ) from exc + if max_structures <= 0: + raise argparse.ArgumentTypeError( + "--max-structures must be a positive integer or 'all'." + ) + return max_structures - drawer = OrbitalConnectivityMoleculeDrawer( - xyz_file=drawer_input.xyz_file, - output_dir=output_dir, - charge=charge, - orbital_atom_rows=parsed_data.orb, - active_bond_atom=drawer_input.active_bond_atom, - active_space=drawer_input.active_space, - baseline_unpaired_atoms=drawer_input.baseline_unpaired_atoms, - active_space_color=DEFAULT_XMO_ACTIVE_SPACE_COLOR, - active_space_width=DEFAULT_XMO_ACTIVE_SPACE_WIDTH, - color_active_space=True, - show_atom_labels=show_atom_labels, - hide_hydrogens=hide_hydrogens, - show_lone_pairs=show_lone_pairs, - write_individual_svgs=write_individual_svgs, - structures_per_row=structures_per_row, - projection=projection, - condense_hydrogens=condense_hydrogens, - ) - result = drawer.draw() - grid_path = output_dir / f"{xmo_path.stem}_grid.svg" - output_path = output_dir / f"{xmo_path.stem}.svg" - grid_path.replace(output_path) - result.written_files = [ - output_path if written_file == grid_path else written_file - for written_file in result.written_files - ] - print(f"Read XMO from: {parsed_data.source_file.resolve()}") - print(f"Generated XYZ: {drawer_input.xyz_file.resolve()}") - print(f"Active orbital -> atom: {drawer_input.orbital_to_atom}") - print(f"Weight table: {drawer_input.weight_table}") - print(f"active_bond_atom: {drawer_input.active_bond_atom}") - print(f"Connectivity source: $orb") - print(f"Projection: {projection}") - print(f"Drawn structures: {len(drawer_input.active_space)}") - print(f"Output directory: {result.output_dir.resolve()}") - for out_file in result.written_files: - print(f" - {out_file.name}") - - return result +def parse_draw_xmo_structures_per_row(value: str) -> int: + try: + structures_per_row = int(value) + except ValueError as exc: + raise argparse.ArgumentTypeError( + "--structures-per-row must be a positive integer." + ) from exc + if structures_per_row <= 0: + raise argparse.ArgumentTypeError( + "--structures-per-row must be a positive integer." + ) + return structures_per_row def xmo2svg(argv=None) -> int: @@ -109,10 +53,16 @@ def xmo2svg(argv=None) -> int: ), ) parser.add_argument("xmo_file", help="input .xmo file") + parser.add_argument( + "--connectivity", + choices=("orb", "rdkit"), + default="orb", + help="connectivity source: $orb labels or RDKit bond perception, default: orb", + ) parser.add_argument( "--weight", "-w", - choices=("lowdin", "cc", "both"), + choices=("lowdin", "cc", "inverse", "renormalized", "both"), default=DEFAULT_XMO_WEIGHT_TABLE, help=( "weight table to display; both uses Lowdin weights for selection " @@ -193,8 +143,9 @@ def xmo2svg(argv=None) -> int: ) args = parser.parse_args(argv) - xmo2svg_file( + result = xmo2svg_file( args.xmo_file, + connectivity=args.connectivity, weight_table=args.weight, max_structures=args.max_structures, baseline_index=args.baseline_index, @@ -208,6 +159,9 @@ def xmo2svg(argv=None) -> int: condense_hydrogens=args.condense_hydrogens, show_connection_labels=not args.hide_connection_labels, ) + if result is not None: + for line in xmo2svg_report_lines(result): + print(line) return 0 diff --git a/src/autoVB/draw_xmo/xmo_drawer_input_converter.py b/src/autoVB/draw_xmo/xmo_drawer_input_converter.py index beb6f2d..2727f69 100644 --- a/src/autoVB/draw_xmo/xmo_drawer_input_converter.py +++ b/src/autoVB/draw_xmo/xmo_drawer_input_converter.py @@ -18,7 +18,8 @@ class XmoDrawerInput: baseline_unpaired_atoms: 基准价键结构中的未成对电子原子。 active_space: 需要绘制的价键结构列表。 orbital_to_atom: XMVb 活性轨道编号到绘图原子编号的映射。 - weight_table: 当前使用的权重表,取值为 `"cc"`、`"lowdin"` 或 `"both"`。 + weight_table: 当前使用的权重表,取值为 `"cc"`、`"lowdin"`、 + `"inverse"`、`"renormalized"` 或 `"both"`。 """ xyz_file: Path @@ -54,9 +55,8 @@ def __init__( max_structures: 最多转换多少个 CC 结构;`None` 表示转换全部。 baseline_index: 作为初始电子排布基准的权重序号;`None` 表示使用 当前权重表中权重最大的结构。 - weight_table: 使用哪一种权重表,`"cc"` 表示 `WEIGHTS OF STRUCTURES`, - `"lowdin"` 表示 `Lowdin Weights`,`"both"` 同时显示两者并按 - Lowdin 权重选择结构。 + weight_table: 使用哪一种权重表。`"both"` 同时显示 CC 和 Lowdin, + 并按 Lowdin 权重选择结构。 show_connection_labels: 是否在图例中显示成键原子对和自由基位置。 """ self.parsed_data = parsed_data @@ -221,9 +221,9 @@ def _weights(self) -> list[XmoStructureWeight]: Returns: CC 权重或 Lowdin 权重列表;`both` 模式返回 Lowdin 权重列表。 """ - if self.weight_table in {"lowdin", "both"}: + if self.weight_table == "both": return self.parsed_data.lowdin_weights - return self.parsed_data.cc_weights + return getattr(self.parsed_data, f"{self.weight_table}_weights") @staticmethod def _normalize_weight_table(weight_table: str) -> str: @@ -236,13 +236,13 @@ def _normalize_weight_table(weight_table: str) -> str: 标准化后的权重表名称。 Raises: - ValueError: 权重表名称不是 `"cc"`、`"lowdin"` 或 `"both"`。 + ValueError: 权重表名称不受支持。 """ normalized_name = weight_table.strip().lower() - if normalized_name in {"cc", "lowdin", "both"}: + if normalized_name in {"cc", "lowdin", "inverse", "renormalized", "both"}: return normalized_name raise ValueError( - "weight_table must be 'cc', 'lowdin', or 'both', " + "weight_table must be 'cc', 'lowdin', 'inverse', 'renormalized', or 'both', " f"but got {weight_table!r}." ) @@ -394,7 +394,12 @@ def _legend( f"Lowdin {weight.index} w={weight.weight:.5f}" ) else: - table_label = "Lowdin" if self.weight_table == "lowdin" else "CC" + table_label = { + "cc": "CC", + "lowdin": "Lowdin", + "inverse": "Inverse", + "renormalized": "Renormalized", + }[self.weight_table] legend = f"{table_label} {weight.index} w={weight.weight:.5f}" if not self.show_connection_labels: return legend diff --git a/src/autoVB/io/readers.py b/src/autoVB/io/readers.py index ede6cab..7443b29 100644 --- a/src/autoVB/io/readers.py +++ b/src/autoVB/io/readers.py @@ -119,7 +119,12 @@ def parse_xmi(self) -> autoVBInputData: settings = VBSettings() type_hints = get_type_hints(VBSettings) - alias_map = {"int": "inte", "str": "stru", "aat": "aoa"} + alias_map = { + "int": "inte", + "str": "stru", + "aat": "aoa", + "draw_xmo": "xmo2svg", + } passthrough = XMIPassthrough() # 默认方法 @@ -341,7 +346,12 @@ def parse_autovb_options(self, s: str) -> VBSettings: pair_list: list[str] = [p.strip() for p in re.findall(pattern, inner) if p.strip()] settings = VBSettings() type_hints = get_type_hints(VBSettings) - alias_map = {"int": "inte", "str": "stru", "aat": "aoa"} + alias_map = { + "int": "inte", + "str": "stru", + "aat": "aoa", + "draw_xmo": "xmo2svg", + } for pair in pair_list: if "=" not in pair: diff --git a/src/autoVB/main.py b/src/autoVB/main.py index a303ce4..6a87e2b 100644 --- a/src/autoVB/main.py +++ b/src/autoVB/main.py @@ -66,7 +66,6 @@ class VBSettings: guess: str = "nbo" active_order: str = "default" nbo_file: Path = None - draw_xmo: bool = False xmo2svg: Optional[str] = None svgweight: str = "both" svgbaseline: int = 0 @@ -117,9 +116,10 @@ def validate(self) -> None: ) self.svgweight = self.svgweight.strip().lower() - if self.svgweight not in ("cc", "lowdin", "both"): + if self.svgweight not in ("cc", "lowdin", "inverse", "renormalized", "both"): raise ValueError( - "VBSettings: 'svgweight' must be 'cc', 'lowdin', or 'both'" + "VBSettings: 'svgweight' must be 'cc', 'lowdin', 'inverse', " + "'renormalized', or 'both'" ) if self.svgbaseline < 0: @@ -426,65 +426,6 @@ def get_gvb_filename(self) -> Path: gvb_stem = Path(line.split()[1]).stem return Path(f"{gvb_stem}_s.fch") - def draw_xmo(self, parsed_data: 'XmoParsedData', weight_table: str = 'cc', max_str: int = 20): - ''' - 使用XMVB的输出文件(.xmo)来绘制价键结构,核心步骤包括: - 1. 解析.xmo文件,提取分子结构、活性空间信息、以及每个价键结构的权重。 - 2. 根据提取的信息,使用MoleculeBondVariantDrawer类来绘制 - 3. 将绘制的结果保存到当前目录,并记录输出文件的信息。 - Args: - parsed_data ('XmoParsedData'): 从.xmo文件解析得到的数据对象,包含分子结构、活性空间信息、以及每个价键结构的权重等。 - weight_table (str): 权重表的选择,默认为'cc',可以是 'lowdin', 'inverse', 'renormalized'等。 - max_str (int): 最大绘制的价键结构数量,默认为20。 - Returns: - None - ''' - from .draw_xmo.molecule_bond_variant_drawer import MoleculeBondVariantDrawer - from .draw_xmo.xmo_drawer_input_converter import XmoToDrawerInputConverter - - WEIGHT = weight_table - MAX_STR = max_str - output_dir = Path.cwd() - hide_hydrogens = True - - converter = XmoToDrawerInputConverter( - parsed_data, - output_dir, - hide_hydrogens=hide_hydrogens, - max_structures=MAX_STR, - weight_table=WEIGHT, - ) - drawer_input = converter.convert() - hide_hydrogens = converter.hide_hydrogens - - drawer = MoleculeBondVariantDrawer( - xyz_file=drawer_input.xyz_file, - output_dir=output_dir, - charge=int(parsed_data.ctrl_options.get("ncharge", self.input_data.charge)), - active_bond_atom=drawer_input.active_bond_atom, - active_space=drawer_input.active_space, - baseline_unpaired_atoms=drawer_input.baseline_unpaired_atoms, - active_space_color="#B00000", - active_space_width=3.0, - color_active_space=True, - show_atom_labels=True, - hide_hydrogens=hide_hydrogens, - show_lone_pairs=True, - write_individual_svgs=False, - ) - result = drawer.draw() - - logger.info(f"Read XMO from: {parsed_data.source_file.resolve()}") - logger.info(f"Generated XYZ: {drawer_input.xyz_file.resolve()}") - logger.info(f"Active orbital -> atom: {drawer_input.orbital_to_atom}") - logger.info(f"Weight table: {drawer_input.weight_table}") - logger.info(f"active_bond_atom: {drawer_input.active_bond_atom}") - logger.info(f"Bond perception mode: {drawer.bond_perception_mode}") - logger.info(f"Drawn structures: {len(drawer_input.active_space)}") - logger.info(f"Output directory: {result.output_dir.resolve()}") - for out_file in result.written_files: - logger.info(f" - {out_file.name}") - def draw_xmo2svg( self, xmo_file: Path, @@ -495,8 +436,9 @@ def draw_xmo2svg( ): """调用 xmo2svg,按指定三维或二维排布方式生成 SVG。""" from .cli.xmo2svg import xmo2svg_file + from .vbkit.xmo2svg import xmo2svg_report_lines - return xmo2svg_file( + result = xmo2svg_file( xmo_file, projection=projection, weight_table=weight_table, @@ -504,6 +446,10 @@ def draw_xmo2svg( show_atom_labels=not hide_svg_labels, show_connection_labels=not hide_svg_labels, ) + if result is not None: + for line in xmo2svg_report_lines(result): + logger.info(line) + return result def parser_xmo(self, xmo_file: Path, method: str | None = None) -> 'XmoParsedData': ''' @@ -702,20 +648,6 @@ def main(self): else: self.timed_call("parser_xmo", self.parser_xmo, xmo_path) - # draw_xmo 调用 - if self.input_data.vbsettings.draw_xmo and is_bovb: - logger.warning("Skipping draw_xmo because BOVB output parsing is not supported yet.") - elif self.input_data.vbsettings.draw_xmo: - log_subroutine("Entry draw_xmo") - # novb模式下没有生成xmo文件,因此需要先解析xmo文件,如果没有解析到数据则跳过绘制步骤 - if not hasattr(self, 'parsed_data'): - try: - self.timed_call("parser_xmo", self.parser_xmo, xmo_path) - except Exception as e: - logger.warning("No parsed .xmo data available for drawing. Skipping draw_xmo step.") - logger.warning("If you want to draw the .xmo, you can use command line tool 'draw_xmo' with the generated .xmo file after running XMVB.") - self.timed_call("draw_xmo", self.draw_xmo, self.parsed_data, 'cc') - if self.input_data.vbsettings.xmo2svg is not None and is_bovb: logger.warning("Skipping xmo2svg because BOVB output parsing is not supported yet.") elif self.input_data.vbsettings.xmo2svg is not None: diff --git a/src/autoVB/vbkit/xmo2svg.py b/src/autoVB/vbkit/xmo2svg.py new file mode 100644 index 0000000..cefb01f --- /dev/null +++ b/src/autoVB/vbkit/xmo2svg.py @@ -0,0 +1,156 @@ +from dataclasses import dataclass +from pathlib import Path +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from ..draw_xmo.molecule_bond_variant_drawer import MoleculeBondVariantDrawer + from ..draw_xmo.xmo_drawer_input_converter import XmoDrawerInput + from ..io.xmo_output_parser import XmoParsedData + +DEFAULT_XMO_MAX_STRUCTURES = 20 +DEFAULT_XMO_WEIGHT_TABLE = "lowdin" +DEFAULT_XMO_ACTIVE_SPACE_COLOR = "#B00000" +DEFAULT_XMO_ACTIVE_SPACE_WIDTH = 3.0 +DEFAULT_XMO_STRUCTURES_PER_ROW = 2 + + +@dataclass +class Xmo2SvgResult: + """保存一次 XMO 绘图任务的结果和报告信息。""" + + draw_result: "MoleculeBondVariantDrawer.Result" + parsed_data: "XmoParsedData" + drawer_input: "XmoDrawerInput" + connectivity: str + projection: str + + @property + def xyz_file(self) -> Path: + return self.draw_result.xyz_file + + @property + def output_dir(self) -> Path: + return self.draw_result.output_dir + + @property + def displayed_atom_count(self) -> int: + return self.draw_result.displayed_atom_count + + @property + def written_files(self) -> list[Path]: + return self.draw_result.written_files + + +def xmo2svg_file( + xmo_file: str | Path, + *, + connectivity: str = "orb", + weight_table: str = DEFAULT_XMO_WEIGHT_TABLE, + max_structures: int | None = DEFAULT_XMO_MAX_STRUCTURES, + baseline_index: int | None = None, + charge: int = 0, + hide_hydrogens: bool = True, + write_individual_svgs: bool = False, + show_atom_labels: bool = True, + show_lone_pairs: bool = True, + structures_per_row: int = DEFAULT_XMO_STRUCTURES_PER_ROW, + projection: str = "rdkit", + condense_hydrogens: bool = True, + show_connection_labels: bool = True, + rename_grid: bool = True, +) -> Xmo2SvgResult: + """读取 XMO 并按指定连接关系生成价键结构 SVG。""" + from ..draw_xmo.molecule_bond_variant_drawer import MoleculeBondVariantDrawer + from ..draw_xmo.orbital_connectivity_molecule_drawer import ( + OrbitalConnectivityMoleculeDrawer, + ) + from ..draw_xmo.xmo_drawer_input_converter import XmoToDrawerInputConverter + from ..io.xmo_output_parser import XmoParser + + xmo_path = Path(xmo_file) + if not xmo_path.exists(): + raise FileNotFoundError(f"XMO file not found: {xmo_path}") + if not xmo_path.is_file(): + raise ValueError(f"XMO path is not a file: {xmo_path}") + + output_dir = xmo_path.parent + parsed_data = XmoParser(xmo_path).parse() + converter = XmoToDrawerInputConverter( + parsed_data, + output_dir, + hide_hydrogens=hide_hydrogens, + max_structures=max_structures, + baseline_index=baseline_index, + weight_table=weight_table, + show_connection_labels=show_connection_labels, + ) + drawer_input = converter.convert() + hide_hydrogens = converter.hide_hydrogens + + drawer_kwargs = dict( + xyz_file=drawer_input.xyz_file, + output_dir=output_dir, + charge=charge, + active_bond_atom=drawer_input.active_bond_atom, + active_space=drawer_input.active_space, + baseline_unpaired_atoms=drawer_input.baseline_unpaired_atoms, + active_space_color=DEFAULT_XMO_ACTIVE_SPACE_COLOR, + active_space_width=DEFAULT_XMO_ACTIVE_SPACE_WIDTH, + color_active_space=True, + show_atom_labels=show_atom_labels, + hide_hydrogens=hide_hydrogens, + show_lone_pairs=show_lone_pairs, + write_individual_svgs=write_individual_svgs, + structures_per_row=structures_per_row, + ) + if connectivity == "orb": + drawer = OrbitalConnectivityMoleculeDrawer( + **drawer_kwargs, + orbital_atom_rows=parsed_data.orb, + projection=projection, + condense_hydrogens=condense_hydrogens, + ) + elif connectivity == "rdkit": + drawer = MoleculeBondVariantDrawer(**drawer_kwargs) + else: + raise ValueError(f"Unsupported connectivity mode: {connectivity}") + + draw_result = drawer.draw() + if rename_grid: + grid_path = output_dir / f"{xmo_path.stem}_grid.svg" + output_path = output_dir / f"{xmo_path.stem}.svg" + grid_path.replace(output_path) + draw_result.written_files = [ + output_path if written_file == grid_path else written_file + for written_file in draw_result.written_files + ] + + return Xmo2SvgResult( + draw_result=draw_result, + parsed_data=parsed_data, + drawer_input=drawer_input, + connectivity=connectivity, + projection=projection, + ) + + +def xmo2svg_report_lines(result: Xmo2SvgResult) -> list[str]: + """生成 XMO 绘图任务的用户可读报告行。""" + from ..utils import constants + + if not isinstance(result, Xmo2SvgResult): + return [] + + return [ + f"XMO2SVG version: {constants.VERSION}", + f"Read XMO from: {result.parsed_data.source_file.resolve()}", + f"Generated XYZ: {result.drawer_input.xyz_file.resolve()}", + f"Active orbital -> atom: {result.drawer_input.orbital_to_atom}", + f"Weight table: {result.drawer_input.weight_table}", + f"active_bond_atom: {result.drawer_input.active_bond_atom}", + f"Connectivity source: {result.connectivity}", + f"Projection: {result.projection}", + f"Drawn structures: {len(result.drawer_input.active_space)}", + f"Output directory: {result.output_dir.resolve()}", + *[f" - {out_file.name}" for out_file in result.written_files], + ] From 2c2e151035b54a49cde6831c24f85f4d66c732b5 Mon Sep 17 00:00:00 2001 From: Loach1703 Date: Tue, 25 Aug 2026 20:04:04 +0800 Subject: [PATCH 3/3] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 97 +++++++++++++----------- UserGuide_en.md | 195 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 243 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 1c493dc..583d5a5 100644 --- a/README.md +++ b/README.md @@ -1,84 +1,91 @@ # autoVB -autoVB is a Python package for generating and running XMVB workflows from Gaussian/NBO based inputs. +`autoVB` is a Python workflow tool for preparing and running XMVB valence-bond calculations. +It can select an active space, prepare initial guesses, generate XMVB input files, run calculations, and produce result summaries and SVG plots. -## 1. Prerequisites +The full documentation is available in [UserGuide.md](UserGuide.md) and [UserGuide_en.md](UserGuide_en.md). -You need the following external programs available in your runtime environment: +## Prerequisites -- Gaussian executable (`g16`/`g09`) -- `formchk` -- `xmvb` +- Python >= 3.11 +- Gaussian and `formchk` for the default NBO workflow +- XMVB (`xmvb`) for VB calculations +- MOKIT (`automr`) and GAMESS (`rungms`) when using `guess=gvb` -Typical environment setup (example paths): +Example environment configuration: ```bash -export GAUSS_EXE=/share/apps/g16_avx2/g16/g16 -export PATH=/share/apps/g16_avx2/g16:$PATH +export GAUSS_EXE=/share/apps/gaussian/g16/g16 +export PATH=/share/apps/gaussian/16/formchk:$PATH export PATH=/share/apps/xmvb/latest/bin:$PATH +export PATH=/share/apps/mokit/bin:$PATH +export GMS=/share/apps/gamess/rungms ``` -## 2. User Installation (Recommended, avoid gcc build issues) +Adjust these paths for your local installation. Add them to `~/.bashrc` or the corresponding shell startup file if they should persist between sessions. -To avoid local C/C++/Fortran compilation (gcc/gfortran), install heavy scientific dependencies from prebuilt binaries first (Conda), then install `autoVB` wheel. +## Installation + +Using Conda for the scientific dependencies is recommended: ```bash conda create -n autovb python=3.11 -y conda activate autovb - -# Prebuilt binary dependencies -conda install -c conda-forge numpy pyscf -y +conda install -c conda-forge numpy pyscf rdkit -y conda install -c mokit -c conda-forge mokit -y pip install pyssian - -# Install autoVB from built wheel (recommended) -pip install --no-deps autovb-0.1.0-py3-none-any.whl ``` -Why `--no-deps`: dependencies are already installed from Conda binaries, so pip will not try source builds. - -## 3. Developer Installation +For a source checkout, install the package normally after preparing the dependencies above: ```bash -conda create -n autovb-dev python=3.11 -y -conda activate autovb-dev -conda install -c conda-forge numpy pyscf -y -conda install -c mokit -c conda-forge mokit -y -pip install pyssian -pip install -e . +pip install --no-deps . ``` -## 4. Build Package (for maintainers) - -Run at project root: +If a wheel has already been built, install it instead: ```bash -python -m pip install -U pip build twine -python -m build -twine check dist/* +pip install --no-deps dist/autovb-*.whl ``` -Artifacts will be generated in `dist/`: - -- `autovb-0.1.0-py3-none-any.whl` -- `autovb-0.1.0.tar.gz` - -## 5. Install From Local Dist Files +For developers working directly from a source checkout, editable installation is optional: ```bash -pip install --no-deps dist/autovb-0.1.0-py3-none-any.whl +pip install --no-deps -e . ``` -If your machine is fully pip-based and has suitable binary wheels for dependencies, you may also use: +Check the installation with: ```bash -pip install dist/autovb-0.1.0-py3-none-any.whl +python -c "import autoVB, mokit, numpy, pyscf, rdkit, pyssian; print('Python dependencies are ready')" +autovb --help ``` -If pip tries to compile dependencies (gcc/gfortran errors), switch back to the Conda-first workflow in Section 2. +The external programs are checked separately by autoVB when a workflow is run. Make sure `formchk`, `xmvb`, `automr`, and `rungms` are available when the corresponding workflow requires them. + +## Command-Line Tools + +Run ` --help` to see all options. -## 6. Verify Installation +| Command | Purpose | +| --- | --- | +| `autovb` | Run the complete autoVB workflow from an `.autovb`, `.gjf`, or `.xmi` input. | +| `xyz2nbo` | Generate a Gaussian NBO `.gjf` input from an `.xyz` file. | +| `nbo2xmi` | Generate an XMVB `.xmi` input from an NBO `.fch`/`.chk` result. | +| `fch2vb` / `fch2xmi` | Convert `.fch` orbitals into a minimal XMVB `.xmi` initial guess. | +| `xmo2svg` / `draw_xmo` | Convert an XMVB `.xmo` output into SVG valence-bond structures. | +| `xmo2json` | Convert an XMVB `.xmo` output into a JSON summary. | +| `xmo2xmi` | Replace an `.xmi` initial guess with the matching `.orb` file. | + +Typical examples: ```bash -autovb --help -``` \ No newline at end of file +autovb C6H6.autovb +xyz2nbo C6H6.xyz 6-31g* +nbo2xmi C6H6.fch 6-31g* +fch2xmi C6H6.fch -o C6H6_guess.xmi +xmo2svg C6H6_vb.xmo --weight both +xmo2json C6H6_vb.xmo +``` + +See [UserGuide.md](UserGuide.md) for input syntax, active-space selection, GVB/BOVB workflows, plotting options, and detailed examples. diff --git a/UserGuide_en.md b/UserGuide_en.md index 4155636..e06edc7 100644 --- a/UserGuide_en.md +++ b/UserGuide_en.md @@ -142,7 +142,7 @@ Controls how the active orbitals are reordered. The default is `rumer`; when [ao **none**: Do not reorder the active orbitals. ##### 2.3.1.8 aoa_bond=(n1, n2, ...) -Specifies the atom sequence for bonding active orbitals. For example, `aoa_old=(1,2,3,4)` indicates bonds between atoms 1 and 2 and between atoms 3 and 4; these two bonds are then selected for the active space. If an odd number of indices is supplied, the final atom is interpreted as a lone pair. Atom indices are one-based integers in the range `[1, number of atoms]`. This option cannot handle an intended active space containing more than one lone pair correctly, because two lone-pair atoms would be interpreted as a bond. Therefore, this option is not recommended in that case. +Specifies the atom sequence for bonding active orbitals. For example, `aoa_bond=(1,2,3,4)` indicates bonds between atoms 1 and 2 and between atoms 3 and 4; these two bonds are then selected for the active space. If an odd number of indices is supplied, the final atom is interpreted as a lone pair. Atom indices are one-based integers in the range `[1, number of atoms]`. This option cannot handle an intended active space containing more than one lone pair correctly, because two lone-pair atoms would be interpreted as a bond. Therefore, this option is not recommended in that case. ##### 2.3.1.9 bond_first A sub-option of [aoa](#2313-aoan1-n2-). When enabled, bonding orbitals are searched before lone pairs. It can be enabled when the intended active space does not contain low-occupation lone pairs. @@ -196,7 +196,7 @@ Applies only to the BOVB method. When enabled, autoVB first runs a VBSCF calcula #### 2.3.4 Plotting Parameters ##### 2.3.4.1 draw_xmo -Invokes the `draw_xmo` tool to parse the `.xmo` file and generate an `.svg` image of the molecular valence bond structures. The generated molecular layout is provided for reference and may contain errors. +`draw_xmo` is an alias for `xmo2svg`. It uses the same projection value, for example, `autovb{draw_xmo=optimized3d}` is equivalent to `autovb{xmo2svg=optimized3d}`. The generated molecular layout is provided for reference and may contain errors. ##### 2.3.4.2 xmo2svg Parses the `.xmo` file after the XMVB calculation and generates a valence bond structure `.svg` image with the same base name as the `.xmo` file. The syntax is `autovb{xmo2svg=projection-method}`. The following options are supported: @@ -219,7 +219,7 @@ autovb{xmo2svg=rdkit,hide_svg_labels} ``` ##### 2.3.4.4 svgweight -Selects the structure weights displayed in the `xmo2svg` image. Supported values are `cc`, `lowdin`, and `both`; the default is `both`. With `both`, the CC and Lowdin weights are shown on separate lines, while structures are still selected and sorted by Lowdin weight. For example: +Selects the structure weights displayed in the `xmo2svg` image. Supported values are `cc`, `lowdin`, `inverse`, `renormalized`, and `both`; the default is `both`. With `both`, the CC and Lowdin weights are shown on separate lines, while structures are still selected and sorted by Lowdin weight. For example: ```text autovb{xmo2svg=optimized3d,svgweight=both} @@ -240,7 +240,32 @@ Generates a molecular `.svg` image when the selected active-space atoms are orde ##### 2.3.5.1 debug Enables debug mode and prints additional output. -### 3. Submitting Jobs +## 3. Command-Line Tools + +After installing `autoVB`, the following commands are available through the Python package script entry points. Run ` --help` to see the available options. Unless otherwise noted, run commands in the directory containing the input files. + +### 3.1 `autovb` + +`autovb` is the main entry point. It runs the complete autoVB workflow from an `.autovb`, Gaussian `.gjf`, or XMVB `.xmi` input, including NBO/GVB guess preparation, active-space selection, XMVB input generation, calculation, result parsing, and plotting. + +```bash +autovb [--mem MEM] [--nproc NPROC] +``` + +Arguments: + +- ``: Input file path. +- `--mem MEM`: Override the memory setting in the input file, for example `4GB`, `8G`, or `4000MB`. +- `--nproc NPROC`: Override the number of parallel processes in the input file. + +The `--mem` and `--nproc` options override the memory and CPU settings in the input file. For example: + +```bash +autovb C6H6.autovb --mem 8GB --nproc 8 +``` + +#### 3.1.1 Job Submission + After configuring the environment variables, run `autoVB` from a terminal by supplying an input file: ```bash autovb @@ -254,6 +279,168 @@ Do not run calculations on a login node. Put the command in a SLURM, PBS, or sim sbatch example_slurm.sh ``` +### 3.2 `xyz2nbo` + +`xyz2nbo` generates a Gaussian NBO `.gjf` input file from an `.xyz` geometry. It only writes the input file; it does not run Gaussian or NBO automatically. + +```bash +xyz2nbo [-c CHARGE] [-s SPIN | -m MULTIPLICITY] +``` + +Arguments: + +- ``: Input `.xyz` file. +- ``: Gaussian basis set, such as `6-31g*`. +- `-c`/`--charge`: Total molecular charge, default `0`. +- `-s`/`--spin`: Number of unpaired electrons, default `0`. +- `-m`/`--multiplicity`: Spin multiplicity, mutually exclusive with `--spin`, default `1`. + +The output is a `.gjf` file with the same base name as the XYZ file. + +For example: + +```bash +xyz2nbo C6H6.xyz 6-31g* +xyz2nbo radical.xyz 6-31g* --charge 0 --multiplicity 2 +``` + +### 3.3 `nbo2xmi` + +`nbo2xmi` generates an XMVB `.xmi` input from an existing Gaussian `.fch` or `.chk` NBO result. It uses the NBO result to select the active space and generate the NBO orbital initial guess. + +```bash +nbo2xmi [options] +``` + +Arguments: + +- ``: An `.fch` or `.chk` file, or a basename that can be completed to one of these files. +- ``: Basis-set text written to the XMVB input file. +- `-t`/`--threshold`: Active-space selection threshold, default `1.96`. +- `-nae`/`--active_electron`: Explicit number of active electrons, default `0`. +- `-nao`/`--active_orbital`: Explicit number of active orbitals, default `0`. +- `-aoa`/`-aat`/`--active_orbital_atom`: Atom indices involved in the active orbitals; multiple integers can be supplied. + +The output is an `.xmi` file with the same base name as the input. + +For example: + +```bash +nbo2xmi C6H6.fch 6-31g* +nbo2xmi C6H6.fch 6-31g* -nae 6 -nao 6 +nbo2xmi C6H6.fch 6-31g* -aoa 1 3 5 7 9 11 +``` + +### 3.4 `xmo2svg` + +`xmo2svg` reads an XMVB `.xmo` output and generates SVG valence-bond structure images. Use `--connectivity` to select the connectivity source: `$orb` labels are used by default, while `rdkit` uses RDKit bond perception. + +```bash +xmo2svg [--connectivity {orb,rdkit}] [options] +``` + +Arguments: + +- `--connectivity {orb,rdkit}`: Connectivity source, default `orb`. `orb` uses `$orb` labels and `rdkit` uses RDKit bond perception. +- `-w`/`--weight {lowdin,cc,inverse,renormalized,both}`: Weight table used for display and ordering, default `lowdin`; `both` displays CC and Lowdin weights together. +- `-m`/`--max-structures {N,all}`: Maximum number of structures to draw, default `20`; use `all` to draw every structure. +- `--baseline-index N`: Baseline structure index, defaulting to the highest-weight structure. +- `--charge CHARGE`: Total charge used by RDKit for bond-order perception, default `0`. +- `--projection {rdkit,pca,optimized3d,contact}`: Atom layout method, default `rdkit`. +- `--show-hydrogens`: Show hydrogen atoms; hidden by default. +- `--no-condensed-hydrogens`: Disable compact hydrogen labels for heteroatoms or isolated carbon atoms. +- `--write-individual-svgs`: Write one SVG for each structure in addition to the grid SVG. +- `-n`/`--structures-per-row N`: Number of structures per grid row, default `2`. +- `--hide-atom-labels`: Hide atom-number labels. +- `--hide-connection-labels`: Hide bonded-atom and radical labels after each structure weight. +- `--hide-lone-pairs`: Hide lone-pair markers. + +Examples: + +```bash +xmo2svg C6H6_vb.xmo --connectivity rdkit +xmo2svg R24_vb.xmo --projection optimized3d --weight both +xmo2svg mens_vb.xmo --projection contact --hide-connection-labels +``` + +`draw_xmo` is an alias for `xmo2svg` and accepts the same arguments. + +### 3.5 `fch2vb` + +`fch2vb` converts a Gaussian `.fch` file to GAMESS `.inp` through MOKIT's `fch2inp`, reads the orbital information, and writes a minimal XMVB `.xmi` containing the molecular geometry and initial-guess orbitals. It does not select an active space; `nae` and `nao` are both written as `0`, with `orbtyp=oeo`. + +`fch2xmi` is an alias for `fch2vb`. + +```bash +fch2vb [-o OUTPUT] [--basis BASIS] [--norb N] +fch2xmi [-o OUTPUT] [--basis BASIS] [--norb N] +``` + +Arguments: + +- ``: Gaussian formatted checkpoint file. +- `-o`/`--output`: Output `.xmi` path, defaulting to the `.fch` base name. +- `--basis`: Basis-set text written to XMVB `$ctrl`, default empty. +- `--norb`: Number of orbitals in the initial guess, defaulting to the number of occupied orbitals. + +For example: + +```bash +fch2vb C4H6.fch --basis cc-pVDZ --norb 15 -o C4H6_guess.xmi +``` + +### 3.6 `xmo2json` + +`xmo2json` converts an XMVB `.xmo` output into a JSON summary containing molecular information, the `orb` section, energies, convergence status, valence-bond structures, and structure weights. + +```bash +xmo2json [-o OUTPUT] +``` + +Arguments: + +- ``: Input XMVB `.xmo` file. +- `-o`/`--output`: Output JSON path, defaulting to the `.xmo` base name with a `.json` extension. + +For example: + +```bash +xmo2json C6H6_vb.xmo +xmo2json C6H6_vb.xmo -o results/C6H6.json +``` + +### 3.7 `xmo2xmi` + +`xmo2xmi` reads an `.xmi` file and replaces its initial-guess orbitals with the same-directory `.orb` file, while keeping the other input sections unchanged. + +```bash +xmo2xmi [-o OUTPUT] [--method METHOD] [--iscf {2,5,6}] +``` + +Arguments: + +- ``: Input XMVB `.xmi` file; a same-name `.orb` file must also exist. +- `-o`/`--output`: Output `.xmi` path, defaulting to `_new.xmi`. +- `--method METHOD`: Replace the method in `$ctrl`, for example `vbpt2` or `bovb`; unchanged by default. +- `--iscf {2,5,6}`: Replace `iscf` in `$ctrl`; unchanged by default. + +For example: + +```bash +xmo2xmi C6H6_vb.xmi +xmo2xmi C6H6_vb.xmi --method bovb --iscf 5 -o C6H6_bovb.xmi +``` + +### 3.8 Command Selection + +- Complete workflow from a molecular input: use `autovb`. +- Generate only a Gaussian NBO input: use `xyz2nbo`. +- Generate an XMVB `.xmi` from an NBO `.fch`/`.chk`: use `nbo2xmi`. +- Convert an `.fch` file to a minimal XMVB initial guess: use `fch2vb` or `fch2xmi`. +- Plot an `.xmo` output: use `xmo2svg` or `draw_xmo`. +- Extract an `.xmo` result summary: use `xmo2json`. +- Replace an `.xmi` initial guess with an `.orb` file: use `xmo2xmi`. + ## 4. Examples ### 4.1 Automatic Calculation of Benzene