lammps-analysis-tools 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lammps_analysis_tools-1.0.0.dist-info/LICENSE +14 -0
- lammps_analysis_tools-1.0.0.dist-info/METADATA +231 -0
- lammps_analysis_tools-1.0.0.dist-info/RECORD +74 -0
- lammps_analysis_tools-1.0.0.dist-info/WHEEL +5 -0
- lammps_analysis_tools-1.0.0.dist-info/entry_points.txt +2 -0
- lammps_analysis_tools-1.0.0.dist-info/top_level.txt +1 -0
- lat/__init__.py +3 -0
- lat/__main__.py +6 -0
- lat/cli.py +270 -0
- lat/config.py +106 -0
- lat/core/__init__.py +6 -0
- lat/core/context.py +155 -0
- lat/core/correlate.py +67 -0
- lat/core/errors.py +60 -0
- lat/core/frame.py +74 -0
- lat/core/grid.py +59 -0
- lat/core/io/__init__.py +184 -0
- lat/core/io/gmx.py +223 -0
- lat/core/io/lammps_data.py +210 -0
- lat/core/io/lammps_dump.py +81 -0
- lat/core/neighbor.py +104 -0
- lat/core/output.py +133 -0
- lat/core/pbc.py +140 -0
- lat/core/periodic.py +694 -0
- lat/core/selection.py +216 -0
- lat/core/table.py +90 -0
- lat/core/topology.py +145 -0
- lat/core/unwrap.py +68 -0
- lat/data/lat.yaml +259 -0
- lat/data/manual/README.md +44 -0
- lat/data/manual/agg.md +57 -0
- lat/data/manual/cluster.md +56 -0
- lat/data/manual/common.md +111 -0
- lat/data/manual/contact.md +54 -0
- lat/data/manual/density.md +55 -0
- lat/data/manual/describe.md +47 -0
- lat/data/manual/freevol.md +60 -0
- lat/data/manual/gyrate.md +49 -0
- lat/data/manual/hbond.md +61 -0
- lat/data/manual/msd.md +55 -0
- lat/data/manual/occupancy.md +54 -0
- lat/data/manual/pistack.md +55 -0
- lat/data/manual/plot1d.md +50 -0
- lat/data/manual/plot2d.md +45 -0
- lat/data/manual/rdf.md +55 -0
- lat/data/manual/residence.md +56 -0
- lat/data/manual/rms.md +54 -0
- lat/data/manual/sasa.md +53 -0
- lat/data/manual/select.md +52 -0
- lat/data/manual/transport.md +55 -0
- lat/docs.py +55 -0
- lat/modules/__init__.py +54 -0
- lat/modules/_graph.py +130 -0
- lat/modules/agg.py +162 -0
- lat/modules/base.py +58 -0
- lat/modules/cluster.py +89 -0
- lat/modules/contact.py +106 -0
- lat/modules/density.py +164 -0
- lat/modules/describe.py +42 -0
- lat/modules/freevol.py +328 -0
- lat/modules/gyrate.py +88 -0
- lat/modules/hbond.py +374 -0
- lat/modules/msd.py +144 -0
- lat/modules/occupancy.py +179 -0
- lat/modules/pistack.py +129 -0
- lat/modules/rdf.py +175 -0
- lat/modules/residence.py +188 -0
- lat/modules/rms.py +158 -0
- lat/modules/sasa.py +78 -0
- lat/modules/select.py +67 -0
- lat/modules/transport.py +187 -0
- lat/plotting/__init__.py +6 -0
- lat/plotting/plot1d.py +161 -0
- lat/plotting/plot2d.py +78 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
Copyright (c) 2026 tgraphite. All rights reserved.
|
|
2
|
+
|
|
3
|
+
This software and its accompanying documentation (the "Software") are
|
|
4
|
+
proprietary. No permission is granted to use, copy, modify, merge, publish,
|
|
5
|
+
distribute, sublicense, or sell copies of the Software without the prior
|
|
6
|
+
written permission of the copyright holder.
|
|
7
|
+
|
|
8
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
9
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
10
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
11
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
12
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
13
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
14
|
+
SOFTWARE.
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: lammps-analysis-tools
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Trajectory analysis for LAMMPS data/dump files, with GROMACS-compatible commands
|
|
5
|
+
Author: tgraphite
|
|
6
|
+
License: Proprietary
|
|
7
|
+
Project-URL: Homepage, https://github.com/tgraphite/LammpsAnalysisTools
|
|
8
|
+
Project-URL: Documentation, https://github.com/tgraphite/LammpsAnalysisTools/tree/main/docs/manual
|
|
9
|
+
Project-URL: Repository, https://github.com/tgraphite/LammpsAnalysisTools
|
|
10
|
+
Project-URL: Issues, https://github.com/tgraphite/LammpsAnalysisTools/issues
|
|
11
|
+
Keywords: molecular dynamics,LAMMPS,GROMACS,trajectory analysis,RDF,hydrogen bonds,free volume,SASA
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: License :: Other/Proprietary License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
24
|
+
Requires-Python: >=3.9
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: numpy >=1.22
|
|
28
|
+
Requires-Dist: scipy >=1.8
|
|
29
|
+
Requires-Dist: pyyaml >=5.4
|
|
30
|
+
Requires-Dist: matplotlib >=3.5
|
|
31
|
+
Requires-Dist: MDAnalysis >=2.4
|
|
32
|
+
Requires-Dist: ase >=3.22
|
|
33
|
+
|
|
34
|
+
# lat — LAMMPS Analysis Tool
|
|
35
|
+
|
|
36
|
+
[](https://pypi.org/project/lammps-analysis-tools/)
|
|
37
|
+
[](https://pypi.org/project/lammps-analysis-tools/)
|
|
38
|
+
|
|
39
|
+
面向 LAMMPS `data` / `lammpstrj` 的轨迹分析工具。命令风格对齐 GROMACS(`-s` 拓扑、`-f` 轨迹、单横线参数),
|
|
40
|
+
输出统一为带审计头的 CSV,适合脚本批处理、回归与作图。
|
|
41
|
+
|
|
42
|
+
## 特性
|
|
43
|
+
|
|
44
|
+
- **直接读 LAMMPS**:`*.data` / `*.lmp` + `*.lammpstrj`,自动识别 `atom_style`,按质量推断元素。
|
|
45
|
+
- **GROMACS 兼容输入**:`.tpr/.gro/.pdb` + `.xtc/.trr/.gro` 可直接分析,便于交叉验证。
|
|
46
|
+
- **周期几何一致性**:所有距离、质心、整分子复原、网格与曲面都走同一套最小镜像实现。
|
|
47
|
+
- **可复现输出**:文件名即意图;CSV 头记录命令、选择、参数、警告与标量;同名输出自动备份。
|
|
48
|
+
- **自解释**:`lat --help` 列出模块,`lat <module> -h` 给出参数与默认值,`lat describe -module <name>` 给出完整契约。
|
|
49
|
+
|
|
50
|
+
## 安装
|
|
51
|
+
|
|
52
|
+
需要 Python ≥ 3.9。
|
|
53
|
+
|
|
54
|
+
pip install lammps-analysis-tools
|
|
55
|
+
|
|
56
|
+
安装后命令是 `lat`:
|
|
57
|
+
|
|
58
|
+
lat --version
|
|
59
|
+
lat --help
|
|
60
|
+
|
|
61
|
+
升级:
|
|
62
|
+
|
|
63
|
+
pip install --upgrade lammps-analysis-tools
|
|
64
|
+
|
|
65
|
+
从源码或离线安装:
|
|
66
|
+
|
|
67
|
+
git clone https://github.com/tgraphite/LammpsAnalysisTools.git
|
|
68
|
+
cd LammpsAnalysisTools
|
|
69
|
+
bash install.sh
|
|
70
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
71
|
+
|
|
72
|
+
`install.sh` 会建独立虚拟环境、安装依赖,并把 `lat` 放到 `~/.local/bin`;系统 Python < 3.9 时会用
|
|
73
|
+
`uv` 引导一个私有 Python 3.11。也可以直接 `pip install .`。
|
|
74
|
+
|
|
75
|
+
依赖:numpy、scipy、pyyaml、matplotlib、MDAnalysis、ase。
|
|
76
|
+
|
|
77
|
+
## 快速开始
|
|
78
|
+
|
|
79
|
+
# 径向分布函数 + 配位数
|
|
80
|
+
lat rdf -s system.data -f run.lammpstrj -sel1 "type 2" -sel2 "type 5" -cutoff 10 -o out
|
|
81
|
+
|
|
82
|
+
# 沿 z 的密度剖面
|
|
83
|
+
lat density -s system.data -f run.lammpstrj -axis z -nbins 200 -o out
|
|
84
|
+
|
|
85
|
+
# 均方位移与扩散系数
|
|
86
|
+
lat msd -s system.data -f run.lammpstrj -sel "type 2" -o out
|
|
87
|
+
|
|
88
|
+
# 画图(输入是上一步的 CSV)
|
|
89
|
+
lat plot1d -f out.rdf.out.csv -o rdf.png
|
|
90
|
+
|
|
91
|
+
结果写入当前目录或 `-o` 指定的基名:
|
|
92
|
+
|
|
93
|
+
out.rdf.out.csv
|
|
94
|
+
out.rdf.cn.out.csv
|
|
95
|
+
|
|
96
|
+
## 支持输入
|
|
97
|
+
|
|
98
|
+
| | 拓扑 | 轨迹 |
|
|
99
|
+
|---|---|---|
|
|
100
|
+
| LAMMPS(首选) | `.data` / `.lmp`:Masses、Atoms;含 Bonds 才能做氢键/整分子分析 | `.lammpstrj`(dump) |
|
|
101
|
+
| GROMACS | `.tpr` / `.gro` / `.pdb` | `.xtc` / `.trr` / `.gro` |
|
|
102
|
+
|
|
103
|
+
- 自动识别 `atomic`、`charge`、`molecular`、`full`,支持 `full/kk` 等加速器后缀;六列歧义时用 `-style`。
|
|
104
|
+
- 类型→元素默认按质量 ±0.2% 匹配;不确定时用 `-types` 显式指定,或让 dump 带 `element` 列。
|
|
105
|
+
- 坐标支持 `x/y/z`、`xu/yu/zu`、`xs/ys/zs`、`xsu/ysu/zsu`;带 `ix/iy/iz` 可解包。
|
|
106
|
+
- 反应轨迹原子数逐帧变化时会报错,并提示用 `-frame_range` / `-stride` 限定到一致窗口。
|
|
107
|
+
|
|
108
|
+
## 模块总览
|
|
109
|
+
|
|
110
|
+
| 模块 | 用途 | 手册 |
|
|
111
|
+
|---|---|---|
|
|
112
|
+
| `rdf` | 径向分布函数 g(r) 与配位数 | [rdf](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/manual/rdf.md) |
|
|
113
|
+
| `density` | 一维/二维密度剖面 | [density](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/manual/density.md) |
|
|
114
|
+
| `msd` | 均方位移与扩散系数 | [msd](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/manual/msd.md) |
|
|
115
|
+
| `gyrate` | 回转半径 Rg | [gyrate](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/manual/gyrate.md) |
|
|
116
|
+
| `rms` | RMSD / RMSF | [rms](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/manual/rms.md) |
|
|
117
|
+
| `contact` | 两组间接触数与距离 | [contact](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/manual/contact.md) |
|
|
118
|
+
| `hbond` | 氢键数量、寿命与空间分布 | [hbond](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/manual/hbond.md) |
|
|
119
|
+
| `agg` | SSIP / CIP / AGG 离子聚合形态 | [agg](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/manual/agg.md) |
|
|
120
|
+
| `cluster` | 配位数与团簇尺寸分布 | [cluster](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/manual/cluster.md) |
|
|
121
|
+
| `pistack` | π–π 堆积 | [pistack](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/manual/pistack.md) |
|
|
122
|
+
| `freevol` | 自由体积、孔径分布、连通性 | [freevol](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/manual/freevol.md) |
|
|
123
|
+
| `sasa` | 溶剂可及表面积 | [sasa](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/manual/sasa.md) |
|
|
124
|
+
| `residence` | 配体滞留时间 | [residence](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/manual/residence.md) |
|
|
125
|
+
| `transport` | 扩散、Nernst–Einstein、Green–Kubo | [transport](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/manual/transport.md) |
|
|
126
|
+
| `occupancy` | 区域占据、穿越、首次通过 | [occupancy](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/manual/occupancy.md) |
|
|
127
|
+
| `select` | 检查选择、导出 .ndx | [select](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/manual/select.md) |
|
|
128
|
+
| `describe` | 模块清单与契约 | [describe](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/manual/describe.md) |
|
|
129
|
+
| `plot1d` | 一维 CSV 绘图 | [plot1d](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/manual/plot1d.md) |
|
|
130
|
+
| `plot2d` | 二维 CSV 绘图 | [plot2d](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/manual/plot2d.md) |
|
|
131
|
+
|
|
132
|
+
完整手册(公共参数、输入、选择语法、输出契约):[docs/manual](https://github.com/tgraphite/LammpsAnalysisTools/tree/main/docs/manual)。
|
|
133
|
+
|
|
134
|
+
## 公共参数
|
|
135
|
+
|
|
136
|
+
| 参数 | 说明 |
|
|
137
|
+
|---|---|
|
|
138
|
+
| `-s, -topo` | 拓扑文件(分析模块必填) |
|
|
139
|
+
| `-f, -traj` | 轨迹文件 |
|
|
140
|
+
| `-o` | 输出基名;缺省用拓扑文件名 |
|
|
141
|
+
| `-unit` | 长度单位:`real`、`metal`、`lj`;缺省用配置 |
|
|
142
|
+
| `-style` | 强制 LAMMPS `atom_style` |
|
|
143
|
+
| `-types` | type→元素映射文件,每行 `type element` |
|
|
144
|
+
| `-index, -n` | GROMACS `.ndx`,为选择提供命名组 |
|
|
145
|
+
| `-frame_range` | 帧窗口 `start:stop[:stride]`,stop 不含 |
|
|
146
|
+
| `-stride` | 每隔多少帧取一帧 |
|
|
147
|
+
| `-v` | 显示 INFO 进度 |
|
|
148
|
+
| `-debug` | 额外写 JSON 审计 |
|
|
149
|
+
| `-h` | 模块帮助(含默认值) |
|
|
150
|
+
| `-V, --version` | 版本号 |
|
|
151
|
+
|
|
152
|
+
PBC 始终开启,所有距离使用最小镜像。时间轴是帧号,不解析文件中的物理时间。
|
|
153
|
+
|
|
154
|
+
## 选择语法
|
|
155
|
+
|
|
156
|
+
MDAnalysis 风格子集,支持 `and`、`or`、`not` 与括号;相邻关键字隐含 `and`。
|
|
157
|
+
|
|
158
|
+
| 关键字 | 含义 | LAMMPS | GROMACS |
|
|
159
|
+
|---|---|---|---|
|
|
160
|
+
| `all` | 全部原子 | 是 | 是 |
|
|
161
|
+
| `type` | 原子类型 | 是 | 是 |
|
|
162
|
+
| `element` | 元素符号 | 是(需推断或 `-types`) | 是 |
|
|
163
|
+
| `mol` | 分子 ID | 是(需分子信息) | 是 |
|
|
164
|
+
| `id` | 原子 id | 是 | 是 |
|
|
165
|
+
| `index` | 0-based 原子序号 | 是 | 是 |
|
|
166
|
+
| `name` | 原子名 | 否 | 是 |
|
|
167
|
+
| `resname` | 残基名 | 否 | 是 |
|
|
168
|
+
| `resid` | 残基号 | 否 | 是 |
|
|
169
|
+
|
|
170
|
+
-sel "type 2"
|
|
171
|
+
-sel "type 2 or type 5"
|
|
172
|
+
-sel1 "resname LI" -sel2 "resname FSI"
|
|
173
|
+
-sel "all and not type 1"
|
|
174
|
+
|
|
175
|
+
单选择模块用 `-sel`;双选择模块用 `-sel1`/`-sel2`。先运行 `lat select` 验证命中。
|
|
176
|
+
|
|
177
|
+
## 输出
|
|
178
|
+
|
|
179
|
+
- 结果全部写入 CSV;stdout 为空,进度/警告/错误走 stderr。
|
|
180
|
+
- 文件名:`<basename>.<tag>[.<mode>].out.csv`。
|
|
181
|
+
- 文件头以 `#` 开头,包含 program、module、command、selections、definitions、frame_range、
|
|
182
|
+
scalars、warning、title、xlabel、ylabel、columns,最后是 `# --- data ---`。
|
|
183
|
+
- 标量(首壳配位数、D、R²、寿命、积分等)在 `# scalars:` 行,分号分隔。
|
|
184
|
+
- 同名文件先备份为 `.bak.1`、`.bak.2`……,不会静默覆盖。
|
|
185
|
+
- 退出码:0 成功,1 参数/输入/计算错误,130 中断;警告不改变退出码。
|
|
186
|
+
|
|
187
|
+
## 绘图
|
|
188
|
+
|
|
189
|
+
`plot1d` / `plot2d` 只读 CSV,计算与绘图解耦。
|
|
190
|
+
|
|
191
|
+
lat plot1d -f out.rdf.out.csv -o rdf.png
|
|
192
|
+
lat plot1d -f out.agg.labels.out.csv -columns A_SSIP,A_CIP,A_AGG -o spec.png
|
|
193
|
+
lat plot1d -f out.agg.labels.out.csv -stack -o spec_stack.png
|
|
194
|
+
lat plot2d -f out.density.2d.out.csv -o density2d.png
|
|
195
|
+
|
|
196
|
+
`-smooth`(`none`/`gaussian`/`savgol`)只在绘图阶段生效,CSV 始终是原始值;
|
|
197
|
+
`-bar` 与 `-stack` 互斥,且不做平滑。
|
|
198
|
+
|
|
199
|
+
## 配置
|
|
200
|
+
|
|
201
|
+
默认值来自 `lat.yaml`:源码树是 `config/lat.yaml`,安装后是包内 `data/lat.yaml`。
|
|
202
|
+
命令行覆盖配置。
|
|
203
|
+
|
|
204
|
+
| 环境变量 | 作用 |
|
|
205
|
+
|---|---|
|
|
206
|
+
| `LAT_CONFIG` | 使用自定义配置文件 |
|
|
207
|
+
| `LAT_VENV` | `install.sh` 创建的虚拟环境路径 |
|
|
208
|
+
| `LAT_BIN` | `install.sh` 放置 `lat` 的目录 |
|
|
209
|
+
| `PYTHON` | `install.sh` 使用的解释器 |
|
|
210
|
+
|
|
211
|
+
## 文档
|
|
212
|
+
|
|
213
|
+
- 逐模块手册:[docs/manual](https://github.com/tgraphite/LammpsAnalysisTools/tree/main/docs/manual)
|
|
214
|
+
- 公共参数与输出契约:[common.md](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/manual/common.md)
|
|
215
|
+
- 版本变更:[CHANGELOG.md](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/docs/CHANGELOG.md)
|
|
216
|
+
|
|
217
|
+
## 常见问题
|
|
218
|
+
|
|
219
|
+
**选择命中 0 个原子?** 用 `lat select` 检查表达式;LAMMPS 拓扑通常没有 `resname`/`name`。
|
|
220
|
+
|
|
221
|
+
**元素推断失败?** 补 `Masses`,或让 dump 带 `element` 列,或用 `-types`。
|
|
222
|
+
|
|
223
|
+
**氢键报 “no donor”?** 给体只认 N/O/F/S/Cl/Br/I 上的 H;C–H 不是给体。
|
|
224
|
+
|
|
225
|
+
**MSD 提示没有 image flags?** 轨迹只有 wrapped 坐标,MSD 可能饱和;改用带 `xu/yu/zu` 或 `ix/iy/iz` 的 dump。
|
|
226
|
+
|
|
227
|
+
**freevol 报三斜盒?** 体素网格只支持正交且固定的盒子;改用分子/原子对分析或正交化盒子。
|
|
228
|
+
|
|
229
|
+
## 许可
|
|
230
|
+
|
|
231
|
+
Proprietary。详见 [LICENSE](https://github.com/tgraphite/LammpsAnalysisTools/blob/main/LICENSE)。
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
lat/__init__.py,sha256=_08jkCobSbDO7MmSOi76TV4OTzIxDt9haScRSuCIVUI,59
|
|
2
|
+
lat/__main__.py,sha256=4JMK66Wj4uLZTKbF-sT3LAxOsr6buig77PmOkJCRRxw,83
|
|
3
|
+
lat/cli.py,sha256=IY-PdlxT2QDyTNaq63aQSPyI-ePaJbB0RpcLT8v4E8M,10637
|
|
4
|
+
lat/config.py,sha256=dLCb5geWzA-4Gu4l_LQar4m9os-BvbEeg1CeGKQFPH0,3250
|
|
5
|
+
lat/docs.py,sha256=9BUyIm5f8IxF2E0QZzCqt5Uid1RHfQ3tLWctnvBgCxM,1545
|
|
6
|
+
lat/core/__init__.py,sha256=rpCVNW7D8SoA1kSsO-dN7u-TLEXOW92DftQGZiUkwV8,277
|
|
7
|
+
lat/core/context.py,sha256=gQ9aTQfECZ-00D1MJ6U9SwQjYc1ctvQKd3I7hOpn9KI,6219
|
|
8
|
+
lat/core/correlate.py,sha256=7K-tC2DCN2S1g1Yff7cc-TyoFE7kB1cH_xlv4o4dh7I,2187
|
|
9
|
+
lat/core/errors.py,sha256=O0MFv-yUO_fFt3AfLThiyroEYwMZ1KEaw4CIlFpEuUI,1604
|
|
10
|
+
lat/core/frame.py,sha256=9kDl8BVmnyb05Hi9zMeympHDsNNRttX3nxoLJak3qsI,2759
|
|
11
|
+
lat/core/grid.py,sha256=Uexh80WPKEFo6sFfLj8CiGLzWSadLmHQqk9FKa_b7P0,2055
|
|
12
|
+
lat/core/neighbor.py,sha256=A9V1xavPyfibtftRFW_rKDHRZBmiM7JL34mSK_QUN88,3664
|
|
13
|
+
lat/core/output.py,sha256=7mtf6afvUTPg6peTox2rHuuhTwFQR29mrK0pVTJr7dE,3939
|
|
14
|
+
lat/core/pbc.py,sha256=hPGiqjUDfYNelXabY6s0XQizVXqASe2qCy19-Lic7uU,5173
|
|
15
|
+
lat/core/periodic.py,sha256=XSAxjjqCasHJrSA7NqK1aoxR_ig8-fvpL5eKxceue_Q,26916
|
|
16
|
+
lat/core/selection.py,sha256=2M9BkAUzfXk5YHMcALlvKM4PugvAobl0LTVw6HjE50k,7401
|
|
17
|
+
lat/core/table.py,sha256=8tGh6g1TyyT57bu7FDGYsoJZhHUGd8AI0TUvjSxH3nQ,2634
|
|
18
|
+
lat/core/topology.py,sha256=kpzQx4x-qfUijthUMdPtIB7ZnBKnM7nsPpdzXamc5e4,5184
|
|
19
|
+
lat/core/unwrap.py,sha256=7eU4ZDP9K2O8cZzbk_xYksjEXZYQMidk_oMeoybUv2U,2428
|
|
20
|
+
lat/core/io/__init__.py,sha256=Czboss4kdeGoZHyEL5t7l3b90yxl73fVWmL6rySvvx0,6504
|
|
21
|
+
lat/core/io/gmx.py,sha256=CEkVtwZVzkClW2SvBnl5XXIzdiVi9V6LuUWtZgP0NiM,8528
|
|
22
|
+
lat/core/io/lammps_data.py,sha256=bjYP6DtCWu0pMPcAQxWGN66BkeSEP7g5pyYsmQo49Nw,7749
|
|
23
|
+
lat/core/io/lammps_dump.py,sha256=7FuiQbVvgyN1yWUCGbd1QGOZ5mbkH7NeJcXsSwCCArk,3048
|
|
24
|
+
lat/data/lat.yaml,sha256=DPmjL_xmbefB7DPjAtiApubzPc5E-nGnfWT4pvXCJ2g,6429
|
|
25
|
+
lat/data/manual/README.md,sha256=TvAJzXpMgLoWMqC-u36aYvNLeJTNqz42cbvCUoNWW_M,2193
|
|
26
|
+
lat/data/manual/agg.md,sha256=JHLz66tBC89wEXkuED0wC6g8Q2mMyOVixG4iySWnGlM,2735
|
|
27
|
+
lat/data/manual/cluster.md,sha256=PC8ZKV4-4WZcMU9YXmaTM8xByLL540R3VSwwtDtCRSM,2242
|
|
28
|
+
lat/data/manual/common.md,sha256=lVG65e7N-FTYjeGgGnCeMJcNnjJVTrcc2Nk6awU5epg,5289
|
|
29
|
+
lat/data/manual/contact.md,sha256=mj8m8J9nNUSyAA6oKVVrAU-b8sDmX0tmGhM_8yj3XRY,2366
|
|
30
|
+
lat/data/manual/density.md,sha256=Irx7rPdb1Yk_WAeFI3l99V1Eb33y6HQWGAPN03oeU-Q,2429
|
|
31
|
+
lat/data/manual/describe.md,sha256=Ykii0F1mGeD3QlJ0aRzwGIXs3NhI6ZQ71kfV78tkET4,1396
|
|
32
|
+
lat/data/manual/freevol.md,sha256=71Xw0oBMgDZkaZGmLD9gou-grVA_kOBcyfQ0noVAsHA,3103
|
|
33
|
+
lat/data/manual/gyrate.md,sha256=brj5wynFu74uyE3tCNUw552lvuVsK8kpVjFpfbcXCLE,1849
|
|
34
|
+
lat/data/manual/hbond.md,sha256=Ki1pesR46Hmp-FrtQ5ijBwv-ve33ZYAyeE_uiGt2L80,2984
|
|
35
|
+
lat/data/manual/msd.md,sha256=BqFUh0Mw4runZmCayGqzP9X5j6e_7zIV5oTya5-Pi7k,2389
|
|
36
|
+
lat/data/manual/occupancy.md,sha256=SFJ1-EcMmiLZtaSvO6Hpp7rbCyUeRXpjLqiy9ghVesY,2320
|
|
37
|
+
lat/data/manual/pistack.md,sha256=GHU6VyBC1iIB4dnT47yWcaZHalRRDH0Ef9WkynpWo9c,2186
|
|
38
|
+
lat/data/manual/plot1d.md,sha256=BwCLO6xANdzPTBPhAXXV734ZnVxKxlbf775_diOf8yI,2157
|
|
39
|
+
lat/data/manual/plot2d.md,sha256=jCCTpN8RQXny_T0jx1ok2aG2mPldMhYeMl2zLF5gDGI,1386
|
|
40
|
+
lat/data/manual/rdf.md,sha256=usplbv6kCt9nKJBOo4zMXKIxrx7Mf5EFu3pI3b6WmiM,2678
|
|
41
|
+
lat/data/manual/residence.md,sha256=ycA2MrrMXQ0QsGJRkw8NWVl3cnvl3pPGw8eS5KLujvE,2430
|
|
42
|
+
lat/data/manual/rms.md,sha256=Cw7xAuIEl6gCFkHANhmIVqQycmrs9nZS_jF2pBqnP0A,1885
|
|
43
|
+
lat/data/manual/sasa.md,sha256=wifONC48wGVWXWPlydW_zPhsaOJ2QY4A6_QotEHUG50,2103
|
|
44
|
+
lat/data/manual/select.md,sha256=NqqdGzuIIbUlp--D6b592-e8lLzM0acDIk1uBsPksLw,1919
|
|
45
|
+
lat/data/manual/transport.md,sha256=ZpluEjZCSKPZ8teUaU0SvqNMrYOF7ItB2xph6suFAxc,2363
|
|
46
|
+
lat/modules/__init__.py,sha256=4sLaqGQe0PlpLi_tCy3V9AA7x38OjtI_ltvdrG5RG04,1018
|
|
47
|
+
lat/modules/_graph.py,sha256=MZZnkUS1XYOpBSbR0nwZUyMix5EczQdJBvLZhfz7CM4,4671
|
|
48
|
+
lat/modules/agg.py,sha256=zqTB4Em4tuSzfy4px3iQQfhvTVtJV82Xr_Eel4rWMHI,7116
|
|
49
|
+
lat/modules/base.py,sha256=wMg8UrbQrxqepgnvBz9bc67ywo4zaz-0weNK3n6Q40E,1684
|
|
50
|
+
lat/modules/cluster.py,sha256=08Ls2RZYPzLMJXTvYI4V1-gXmO8zDEQ-SCvTYTPHhcY,4068
|
|
51
|
+
lat/modules/contact.py,sha256=ypxOgOnf1d5LjMhc30iwtWFMJjIqSy1ehxuaHxx_ta0,5223
|
|
52
|
+
lat/modules/density.py,sha256=B2sJ5oK-_zd-uo2VDHoFiHOTWius4On1tnGLJoWNlgo,6796
|
|
53
|
+
lat/modules/describe.py,sha256=KHIRqZjv18KB7sXdWFHrJA7sD8xFMyBrf0EIzn_YB3g,1384
|
|
54
|
+
lat/modules/freevol.py,sha256=9faFrq_WaQew4BG7AzKJhmi8-KFD1iX_LywrhBGxqPM,15415
|
|
55
|
+
lat/modules/gyrate.py,sha256=ySh_mQFvSNeNFs1M8w-Sb_AHBOo0jN0gimEZCNcpX74,3582
|
|
56
|
+
lat/modules/hbond.py,sha256=OhV68WM_kRYHLsbHmYe3iuFfE3J017fJVh8g_X_K2h0,14911
|
|
57
|
+
lat/modules/msd.py,sha256=MyBtnZenjo5-MN3vDdEYsEmfRHYqYM65yu6QgaWDTt8,5586
|
|
58
|
+
lat/modules/occupancy.py,sha256=5-xJXMH7thhr7K6DixcKlbx3Q_RmtFOC-bCpLEd62kw,7347
|
|
59
|
+
lat/modules/pistack.py,sha256=d8LCLuGSgIXL-biURkhOjmIEBg9W-1AkV_ZvoVlCnoY,5618
|
|
60
|
+
lat/modules/rdf.py,sha256=eJV981C55lYHQqHmD6BfzpIWbyZHP0748ku_zk2Eqr0,6867
|
|
61
|
+
lat/modules/residence.py,sha256=kiqoUcmoz2Hs1-HoIoc8giLUpFL7vTMaoZrX3dPJktA,7577
|
|
62
|
+
lat/modules/rms.py,sha256=jp093XWbmSK0lO0y8uT2CNpr8RQ9wIRfCFVVnneay-M,6139
|
|
63
|
+
lat/modules/sasa.py,sha256=QkuvkNvd7bBL-tZM1Cst6vF4GDV5eI9gIojzR3KueVY,3359
|
|
64
|
+
lat/modules/select.py,sha256=thtgMK28gEwB75os4YDYeaokybxg41njlNA1etpvX1E,2738
|
|
65
|
+
lat/modules/transport.py,sha256=mh45dp9svltlZHXf-0uos0FoI3-EgaJohijJzWz8Mh8,7806
|
|
66
|
+
lat/plotting/__init__.py,sha256=0ZnzpHadshqLFHpnIjGLiPUrHIyghXBEaxDdKEZ3xN0,189
|
|
67
|
+
lat/plotting/plot1d.py,sha256=DhkM2ZF-0IvTdNEwhFrzLiaGhsyq7lJ_n-DkVUH-DzI,5781
|
|
68
|
+
lat/plotting/plot2d.py,sha256=Hjr9CRZbtHa4YHqjBbh1HQhnJxSqASflBFZcdi4Gy9E,2760
|
|
69
|
+
lammps_analysis_tools-1.0.0.dist-info/LICENSE,sha256=VoRURheY1Xmtlomv4tvkvlSZbBjH0BXJ_ncieFHd1Ug,777
|
|
70
|
+
lammps_analysis_tools-1.0.0.dist-info/METADATA,sha256=tHltDQ7MlzGbZfr3VmxCHZDb_YmLvSTInQ9YXd4uRrI,11354
|
|
71
|
+
lammps_analysis_tools-1.0.0.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
|
72
|
+
lammps_analysis_tools-1.0.0.dist-info/entry_points.txt,sha256=VtlsI-b3Z3N06E5rchT1YUBrVCD6tsK5L-5NGEgzOjg,37
|
|
73
|
+
lammps_analysis_tools-1.0.0.dist-info/top_level.txt,sha256=G6os795izf-wFzozl8F4xCW-epxSDb0hIH32xx1AGQY,4
|
|
74
|
+
lammps_analysis_tools-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
lat
|
lat/__init__.py
ADDED
lat/__main__.py
ADDED
lat/cli.py
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
"""lat command line: lat <module> -s <data> -f <traj> [...]."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import json
|
|
7
|
+
import sys
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
from . import __version__
|
|
11
|
+
from .config import load as load_config
|
|
12
|
+
from .core.context import Context
|
|
13
|
+
from .core.errors import LatError, Logger, get_logger, set_logger
|
|
14
|
+
from .core.io import open_system
|
|
15
|
+
from .core.output import write_all
|
|
16
|
+
from .core.selection import read_ndx
|
|
17
|
+
from .modules import all_modules, get
|
|
18
|
+
|
|
19
|
+
_ALLOWED_UNITS = {"real", "metal", "lj"}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _type_of(type_name):
|
|
23
|
+
return {"str": str, "int": int, "float": float}.get(type_name)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def build_parser(cls, cfg=None) -> argparse.ArgumentParser:
|
|
27
|
+
epilog = (f"manual: docs/{cls.help_doc or 'manual/index.md'} | "
|
|
28
|
+
f"`lat describe -module {cls.name}` for the full contract; "
|
|
29
|
+
"defaults come from the lat config")
|
|
30
|
+
parser = argparse.ArgumentParser(
|
|
31
|
+
prog=f"lat {cls.name}", description=cls.summary, epilog=epilog,
|
|
32
|
+
formatter_class=argparse.RawDescriptionHelpFormatter, add_help=True
|
|
33
|
+
)
|
|
34
|
+
if getattr(cls, "requires_topology", True):
|
|
35
|
+
parser.add_argument("-s", "-topo", dest="topo", required=True,
|
|
36
|
+
help="topology: LAMMPS .data/.lmp (or GROMACS .tpr/.gro/.pdb)")
|
|
37
|
+
parser.add_argument("-f", "-traj", dest="traj",
|
|
38
|
+
help="trajectory: LAMMPS .lammpstrj (or GROMACS .xtc/.trr/.gro)")
|
|
39
|
+
parser.add_argument("-o", dest="output",
|
|
40
|
+
help="output basename (default: topology file stem)")
|
|
41
|
+
parser.add_argument("-unit", dest="unit",
|
|
42
|
+
help="length unit: real|metal|lj (default: config io.default_unit)")
|
|
43
|
+
parser.add_argument("-style", dest="style",
|
|
44
|
+
help="force the LAMMPS atom_style when the Atoms header is ambiguous")
|
|
45
|
+
parser.add_argument("-types", dest="types",
|
|
46
|
+
help="explicit type->element file (one 'type element' pair per line)")
|
|
47
|
+
parser.add_argument("-index", "-n", dest="index",
|
|
48
|
+
help="GROMACS .ndx file providing named groups for selections")
|
|
49
|
+
parser.add_argument("-debug", dest="debug", action="store_true",
|
|
50
|
+
help="also write a JSON audit next to the CSV")
|
|
51
|
+
parser.add_argument("-v", dest="verbose", action="store_true",
|
|
52
|
+
help="show INFO progress on stderr")
|
|
53
|
+
for p in cls.params:
|
|
54
|
+
help_text = p.help
|
|
55
|
+
if p.config and cfg is not None:
|
|
56
|
+
val = cfg.get(p.config)
|
|
57
|
+
if val is not None:
|
|
58
|
+
help_text = f"{help_text} [default: {val}]".strip()
|
|
59
|
+
kwargs = {"help": help_text}
|
|
60
|
+
if p.choices:
|
|
61
|
+
kwargs["choices"] = list(p.choices)
|
|
62
|
+
if p.type == "flag":
|
|
63
|
+
parser.add_argument(*p.flags, dest=p.name, action="store_true", default=None, **kwargs)
|
|
64
|
+
else:
|
|
65
|
+
parser.add_argument(*p.flags, dest=p.name, type=_type_of(p.type), default=None, **kwargs)
|
|
66
|
+
return parser
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _parse_types_file(path) -> dict[int, str]:
|
|
70
|
+
mapping = {}
|
|
71
|
+
with open(path) as fh:
|
|
72
|
+
for line in fh:
|
|
73
|
+
line = line.split("#")[0].strip()
|
|
74
|
+
if not line:
|
|
75
|
+
continue
|
|
76
|
+
parts = line.replace(",", " ").split()
|
|
77
|
+
if len(parts) < 2:
|
|
78
|
+
continue
|
|
79
|
+
a, b = parts[0], parts[1]
|
|
80
|
+
if a.isdigit():
|
|
81
|
+
mapping[int(a)] = b.capitalize()
|
|
82
|
+
elif b.isdigit():
|
|
83
|
+
mapping[int(b)] = a.capitalize()
|
|
84
|
+
if not mapping:
|
|
85
|
+
raise LatError(f"{path}: no type->element pairs parsed")
|
|
86
|
+
return mapping
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _run_plot(kind: str, argv) -> int:
|
|
90
|
+
parser = argparse.ArgumentParser(prog=f"lat {kind}")
|
|
91
|
+
parser.add_argument("-f", dest="csv", required=True,
|
|
92
|
+
help="lat output CSV (header carries title/xlabel/ylabel/columns)")
|
|
93
|
+
parser.add_argument("-o", dest="out", help="output image path")
|
|
94
|
+
parser.add_argument("-title", dest="title", help="override the header title")
|
|
95
|
+
parser.add_argument("-smooth", dest="smooth", choices=("none", "gaussian", "savgol"),
|
|
96
|
+
help="smooth the plotted curve(s); the CSV stays raw")
|
|
97
|
+
if kind == "plot1d":
|
|
98
|
+
parser.add_argument("-columns", dest="columns", nargs="+", metavar="NAME",
|
|
99
|
+
help="only draw these y columns (comma- or space-separated); "
|
|
100
|
+
"the x axis is always the first column")
|
|
101
|
+
parser.add_argument("-bar", dest="bar", action="store_true",
|
|
102
|
+
help="grouped bar chart, one bar per y column")
|
|
103
|
+
parser.add_argument("-stack", dest="stack", action="store_true",
|
|
104
|
+
help="stacked bar chart; y columns are normalized to "
|
|
105
|
+
"occupancy fractions")
|
|
106
|
+
args = parser.parse_args(argv)
|
|
107
|
+
from .plotting import plot1d, plot2d
|
|
108
|
+
|
|
109
|
+
cfg = load_config()
|
|
110
|
+
smooth = args.smooth or str(cfg.get("plot.smooth", default="none") or "none")
|
|
111
|
+
sm = {
|
|
112
|
+
"window": int(cfg.get("plot.savgol_window", default=5) or 5),
|
|
113
|
+
"order": int(cfg.get("plot.savgol_order", default=2) or 2),
|
|
114
|
+
"sigma": float(cfg.get("plot.gaussian_sigma", default=1.0) or 1.0),
|
|
115
|
+
}
|
|
116
|
+
if kind == "plot1d":
|
|
117
|
+
if args.bar and args.stack:
|
|
118
|
+
raise LatError("-bar and -stack are mutually exclusive")
|
|
119
|
+
col_sel = None
|
|
120
|
+
if args.columns:
|
|
121
|
+
col_sel = [c for tok in args.columns
|
|
122
|
+
for c in (t.strip() for t in tok.split(",")) if c]
|
|
123
|
+
mode = "bar" if args.bar else "stack" if args.stack else "line"
|
|
124
|
+
out = plot1d(args.csv, out=args.out, title=args.title, smooth=smooth,
|
|
125
|
+
columns=col_sel, mode=mode, **sm)
|
|
126
|
+
else:
|
|
127
|
+
out = plot2d(args.csv, out=args.out, title=args.title, smooth=smooth, **sm)
|
|
128
|
+
print(f"wrote {out}", file=sys.stderr)
|
|
129
|
+
return 0
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _apply_config_paths(cfg) -> None:
|
|
133
|
+
pass
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def main(argv=None) -> int:
|
|
137
|
+
argv = list(sys.argv[1:] if argv is None else argv)
|
|
138
|
+
if not argv or argv[0] in ("-h", "--help", "help"):
|
|
139
|
+
_top_help()
|
|
140
|
+
return 0
|
|
141
|
+
if argv[0] in ("-V", "--version"):
|
|
142
|
+
print(f"lat {__version__}")
|
|
143
|
+
return 0
|
|
144
|
+
|
|
145
|
+
module_name = argv[0]
|
|
146
|
+
if module_name in ("plot1d", "plot2d"):
|
|
147
|
+
try:
|
|
148
|
+
return _run_plot(module_name, argv[1:])
|
|
149
|
+
except LatError as exc:
|
|
150
|
+
print(f"[lat ERROR] {exc}", file=sys.stderr)
|
|
151
|
+
return 1
|
|
152
|
+
|
|
153
|
+
try:
|
|
154
|
+
cfg = load_config()
|
|
155
|
+
logger = Logger(level="warning")
|
|
156
|
+
set_logger(logger)
|
|
157
|
+
cls = get(module_name)
|
|
158
|
+
parser = build_parser(cls, cfg)
|
|
159
|
+
args = parser.parse_args(argv[1:])
|
|
160
|
+
|
|
161
|
+
if getattr(args, "verbose", None):
|
|
162
|
+
logger.level = "info"
|
|
163
|
+
elif cfg.get("logger.level"):
|
|
164
|
+
logger.level = str(cfg.get("logger.level"))
|
|
165
|
+
|
|
166
|
+
command = "lat " + " ".join(argv)
|
|
167
|
+
_execute(cls, args, cfg, command)
|
|
168
|
+
return 0
|
|
169
|
+
except LatError as exc:
|
|
170
|
+
print(f"[lat ERROR] {exc}", file=sys.stderr)
|
|
171
|
+
return 1
|
|
172
|
+
except KeyboardInterrupt:
|
|
173
|
+
print("[lat ERROR] interrupted", file=sys.stderr)
|
|
174
|
+
return 130
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _execute(cls, args, cfg, command):
|
|
178
|
+
logger = get_logger()
|
|
179
|
+
provided = {}
|
|
180
|
+
for p in cls.params:
|
|
181
|
+
provided[p.name] = getattr(args, p.name, None)
|
|
182
|
+
params = cls.resolve_defaults(cfg, provided)
|
|
183
|
+
|
|
184
|
+
mod = cls()
|
|
185
|
+
if not getattr(cls, "requires_topology", True):
|
|
186
|
+
mod.run(None, **params)
|
|
187
|
+
return []
|
|
188
|
+
|
|
189
|
+
unit = args.unit or cfg.get("io.default_unit")
|
|
190
|
+
if args.unit is None:
|
|
191
|
+
logger.info(f"no -unit given; assuming {unit} (Angstrom)")
|
|
192
|
+
if unit not in _ALLOWED_UNITS:
|
|
193
|
+
raise LatError(f"unit {unit!r} not supported (allowed: {sorted(_ALLOWED_UNITS)})")
|
|
194
|
+
|
|
195
|
+
ndx = read_ndx(args.index) if args.index else None
|
|
196
|
+
import time as _time
|
|
197
|
+
_t0 = _time.time()
|
|
198
|
+
logger.notice(f"reading topology {args.topo}")
|
|
199
|
+
topo, source = open_system(args.topo, args.traj, style=args.style, cfg=cfg)
|
|
200
|
+
logger.notice(f" parsed {topo.n_atoms} atoms in {_time.time() - _t0:.1f}s"
|
|
201
|
+
+ (f"; trajectory {args.traj}" if args.traj else ""))
|
|
202
|
+
|
|
203
|
+
if args.types:
|
|
204
|
+
topo.type_element.update(_parse_types_file(args.types))
|
|
205
|
+
topo.element_problems = {}
|
|
206
|
+
|
|
207
|
+
ctx = Context(topo, source, cfg=cfg, unit=unit, command=command,
|
|
208
|
+
debug=bool(args.debug), ndx=ndx)
|
|
209
|
+
|
|
210
|
+
tables = mod.run(ctx, **params)
|
|
211
|
+
emitted = set()
|
|
212
|
+
for t in tables:
|
|
213
|
+
for w in t.warnings:
|
|
214
|
+
if w not in emitted:
|
|
215
|
+
logger.warning(w)
|
|
216
|
+
emitted.add(w)
|
|
217
|
+
if getattr(cls, "screen_only", False) or not tables:
|
|
218
|
+
return tables
|
|
219
|
+
|
|
220
|
+
basename = args.output or Path(args.topo).stem
|
|
221
|
+
outdir = Path(basename).parent if Path(basename).parent != Path("") else Path(".")
|
|
222
|
+
stem = Path(basename).name
|
|
223
|
+
out_cfg = cfg.get("output", default={}) or {}
|
|
224
|
+
paths = write_all(
|
|
225
|
+
tables,
|
|
226
|
+
basename=stem,
|
|
227
|
+
outdir=outdir,
|
|
228
|
+
ext=out_cfg.get("ext", "csv"),
|
|
229
|
+
suffix=out_cfg.get("suffix", "out"),
|
|
230
|
+
prefix=out_cfg.get("header_prefix", "#"),
|
|
231
|
+
float_format=out_cfg.get("float_format", "%.6g"),
|
|
232
|
+
atomic=bool(out_cfg.get("atomic_write", True)),
|
|
233
|
+
backup_on_conflict=bool(cfg.get("io.backup_on_conflict", default=True)),
|
|
234
|
+
include_audit=bool(out_cfg.get("include_audit", True)),
|
|
235
|
+
command=command,
|
|
236
|
+
version=__version__,
|
|
237
|
+
)
|
|
238
|
+
for path in paths:
|
|
239
|
+
logger.notice(f"wrote {path}")
|
|
240
|
+
if args.debug and out_cfg.get("debug_json", False):
|
|
241
|
+
audit = {
|
|
242
|
+
"command": command,
|
|
243
|
+
"version": __version__,
|
|
244
|
+
"config": str(cfg.path),
|
|
245
|
+
"tables": [{"tag": t.tag, "rows": t.n_rows, "scalars": t.scalars,
|
|
246
|
+
"selection": t.selection, "warnings": t.warnings} for t in tables],
|
|
247
|
+
"warnings": logger.warnings,
|
|
248
|
+
}
|
|
249
|
+
apath = Path(outdir) / f"{stem}.debug.json"
|
|
250
|
+
with open(apath, "w") as fh:
|
|
251
|
+
json.dump(audit, fh, indent=2)
|
|
252
|
+
logger.info(f"wrote {apath}")
|
|
253
|
+
return tables
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def _top_help() -> None:
|
|
257
|
+
print("lat — LAMMPS Analysis Tool")
|
|
258
|
+
print(f"version {__version__}")
|
|
259
|
+
print("\nusage: lat <module> -s <data> [-f <traj>] [options]\n")
|
|
260
|
+
print("modules:")
|
|
261
|
+
for name in sorted(all_modules()):
|
|
262
|
+
print(f" {name:<12} {get(name).summary}")
|
|
263
|
+
print("\nplotting:")
|
|
264
|
+
print(" plot1d plot a 1D CSV")
|
|
265
|
+
print(" plot2d plot a 2D CSV")
|
|
266
|
+
print("\n describe -module <name> show a module's parameters and contract")
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
if __name__ == "__main__":
|
|
270
|
+
sys.exit(main())
|