GraphAtoms 2.3.1__tar.gz → 2.3.3__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-2.3.1 → graphatoms-2.3.3}/PKG-INFO +2 -2
- {graphatoms-2.3.1 → graphatoms-2.3.3}/pyproject.toml +28 -28
- {graphatoms-2.3.1 → graphatoms-2.3.3}/pyproject.toml.orig +28 -28
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/dataclasses/_pydanticMixin.py +38 -20
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/dataclasses/_pydanticModel.py +1 -1
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/network/_clsnetwork.py +15 -7
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/network/_metadata.py +43 -3
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/network/_scheduler.py +14 -8
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/parallel/__init__.py +22 -6
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/parallel/_base.py +24 -5
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/parallel/_ray.py +35 -12
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/runner/__init__.py +10 -14
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/runner/common/_base.py +6 -3
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/runner/common/_helper.py +7 -5
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/runner/general/otfkmc.py +5 -1
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/runner/general/rxngen.py +24 -14
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/geometry/_bond_list.py +1 -2
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/geometry/_neighbor_list.py +6 -3
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/geometry/sample.py +7 -1
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/system/database/abc.py +8 -5
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/system/graph.py +18 -4
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/utils/adsorption.py +6 -2
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/utils/bytestool.py +52 -1
- {graphatoms-2.3.1 → graphatoms-2.3.3}/README.md +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/LICENSE +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/arrayapi/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/arrayapi/compat.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/arrayapi/typing.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/dataclasses/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/dataclasses/_numpydantic.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/dataclasses/_pydantic2pyarrow.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/dataclasses/graph.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/config/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/config/atoms/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/config/atoms/aseread.yaml +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/config/atoms/octahedron.yaml +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/config/bonds/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/config/bonds/raw.yaml +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/config/calculator/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/config/calculator/emt.yaml +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/config/calculator/nequip.yaml +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/config/example.yaml +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/config/run.yaml +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/network/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/network/_commands.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/network/_recorder.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/parallel/_dask.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/parallel/_executorlib.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/runner/common/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/runner/common/_errors.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/runner/general/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/runner/general/_expl.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/runner/v2/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/runner/v2/_helperv2.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/runner/v2/general/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/runner/v2/general/_expl.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/runner/v2/general/otfkmc.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/runner/v2/general/rxngen.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/runner/v2/ray/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/runner/v2/ray/_expl.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/runner/v2/ray/_helper.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/runner/v2/ray/otfkmc.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/enterpoint/runner/v2/ray/rxngen.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/geometry/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/geometry/_distance_pairs.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/geometry/_inner_outer.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/geometry/mic.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/geometry/rotation.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/reaction/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/reaction/_event.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/reaction/reaction.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/reaction/xxsorption.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/system/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/system/atoms.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/system/bonds.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/system/database/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/system/database/dict.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/system/database/dir.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/system/database/hdf5.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/system/database/sqliteASE.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/system/sysCluster.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/system/sysGas.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/system/system.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/utils/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/utils/aseqhull.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/utils/asetools.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/utils/logger.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/utils/parser.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/utils/rdutils.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.3}/src/graphatoms/utils/subgraph.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: graphatoms
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.3
|
|
4
4
|
Summary: The Chemical Core Class for Graph Theory Analysis.
|
|
5
5
|
Keywords: chemistry,graph theory,reaction,event,KMC
|
|
6
6
|
Author: LiuGaoyong
|
|
@@ -14,12 +14,12 @@ Requires-Dist: ase
|
|
|
14
14
|
Requires-Dist: pymatgen>2023.6
|
|
15
15
|
Requires-Dist: rdkit>=2025
|
|
16
16
|
Requires-Dist: numpy>=2,<3
|
|
17
|
-
Requires-Dist: pandas>=2,<4
|
|
18
17
|
Requires-Dist: scipy>=1.10,<2
|
|
19
18
|
Requires-Dist: scikit-learn>=1.5
|
|
20
19
|
Requires-Dist: array-api-compat>=1.10
|
|
21
20
|
Requires-Dist: array-api-extra>=0.10
|
|
22
21
|
Requires-Dist: pyarrow
|
|
22
|
+
Requires-Dist: pandas
|
|
23
23
|
Requires-Dist: igraph>=0.11
|
|
24
24
|
Requires-Dist: h5py>=3.16
|
|
25
25
|
Requires-Dist: numpydantic
|
|
@@ -4,7 +4,7 @@ build-backend = "uv_build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "graphatoms"
|
|
7
|
-
version = "2.3.
|
|
7
|
+
version = "2.3.3"
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
description = "The Chemical Core Class for Graph Theory Analysis."
|
|
10
10
|
license-files = ["src/LICENSE"]
|
|
@@ -27,12 +27,12 @@ dependencies = [
|
|
|
27
27
|
"pymatgen>2023.6",
|
|
28
28
|
"rdkit>=2025",
|
|
29
29
|
"numpy>=2,<3",
|
|
30
|
-
"pandas>=2,<4",
|
|
31
30
|
"scipy>=1.10,<2",
|
|
32
31
|
"scikit-learn>=1.5",
|
|
33
32
|
"array-api-compat>=1.10",
|
|
34
33
|
"array_api-extra>=0.10",
|
|
35
34
|
"pyarrow",
|
|
35
|
+
"pandas",
|
|
36
36
|
"igraph>=0.11",
|
|
37
37
|
"h5py>=3.16",
|
|
38
38
|
"numpydantic",
|
|
@@ -146,29 +146,29 @@ benchmark = "pytest -s src/tests-benchmark/*.py"
|
|
|
146
146
|
|
|
147
147
|
[tool.pixi.dependencies]
|
|
148
148
|
python = ">=3.12"
|
|
149
|
-
pytest = ">=
|
|
150
|
-
array-api-compat = ">=1.15.0
|
|
151
|
-
array-api-extra = ">=0.11.0
|
|
152
|
-
array-api-strict = ">=2.5
|
|
153
|
-
ase = ">=3.28.0
|
|
154
|
-
pymatgen = ">=2026.5.4
|
|
155
|
-
rdkit = ">=2025.9.5
|
|
156
|
-
openbabel = ">=3.1.1
|
|
157
|
-
pyarrow = ">=21.0.0
|
|
158
|
-
scikit-learn = ">=1.8.0
|
|
159
|
-
python-igraph = ">=0.11.9
|
|
160
|
-
numpy = ">=2.0.0
|
|
161
|
-
pydantic = ">=2.10.0
|
|
162
|
-
numpydantic = ">=1.8.1
|
|
163
|
-
python-snappy = ">=0.7.3
|
|
164
|
-
h5py = ">=3.16
|
|
165
|
-
hydra-core = ">=1.3.
|
|
166
|
-
tomli-w = ">=1.2.0
|
|
167
|
-
loguru = ">=0.7.3
|
|
168
|
-
jupyterlab = ">=4.5.8
|
|
169
|
-
joblib = ">=1.1.0
|
|
170
|
-
ovld = ">=0.5.15
|
|
171
|
-
pytest-xdist = ">=3.8.0
|
|
172
|
-
executorlib = ">=1.8
|
|
173
|
-
typer = ">=0.20
|
|
174
|
-
grpcio = ">=1.52.0
|
|
149
|
+
pytest = ">=8"
|
|
150
|
+
array-api-compat = ">=1.15.0"
|
|
151
|
+
array-api-extra = ">=0.11.0"
|
|
152
|
+
array-api-strict = ">=2.5"
|
|
153
|
+
ase = ">=3.28.0"
|
|
154
|
+
pymatgen = ">=2026.5.4"
|
|
155
|
+
rdkit = ">=2025.9.5"
|
|
156
|
+
openbabel = ">=3.1.1"
|
|
157
|
+
pyarrow = ">=21.0.0"
|
|
158
|
+
scikit-learn = ">=1.8.0"
|
|
159
|
+
python-igraph = ">=0.11.9"
|
|
160
|
+
numpy = ">=2.0.0"
|
|
161
|
+
pydantic = ">=2.10.0"
|
|
162
|
+
numpydantic = ">=1.8.1"
|
|
163
|
+
python-snappy = ">=0.7.3"
|
|
164
|
+
h5py = ">=3.16"
|
|
165
|
+
hydra-core = ">=1.3.0"
|
|
166
|
+
tomli-w = ">=1.2.0"
|
|
167
|
+
loguru = ">=0.7.3"
|
|
168
|
+
jupyterlab = ">=4.5.8"
|
|
169
|
+
joblib = ">=1.1.0"
|
|
170
|
+
ovld = ">=0.5.15"
|
|
171
|
+
pytest-xdist = ">=3.8.0"
|
|
172
|
+
executorlib = ">=1.8"
|
|
173
|
+
typer = ">=0.20"
|
|
174
|
+
grpcio = ">=1.52.0"
|
|
@@ -12,7 +12,7 @@ graphatoms-network = "graphatoms.enterpoint.network:main"
|
|
|
12
12
|
graphatoms-run = "graphatoms.enterpoint.runner:run"
|
|
13
13
|
[project]
|
|
14
14
|
name = "graphatoms"
|
|
15
|
-
version = "2.3.
|
|
15
|
+
version = "2.3.3"
|
|
16
16
|
readme = "README.md"
|
|
17
17
|
description = "The Chemical Core Class for Graph Theory Analysis."
|
|
18
18
|
authors = [{ name = "LiuGaoyong", email = "liugaoyong_88@163.com" }]
|
|
@@ -39,12 +39,12 @@ dependencies = [
|
|
|
39
39
|
|
|
40
40
|
# Scientific Computing
|
|
41
41
|
"numpy>=2,<3",
|
|
42
|
-
"pandas>=2,<4",
|
|
43
42
|
"scipy>=1.10,<2",
|
|
44
43
|
"scikit-learn>=1.5",
|
|
45
44
|
"array-api-compat>=1.10",
|
|
46
45
|
"array_api-extra>=0.10",
|
|
47
46
|
"pyarrow",
|
|
47
|
+
"pandas",
|
|
48
48
|
|
|
49
49
|
# Graph Theory
|
|
50
50
|
"igraph>=0.11", # high performance graph library based on C
|
|
@@ -145,29 +145,29 @@ benchmark = "pytest -s src/tests-benchmark/*.py"
|
|
|
145
145
|
|
|
146
146
|
[tool.pixi.dependencies]
|
|
147
147
|
python = ">=3.12"
|
|
148
|
-
pytest = ">=
|
|
149
|
-
array-api-compat = ">=1.15.0
|
|
150
|
-
array-api-extra = ">=0.11.0
|
|
151
|
-
array-api-strict = ">=2.5
|
|
152
|
-
ase = ">=3.28.0
|
|
153
|
-
pymatgen = ">=2026.5.4
|
|
154
|
-
rdkit = ">=2025.9.5
|
|
155
|
-
openbabel = ">=3.1.1
|
|
156
|
-
pyarrow = ">=21.0.0
|
|
157
|
-
scikit-learn = ">=1.8.0
|
|
158
|
-
python-igraph = ">=0.11.9
|
|
159
|
-
numpy = ">=2.0.0
|
|
160
|
-
pydantic = ">=2.10.0
|
|
161
|
-
numpydantic = ">=1.8.1
|
|
162
|
-
python-snappy = ">=0.7.3
|
|
163
|
-
h5py = ">=3.16
|
|
164
|
-
hydra-core = ">=1.3.
|
|
165
|
-
tomli-w = ">=1.2.0
|
|
166
|
-
loguru = ">=0.7.3
|
|
167
|
-
jupyterlab = ">=4.5.8
|
|
168
|
-
joblib = ">=1.1.0
|
|
169
|
-
ovld = ">=0.5.15
|
|
170
|
-
pytest-xdist = ">=3.8.0
|
|
171
|
-
executorlib = ">=1.8
|
|
172
|
-
typer = ">=0.20
|
|
173
|
-
grpcio = ">=1.52.0
|
|
148
|
+
pytest = ">=8"
|
|
149
|
+
array-api-compat = ">=1.15.0"
|
|
150
|
+
array-api-extra = ">=0.11.0"
|
|
151
|
+
array-api-strict = ">=2.5"
|
|
152
|
+
ase = ">=3.28.0"
|
|
153
|
+
pymatgen = ">=2026.5.4"
|
|
154
|
+
rdkit = ">=2025.9.5"
|
|
155
|
+
openbabel = ">=3.1.1"
|
|
156
|
+
pyarrow = ">=21.0.0"
|
|
157
|
+
scikit-learn = ">=1.8.0"
|
|
158
|
+
python-igraph = ">=0.11.9"
|
|
159
|
+
numpy = ">=2.0.0"
|
|
160
|
+
pydantic = ">=2.10.0"
|
|
161
|
+
numpydantic = ">=1.8.1"
|
|
162
|
+
python-snappy = ">=0.7.3"
|
|
163
|
+
h5py = ">=3.16"
|
|
164
|
+
hydra-core = ">=1.3.0"
|
|
165
|
+
tomli-w = ">=1.2.0"
|
|
166
|
+
loguru = ">=0.7.3"
|
|
167
|
+
jupyterlab = ">=4.5.8"
|
|
168
|
+
joblib = ">=1.1.0"
|
|
169
|
+
ovld = ">=0.5.15"
|
|
170
|
+
pytest-xdist = ">=3.8.0"
|
|
171
|
+
executorlib = ">=1.8"
|
|
172
|
+
typer = ">=0.20"
|
|
173
|
+
grpcio = ">=1.52.0"
|
|
@@ -229,7 +229,11 @@ class __Json(PydanticConvertFactoryMixin):
|
|
|
229
229
|
indent=indent,
|
|
230
230
|
)
|
|
231
231
|
)
|
|
232
|
-
|
|
232
|
+
bytesutils.atomic_write_text(
|
|
233
|
+
target=filename,
|
|
234
|
+
text=self.to_str(**kwargs),
|
|
235
|
+
encoding="utf-8",
|
|
236
|
+
)
|
|
233
237
|
return filename
|
|
234
238
|
|
|
235
239
|
@classmethod
|
|
@@ -260,13 +264,15 @@ class __Toml(PydanticConvertFactoryMixin):
|
|
|
260
264
|
numpy_ndarray_compatible=True,
|
|
261
265
|
)
|
|
262
266
|
)
|
|
263
|
-
|
|
264
|
-
|
|
267
|
+
bytesutils.atomic_write_text(
|
|
268
|
+
target=filename,
|
|
269
|
+
text=toml_w.dumps(
|
|
265
270
|
self.to_dict(**kwargs),
|
|
266
|
-
f,
|
|
267
271
|
indent=indent,
|
|
268
272
|
multiline_strings=True,
|
|
269
|
-
)
|
|
273
|
+
),
|
|
274
|
+
encoding="utf-8",
|
|
275
|
+
)
|
|
270
276
|
return filename
|
|
271
277
|
|
|
272
278
|
@classmethod
|
|
@@ -301,16 +307,17 @@ class __Yaml(PydanticConvertFactoryMixin):
|
|
|
301
307
|
numpy_ndarray_compatible=True,
|
|
302
308
|
)
|
|
303
309
|
)
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
310
|
+
bytesutils.atomic_write_text(
|
|
311
|
+
target=filename,
|
|
312
|
+
text=OmegaConf.to_yaml(
|
|
313
|
+
self.to_dict(**kwargs),
|
|
314
|
+
# f,
|
|
315
|
+
# encoding="utf-8",
|
|
316
|
+
# # default_flow_style=False,
|
|
317
|
+
# indent=4,
|
|
318
|
+
),
|
|
319
|
+
encoding="utf-8",
|
|
320
|
+
)
|
|
314
321
|
return filename
|
|
315
322
|
|
|
316
323
|
@classmethod
|
|
@@ -345,10 +352,14 @@ class __Npz(PydanticConvertFactoryMixin):
|
|
|
345
352
|
numpy_ndarray_compatible=True,
|
|
346
353
|
)
|
|
347
354
|
)
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
355
|
+
func = np.savez_compressed if compress else np.savez
|
|
356
|
+
bytesutils.atomic_write(
|
|
357
|
+
target=filename,
|
|
358
|
+
writer=lambda p: func(
|
|
359
|
+
p,
|
|
360
|
+
allow_pickle=False,
|
|
361
|
+
**self.to_dict(**kwargs),
|
|
362
|
+
),
|
|
352
363
|
)
|
|
353
364
|
return filename
|
|
354
365
|
|
|
@@ -411,7 +422,14 @@ class __Pickle(PydanticConvertFactoryMixin):
|
|
|
411
422
|
numpy_ndarray_compatible=True,
|
|
412
423
|
)
|
|
413
424
|
)
|
|
414
|
-
|
|
425
|
+
bytesutils.atomic_write(
|
|
426
|
+
target=filename,
|
|
427
|
+
writer=lambda p: dump(
|
|
428
|
+
value=self.to_dict(**kwargs),
|
|
429
|
+
filename=p,
|
|
430
|
+
compress=compress, # type: ignore
|
|
431
|
+
),
|
|
432
|
+
)
|
|
415
433
|
return filename
|
|
416
434
|
|
|
417
435
|
@classmethod
|
|
@@ -27,6 +27,7 @@ from graphatoms.reaction import (
|
|
|
27
27
|
)
|
|
28
28
|
from graphatoms.system import Cluster, Gas, SysGraph, System
|
|
29
29
|
from graphatoms.system.database import DatabaseABC, get_db
|
|
30
|
+
from graphatoms.utils.bytestool import atomic_write, atomic_write_text
|
|
30
31
|
|
|
31
32
|
__all__ = [
|
|
32
33
|
"MetaData",
|
|
@@ -88,8 +89,9 @@ class ReactionNetwork(Mapping[str, tuple[EventInfo, EventBase]]):
|
|
|
88
89
|
+ " Please delete it or use `restart=True`."
|
|
89
90
|
)
|
|
90
91
|
self.__path.mkdir(parents=True, exist_ok=True)
|
|
91
|
-
|
|
92
|
-
|
|
92
|
+
atomic_write_text(
|
|
93
|
+
self.__path_exploration_recorder,
|
|
94
|
+
RecorderInfo.get_csv_title() + "\n",
|
|
93
95
|
)
|
|
94
96
|
self.__recorder = Recorder()
|
|
95
97
|
self.__scheduler = Scheduler()
|
|
@@ -130,6 +132,7 @@ class ReactionNetwork(Mapping[str, tuple[EventInfo, EventBase]]):
|
|
|
130
132
|
config: Config,
|
|
131
133
|
*args,
|
|
132
134
|
restart: bool | None = None,
|
|
135
|
+
remote_retry_times: float = 2.0,
|
|
133
136
|
remote_mode: bool = False,
|
|
134
137
|
**kwargs,
|
|
135
138
|
) -> Self: # type: ignore
|
|
@@ -152,7 +155,7 @@ class ReactionNetwork(Mapping[str, tuple[EventInfo, EventBase]]):
|
|
|
152
155
|
)
|
|
153
156
|
break
|
|
154
157
|
except Exception as e:
|
|
155
|
-
time.sleep(
|
|
158
|
+
time.sleep(abs(remote_retry_times))
|
|
156
159
|
err = e
|
|
157
160
|
if err is not None:
|
|
158
161
|
raise RuntimeError(
|
|
@@ -535,8 +538,11 @@ class ReactionNetwork(Mapping[str, tuple[EventInfo, EventBase]]):
|
|
|
535
538
|
msg = f"Event {event._string()} failed "
|
|
536
539
|
msg += f"to simplify. because of {e}"
|
|
537
540
|
fname = self.__path / "event-simplify-fail.pkl"
|
|
538
|
-
fname.with_suffix(".err")
|
|
539
|
-
|
|
541
|
+
atomic_write_text(fname.with_suffix(".err"), msg)
|
|
542
|
+
atomic_write(
|
|
543
|
+
fname,
|
|
544
|
+
writer=lambda p: p.write_bytes(pickle.dumps(event)),
|
|
545
|
+
)
|
|
540
546
|
event.R.write_npz(fname.with_suffix(".R.npz"))
|
|
541
547
|
event.P.write_npz(fname.with_suffix(".P.npz"))
|
|
542
548
|
if event.G is not None:
|
|
@@ -789,8 +795,10 @@ if __name__ == "__main__":
|
|
|
789
795
|
if "merge" not in zzzz_path.name:
|
|
790
796
|
p = zzzz_path / "event"
|
|
791
797
|
(p / "recorder.json").unlink(missing_ok=True)
|
|
792
|
-
|
|
793
|
-
json
|
|
798
|
+
atomic_write_text(
|
|
799
|
+
p / "recorder.json",
|
|
800
|
+
json.dumps({}, indent=4),
|
|
801
|
+
)
|
|
794
802
|
network_lst.append(
|
|
795
803
|
ReactionNetwork(
|
|
796
804
|
zzzz_path / "event",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import dataclasses as dc
|
|
2
|
+
import types
|
|
2
3
|
from pathlib import Path
|
|
3
|
-
from typing import Any, Self, override
|
|
4
|
+
from typing import Any, Self, Union, get_args, get_origin, override
|
|
4
5
|
|
|
5
6
|
import numpy as np
|
|
6
7
|
import pandas as pd
|
|
@@ -10,10 +11,30 @@ from graphatoms.dataclasses import OurBaseModel
|
|
|
10
11
|
from graphatoms.enterpoint.config import Config, EventConfig
|
|
11
12
|
from graphatoms.reaction import EventBase, EventInfo
|
|
12
13
|
from graphatoms.system.bonds import matchmode2nmatch
|
|
14
|
+
from graphatoms.utils.bytestool import atomic_write
|
|
13
15
|
|
|
14
16
|
__all__ = ["MetaData"]
|
|
15
17
|
|
|
16
18
|
|
|
19
|
+
def _is_list_of_optional_str(annotation: Any) -> bool:
|
|
20
|
+
"""Whether the annotation is ``list[str | None]``."""
|
|
21
|
+
if get_origin(annotation) is not list:
|
|
22
|
+
return False
|
|
23
|
+
element = get_args(annotation)[0]
|
|
24
|
+
if get_origin(element) not in (Union, types.UnionType):
|
|
25
|
+
return False
|
|
26
|
+
return set(get_args(element)) == {str, type(None)}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _missing_to_none(value: Any) -> Any:
|
|
30
|
+
"""Convert a missing value marker of pandas to ``None``."""
|
|
31
|
+
if value is None or value is pd.NA:
|
|
32
|
+
return None
|
|
33
|
+
if isinstance(value, float) and np.isnan(value):
|
|
34
|
+
return None
|
|
35
|
+
return value
|
|
36
|
+
|
|
37
|
+
|
|
17
38
|
class _MetaDataBasic(OurBaseModel, EventConfig):
|
|
18
39
|
gas_sticking: dict[str, NonNegativeFloat] = {}
|
|
19
40
|
|
|
@@ -108,7 +129,23 @@ class _MetaDataTable(BaseModel):
|
|
|
108
129
|
|
|
109
130
|
@classmethod
|
|
110
131
|
def from_dataframe(cls, df: pd.DataFrame) -> Self:
|
|
111
|
-
|
|
132
|
+
"""Create the table from a DataFrame.
|
|
133
|
+
|
|
134
|
+
Note:
|
|
135
|
+
Since pandas 3.0, a string column containing missing values is
|
|
136
|
+
read back as the new default string dtype (``str``), whose
|
|
137
|
+
missing value marker is ``numpy.nan`` instead of ``None``.
|
|
138
|
+
Such ``nan`` values are rejected by the ``str | None`` fields,
|
|
139
|
+
so they are converted back to ``None`` here.
|
|
140
|
+
"""
|
|
141
|
+
data: dict[str, list[Any]] = {}
|
|
142
|
+
for k in df.columns:
|
|
143
|
+
values: list[Any] = df[k].to_list()
|
|
144
|
+
field = cls.__pydantic_fields__.get(k)
|
|
145
|
+
if field is not None and _is_list_of_optional_str(field.annotation):
|
|
146
|
+
values = [_missing_to_none(v) for v in values]
|
|
147
|
+
data[k] = values
|
|
148
|
+
return cls(**data)
|
|
112
149
|
|
|
113
150
|
def merge(self, other: Self, idxs: list[int] | None = None) -> None:
|
|
114
151
|
if idxs is None:
|
|
@@ -187,7 +224,10 @@ class MetaData(BaseModel):
|
|
|
187
224
|
|
|
188
225
|
def persistence(self, path: Path | str) -> None:
|
|
189
226
|
self.basic.write_json(Path(path) / "metadata-basic.json")
|
|
190
|
-
|
|
227
|
+
atomic_write(
|
|
228
|
+
Path(path) / "metadata-table.feather",
|
|
229
|
+
writer=lambda p: self.table.dataframe.to_feather(p),
|
|
230
|
+
)
|
|
191
231
|
|
|
192
232
|
@classmethod
|
|
193
233
|
def from_storage(cls, path: Path | str) -> Self:
|
|
@@ -9,6 +9,7 @@ from sklearn.metrics.pairwise import cosine_similarity
|
|
|
9
9
|
|
|
10
10
|
from graphatoms.dataclasses._numpydantic import NDArray
|
|
11
11
|
from graphatoms.system import SysGraph # type: ignore
|
|
12
|
+
from graphatoms.utils.bytestool import atomic_write
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
class Scheduler(BaseModel):
|
|
@@ -35,17 +36,21 @@ class Scheduler(BaseModel):
|
|
|
35
36
|
save: Callable = np.savez_compressed if compress else np.savez
|
|
36
37
|
dct = {f"{k}_is_fixed": v for k, v in self.is_fixed.items()}
|
|
37
38
|
dct = {f"{k}_dR": v for k, v in self.dR.items()} | dct
|
|
38
|
-
|
|
39
|
+
atomic_write(
|
|
40
|
+
target=filename,
|
|
41
|
+
writer=lambda p: save(p, allow_pickle=False, **dct),
|
|
42
|
+
)
|
|
39
43
|
return filename
|
|
40
44
|
|
|
41
45
|
@classmethod
|
|
42
46
|
@validate_call
|
|
43
47
|
def read_npz(cls, filename: FilePath, *args, **kwargs) -> Self:
|
|
44
48
|
data: dict[str, dict[str, NDArray]] = defaultdict(dict)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
with np.load(filename) as npz:
|
|
50
|
+
dct: Mapping[str, NDArray] = npz
|
|
51
|
+
for k, v in dct.items():
|
|
52
|
+
k2, k1 = k.rsplit("_", 1)
|
|
53
|
+
data[k1][k2] = v
|
|
49
54
|
return cls(**data)
|
|
50
55
|
|
|
51
56
|
def can_be_skip(
|
|
@@ -58,7 +63,6 @@ class Scheduler(BaseModel):
|
|
|
58
63
|
**kwargs,
|
|
59
64
|
) -> tuple[bool, float]:
|
|
60
65
|
diffpositions = np.asarray(diffpositions, dtype=float)
|
|
61
|
-
print(diffpositions)
|
|
62
66
|
assert 0 <= thetacutoff <= 180, "thetacutoff must be in 0-180"
|
|
63
67
|
if isinstance(graph, str):
|
|
64
68
|
if is_fixed is None:
|
|
@@ -106,7 +110,6 @@ class Scheduler(BaseModel):
|
|
|
106
110
|
cos: np.ndarray = cosine_similarity(dR, dR_new)
|
|
107
111
|
if np.max(cos) <= np.cos(np.deg2rad(thetacutoff)):
|
|
108
112
|
self.dR[key] = np.vstack((dR, dR_new)) # row_stack
|
|
109
|
-
print(self.dR[key])
|
|
110
113
|
return False, np.max(cos)
|
|
111
114
|
return True, np.max(cos)
|
|
112
115
|
|
|
@@ -151,5 +154,8 @@ if __name__ == "__main__":
|
|
|
151
154
|
plt.title("Blue: Keep; Red: Skip")
|
|
152
155
|
|
|
153
156
|
p = Path(__file__).with_suffix(".png")
|
|
154
|
-
|
|
157
|
+
atomic_write(
|
|
158
|
+
p,
|
|
159
|
+
writer=lambda p: plt.savefig(p),
|
|
160
|
+
)
|
|
155
161
|
obj.write_npz(p.with_suffix(".npz"))
|
|
@@ -10,7 +10,7 @@ from graphatoms.enterpoint.parallel._base import (
|
|
|
10
10
|
)
|
|
11
11
|
from graphatoms.enterpoint.parallel._dask import DaskExecutor
|
|
12
12
|
from graphatoms.enterpoint.parallel._executorlib import ExecutorLibExecutor
|
|
13
|
-
from graphatoms.enterpoint.parallel._ray import
|
|
13
|
+
from graphatoms.enterpoint.parallel._ray import RayExecutor, ray
|
|
14
14
|
|
|
15
15
|
__all__ = [
|
|
16
16
|
"SerialExecutor",
|
|
@@ -18,6 +18,14 @@ __all__ = [
|
|
|
18
18
|
"ParallelExecutorABC",
|
|
19
19
|
"get_executor",
|
|
20
20
|
]
|
|
21
|
+
BACKENDS = [
|
|
22
|
+
"serial",
|
|
23
|
+
"multiprocessing",
|
|
24
|
+
"ray",
|
|
25
|
+
"dask",
|
|
26
|
+
"executorlib",
|
|
27
|
+
"joblib",
|
|
28
|
+
]
|
|
21
29
|
|
|
22
30
|
|
|
23
31
|
def get_executor(
|
|
@@ -40,7 +48,11 @@ def get_executor(
|
|
|
40
48
|
backend = str(backend).lower()
|
|
41
49
|
if backend in ("ray",):
|
|
42
50
|
return RayExecutor(nworkers=nworkers, **kwargs) # type: ignore[arg-type]
|
|
43
|
-
|
|
51
|
+
# `ncpus_for_tasks` only applies to the ray backend; `RunnerABC` passes
|
|
52
|
+
# it unconditionally, so drop it for the other backends instead of
|
|
53
|
+
# forwarding it to `ProcessPoolExecutor`.
|
|
54
|
+
kwargs.pop("ncpus_for_tasks", None)
|
|
55
|
+
if backend in ("dask",):
|
|
44
56
|
return DaskExecutor(nworkers=nworkers, **kwargs) # type: ignore[arg-type]
|
|
45
57
|
elif backend in ("executorlib",):
|
|
46
58
|
return ExecutorLibExecutor( # type: ignore[arg-type]
|
|
@@ -53,10 +65,7 @@ def get_executor(
|
|
|
53
65
|
nworkers = None
|
|
54
66
|
return MultiprocessingExecutor(nworkers=nworkers, **kwargs) # type: ignore[call-arg]
|
|
55
67
|
else:
|
|
56
|
-
raise ValueError(
|
|
57
|
-
f"Unknown backend: {backend} Available: "
|
|
58
|
-
f"{['serial', 'multiprocessing', 'ray', 'dask', 'executorlib']}"
|
|
59
|
-
)
|
|
68
|
+
raise ValueError(f"Unknown backend: {backend} Available: {BACKENDS}")
|
|
60
69
|
|
|
61
70
|
|
|
62
71
|
def executor_map(
|
|
@@ -69,12 +78,19 @@ def executor_map(
|
|
|
69
78
|
) -> Sequence[Any]:
|
|
70
79
|
if isinstance(executor, RayExecutor):
|
|
71
80
|
dct: dict[int, ray.ObjectRef] = {}
|
|
81
|
+
# Hold a strong reference to every deduplicated object. Keying the
|
|
82
|
+
# cache on `id(v)` alone is only safe while the objects stay alive;
|
|
83
|
+
# if an intermediate object were collected, CPython could hand its
|
|
84
|
+
# `id` to a *different* object and the wrong value would be
|
|
85
|
+
# substituted into a task.
|
|
86
|
+
keepalive: list[Any] = []
|
|
72
87
|
remote_params: list[dict[str, ray.ObjectRef]] = []
|
|
73
88
|
for params in fn_params:
|
|
74
89
|
item: dict[str, ray.ObjectRef] = {}
|
|
75
90
|
for k, v in params.items():
|
|
76
91
|
if id(v) not in dct:
|
|
77
92
|
dct[id(v)] = ray.put(v)
|
|
93
|
+
keepalive.append(v)
|
|
78
94
|
item[k] = dct[id(v)]
|
|
79
95
|
remote_params.append(item)
|
|
80
96
|
fn_params = remote_params
|
|
@@ -111,12 +111,21 @@ class MultiprocessingExecutor(ParallelExecutorABC):
|
|
|
111
111
|
return_when=cf.FIRST_COMPLETED,
|
|
112
112
|
timeout=timeout,
|
|
113
113
|
)
|
|
114
|
-
|
|
115
|
-
|
|
114
|
+
if len(done) == 0:
|
|
115
|
+
raise TimeoutError(
|
|
116
|
+
"concurrent.futures.wait() returned no finished task "
|
|
117
|
+
f"within timeout={timeout!r}."
|
|
118
|
+
)
|
|
119
|
+
# `FIRST_COMPLETED` may return *several* futures at once. Only one
|
|
120
|
+
# result can be returned by this API, so the other already-finished
|
|
121
|
+
# futures must be pushed back into the remaining list; otherwise their
|
|
122
|
+
# results are silently dropped by callers that loop until the list is
|
|
123
|
+
# empty.
|
|
124
|
+
done = list(done)
|
|
125
|
+
return self.get(done[0]), list(undone) + done[1:] # type: ignore[override]
|
|
116
126
|
|
|
117
127
|
@override
|
|
118
128
|
def map(self, fn, *iterables, timeout=None, chunksize=1) -> list[Any]:
|
|
119
|
-
print(iterables)
|
|
120
129
|
return list(
|
|
121
130
|
self.__executor.map(
|
|
122
131
|
fn,
|
|
@@ -128,6 +137,16 @@ class MultiprocessingExecutor(ParallelExecutorABC):
|
|
|
128
137
|
|
|
129
138
|
|
|
130
139
|
class SerialExecutor(MultiprocessingExecutor):
|
|
140
|
+
"""Run tasks one at a time.
|
|
141
|
+
|
|
142
|
+
.. warning::
|
|
143
|
+
This is *not* an in-process executor: it delegates to a
|
|
144
|
+
single-worker :class:`~concurrent.futures.ProcessPoolExecutor`, so
|
|
145
|
+
every task and its arguments must be picklable and each call runs in a
|
|
146
|
+
forked child process. See the project bug report for the implications
|
|
147
|
+
under Slurm.
|
|
148
|
+
"""
|
|
149
|
+
|
|
131
150
|
@override
|
|
132
|
-
def __init__(self,
|
|
133
|
-
super().__init__(nworkers=1
|
|
151
|
+
def __init__(self, *a, **kw) -> None:
|
|
152
|
+
super().__init__(nworkers=1)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import os
|
|
2
4
|
import weakref
|
|
3
5
|
from collections.abc import Callable
|
|
@@ -18,6 +20,17 @@ if TYPE_CHECKING:
|
|
|
18
20
|
import ray # type: ignore
|
|
19
21
|
|
|
20
22
|
|
|
23
|
+
###############################################################################
|
|
24
|
+
# NOTE: `from __future__ import annotations` above is required, *not* optional.
|
|
25
|
+
# `ray` is an optional dependency (it is only a dev dependency in
|
|
26
|
+
# pyproject.toml), so when it is absent this module sets `ray = None`. Without
|
|
27
|
+
# postponed evaluation the `-> ray.ObjectRef` annotations below would be
|
|
28
|
+
# evaluated eagerly at class-definition time and raise
|
|
29
|
+
# `AttributeError: 'NoneType' object has no attribute 'ObjectRef'`, which makes
|
|
30
|
+
# `import graphatoms.enterpoint.parallel` (and therefore `graphatoms-run`)
|
|
31
|
+
# fail on any installation that does not happen to have ray installed.
|
|
32
|
+
|
|
33
|
+
|
|
21
34
|
class RayExecutor(ParallelExecutorABC):
|
|
22
35
|
"""An executor backed by :mod:`ray`."""
|
|
23
36
|
|
|
@@ -35,15 +48,12 @@ class RayExecutor(ParallelExecutorABC):
|
|
|
35
48
|
raise ImportError(
|
|
36
49
|
"ray is not installed. Install it with: pip install ray"
|
|
37
50
|
)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
)
|
|
45
|
-
except Exception:
|
|
46
|
-
pass
|
|
51
|
+
if not ray.is_initialized(): # type: ignore
|
|
52
|
+
ray.init( # type: ignore
|
|
53
|
+
ignore_reinit_error=True,
|
|
54
|
+
num_cpus=nworkers,
|
|
55
|
+
**kwargs,
|
|
56
|
+
)
|
|
47
57
|
|
|
48
58
|
@override
|
|
49
59
|
def submit(
|
|
@@ -68,7 +78,7 @@ class RayExecutor(ParallelExecutorABC):
|
|
|
68
78
|
func_ref = weakref.ref(func) # type: ignore
|
|
69
79
|
except TypeError:
|
|
70
80
|
|
|
71
|
-
def func_ref(): # type: ignore
|
|
81
|
+
def func_ref() -> Callable[..., Any]: # type: ignore
|
|
72
82
|
return func
|
|
73
83
|
|
|
74
84
|
self._remote_fn_cache[key] = (func_ref, remote_fn) # type: ignore
|
|
@@ -90,8 +100,21 @@ class RayExecutor(ParallelExecutorABC):
|
|
|
90
100
|
timeout: float | None = None,
|
|
91
101
|
**kwargs,
|
|
92
102
|
) -> tuple[Any, list[ray.ObjectRef]]: # type: ignore
|
|
93
|
-
done, unfinished = ray.wait(
|
|
94
|
-
|
|
103
|
+
done, unfinished = ray.wait( # type: ignore
|
|
104
|
+
futures,
|
|
105
|
+
timeout=timeout,
|
|
106
|
+
num_returns=1,
|
|
107
|
+
**kwargs,
|
|
108
|
+
)
|
|
109
|
+
if len(done) == 0:
|
|
110
|
+
raise TimeoutError(
|
|
111
|
+
"ray.wait() returned no finished task "
|
|
112
|
+
f"within timeout={timeout!r}."
|
|
113
|
+
)
|
|
114
|
+
# `ray.wait` defaults to `num_returns=1`, but a caller may ask for
|
|
115
|
+
# more. Keep every finished ref accounted for so that no completed
|
|
116
|
+
# result is silently dropped from the caller's work queue.
|
|
117
|
+
return ray.get(done[0]), list(unfinished) + list(done[1:]) # type: ignore
|
|
95
118
|
|
|
96
119
|
@override
|
|
97
120
|
def map(self, fn, *iterables, timeout=None, chunksize=1) -> list[Any]:
|