chemparseplot 1.2.0__tar.gz → 1.4.0__tar.gz
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.
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/.gitignore +13 -0
- chemparseplot-1.4.0/PKG-INFO +199 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/_version.py +2 -2
- chemparseplot-1.4.0/chemparseplot/parse/__init__.py +9 -0
- chemparseplot-1.4.0/chemparseplot/parse/chemgp_hdf5.py +174 -0
- chemparseplot-1.4.0/chemparseplot/parse/chemgp_jsonl.py +305 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/parse/eon/neb.py +1 -1
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/parse/neb_utils.py +2 -2
- chemparseplot-1.4.0/chemparseplot/parse/orca/neb/__init__.py +24 -0
- chemparseplot-1.4.0/chemparseplot/parse/orca/neb/opi_parser.py +249 -0
- chemparseplot-1.4.0/chemparseplot/parse/plumed.py +425 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/parse/trajectory/hdf5.py +2 -2
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/parse/trajectory/neb.py +1 -1
- chemparseplot-1.4.0/chemparseplot/plot/__init__.py +36 -0
- chemparseplot-1.4.0/chemparseplot/plot/chemgp.py +1314 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/plot/geomscan.py +8 -1
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/plot/neb.py +358 -12
- chemparseplot-1.4.0/chemparseplot/plot/plumed.py +137 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/plot/theme.py +24 -0
- {chemparseplot-1.2.0/chemparseplot/parse → chemparseplot-1.4.0/chemparseplot/scripts}/__init__.py +0 -2
- chemparseplot-1.4.0/chemparseplot/scripts/plot_gp.py +732 -0
- chemparseplot-1.4.0/chemparseplot/scripts/plt_neb.py +423 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/pyproject.toml +65 -6
- chemparseplot-1.4.0/readme.md +142 -0
- chemparseplot-1.4.0/tests/parse/test_chemgp_hdf5.py +117 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/tests/parse/test_neb_utils.py +1 -1
- chemparseplot-1.4.0/tests/parse/test_plumed.py +167 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/tests/parse/test_trajectory_hdf5.py +2 -2
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/tests/parse/test_trajectory_neb.py +3 -3
- chemparseplot-1.4.0/tests/plot/test_chemgp_utils.py +61 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/tests/plot/test_neb_renderers.py +3 -3
- chemparseplot-1.4.0/tests/scripts/__init__.py +3 -0
- chemparseplot-1.4.0/tests/scripts/test_plot_gp_cli.py +54 -0
- chemparseplot-1.4.0/tests/scripts/test_plt_neb_cli.py +54 -0
- chemparseplot-1.4.0/tests/tutorials/test_chemparseplot.py +151 -0
- chemparseplot-1.2.0/PKG-INFO +0 -140
- chemparseplot-1.2.0/chemparseplot/plot/__init__.py +0 -9
- chemparseplot-1.2.0/readme.md +0 -91
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/LICENSE +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/__init__.py +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/parse/converter.py +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/parse/eon/gprd.py +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/parse/eon/minimization.py +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/parse/eon/saddle_search.py +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/parse/file_.py +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/parse/orca/__init__.py +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/parse/orca/geomscan.py +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/parse/orca/neb/interp.py +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/parse/patterns.py +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/parse/sella/saddle_search.py +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/parse/trajectory/__init__.py +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/plot/structs.py +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/units.py +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/chemparseplot/util.py +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/tests/conftest.py +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/tests/parse/orca/test_geomscan.py +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/tests/parse/orca/test_interp.py +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/tests/parse/test_converter.py +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/tests/parse/test_patterns.py +0 -0
- {chemparseplot-1.2.0 → chemparseplot-1.4.0}/tests/plot/__init__.py +0 -0
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
.pixi
|
|
2
|
+
CLAUDE.md
|
|
3
|
+
.claude/
|
|
2
4
|
apidocs/*
|
|
5
|
+
doc/source/apidocs/
|
|
6
|
+
doc/jupyter_execute/
|
|
7
|
+
doc/build/
|
|
3
8
|
### Generated by gibo (https://github.com/simonwhitaker/gibo)
|
|
4
9
|
### https://raw.github.com/github/gitignore/4488915eec0b3a45b5c63ead28f286819c0917de/Python.gitignore
|
|
5
10
|
|
|
@@ -166,3 +171,11 @@ cython_debug/
|
|
|
166
171
|
/_version.py
|
|
167
172
|
/.pdm-python
|
|
168
173
|
*.ipynb
|
|
174
|
+
|
|
175
|
+
# Dolt database files (added by bd init)
|
|
176
|
+
.dolt/
|
|
177
|
+
*.db
|
|
178
|
+
|
|
179
|
+
# Lychee link checker cache
|
|
180
|
+
.lycheecache
|
|
181
|
+
.beads/
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: chemparseplot
|
|
3
|
+
Version: 1.4.0
|
|
4
|
+
Summary: Parsers and plotting tools for computational chemistry
|
|
5
|
+
Project-URL: Documentation, https://chemparseplot.rgoswami.me
|
|
6
|
+
Project-URL: Issues, https://github.com/HaoZeke/chemparseplot/issues
|
|
7
|
+
Project-URL: Source, https://github.com/HaoZeke/chemparseplot
|
|
8
|
+
Project-URL: Changelog, https://github.com/HaoZeke/chemparseplot/blob/main/CHANGELOG.md
|
|
9
|
+
Author-email: Rohit Goswami <rog32@hi.is>
|
|
10
|
+
License: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: compchem,parser,plot
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Programming Language :: Python
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Requires-Dist: numpy>=1.26.2
|
|
22
|
+
Requires-Dist: pint>=0.22
|
|
23
|
+
Requires-Dist: rgpycrumbs>=1.3.0
|
|
24
|
+
Provides-Extra: all
|
|
25
|
+
Requires-Dist: ase>=3.22; extra == 'all'
|
|
26
|
+
Requires-Dist: cmcrameri>=1.7; extra == 'all'
|
|
27
|
+
Requires-Dist: h5py>=3.0; extra == 'all'
|
|
28
|
+
Requires-Dist: matplotlib>=3.8.2; extra == 'all'
|
|
29
|
+
Requires-Dist: polars>=0.20; extra == 'all'
|
|
30
|
+
Requires-Dist: xyzrender>=0.1.2; extra == 'all'
|
|
31
|
+
Provides-Extra: doc
|
|
32
|
+
Requires-Dist: mdit-py-plugins>=0.3.4; extra == 'doc'
|
|
33
|
+
Requires-Dist: myst-nb>=1; extra == 'doc'
|
|
34
|
+
Requires-Dist: myst-parser>=2; extra == 'doc'
|
|
35
|
+
Requires-Dist: sphinx-autodoc2>=0.5; extra == 'doc'
|
|
36
|
+
Requires-Dist: sphinx-copybutton>=0.5.2; extra == 'doc'
|
|
37
|
+
Requires-Dist: sphinx-library>=1.1.2; extra == 'doc'
|
|
38
|
+
Requires-Dist: sphinx-sitemap>=2.5.1; extra == 'doc'
|
|
39
|
+
Requires-Dist: sphinx-togglebutton>=0.3.2; extra == 'doc'
|
|
40
|
+
Requires-Dist: sphinx>=7.2.6; extra == 'doc'
|
|
41
|
+
Requires-Dist: sphinxcontrib-apidoc>=0.4; extra == 'doc'
|
|
42
|
+
Provides-Extra: lint
|
|
43
|
+
Requires-Dist: ruff>=0.1.6; extra == 'lint'
|
|
44
|
+
Provides-Extra: neb
|
|
45
|
+
Requires-Dist: ase>=3.22; extra == 'neb'
|
|
46
|
+
Requires-Dist: h5py>=3.0; extra == 'neb'
|
|
47
|
+
Requires-Dist: polars>=0.20; extra == 'neb'
|
|
48
|
+
Provides-Extra: plot
|
|
49
|
+
Requires-Dist: cmcrameri>=1.7; extra == 'plot'
|
|
50
|
+
Requires-Dist: matplotlib>=3.8.2; extra == 'plot'
|
|
51
|
+
Provides-Extra: test
|
|
52
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == 'test'
|
|
53
|
+
Requires-Dist: pytest>=7.4.3; extra == 'test'
|
|
54
|
+
Provides-Extra: xyzrender
|
|
55
|
+
Requires-Dist: xyzrender>=0.1.2; extra == 'xyzrender'
|
|
56
|
+
Description-Content-Type: text/markdown
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# Table of Contents
|
|
60
|
+
|
|
61
|
+
- [About](#org69d0d18)
|
|
62
|
+
- [Installation](#org6425b9a)
|
|
63
|
+
- [Ecosystem Overview](#org7717c22)
|
|
64
|
+
- [Features](#org7ec2e1c)
|
|
65
|
+
- [Supported Engines](#org3c6cfc2)
|
|
66
|
+
- [Documentation](#org7d2bbf4)
|
|
67
|
+
- [Contributing](#orgc77604d)
|
|
68
|
+
- [License](#org8180f68)
|
|
69
|
+
- [Acknowledgments](#org7ebb45c)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
<a id="org69d0d18"></a>
|
|
74
|
+
|
|
75
|
+
# About
|
|
76
|
+
|
|
77
|
+

|
|
78
|
+
|
|
79
|
+
[](https://github.com/HaoZeke/chemparseplot/actions/workflows/build_test.yml)
|
|
80
|
+
[](https://github.com/HaoZeke/chemparseplot/actions/workflows/ci_prek.yml)
|
|
81
|
+
[](https://github.com/HaoZeke/chemparseplot/actions/workflows/build_docs.yml)
|
|
82
|
+
[](https://pypi.org/project/chemparseplot/)
|
|
83
|
+
[](https://pypi.org/project/chemparseplot/)
|
|
84
|
+
[](https://opensource.org/licenses/MIT)
|
|
85
|
+
[](https://onegoodtutorial.org/about/badge/?v=1)
|
|
86
|
+
[](https://github.com/pypa/hatch)
|
|
87
|
+
[](https://doi.org/10.5281/zenodo.18529752)
|
|
88
|
+
|
|
89
|
+
A **pure-python**<sup><a id="fnr.butwhy" class="footref" href="#fn.butwhy" role="doc-backlink">1</a></sup> parsing and plotting library for computational
|
|
90
|
+
chemistry outputs. `chemparseplot` extracts structured data from quantum
|
|
91
|
+
chemistry codes (ORCA, eOn, Sella, ChemGP) and produces publication-quality,
|
|
92
|
+
unit-aware visualizations with [scientific color maps](https://www.fabiocrameri.ch/colourmaps/).
|
|
93
|
+
|
|
94
|
+
Computational tasks (surface fitting, structure analysis, interpolation) are
|
|
95
|
+
handled by [`rgpycrumbs`](https://github.com/HaoZeke/rgpycrumbs), which is a required dependency. `chemparseplot` parses
|
|
96
|
+
output files, delegates heavy computation to `rgpycrumbs`, and produces
|
|
97
|
+
publication-quality plots.
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
<a id="org6425b9a"></a>
|
|
101
|
+
|
|
102
|
+
## Installation
|
|
103
|
+
|
|
104
|
+
pip install chemparseplot
|
|
105
|
+
# With plotting support
|
|
106
|
+
pip install "chemparseplot[plot]"
|
|
107
|
+
# Everything
|
|
108
|
+
pip install "chemparseplot[all]"
|
|
109
|
+
|
|
110
|
+
For development:
|
|
111
|
+
|
|
112
|
+
git clone https://github.com/HaoZeke/chemparseplot
|
|
113
|
+
cd chemparseplot
|
|
114
|
+
uv sync --all-extras
|
|
115
|
+
|
|
116
|
+
See the [installation guide](https://chemparseplot.rgoswami.me/installation.html) and [quickstart](https://chemparseplot.rgoswami.me/quickstart.html) for details.
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
<a id="org7717c22"></a>
|
|
120
|
+
|
|
121
|
+
## Ecosystem Overview
|
|
122
|
+
|
|
123
|
+
`chemparseplot` is part of the `rgpycrumbs` suite of interlinked libraries.
|
|
124
|
+
|
|
125
|
+

|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
<a id="org7ec2e1c"></a>
|
|
129
|
+
|
|
130
|
+
## Features
|
|
131
|
+
|
|
132
|
+
- **Parsing** computational chemistry output files into structured data
|
|
133
|
+
- **Plotting** with [scientific color maps](https://www.fabiocrameri.ch/colourmaps/) (camera-ready)
|
|
134
|
+
- **Unit preserving** throughout via `pint`
|
|
135
|
+
- **Computation** delegated to [`rgpycrumbs`](https://github.com/HaoZeke/rgpycrumbs) for surface fitting, interpolation,
|
|
136
|
+
and structure analysis
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
<a id="org3c6cfc2"></a>
|
|
140
|
+
|
|
141
|
+
### Supported Engines
|
|
142
|
+
|
|
143
|
+
- ORCA (**5.x**)
|
|
144
|
+
- Geometry scan (`OPT`) energy profiles
|
|
145
|
+
- Nudged elastic band (`NEB`) path visualization
|
|
146
|
+
- eOn
|
|
147
|
+
- Saddle search parsing (Dimer, GPRD, LBFGS methods)
|
|
148
|
+
- NEB path energy profiles with landscape projections
|
|
149
|
+
- Sella
|
|
150
|
+
- Saddle point optimization result parsing
|
|
151
|
+
- Trajectory formats
|
|
152
|
+
- HDF5 trajectories (ChemGP output with pre-computed forces)
|
|
153
|
+
- Generic ASE-readable formats (extxyz, .traj) for NEB analysis
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
<a id="org7d2bbf4"></a>
|
|
157
|
+
|
|
158
|
+
## Documentation
|
|
159
|
+
|
|
160
|
+
Full documentation is at <https://chemparseplot.rgoswami.me>. This includes:
|
|
161
|
+
|
|
162
|
+
- A [quickstart guide](https://chemparseplot.rgoswami.me/quickstart.html)
|
|
163
|
+
- [Tutorials](https://chemparseplot.rgoswami.me/tutorials/index.html) for common workflows
|
|
164
|
+
- [API reference](https://chemparseplot.rgoswami.me/apidocs/index.html)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
<a id="orgc77604d"></a>
|
|
168
|
+
|
|
169
|
+
## Contributing
|
|
170
|
+
|
|
171
|
+
Contributions are welcome. See [CONTRIBUTING.md](https://github.com/HaoZeke/chemparseplot/blob/main/CONTRIBUTING.md) for development setup and
|
|
172
|
+
guidelines, and our [Code of Conduct](https://github.com/HaoZeke/chemparseplot/blob/main/CODE_OF_CONDUCT.md).
|
|
173
|
+
|
|
174
|
+
For bug reports or questions, open an issue on [GitHub](https://github.com/HaoZeke/chemparseplot/issues).
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
<a id="org8180f68"></a>
|
|
178
|
+
|
|
179
|
+
# License
|
|
180
|
+
|
|
181
|
+
MIT. However, this is an academic resource, so **please cite** as much as possible
|
|
182
|
+
via:
|
|
183
|
+
|
|
184
|
+
- The [Zenodo DOI](https://doi.org/10.5281/zenodo.18529752) for general use.
|
|
185
|
+
- The `wailord` paper for ORCA usage
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
<a id="org7ebb45c"></a>
|
|
189
|
+
|
|
190
|
+
# Acknowledgments
|
|
191
|
+
|
|
192
|
+
This project builds on work supported by the University of Iceland and the
|
|
193
|
+
Icelandic Research Fund. `chemparseplot` relies on [`rgpycrumbs`](https://github.com/HaoZeke/rgpycrumbs) for computational
|
|
194
|
+
modules.
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
# Footnotes
|
|
198
|
+
|
|
199
|
+
<sup><a id="fn.1" href="#fnr.1">1</a></sup> To distinguish it from my other thin-python wrapper projects
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '1.
|
|
32
|
-
__version_tuple__ = version_tuple = (1,
|
|
31
|
+
__version__ = version = '1.4.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 4, 0)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2023-present Rohit Goswami <rog32@hi.is>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
|
|
5
|
+
from chemparseplot.parse import orca, patterns
|
|
6
|
+
|
|
7
|
+
# Lazy imports for modules with optional heavy deps (h5py, pandas)
|
|
8
|
+
# Import directly: from chemparseplot.parse.chemgp_hdf5 import read_h5_table
|
|
9
|
+
# Or: from chemparseplot.parse import plumed
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2023-present Rohit Goswami <rog32@hi.is>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
|
|
5
|
+
"""HDF5 file I/O utilities for ChemGP data.
|
|
6
|
+
|
|
7
|
+
This module provides functions for reading structured data from ChemGP HDF5
|
|
8
|
+
output files. The HDF5 layout mirrors the Julia common_plot.jl helpers.
|
|
9
|
+
|
|
10
|
+
HDF5 Layout
|
|
11
|
+
-----------
|
|
12
|
+
- ``grids/<name>``: 2D arrays with attrs x_range, y_range, x_length, y_length
|
|
13
|
+
- ``table/<name>``: group of same-length 1D arrays
|
|
14
|
+
- ``paths/<name>``: point sequences (x, y or rAB, rBC)
|
|
15
|
+
- ``points/<name>``: point sets (x, y or pc1, pc2)
|
|
16
|
+
- Root attrs: metadata scalars
|
|
17
|
+
|
|
18
|
+
.. versionadded:: 1.7.0
|
|
19
|
+
Extracted from chemgp.plt_gp to standalone module.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from typing import Any
|
|
23
|
+
|
|
24
|
+
import numpy as np
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def read_h5_table(f: Any, name: str = "table") -> Any:
|
|
28
|
+
"""Read a group of same-length vectors as a DataFrame.
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
f
|
|
33
|
+
Open HDF5 file object
|
|
34
|
+
name
|
|
35
|
+
Name of the table group (default: "table")
|
|
36
|
+
|
|
37
|
+
Returns
|
|
38
|
+
-------
|
|
39
|
+
DataFrame
|
|
40
|
+
DataFrame with columns from the HDF5 group
|
|
41
|
+
"""
|
|
42
|
+
import pandas as pd
|
|
43
|
+
|
|
44
|
+
g = f[name]
|
|
45
|
+
cols = {}
|
|
46
|
+
for k in g.keys():
|
|
47
|
+
arr = g[k][()]
|
|
48
|
+
if arr.dtype.kind in {"S", "O"}:
|
|
49
|
+
cols[k] = arr.astype(str).tolist()
|
|
50
|
+
else:
|
|
51
|
+
cols[k] = arr.tolist()
|
|
52
|
+
return pd.DataFrame(cols)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def read_h5_grid(
|
|
56
|
+
f: Any, name: str
|
|
57
|
+
) -> tuple[np.ndarray, np.ndarray | None, np.ndarray | None]:
|
|
58
|
+
"""Read a 2D grid with optional axis ranges.
|
|
59
|
+
|
|
60
|
+
Parameters
|
|
61
|
+
----------
|
|
62
|
+
f
|
|
63
|
+
Open HDF5 file object
|
|
64
|
+
name
|
|
65
|
+
Name of the grid dataset
|
|
66
|
+
|
|
67
|
+
Returns
|
|
68
|
+
-------
|
|
69
|
+
tuple
|
|
70
|
+
(data, x_coords, y_coords) where x_coords and y_coords may be None
|
|
71
|
+
if axis range attributes are not present
|
|
72
|
+
"""
|
|
73
|
+
ds = f[f"grids/{name}"]
|
|
74
|
+
data = ds[()]
|
|
75
|
+
x_coords = None
|
|
76
|
+
y_coords = None
|
|
77
|
+
|
|
78
|
+
if "x_range" in ds.attrs and "x_length" in ds.attrs:
|
|
79
|
+
lo, hi = ds.attrs["x_range"]
|
|
80
|
+
n = int(ds.attrs["x_length"])
|
|
81
|
+
x_coords = np.linspace(lo, hi, n)
|
|
82
|
+
|
|
83
|
+
if "y_range" in ds.attrs and "y_length" in ds.attrs:
|
|
84
|
+
lo, hi = ds.attrs["y_range"]
|
|
85
|
+
n = int(ds.attrs["y_length"])
|
|
86
|
+
y_coords = np.linspace(lo, hi, n)
|
|
87
|
+
|
|
88
|
+
return data, x_coords, y_coords
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def read_h5_path(f: Any, name: str) -> dict[str, np.ndarray]:
|
|
92
|
+
"""Read a path (ordered point sequence).
|
|
93
|
+
|
|
94
|
+
Parameters
|
|
95
|
+
----------
|
|
96
|
+
f
|
|
97
|
+
Open HDF5 file object
|
|
98
|
+
name
|
|
99
|
+
Name of the path dataset
|
|
100
|
+
|
|
101
|
+
Returns
|
|
102
|
+
-------
|
|
103
|
+
dict
|
|
104
|
+
Dictionary mapping coordinate names to arrays
|
|
105
|
+
"""
|
|
106
|
+
g = f[f"paths/{name}"]
|
|
107
|
+
return {k: g[k][()] for k in g.keys()}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def read_h5_points(f: Any, name: str) -> dict[str, np.ndarray]:
|
|
111
|
+
"""Read a point set.
|
|
112
|
+
|
|
113
|
+
Parameters
|
|
114
|
+
----------
|
|
115
|
+
f
|
|
116
|
+
Open HDF5 file object
|
|
117
|
+
name
|
|
118
|
+
Name of the points dataset
|
|
119
|
+
|
|
120
|
+
Returns
|
|
121
|
+
-------
|
|
122
|
+
dict
|
|
123
|
+
Dictionary mapping coordinate names to arrays
|
|
124
|
+
"""
|
|
125
|
+
g = f[f"points/{name}"]
|
|
126
|
+
return {k: g[k][()] for k in g.keys()}
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def read_h5_metadata(f: Any) -> dict[str, Any]:
|
|
130
|
+
"""Read root-level metadata attributes.
|
|
131
|
+
|
|
132
|
+
Parameters
|
|
133
|
+
----------
|
|
134
|
+
f
|
|
135
|
+
Open HDF5 file object
|
|
136
|
+
|
|
137
|
+
Returns
|
|
138
|
+
-------
|
|
139
|
+
dict
|
|
140
|
+
Dictionary of metadata attributes
|
|
141
|
+
"""
|
|
142
|
+
return {k: f.attrs[k] for k in f.attrs.keys()}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def validate_hdf5_structure(
|
|
146
|
+
f: Any, required_groups: list[str] | None = None
|
|
147
|
+
) -> list[str]:
|
|
148
|
+
"""Validate HDF5 file has expected structure.
|
|
149
|
+
|
|
150
|
+
Parameters
|
|
151
|
+
----------
|
|
152
|
+
f
|
|
153
|
+
Open HDF5 file object
|
|
154
|
+
required_groups
|
|
155
|
+
List of required group names (default: ["grids", "table"])
|
|
156
|
+
|
|
157
|
+
Returns
|
|
158
|
+
-------
|
|
159
|
+
list[str]
|
|
160
|
+
List of missing groups (empty if all present)
|
|
161
|
+
|
|
162
|
+
Raises
|
|
163
|
+
------
|
|
164
|
+
ValueError
|
|
165
|
+
If required groups are missing
|
|
166
|
+
"""
|
|
167
|
+
if required_groups is None:
|
|
168
|
+
required_groups = ["grids", "table"]
|
|
169
|
+
|
|
170
|
+
missing = [g for g in required_groups if g not in f]
|
|
171
|
+
if missing:
|
|
172
|
+
msg = f"Invalid HDF5 structure. Missing groups: {missing}"
|
|
173
|
+
raise ValueError(msg)
|
|
174
|
+
return missing
|