GraphAtoms 2.3.3__tar.gz → 3.0.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.
- graphatoms-3.0.0/PKG-INFO +305 -0
- graphatoms-3.0.0/README.md +268 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/pyproject.toml +11 -24
- {graphatoms-2.3.3 → graphatoms-3.0.0}/pyproject.toml.orig +16 -36
- graphatoms-3.0.0/src/graphatoms/geometry/__init__.py +23 -0
- graphatoms-3.0.0/src/graphatoms/geometry/itlee.py +599 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/system/bonds.py +59 -11
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/system/graph.py +484 -2
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/system/sysCluster.py +4 -1
- graphatoms-2.3.3/PKG-INFO +0 -185
- graphatoms-2.3.3/README.md +0 -143
- graphatoms-2.3.3/src/graphatoms/enterpoint/__init__.py +0 -0
- graphatoms-2.3.3/src/graphatoms/enterpoint/config/__init__.py +0 -116
- graphatoms-2.3.3/src/graphatoms/enterpoint/config/atoms/__init__.py +0 -24
- graphatoms-2.3.3/src/graphatoms/enterpoint/config/atoms/aseread.yaml +0 -5
- graphatoms-2.3.3/src/graphatoms/enterpoint/config/atoms/octahedron.yaml +0 -7
- graphatoms-2.3.3/src/graphatoms/enterpoint/config/bonds/__init__.py +0 -23
- graphatoms-2.3.3/src/graphatoms/enterpoint/config/bonds/raw.yaml +0 -8
- graphatoms-2.3.3/src/graphatoms/enterpoint/config/calculator/__init__.py +0 -29
- graphatoms-2.3.3/src/graphatoms/enterpoint/config/calculator/emt.yaml +0 -4
- graphatoms-2.3.3/src/graphatoms/enterpoint/config/calculator/nequip.yaml +0 -9
- graphatoms-2.3.3/src/graphatoms/enterpoint/config/example.yaml +0 -71
- graphatoms-2.3.3/src/graphatoms/enterpoint/config/run.yaml +0 -25
- graphatoms-2.3.3/src/graphatoms/enterpoint/network/__init__.py +0 -13
- graphatoms-2.3.3/src/graphatoms/enterpoint/network/_clsnetwork.py +0 -808
- graphatoms-2.3.3/src/graphatoms/enterpoint/network/_commands.py +0 -139
- graphatoms-2.3.3/src/graphatoms/enterpoint/network/_metadata.py +0 -405
- graphatoms-2.3.3/src/graphatoms/enterpoint/network/_recorder.py +0 -301
- graphatoms-2.3.3/src/graphatoms/enterpoint/network/_scheduler.py +0 -161
- graphatoms-2.3.3/src/graphatoms/enterpoint/parallel/__init__.py +0 -174
- graphatoms-2.3.3/src/graphatoms/enterpoint/parallel/_base.py +0 -152
- graphatoms-2.3.3/src/graphatoms/enterpoint/parallel/_dask.py +0 -47
- graphatoms-2.3.3/src/graphatoms/enterpoint/parallel/_executorlib.py +0 -48
- graphatoms-2.3.3/src/graphatoms/enterpoint/parallel/_ray.py +0 -121
- graphatoms-2.3.3/src/graphatoms/enterpoint/runner/__init__.py +0 -35
- graphatoms-2.3.3/src/graphatoms/enterpoint/runner/common/__init__.py +0 -21
- graphatoms-2.3.3/src/graphatoms/enterpoint/runner/common/_base.py +0 -426
- graphatoms-2.3.3/src/graphatoms/enterpoint/runner/common/_errors.py +0 -69
- graphatoms-2.3.3/src/graphatoms/enterpoint/runner/common/_helper.py +0 -847
- graphatoms-2.3.3/src/graphatoms/enterpoint/runner/general/__init__.py +0 -0
- graphatoms-2.3.3/src/graphatoms/enterpoint/runner/general/_expl.py +0 -460
- graphatoms-2.3.3/src/graphatoms/enterpoint/runner/general/otfkmc.py +0 -263
- graphatoms-2.3.3/src/graphatoms/enterpoint/runner/general/rxngen.py +0 -161
- graphatoms-2.3.3/src/graphatoms/enterpoint/runner/v2/__init__.py +0 -0
- graphatoms-2.3.3/src/graphatoms/enterpoint/runner/v2/_helperv2.py +0 -427
- graphatoms-2.3.3/src/graphatoms/enterpoint/runner/v2/general/__init__.py +0 -0
- graphatoms-2.3.3/src/graphatoms/enterpoint/runner/v2/general/_expl.py +0 -160
- graphatoms-2.3.3/src/graphatoms/enterpoint/runner/v2/general/otfkmc.py +0 -16
- graphatoms-2.3.3/src/graphatoms/enterpoint/runner/v2/general/rxngen.py +0 -18
- graphatoms-2.3.3/src/graphatoms/enterpoint/runner/v2/ray/__init__.py +0 -0
- graphatoms-2.3.3/src/graphatoms/enterpoint/runner/v2/ray/_expl.py +0 -51
- graphatoms-2.3.3/src/graphatoms/enterpoint/runner/v2/ray/_helper.py +0 -183
- graphatoms-2.3.3/src/graphatoms/enterpoint/runner/v2/ray/otfkmc.py +0 -9
- graphatoms-2.3.3/src/graphatoms/enterpoint/runner/v2/ray/rxngen.py +0 -5
- graphatoms-2.3.3/src/graphatoms/geometry/__init__.py +0 -11
- graphatoms-2.3.3/src/graphatoms/reaction/__init__.py +0 -16
- graphatoms-2.3.3/src/graphatoms/reaction/_event.py +0 -632
- graphatoms-2.3.3/src/graphatoms/reaction/reaction.py +0 -48
- graphatoms-2.3.3/src/graphatoms/reaction/xxsorption.py +0 -214
- graphatoms-2.3.3/src/graphatoms/utils/adsorption.py +0 -794
- graphatoms-2.3.3/src/graphatoms/utils/aseqhull.py +0 -89
- graphatoms-2.3.3/src/graphatoms/utils/asetools.py +0 -420
- graphatoms-2.3.3/src/graphatoms/utils/logger.py +0 -69
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/LICENSE +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/__init__.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/arrayapi/__init__.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/arrayapi/compat.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/arrayapi/typing.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/dataclasses/__init__.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/dataclasses/_numpydantic.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/dataclasses/_pydantic2pyarrow.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/dataclasses/_pydanticMixin.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/dataclasses/_pydanticModel.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/dataclasses/graph.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/geometry/_bond_list.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/geometry/_distance_pairs.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/geometry/_inner_outer.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/geometry/_neighbor_list.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/geometry/mic.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/geometry/rotation.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/geometry/sample.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/system/__init__.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/system/atoms.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/system/database/__init__.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/system/database/abc.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/system/database/dict.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/system/database/dir.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/system/database/hdf5.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/system/database/sqliteASE.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/system/sysGas.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/system/system.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/utils/__init__.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/utils/bytestool.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/utils/parser.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/utils/rdutils.py +0 -0
- {graphatoms-2.3.3 → graphatoms-3.0.0}/src/graphatoms/utils/subgraph.py +0 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: graphatoms
|
|
3
|
+
Version: 3.0.0
|
|
4
|
+
Summary: The Chemical Core Class for Graph Theory Analysis.
|
|
5
|
+
Keywords: chemistry,graph theory,reaction,event,KMC
|
|
6
|
+
Author: LiuGaoyong
|
|
7
|
+
Author-email: LiuGaoyong <liugaoyong_88@163.com>
|
|
8
|
+
License-Expression: GPL-3.0-or-later
|
|
9
|
+
License-File: src/LICENSE
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Requires-Dist: ase
|
|
14
|
+
Requires-Dist: pymatgen>2023.6
|
|
15
|
+
Requires-Dist: rdkit>=2025
|
|
16
|
+
Requires-Dist: numpy>=2,<3
|
|
17
|
+
Requires-Dist: scipy>=1.10,<2
|
|
18
|
+
Requires-Dist: scikit-learn>=1.5
|
|
19
|
+
Requires-Dist: array-api-compat>=1.10
|
|
20
|
+
Requires-Dist: array-api-extra>=0.10
|
|
21
|
+
Requires-Dist: pyarrow
|
|
22
|
+
Requires-Dist: pandas
|
|
23
|
+
Requires-Dist: igraph>=0.11
|
|
24
|
+
Requires-Dist: h5py>=3.16
|
|
25
|
+
Requires-Dist: numpydantic
|
|
26
|
+
Requires-Dist: pydantic>=2.10
|
|
27
|
+
Requires-Dist: tomli ; python_full_version < '3.11'
|
|
28
|
+
Requires-Dist: tomli-w
|
|
29
|
+
Requires-Dist: pyyaml>=6.0
|
|
30
|
+
Requires-Dist: hydra-core>=1.1
|
|
31
|
+
Requires-Dist: typing-extensions
|
|
32
|
+
Requires-Python: >=3.12
|
|
33
|
+
Project-URL: Homepage, https://github.com/LiuGaoyong/GraphAtoms
|
|
34
|
+
Project-URL: Repository, https://github.com/LiuGaoyong/GraphAtoms
|
|
35
|
+
Project-URL: Issues, https://github.com/LiuGaoyong/GraphAtoms/issues/
|
|
36
|
+
Description-Content-Type: text/markdown
|
|
37
|
+
|
|
38
|
+
# graphatoms
|
|
39
|
+
|
|
40
|
+
[](https://anaconda.org/conda-forge/graphatoms)
|
|
41
|
+
[](https://anaconda.org/conda-forge/graphatoms)
|
|
42
|
+
[](https://pypi.org/project/graphatoms/)
|
|
43
|
+
[](https://pepy.tech/projects/graphatoms)
|
|
44
|
+
|
|
45
|
+
The chemical core classes for graph-theory analysis of atomistic systems.
|
|
46
|
+
|
|
47
|
+
`graphatoms` represents extended systems, clusters and gas molecules as
|
|
48
|
+
coloured bond graphs. Everything is a frozen, validated
|
|
49
|
+
[Pydantic](https://docs.pydantic.dev/) model, so structures, energies and
|
|
50
|
+
graph metadata can be exchanged, stored and compared without losing type
|
|
51
|
+
safety.
|
|
52
|
+
|
|
53
|
+
> **Scope (v3)**: the application layer — CLI entry points, Hydra configs,
|
|
54
|
+
> reaction network generation, KMC runners and parallel executors — now lives
|
|
55
|
+
> in [RxNetGen](https://github.com/LiuGaoyong/RxNetGen). This package provides
|
|
56
|
+
> the reusable chemical core: `arrayapi`, `dataclasses`, `geometry`, `system`
|
|
57
|
+
> and `utils`.
|
|
58
|
+
|
|
59
|
+
## Features
|
|
60
|
+
|
|
61
|
+
- **Validated graph models**: `SysGraph`, `System`, `Cluster` and `Gas` are
|
|
62
|
+
immutable Pydantic models with `numpydantic`-checked arrays.
|
|
63
|
+
- **Multi-format interoperability**: build from and export to ASE `Atoms`,
|
|
64
|
+
pymatgen `Structure`/`Molecule`, RDKit molecules, igraph graphs and plain
|
|
65
|
+
dictionaries.
|
|
66
|
+
- **Chemical graph analysis**: bond perception, neighbour lists, hop
|
|
67
|
+
distances, chordless cycles, connected components, Weisfeiler–Lehman
|
|
68
|
+
hashes, canonical keys (BLISS) and SMARTS extraction.
|
|
69
|
+
- **Structure matching**: pattern-to-system matching
|
|
70
|
+
(`BondGraph.get_match_mode`) and system-to-system equivalence via coloured
|
|
71
|
+
graph isomorphism or **ITLEE** — Invariant and Tolerant Local Environment
|
|
72
|
+
Equivalence (Williams, 2024).
|
|
73
|
+
- **Geometry tooling**: minimum image convention, rotation, sphere sampling
|
|
74
|
+
and distance/bond/neighbour construction.
|
|
75
|
+
- **Thermochemistry**: gas-phase enthalpy, entropy and free energy from
|
|
76
|
+
vibrational frequencies, plus minima/transition-state checks.
|
|
77
|
+
- **Persistent storage**: a uniform database interface with in-memory
|
|
78
|
+
(`dict`), folder, HDF5 and SQLite backends.
|
|
79
|
+
- **Array API compatibility**: backend-agnostic helpers that work with
|
|
80
|
+
NumPy, PyTorch, JAX, CuPy and other array-API-compliant libraries.
|
|
81
|
+
|
|
82
|
+
## Installation
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pip install graphatoms
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
With conda:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
conda install -c conda-forge graphatoms
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Python 3.12 or newer is required.
|
|
95
|
+
|
|
96
|
+
## Quick start
|
|
97
|
+
|
|
98
|
+
### A periodic system and a local cluster
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
import numpy as np
|
|
102
|
+
from ase.build import fcc111
|
|
103
|
+
|
|
104
|
+
from graphatoms.system import Cluster, System
|
|
105
|
+
|
|
106
|
+
atoms = fcc111("Pt", size=(3, 3, 4), vacuum=10.0)
|
|
107
|
+
system = System.from_ase(
|
|
108
|
+
atoms,
|
|
109
|
+
parse_bonds={"method": "raw"},
|
|
110
|
+
parse_atoms_is_outer_or_not=True, # detect surface atoms
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
print(system.formula, system.natoms, system.nbonds)
|
|
114
|
+
print(system.is_periodic, system.idx_outer)
|
|
115
|
+
|
|
116
|
+
# Grow a movable cluster around atom 0; atoms farther than `env_threshold`
|
|
117
|
+
# are fixed, and atoms closer than `max_moved_threshold` may move.
|
|
118
|
+
cluster = Cluster.from_select(
|
|
119
|
+
system,
|
|
120
|
+
core=np.array([0]),
|
|
121
|
+
method="hop",
|
|
122
|
+
max_moved_threshold=1,
|
|
123
|
+
env_threshold=2,
|
|
124
|
+
)
|
|
125
|
+
print(cluster.ncore, cluster.nmoved, cluster.nfix)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### A gas molecule
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
import numpy as np
|
|
132
|
+
|
|
133
|
+
from graphatoms.system import Gas
|
|
134
|
+
|
|
135
|
+
gas = Gas.from_name("CH4", sticking=1.0)
|
|
136
|
+
gas = gas.update_energetics(
|
|
137
|
+
energy=-0.5,
|
|
138
|
+
fmax=0.02,
|
|
139
|
+
frequencies=np.array(
|
|
140
|
+
[1300.0, 1300.0, 1300.0, 1500.0, 1500.0, 1500.0, 2900.0, 2900.0, 2900.0]
|
|
141
|
+
),
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
print(gas.formula, gas.natoms)
|
|
145
|
+
print(gas.get_enthalpy(temp=300.0))
|
|
146
|
+
print(gas.get_free_energy(temp=300.0))
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Equivalence checks
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
# `other` is another SysGraph with the same number of atoms.
|
|
153
|
+
same_topology = system.is_equivalent(other, method="graph")
|
|
154
|
+
same_geometry = system.is_equivalent(
|
|
155
|
+
other,
|
|
156
|
+
method="itlee",
|
|
157
|
+
tolerance=0.1, # L2 tolerance in Å
|
|
158
|
+
fields=("numbers", "is_fix"),
|
|
159
|
+
)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
`method="graph"` compares the coloured bond graph (hash bucket first, then
|
|
163
|
+
igraph isomorphism). `method="itlee"` compares equal-sized coloured point
|
|
164
|
+
clouds under rotation, translation and atom permutation. For
|
|
165
|
+
pattern-to-system queries, use `BondGraph.get_match_mode`.
|
|
166
|
+
|
|
167
|
+
### Storage
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
from pathlib import Path
|
|
171
|
+
|
|
172
|
+
from graphatoms.system import SysGraph
|
|
173
|
+
from graphatoms.system.database import get_db
|
|
174
|
+
|
|
175
|
+
db = get_db(format="hdf5", path=Path("systems.h5"))
|
|
176
|
+
db.add(SysGraph.from_ase(atoms, parse_bonds={"method": "raw"}))
|
|
177
|
+
|
|
178
|
+
for key in db:
|
|
179
|
+
stored = SysGraph.from_ase(db[key], parse_bonds=None)
|
|
180
|
+
print(key, stored.formula)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Supported formats: `dict` (default), `folder`/`dir`, `hdf5`/`h5`, `sqlite`.
|
|
184
|
+
Records are stored as ASE `Atoms`; rebuild a graph from a record with
|
|
185
|
+
`SysGraph.from_ase()`.
|
|
186
|
+
|
|
187
|
+
## Module structure
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
src/graphatoms/
|
|
191
|
+
├── arrayapi/ # array-API namespace resolution and typing
|
|
192
|
+
├── dataclasses/ # Pydantic/numpydantic base models, PyArrow schemas
|
|
193
|
+
├── geometry/ # bond_list, neighbor_list, distance_pairs,
|
|
194
|
+
│ # mic, rotation, sample, itlee
|
|
195
|
+
├── system/ # core classes
|
|
196
|
+
│ ├── atoms.py # Box, Energetics, Matter, Structure
|
|
197
|
+
│ ├── bonds.py # BondGraph: graph metrics, hashes, matching
|
|
198
|
+
│ ├── graph.py # SysGraph: structure + bonds + atom tags
|
|
199
|
+
│ ├── system.py # System: full periodic/extended systems
|
|
200
|
+
│ ├── sysCluster.py # Cluster: movable/fixed regions around a site
|
|
201
|
+
│ ├── sysGas.py # Gas: ideal-gas thermochemistry
|
|
202
|
+
│ └── database/ # dict, folder, HDF5, SQLite backends
|
|
203
|
+
└── utils/ # bytestool, parser (Hydra), rdutils, subgraph
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
The public objects live in their submodules rather than the package root:
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
from graphatoms.system import SysGraph, System, Cluster, Gas
|
|
210
|
+
from graphatoms.system.database import get_db
|
|
211
|
+
from graphatoms.geometry import bond_list, neighbor_list, distance_pairs
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Data model
|
|
215
|
+
|
|
216
|
+
`SysGraph` combines four mixins:
|
|
217
|
+
|
|
218
|
+
| Mixin | Contents |
|
|
219
|
+
| ----------- | --------------------------------------------------------------- |
|
|
220
|
+
| `Structure` | `numbers`, `positions`, `cell`/`pbc`, plus `Energetics` |
|
|
221
|
+
| `BondGraph` | bond `pair`, `shift`, `order`, `coordination`, derived `P`/`CN` |
|
|
222
|
+
| `AtomTag` | boolean tags `is_adsorbate`, `is_outer`, `is_core`, `is_fix` |
|
|
223
|
+
| `GasMixin` | `sticking` coefficient and the derived `is_gas` flag |
|
|
224
|
+
|
|
225
|
+
`System` is a `SysGraph` for the full system, `Cluster` is a selected,
|
|
226
|
+
possibly partially fixed region of it, and `Gas` adds a `sticking`
|
|
227
|
+
coefficient and ideal-gas thermodynamics. All of them accept
|
|
228
|
+
`from_ase()`, `to_ase()`, `from_dict()`/`to_dict()`, `from_igraph()`/
|
|
229
|
+
`to_igraph()` and, where meaningful, pymatgen/RDKit conversions.
|
|
230
|
+
|
|
231
|
+
## Requirements
|
|
232
|
+
|
|
233
|
+
Runtime dependencies:
|
|
234
|
+
|
|
235
|
+
- Python >= 3.12
|
|
236
|
+
- ase
|
|
237
|
+
- pymatgen > 2023.6
|
|
238
|
+
- rdkit >= 2025
|
|
239
|
+
- numpy >= 2, < 3
|
|
240
|
+
- scipy >= 1.10
|
|
241
|
+
- scikit-learn >= 1.5
|
|
242
|
+
- array-api-compat >= 1.10
|
|
243
|
+
- array-api-extra >= 0.10
|
|
244
|
+
- pyarrow
|
|
245
|
+
- pandas
|
|
246
|
+
- igraph >= 0.11
|
|
247
|
+
- h5py >= 3.16
|
|
248
|
+
- numpydantic
|
|
249
|
+
- pydantic >= 2.10
|
|
250
|
+
- hydra-core >= 1.1
|
|
251
|
+
- pyyaml >= 6.0
|
|
252
|
+
- tomli-w
|
|
253
|
+
- typing-extensions
|
|
254
|
+
|
|
255
|
+
## Development
|
|
256
|
+
|
|
257
|
+
The project is managed with [pixi](https://pixi.sh/) (or `uv`):
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
pixi install
|
|
261
|
+
pixi run test # pytest -s -vv
|
|
262
|
+
pixi run benchmark # benchmark suite
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
With `uv`:
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
uv sync
|
|
269
|
+
uv run pytest src/tests/ -v
|
|
270
|
+
uv run pytest src/tests-benchmark/ -v
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Lint and format with Ruff:
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
ruff check .
|
|
277
|
+
ruff format .
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Array API compatibility
|
|
281
|
+
|
|
282
|
+
`graphatoms.arrayapi` resolves the active array namespace, and
|
|
283
|
+
`graphatoms.utils.subgraph` implements backend-agnostic graph helpers:
|
|
284
|
+
|
|
285
|
+
- `subgraph()` — extract an induced subgraph from edge indices
|
|
286
|
+
- `map_index()` — map indices to positions in a reference index array
|
|
287
|
+
- `index_to_mask()` — convert indices to a boolean mask
|
|
288
|
+
- `maybe_num_nodes()` — infer the node count from edge indices
|
|
289
|
+
|
|
290
|
+
These functions only use Array API standard operations, so the same code runs
|
|
291
|
+
on NumPy, PyTorch and JAX arrays.
|
|
292
|
+
|
|
293
|
+
## License
|
|
294
|
+
|
|
295
|
+
GPL-3.0-or-later
|
|
296
|
+
|
|
297
|
+
## Authors
|
|
298
|
+
|
|
299
|
+
- LiuGaoyong (liugaoyong_88@163.com)
|
|
300
|
+
|
|
301
|
+
## Links
|
|
302
|
+
|
|
303
|
+
- Homepage: https://github.com/LiuGaoyong/GraphAtoms
|
|
304
|
+
- Repository: https://github.com/LiuGaoyong/GraphAtoms
|
|
305
|
+
- Issues: https://github.com/LiuGaoyong/GraphAtoms/issues/
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# graphatoms
|
|
2
|
+
|
|
3
|
+
[](https://anaconda.org/conda-forge/graphatoms)
|
|
4
|
+
[](https://anaconda.org/conda-forge/graphatoms)
|
|
5
|
+
[](https://pypi.org/project/graphatoms/)
|
|
6
|
+
[](https://pepy.tech/projects/graphatoms)
|
|
7
|
+
|
|
8
|
+
The chemical core classes for graph-theory analysis of atomistic systems.
|
|
9
|
+
|
|
10
|
+
`graphatoms` represents extended systems, clusters and gas molecules as
|
|
11
|
+
coloured bond graphs. Everything is a frozen, validated
|
|
12
|
+
[Pydantic](https://docs.pydantic.dev/) model, so structures, energies and
|
|
13
|
+
graph metadata can be exchanged, stored and compared without losing type
|
|
14
|
+
safety.
|
|
15
|
+
|
|
16
|
+
> **Scope (v3)**: the application layer — CLI entry points, Hydra configs,
|
|
17
|
+
> reaction network generation, KMC runners and parallel executors — now lives
|
|
18
|
+
> in [RxNetGen](https://github.com/LiuGaoyong/RxNetGen). This package provides
|
|
19
|
+
> the reusable chemical core: `arrayapi`, `dataclasses`, `geometry`, `system`
|
|
20
|
+
> and `utils`.
|
|
21
|
+
|
|
22
|
+
## Features
|
|
23
|
+
|
|
24
|
+
- **Validated graph models**: `SysGraph`, `System`, `Cluster` and `Gas` are
|
|
25
|
+
immutable Pydantic models with `numpydantic`-checked arrays.
|
|
26
|
+
- **Multi-format interoperability**: build from and export to ASE `Atoms`,
|
|
27
|
+
pymatgen `Structure`/`Molecule`, RDKit molecules, igraph graphs and plain
|
|
28
|
+
dictionaries.
|
|
29
|
+
- **Chemical graph analysis**: bond perception, neighbour lists, hop
|
|
30
|
+
distances, chordless cycles, connected components, Weisfeiler–Lehman
|
|
31
|
+
hashes, canonical keys (BLISS) and SMARTS extraction.
|
|
32
|
+
- **Structure matching**: pattern-to-system matching
|
|
33
|
+
(`BondGraph.get_match_mode`) and system-to-system equivalence via coloured
|
|
34
|
+
graph isomorphism or **ITLEE** — Invariant and Tolerant Local Environment
|
|
35
|
+
Equivalence (Williams, 2024).
|
|
36
|
+
- **Geometry tooling**: minimum image convention, rotation, sphere sampling
|
|
37
|
+
and distance/bond/neighbour construction.
|
|
38
|
+
- **Thermochemistry**: gas-phase enthalpy, entropy and free energy from
|
|
39
|
+
vibrational frequencies, plus minima/transition-state checks.
|
|
40
|
+
- **Persistent storage**: a uniform database interface with in-memory
|
|
41
|
+
(`dict`), folder, HDF5 and SQLite backends.
|
|
42
|
+
- **Array API compatibility**: backend-agnostic helpers that work with
|
|
43
|
+
NumPy, PyTorch, JAX, CuPy and other array-API-compliant libraries.
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install graphatoms
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
With conda:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
conda install -c conda-forge graphatoms
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Python 3.12 or newer is required.
|
|
58
|
+
|
|
59
|
+
## Quick start
|
|
60
|
+
|
|
61
|
+
### A periodic system and a local cluster
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
import numpy as np
|
|
65
|
+
from ase.build import fcc111
|
|
66
|
+
|
|
67
|
+
from graphatoms.system import Cluster, System
|
|
68
|
+
|
|
69
|
+
atoms = fcc111("Pt", size=(3, 3, 4), vacuum=10.0)
|
|
70
|
+
system = System.from_ase(
|
|
71
|
+
atoms,
|
|
72
|
+
parse_bonds={"method": "raw"},
|
|
73
|
+
parse_atoms_is_outer_or_not=True, # detect surface atoms
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
print(system.formula, system.natoms, system.nbonds)
|
|
77
|
+
print(system.is_periodic, system.idx_outer)
|
|
78
|
+
|
|
79
|
+
# Grow a movable cluster around atom 0; atoms farther than `env_threshold`
|
|
80
|
+
# are fixed, and atoms closer than `max_moved_threshold` may move.
|
|
81
|
+
cluster = Cluster.from_select(
|
|
82
|
+
system,
|
|
83
|
+
core=np.array([0]),
|
|
84
|
+
method="hop",
|
|
85
|
+
max_moved_threshold=1,
|
|
86
|
+
env_threshold=2,
|
|
87
|
+
)
|
|
88
|
+
print(cluster.ncore, cluster.nmoved, cluster.nfix)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### A gas molecule
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
import numpy as np
|
|
95
|
+
|
|
96
|
+
from graphatoms.system import Gas
|
|
97
|
+
|
|
98
|
+
gas = Gas.from_name("CH4", sticking=1.0)
|
|
99
|
+
gas = gas.update_energetics(
|
|
100
|
+
energy=-0.5,
|
|
101
|
+
fmax=0.02,
|
|
102
|
+
frequencies=np.array(
|
|
103
|
+
[1300.0, 1300.0, 1300.0, 1500.0, 1500.0, 1500.0, 2900.0, 2900.0, 2900.0]
|
|
104
|
+
),
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
print(gas.formula, gas.natoms)
|
|
108
|
+
print(gas.get_enthalpy(temp=300.0))
|
|
109
|
+
print(gas.get_free_energy(temp=300.0))
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Equivalence checks
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
# `other` is another SysGraph with the same number of atoms.
|
|
116
|
+
same_topology = system.is_equivalent(other, method="graph")
|
|
117
|
+
same_geometry = system.is_equivalent(
|
|
118
|
+
other,
|
|
119
|
+
method="itlee",
|
|
120
|
+
tolerance=0.1, # L2 tolerance in Å
|
|
121
|
+
fields=("numbers", "is_fix"),
|
|
122
|
+
)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
`method="graph"` compares the coloured bond graph (hash bucket first, then
|
|
126
|
+
igraph isomorphism). `method="itlee"` compares equal-sized coloured point
|
|
127
|
+
clouds under rotation, translation and atom permutation. For
|
|
128
|
+
pattern-to-system queries, use `BondGraph.get_match_mode`.
|
|
129
|
+
|
|
130
|
+
### Storage
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
from pathlib import Path
|
|
134
|
+
|
|
135
|
+
from graphatoms.system import SysGraph
|
|
136
|
+
from graphatoms.system.database import get_db
|
|
137
|
+
|
|
138
|
+
db = get_db(format="hdf5", path=Path("systems.h5"))
|
|
139
|
+
db.add(SysGraph.from_ase(atoms, parse_bonds={"method": "raw"}))
|
|
140
|
+
|
|
141
|
+
for key in db:
|
|
142
|
+
stored = SysGraph.from_ase(db[key], parse_bonds=None)
|
|
143
|
+
print(key, stored.formula)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Supported formats: `dict` (default), `folder`/`dir`, `hdf5`/`h5`, `sqlite`.
|
|
147
|
+
Records are stored as ASE `Atoms`; rebuild a graph from a record with
|
|
148
|
+
`SysGraph.from_ase()`.
|
|
149
|
+
|
|
150
|
+
## Module structure
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
src/graphatoms/
|
|
154
|
+
├── arrayapi/ # array-API namespace resolution and typing
|
|
155
|
+
├── dataclasses/ # Pydantic/numpydantic base models, PyArrow schemas
|
|
156
|
+
├── geometry/ # bond_list, neighbor_list, distance_pairs,
|
|
157
|
+
│ # mic, rotation, sample, itlee
|
|
158
|
+
├── system/ # core classes
|
|
159
|
+
│ ├── atoms.py # Box, Energetics, Matter, Structure
|
|
160
|
+
│ ├── bonds.py # BondGraph: graph metrics, hashes, matching
|
|
161
|
+
│ ├── graph.py # SysGraph: structure + bonds + atom tags
|
|
162
|
+
│ ├── system.py # System: full periodic/extended systems
|
|
163
|
+
│ ├── sysCluster.py # Cluster: movable/fixed regions around a site
|
|
164
|
+
│ ├── sysGas.py # Gas: ideal-gas thermochemistry
|
|
165
|
+
│ └── database/ # dict, folder, HDF5, SQLite backends
|
|
166
|
+
└── utils/ # bytestool, parser (Hydra), rdutils, subgraph
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
The public objects live in their submodules rather than the package root:
|
|
170
|
+
|
|
171
|
+
```python
|
|
172
|
+
from graphatoms.system import SysGraph, System, Cluster, Gas
|
|
173
|
+
from graphatoms.system.database import get_db
|
|
174
|
+
from graphatoms.geometry import bond_list, neighbor_list, distance_pairs
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Data model
|
|
178
|
+
|
|
179
|
+
`SysGraph` combines four mixins:
|
|
180
|
+
|
|
181
|
+
| Mixin | Contents |
|
|
182
|
+
| ----------- | --------------------------------------------------------------- |
|
|
183
|
+
| `Structure` | `numbers`, `positions`, `cell`/`pbc`, plus `Energetics` |
|
|
184
|
+
| `BondGraph` | bond `pair`, `shift`, `order`, `coordination`, derived `P`/`CN` |
|
|
185
|
+
| `AtomTag` | boolean tags `is_adsorbate`, `is_outer`, `is_core`, `is_fix` |
|
|
186
|
+
| `GasMixin` | `sticking` coefficient and the derived `is_gas` flag |
|
|
187
|
+
|
|
188
|
+
`System` is a `SysGraph` for the full system, `Cluster` is a selected,
|
|
189
|
+
possibly partially fixed region of it, and `Gas` adds a `sticking`
|
|
190
|
+
coefficient and ideal-gas thermodynamics. All of them accept
|
|
191
|
+
`from_ase()`, `to_ase()`, `from_dict()`/`to_dict()`, `from_igraph()`/
|
|
192
|
+
`to_igraph()` and, where meaningful, pymatgen/RDKit conversions.
|
|
193
|
+
|
|
194
|
+
## Requirements
|
|
195
|
+
|
|
196
|
+
Runtime dependencies:
|
|
197
|
+
|
|
198
|
+
- Python >= 3.12
|
|
199
|
+
- ase
|
|
200
|
+
- pymatgen > 2023.6
|
|
201
|
+
- rdkit >= 2025
|
|
202
|
+
- numpy >= 2, < 3
|
|
203
|
+
- scipy >= 1.10
|
|
204
|
+
- scikit-learn >= 1.5
|
|
205
|
+
- array-api-compat >= 1.10
|
|
206
|
+
- array-api-extra >= 0.10
|
|
207
|
+
- pyarrow
|
|
208
|
+
- pandas
|
|
209
|
+
- igraph >= 0.11
|
|
210
|
+
- h5py >= 3.16
|
|
211
|
+
- numpydantic
|
|
212
|
+
- pydantic >= 2.10
|
|
213
|
+
- hydra-core >= 1.1
|
|
214
|
+
- pyyaml >= 6.0
|
|
215
|
+
- tomli-w
|
|
216
|
+
- typing-extensions
|
|
217
|
+
|
|
218
|
+
## Development
|
|
219
|
+
|
|
220
|
+
The project is managed with [pixi](https://pixi.sh/) (or `uv`):
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
pixi install
|
|
224
|
+
pixi run test # pytest -s -vv
|
|
225
|
+
pixi run benchmark # benchmark suite
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
With `uv`:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
uv sync
|
|
232
|
+
uv run pytest src/tests/ -v
|
|
233
|
+
uv run pytest src/tests-benchmark/ -v
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Lint and format with Ruff:
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
ruff check .
|
|
240
|
+
ruff format .
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Array API compatibility
|
|
244
|
+
|
|
245
|
+
`graphatoms.arrayapi` resolves the active array namespace, and
|
|
246
|
+
`graphatoms.utils.subgraph` implements backend-agnostic graph helpers:
|
|
247
|
+
|
|
248
|
+
- `subgraph()` — extract an induced subgraph from edge indices
|
|
249
|
+
- `map_index()` — map indices to positions in a reference index array
|
|
250
|
+
- `index_to_mask()` — convert indices to a boolean mask
|
|
251
|
+
- `maybe_num_nodes()` — infer the node count from edge indices
|
|
252
|
+
|
|
253
|
+
These functions only use Array API standard operations, so the same code runs
|
|
254
|
+
on NumPy, PyTorch and JAX arrays.
|
|
255
|
+
|
|
256
|
+
## License
|
|
257
|
+
|
|
258
|
+
GPL-3.0-or-later
|
|
259
|
+
|
|
260
|
+
## Authors
|
|
261
|
+
|
|
262
|
+
- LiuGaoyong (liugaoyong_88@163.com)
|
|
263
|
+
|
|
264
|
+
## Links
|
|
265
|
+
|
|
266
|
+
- Homepage: https://github.com/LiuGaoyong/GraphAtoms
|
|
267
|
+
- Repository: https://github.com/LiuGaoyong/GraphAtoms
|
|
268
|
+
- Issues: https://github.com/LiuGaoyong/GraphAtoms/issues/
|
|
@@ -4,7 +4,7 @@ build-backend = "uv_build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "graphatoms"
|
|
7
|
-
version = "
|
|
7
|
+
version = "3.0.0"
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
description = "The Chemical Core Class for Graph Theory Analysis."
|
|
10
10
|
license-files = ["src/LICENSE"]
|
|
@@ -36,17 +36,12 @@ dependencies = [
|
|
|
36
36
|
"igraph>=0.11",
|
|
37
37
|
"h5py>=3.16",
|
|
38
38
|
"numpydantic",
|
|
39
|
-
"ovld",
|
|
40
39
|
"pydantic>=2.10",
|
|
41
|
-
"python-snappy>=0.7.3",
|
|
42
40
|
"tomli; python_version < '3.11'",
|
|
43
41
|
"tomli-w",
|
|
42
|
+
"pyyaml>=6.0",
|
|
43
|
+
"hydra-core>=1.1",
|
|
44
44
|
"typing-extensions",
|
|
45
|
-
"joblib",
|
|
46
|
-
"executorlib",
|
|
47
|
-
"hydra-core",
|
|
48
|
-
"typer",
|
|
49
|
-
"loguru",
|
|
50
45
|
]
|
|
51
46
|
|
|
52
47
|
[project.urls]
|
|
@@ -54,11 +49,6 @@ Homepage = "https://github.com/LiuGaoyong/GraphAtoms"
|
|
|
54
49
|
Repository = "https://github.com/LiuGaoyong/GraphAtoms"
|
|
55
50
|
Issues = "https://github.com/LiuGaoyong/GraphAtoms/issues/"
|
|
56
51
|
|
|
57
|
-
[project.scripts]
|
|
58
|
-
graphatoms-config = "graphatoms.enterpoint.config:print_config"
|
|
59
|
-
graphatoms-network = "graphatoms.enterpoint.network:main"
|
|
60
|
-
graphatoms-run = "graphatoms.enterpoint.runner:run"
|
|
61
|
-
|
|
62
52
|
[[project.authors]]
|
|
63
53
|
name = "LiuGaoyong"
|
|
64
54
|
email = "liugaoyong_88@163.com"
|
|
@@ -66,22 +56,20 @@ email = "liugaoyong_88@163.com"
|
|
|
66
56
|
[dependency-groups]
|
|
67
57
|
dev = [
|
|
68
58
|
"ruff>=0.11",
|
|
69
|
-
"
|
|
59
|
+
"python-snappy>=0.7.3",
|
|
70
60
|
"array-api-strict",
|
|
71
61
|
"pytest>=8.3",
|
|
72
62
|
"pytest-xdist",
|
|
73
63
|
"jupyterlab",
|
|
74
64
|
"chemiscope",
|
|
75
65
|
"nglview",
|
|
76
|
-
"grpcio",
|
|
77
|
-
"ray",
|
|
78
66
|
]
|
|
79
67
|
|
|
80
68
|
[tool.uv]
|
|
81
69
|
package = true
|
|
82
70
|
|
|
83
71
|
[[tool.uv.index]]
|
|
84
|
-
url = "https://mirrors.
|
|
72
|
+
url = "https://mirrors.cernet.edu.cn/pypi/web/simple"
|
|
85
73
|
default = true
|
|
86
74
|
|
|
87
75
|
[tool.pytest.ini_options]
|
|
@@ -162,13 +150,12 @@ pydantic = ">=2.10.0"
|
|
|
162
150
|
numpydantic = ">=1.8.1"
|
|
163
151
|
python-snappy = ">=0.7.3"
|
|
164
152
|
h5py = ">=3.16"
|
|
165
|
-
hydra-core = ">=1.3.0"
|
|
166
153
|
tomli-w = ">=1.2.0"
|
|
167
|
-
loguru = ">=0.7.3"
|
|
168
154
|
jupyterlab = ">=4.5.8"
|
|
169
|
-
joblib = ">=1.1.0"
|
|
170
|
-
ovld = ">=0.5.15"
|
|
171
155
|
pytest-xdist = ">=3.8.0"
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
156
|
+
nglview = ">=0.14.0"
|
|
157
|
+
ruff = ">=0.11"
|
|
158
|
+
chemiscope = ">=0.1.0"
|
|
159
|
+
pyyaml = ">=6.0"
|
|
160
|
+
hydra-core = ">=1.1"
|
|
161
|
+
typing-extensions = ">=4.12.0"
|