GraphAtoms 1.2.1__tar.gz → 2.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.
Files changed (101) hide show
  1. {graphatoms-1.2.1 → graphatoms-2.0.0}/PKG-INFO +11 -3
  2. {graphatoms-1.2.1 → graphatoms-2.0.0}/pyproject.toml +27 -9
  3. {graphatoms-1.2.1 → graphatoms-2.0.0}/pyproject.toml.orig +38 -20
  4. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/dataclasses/_numpydantic.py +12 -3
  5. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/dataclasses/_pydanticMixin.py +39 -19
  6. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/dataclasses/_pydanticModel.py +10 -4
  7. graphatoms-2.0.0/src/graphatoms/enterpoint/config/__init__.py +110 -0
  8. graphatoms-2.0.0/src/graphatoms/enterpoint/config/atoms/__init__.py +24 -0
  9. graphatoms-2.0.0/src/graphatoms/enterpoint/config/atoms/aseread.yaml +5 -0
  10. graphatoms-2.0.0/src/graphatoms/enterpoint/config/atoms/octahedron.yaml +7 -0
  11. graphatoms-2.0.0/src/graphatoms/enterpoint/config/bonds/__init__.py +23 -0
  12. graphatoms-2.0.0/src/graphatoms/enterpoint/config/bonds/raw.yaml +8 -0
  13. graphatoms-2.0.0/src/graphatoms/enterpoint/config/calculator/__init__.py +29 -0
  14. graphatoms-2.0.0/src/graphatoms/enterpoint/config/calculator/emt.yaml +4 -0
  15. graphatoms-2.0.0/src/graphatoms/enterpoint/config/calculator/nequip.yaml +9 -0
  16. graphatoms-2.0.0/src/graphatoms/enterpoint/config/example.yaml +72 -0
  17. graphatoms-2.0.0/src/graphatoms/enterpoint/config/run.yaml +25 -0
  18. graphatoms-2.0.0/src/graphatoms/enterpoint/network/__init__.py +217 -0
  19. graphatoms-2.0.0/src/graphatoms/enterpoint/network/_metadata.py +311 -0
  20. graphatoms-2.0.0/src/graphatoms/enterpoint/network/_recorder.py +130 -0
  21. graphatoms-2.0.0/src/graphatoms/enterpoint/network/_scheduler.py +151 -0
  22. graphatoms-2.0.0/src/graphatoms/enterpoint/parallel/__init__.py +66 -0
  23. graphatoms-2.0.0/src/graphatoms/enterpoint/parallel/_base.py +132 -0
  24. graphatoms-2.0.0/src/graphatoms/enterpoint/parallel/_dask.py +48 -0
  25. graphatoms-2.0.0/src/graphatoms/enterpoint/parallel/_executorlib.py +49 -0
  26. graphatoms-2.0.0/src/graphatoms/enterpoint/parallel/_ray.py +70 -0
  27. graphatoms-2.0.0/src/graphatoms/enterpoint/runner/__init__.py +24 -0
  28. graphatoms-2.0.0/src/graphatoms/enterpoint/runner/_base.py +737 -0
  29. graphatoms-2.0.0/src/graphatoms/enterpoint/runner/_errors.py +69 -0
  30. graphatoms-2.0.0/src/graphatoms/enterpoint/runner/_helper.py +543 -0
  31. graphatoms-2.0.0/src/graphatoms/enterpoint/runner/otfkmc.py +199 -0
  32. graphatoms-2.0.0/src/graphatoms/enterpoint/runner/rxngen.py +9 -0
  33. graphatoms-2.0.0/src/graphatoms/enterpoint/view.py +106 -0
  34. graphatoms-2.0.0/src/graphatoms/reaction/__init__.py +18 -0
  35. graphatoms-2.0.0/src/graphatoms/reaction/_event.py +519 -0
  36. graphatoms-2.0.0/src/graphatoms/reaction/adsorption.py +99 -0
  37. graphatoms-2.0.0/src/graphatoms/reaction/desorption.py +98 -0
  38. {graphatoms-1.2.1/src/graphatoms/reaction/event → graphatoms-2.0.0/src/graphatoms/reaction}/reaction.py +19 -5
  39. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/system/__init__.py +1 -5
  40. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/system/atoms.py +81 -15
  41. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/system/bonds.py +32 -34
  42. graphatoms-2.0.0/src/graphatoms/system/database/__init__.py +39 -0
  43. graphatoms-2.0.0/src/graphatoms/system/database/abc.py +79 -0
  44. graphatoms-2.0.0/src/graphatoms/system/database/dict.py +42 -0
  45. graphatoms-2.0.0/src/graphatoms/system/database/dir.py +52 -0
  46. graphatoms-2.0.0/src/graphatoms/system/database/hdf5.py +114 -0
  47. graphatoms-2.0.0/src/graphatoms/system/database/sqliteASE.py +91 -0
  48. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/system/graph.py +176 -108
  49. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/system/sysCluster.py +29 -13
  50. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/system/sysGas.py +33 -14
  51. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/system/system.py +0 -2
  52. graphatoms-2.0.0/src/graphatoms/utils/adsorption.py +790 -0
  53. graphatoms-2.0.0/src/graphatoms/utils/asetools.py +411 -0
  54. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/utils/bytestool.py +21 -15
  55. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/utils/parser.py +4 -1
  56. graphatoms-1.2.1/src/graphatoms/reaction/__init__.py +0 -10
  57. graphatoms-1.2.1/src/graphatoms/reaction/base/__init__.py +0 -9
  58. graphatoms-1.2.1/src/graphatoms/reaction/base/move.py +0 -14
  59. graphatoms-1.2.1/src/graphatoms/reaction/base/rtgp.py +0 -152
  60. graphatoms-1.2.1/src/graphatoms/reaction/database/__init__.py +0 -1
  61. graphatoms-1.2.1/src/graphatoms/reaction/database/base.py +0 -92
  62. graphatoms-1.2.1/src/graphatoms/reaction/database/hdf5.py +0 -136
  63. graphatoms-1.2.1/src/graphatoms/reaction/database/sqliteASE.py +0 -141
  64. graphatoms-1.2.1/src/graphatoms/reaction/event/__init__.py +0 -12
  65. graphatoms-1.2.1/src/graphatoms/reaction/event/_event.py +0 -87
  66. graphatoms-1.2.1/src/graphatoms/reaction/event/adsorption.py +0 -17
  67. graphatoms-1.2.1/src/graphatoms/reaction/event/desorption.py +0 -17
  68. graphatoms-1.2.1/src/graphatoms/reaction/mcmove/__init__.py +0 -5
  69. graphatoms-1.2.1/src/graphatoms/reaction/mcmove/_abc.py +0 -12
  70. graphatoms-1.2.1/src/graphatoms/reaction/mcmove/_base.py +0 -142
  71. graphatoms-1.2.1/src/graphatoms/reaction/mcmove/_moveFB.py +0 -179
  72. graphatoms-1.2.1/src/graphatoms/reaction/mcmove/_moveSP.py +0 -120
  73. graphatoms-1.2.1/src/graphatoms/reaction/mcmove/_moveSwap.py +0 -119
  74. graphatoms-1.2.1/src/graphatoms/reaction/mcmove/_simNVT.py +0 -179
  75. graphatoms-1.2.1/src/graphatoms/reaction/mcmove/test_mmc.py +0 -57
  76. graphatoms-1.2.1/src/graphatoms/reaction/mcmove/test_move.py +0 -23
  77. graphatoms-1.2.1/src/graphatoms/reaction/mcmove/zzz.py +0 -103
  78. graphatoms-1.2.1/src/graphatoms/reaction/mdwarpper/__init__.py +0 -36
  79. graphatoms-1.2.1/src/graphatoms/reaction/network/_base.py +0 -60
  80. {graphatoms-1.2.1 → graphatoms-2.0.0}/README.md +0 -0
  81. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/LICENSE +0 -0
  82. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/__init__.py +0 -0
  83. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/arrayapi/__init__.py +0 -0
  84. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/arrayapi/compat.py +0 -0
  85. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/arrayapi/typing.py +0 -0
  86. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/dataclasses/__init__.py +0 -0
  87. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/dataclasses/_pydantic2pyarrow.py +0 -0
  88. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/dataclasses/graph.py +0 -0
  89. {graphatoms-1.2.1/src/graphatoms/reaction/network → graphatoms-2.0.0/src/graphatoms/enterpoint}/__init__.py +0 -0
  90. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/geometry/__init__.py +0 -0
  91. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/geometry/_bond_list.py +0 -0
  92. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/geometry/_distance_pairs.py +0 -0
  93. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/geometry/_inner_outer.py +0 -0
  94. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/geometry/_neighbor_list.py +0 -0
  95. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/geometry/mic.py +0 -0
  96. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/geometry/rotation.py +0 -0
  97. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/geometry/sample.py +0 -0
  98. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/utils/__init__.py +0 -0
  99. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/utils/logger.py +0 -0
  100. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/utils/rdutils.py +0 -0
  101. {graphatoms-1.2.1 → graphatoms-2.0.0}/src/graphatoms/utils/subgraph.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graphatoms
3
- Version: 1.2.1
3
+ Version: 2.0.0
4
4
  Summary: The Chemical Core Class for Graph Theory Analysis.
5
5
  Keywords: chemistry,graph theory,reaction,event,KMC
6
6
  Author: LiuGaoyong
@@ -13,14 +13,15 @@ Classifier: Intended Audience :: Science/Research
13
13
  Requires-Dist: ase
14
14
  Requires-Dist: pymatgen>2023.6
15
15
  Requires-Dist: rdkit>=2025
16
+ Requires-Dist: numpy>=2,<3
17
+ Requires-Dist: pandas>=2,<4
18
+ Requires-Dist: scipy>=1.10,<2
16
19
  Requires-Dist: scikit-learn>=1.5
17
20
  Requires-Dist: array-api-compat>=1.10
18
21
  Requires-Dist: array-api-extra>=0.10
19
22
  Requires-Dist: pyarrow
20
23
  Requires-Dist: igraph>=0.11
21
24
  Requires-Dist: h5py>=3.16
22
- Requires-Dist: hydra-core
23
- Requires-Dist: numpy>=2.0.0,<3
24
25
  Requires-Dist: numpydantic
25
26
  Requires-Dist: ovld
26
27
  Requires-Dist: pydantic>=2.10
@@ -28,6 +29,13 @@ Requires-Dist: python-snappy>=0.7.3
28
29
  Requires-Dist: tomli ; python_full_version < '3.11'
29
30
  Requires-Dist: tomli-w
30
31
  Requires-Dist: typing-extensions
32
+ Requires-Dist: plotext
33
+ Requires-Dist: plotext-plus
34
+ Requires-Dist: matplotlib
35
+ Requires-Dist: executorlib
36
+ Requires-Dist: hydra-core
37
+ Requires-Dist: pipefunc
38
+ Requires-Dist: typer
31
39
  Requires-Dist: loguru
32
40
  Requires-Python: >=3.12
33
41
  Project-URL: Homepage, https://github.com/LiuGaoyong/GraphAtoms
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "graphatoms"
7
- version = "1.2.1"
7
+ version = "2.0.0"
8
8
  readme = "README.md"
9
9
  description = "The Chemical Core Class for Graph Theory Analysis."
10
10
  license-files = ["src/LICENSE"]
@@ -26,14 +26,15 @@ dependencies = [
26
26
  "ase",
27
27
  "pymatgen>2023.6",
28
28
  "rdkit>=2025",
29
+ "numpy>=2,<3",
30
+ "pandas>=2,<4",
31
+ "scipy>=1.10,<2",
29
32
  "scikit-learn>=1.5",
30
33
  "array-api-compat>=1.10",
31
34
  "array_api-extra>=0.10",
32
35
  "pyarrow",
33
36
  "igraph>=0.11",
34
37
  "h5py>=3.16",
35
- "hydra-core",
36
- "numpy>=2.0.0,<3",
37
38
  "numpydantic",
38
39
  "ovld",
39
40
  "pydantic>=2.10",
@@ -41,6 +42,13 @@ dependencies = [
41
42
  "tomli; python_version < '3.11'",
42
43
  "tomli-w",
43
44
  "typing-extensions",
45
+ "plotext",
46
+ "plotext-plus",
47
+ "matplotlib",
48
+ "executorlib",
49
+ "hydra-core",
50
+ "pipefunc",
51
+ "typer",
44
52
  "loguru",
45
53
  ]
46
54
 
@@ -49,6 +57,11 @@ Homepage = "https://github.com/LiuGaoyong/GraphAtoms"
49
57
  Repository = "https://github.com/LiuGaoyong/GraphAtoms"
50
58
  Issues = "https://github.com/LiuGaoyong/GraphAtoms/issues/"
51
59
 
60
+ [project.scripts]
61
+ graphatoms-config = "graphatoms.enterpoint.config:print_config"
62
+ graphatoms-network = "graphatoms.enterpoint.view:main"
63
+ graphatoms-run = "graphatoms.enterpoint.runner:run"
64
+
52
65
  [[project.authors]]
53
66
  name = "LiuGaoyong"
54
67
  email = "liugaoyong_88@163.com"
@@ -56,19 +69,21 @@ email = "liugaoyong_88@163.com"
56
69
  [dependency-groups]
57
70
  dev = [
58
71
  "ruff>=0.11",
72
+ "openbabel-wheel",
59
73
  "array-api-strict",
60
74
  "pytest>=8.3",
61
75
  "pytest-xdist",
62
- "jupyter",
63
- "sqlmodel",
64
- "openbabel-wheel",
76
+ "jupyterlab",
77
+ "chemiscope",
78
+ "nglview",
79
+ "ray",
65
80
  ]
66
81
 
67
82
  [tool.uv]
68
83
  package = true
69
84
 
70
85
  [[tool.uv.index]]
71
- url = "https://mirrors.cernet.edu.cn/pypi/web/simple"
86
+ url = "https://mirrors.nju.edu.cn/pypi/web/simple"
72
87
  default = true
73
88
 
74
89
  [tool.pytest.ini_options]
@@ -76,6 +91,8 @@ filterwarnings = [
76
91
  "error",
77
92
  "ignore::RuntimeWarning",
78
93
  "ignore::DeprecationWarning",
94
+ "ignore::pytest.PytestAssertRewriteWarning",
95
+ "ignore:unclosed file.*:ResourceWarning",
79
96
  ]
80
97
  addopts = "--maxfail=1 -rf"
81
98
  testpaths = ["src/tests"]
@@ -111,6 +128,7 @@ channels = ["conda-forge"]
111
128
  platforms = [
112
129
  "linux-64",
113
130
  "osx-arm64",
131
+ "win-64",
114
132
  ]
115
133
 
116
134
  [tool.pixi.pypi-dependencies.graphatoms]
@@ -149,8 +167,8 @@ h5py = ">=3.16.0,<4"
149
167
  hydra-core = ">=1.3.2,<2"
150
168
  tomli-w = ">=1.2.0,<2"
151
169
  loguru = ">=0.7.3,<0.8"
152
- pytorch = ">=2.10.0,<3"
153
- jax = ">=0.9.0,<0.10"
154
170
  jupyterlab = ">=4.5.8,<5"
155
171
  ovld = ">=0.5.15,<0.6"
156
172
  pytest-xdist = ">=3.8.0,<4"
173
+ executorlib = ">=1.8,<2"
174
+ typer = ">=0.20,<1"
@@ -6,10 +6,13 @@ build-backend = "uv_build"
6
6
  Homepage = "https://github.com/LiuGaoyong/GraphAtoms"
7
7
  Repository = "https://github.com/LiuGaoyong/GraphAtoms"
8
8
  Issues = "https://github.com/LiuGaoyong/GraphAtoms/issues/"
9
-
9
+ [project.scripts]
10
+ graphatoms-config = "graphatoms.enterpoint.config:print_config"
11
+ graphatoms-network = "graphatoms.enterpoint.view:main"
12
+ graphatoms-run = "graphatoms.enterpoint.runner:run"
10
13
  [project]
11
14
  name = "graphatoms"
12
- version = "1.2.1"
15
+ version = "2.0.0"
13
16
  readme = "README.md"
14
17
  description = "The Chemical Core Class for Graph Theory Analysis."
15
18
  authors = [{ name = "LiuGaoyong", email = "liugaoyong_88@163.com" }]
@@ -24,9 +27,9 @@ keywords = [
24
27
  "KMC",
25
28
  ]
26
29
  classifiers = [
27
- 'Development Status :: 5 - Production/Stable',
28
- 'Topic :: Scientific/Engineering :: Chemistry',
29
- 'Intended Audience :: Science/Research',
30
+ "Development Status :: 5 - Production/Stable",
31
+ "Topic :: Scientific/Engineering :: Chemistry",
32
+ "Intended Audience :: Science/Research",
30
33
  ]
31
34
  dependencies = [
32
35
  # Chemoinformatics
@@ -35,7 +38,9 @@ dependencies = [
35
38
  "rdkit>=2025",
36
39
 
37
40
  # Scientific Computing
38
- # numpy pandas, scipy
41
+ "numpy>=2,<3",
42
+ "pandas>=2,<4",
43
+ "scipy>=1.10,<2",
39
44
  "scikit-learn>=1.5",
40
45
  "array-api-compat>=1.10",
41
46
  "array_api-extra>=0.10",
@@ -46,33 +51,44 @@ dependencies = [
46
51
 
47
52
  # Data Model
48
53
  "h5py>=3.16",
49
- "hydra-core",
50
- "numpy>=2.0.0,<3",
51
54
  "numpydantic",
52
- "ovld", # singledispatch which works for multiple arguments.
55
+ "ovld", # singledispatch
53
56
  "pydantic>=2.10",
54
57
  "python-snappy>=0.7.3", # More Fase Data Compression
55
58
  "tomli; python_version < '3.11'", # use tomllib in python>=3.11
56
59
  "tomli-w", # TOML writer
57
60
  "typing-extensions",
61
+
62
+ # Other
63
+ "plotext",
64
+ "plotext-plus",
65
+ "matplotlib",
66
+ "executorlib",
67
+ "hydra-core",
68
+ "pipefunc",
69
+ "typer",
58
70
  "loguru",
59
71
  ]
60
72
  [dependency-groups]
61
73
  dev = [
62
74
  "ruff>=0.11",
75
+ "openbabel-wheel",
63
76
  "array-api-strict",
64
77
  "pytest>=8.3",
65
78
  "pytest-xdist",
66
- "jupyter",
67
- "sqlmodel", # SQL + pydantic
68
- 'openbabel-wheel',
79
+ "jupyterlab",
80
+ "chemiscope",
81
+ # "playwright>=1.52", # chemiscope [headless]
82
+ "nglview",
83
+ "ray",
69
84
  ]
70
85
 
71
86
  # uv config
72
87
  [tool.uv]
73
88
  package = true
74
89
  [[tool.uv.index]]
75
- url = "https://mirrors.cernet.edu.cn/pypi/web/simple" # CERNET
90
+ # url = "https://mirrors.cernet.edu.cn/pypi/web/simple" # CERNET
91
+ url = "https://mirrors.nju.edu.cn/pypi/web/simple" # NJU
76
92
  default = true
77
93
  # [[tool.uv.index]]
78
94
  # name = "pytorch-cpu"
@@ -87,13 +103,15 @@ default = true
87
103
  filterwarnings = [
88
104
  "error", # All other warnings are transformed into errors.
89
105
  # ignore the following warnings that matching a regex
90
- # example: 'ignore:function ham\(\) is deprecated:DeprecationWarning',
106
+ # example: "ignore:function ham\(\) is deprecated:DeprecationWarning",
91
107
  "ignore::RuntimeWarning",
92
108
  "ignore::DeprecationWarning",
109
+ "ignore::pytest.PytestAssertRewriteWarning",
110
+ "ignore:unclosed file.*:ResourceWarning",
93
111
 
94
112
  ]
95
- addopts = '--maxfail=1 -rf' # exit after 1 failures, report fail info
96
- testpaths = ['src/tests']
113
+ addopts = "--maxfail=1 -rf" # exit after 1 failures, report fail info
114
+ testpaths = ["src/tests"]
97
115
 
98
116
  # ruff config
99
117
  [tool.ruff]
@@ -114,7 +132,7 @@ backend = { name = "pixi-build-python", version = "*" }
114
132
  [tool.pixi.workspace]
115
133
  preview = ["pixi-build"]
116
134
  channels = ["conda-forge"]
117
- platforms = ["linux-64", "osx-arm64"]
135
+ platforms = ["linux-64", "osx-arm64", "win-64"]
118
136
 
119
137
  [tool.pixi.pypi-dependencies]
120
138
  graphatoms = { path = ".", editable = true }
@@ -125,7 +143,7 @@ dev = { features = ["dev"], solve-group = "default" }
125
143
 
126
144
  [tool.pixi.tasks]
127
145
  test = "pytest -s -vv"
128
- benchmark = 'pytest -s src/tests-benchmark/*.py'
146
+ benchmark = "pytest -s src/tests-benchmark/*.py"
129
147
 
130
148
  [tool.pixi.dependencies]
131
149
  python = ">=3.12"
@@ -148,8 +166,8 @@ h5py = ">=3.16.0,<4"
148
166
  hydra-core = ">=1.3.2,<2"
149
167
  tomli-w = ">=1.2.0,<2"
150
168
  loguru = ">=0.7.3,<0.8"
151
- pytorch = ">=2.10.0,<3"
152
- jax = ">=0.9.0,<0.10"
153
169
  jupyterlab = ">=4.5.8,<5"
154
170
  ovld = ">=0.5.15,<0.6"
155
171
  pytest-xdist = ">=3.8.0,<4"
172
+ executorlib = ">=1.8,<2"
173
+ typer = ">=0.20,<1"
@@ -14,11 +14,20 @@ from pydantic import (
14
14
  __all__ = ["NDArray", "numpy_validator"]
15
15
  _ENCODING = "latin1"
16
16
 
17
+
18
+ @validate_call
19
+ def __convert2str(x: Any) -> str:
20
+ if isinstance(x, np.ndarray):
21
+ return x.tobytes().decode(_ENCODING)
22
+ else:
23
+ return str(x)
24
+
25
+
17
26
  NDArray = Annotated[
18
27
  _NDArray,
19
- PlainSerializer(lambda x: x.tobytes().decode(_ENCODING), return_type=str),
20
- # for pyarrow compatibility, we need to convert bytes to str
21
- # for numpy.ndarray before serialization.
28
+ PlainSerializer(__convert2str, return_type=str, when_used="json"),
29
+ # # for pyarrow compatibility, we need to convert bytes to str
30
+ # # for numpy.ndarray before serialization.
22
31
  WithJsonSchema({"type": str}, mode="serialization"),
23
32
  ]
24
33
  if TYPE_CHECKING:
@@ -1,4 +1,5 @@
1
1
  # ruff: noqa: D100 D102 E501
2
+ import json
2
3
  from collections.abc import Mapping, Sequence
3
4
  from sys import version_info
4
5
  from typing import Any, Self
@@ -34,6 +35,7 @@ class PydanticConvertFactoryMixin(pydantic.BaseModel):
34
35
  exclude_computed_fields: bool = True,
35
36
  numpy_ndarray_compatible: bool = True,
36
37
  numpy_convert_to_list: bool = False,
38
+ pyarrow_compatible: bool = False,
37
39
  **kwargs,
38
40
  ) -> dict[str, Any]:
39
41
  """Convert model to dictionary."""
@@ -46,27 +48,43 @@ class PydanticConvertFactoryMixin(pydantic.BaseModel):
46
48
  exclude_computed_fields=exclude_computed_fields,
47
49
  )
48
50
  )
49
- result = self.model_dump(**kwargs)
50
- if numpy_ndarray_compatible:
51
- for k, v0 in result.items():
52
- v1 = getattr(self, k, None)
53
- if type(v0) is not type(v1) and isinstance(v1, np.ndarray):
54
- result[k] = v1
55
- if np.isscalar(v1):
51
+ if not pyarrow_compatible:
52
+ result = self.model_dump(**kwargs)
53
+ if numpy_ndarray_compatible:
54
+ for k, v0 in result.items():
55
+ v1 = getattr(self, k, None)
56
+ if type(v0) is not type(v1) and isinstance(v1, np.ndarray):
57
+ result[k] = v1
58
+ if np.isscalar(v1):
59
+ pass
60
+ elif isinstance(v1, list | tuple):
61
+ assert isinstance(
62
+ np.asarray(list(v1)).flat[0], np.str_
63
+ ), "Only list[str] is supported."
64
+ else:
65
+ assert isinstance(v1, np.ndarray) or (
66
+ "Only numpy array or scalar is supported. "
67
+ f"But got `{type(v0)}` for {k}."
68
+ )
69
+ if numpy_convert_to_list:
70
+ for k, v in result.items():
71
+ if isinstance(v, np.ndarray):
72
+ result[k] = v.tolist()
73
+ else:
74
+ jsonstr: str = self.to_str(**kwargs)
75
+ result: dict[str, Any] = json.loads(jsonstr)
76
+ assert isinstance(result, dict), "Only dict is supported."
77
+ for k, v in result.items():
78
+ if isinstance(v, str | float | int | bool):
56
79
  pass
57
- elif isinstance(v1, list | tuple):
58
- assert isinstance(np.asarray(list(v1)).flat[0], np.str_), (
59
- "Only list[str] is supported."
60
- )
80
+ elif isinstance(v, list | tuple):
81
+ assert k == "hashes", "Only hashes is supported."
82
+ result[k] = str(v)
61
83
  else:
62
- assert isinstance(v1, np.ndarray) or (
63
- "Only numpy array or scalar is supported. "
64
- f"But got `{type(v0)}` for {k}."
84
+ raise ValueError(
85
+ f"But got unsupported type: `{type(v)}` for {k}."
65
86
  )
66
- if numpy_convert_to_list:
67
- for k, v in result.items():
68
- if isinstance(v, np.ndarray):
69
- result[k] = v.tolist()
87
+
70
88
  return result
71
89
 
72
90
  @pydantic.validate_call
@@ -94,6 +112,7 @@ class PydanticConvertFactoryMixin(pydantic.BaseModel):
94
112
  indent=indent,
95
113
  )
96
114
  )
115
+ kwargs.pop("mode", None)
97
116
  return self.model_dump_json(**kwargs)
98
117
 
99
118
  @pydantic.validate_call
@@ -184,7 +203,8 @@ class PydanticConvertFactoryMixin(pydantic.BaseModel):
184
203
  @classmethod
185
204
  @pydantic.validate_call
186
205
  def from_dict(cls, data: Mapping[str, Any], **kw) -> Self:
187
- return cls.model_validate({**data, **kw})
206
+ kw.update(data) # Update kwargs with data.
207
+ return cls.model_validate(kw)
188
208
 
189
209
 
190
210
  class __Json(PydanticConvertFactoryMixin):
@@ -6,9 +6,9 @@ from numbers import Real
6
6
  from typing import override
7
7
 
8
8
  import numpy as np
9
+ import pyarrow as pa
9
10
  import pydantic
10
11
  from numpy.typing import ArrayLike
11
- from pyarrow import Schema
12
12
 
13
13
  from graphatoms.dataclasses._pydantic2pyarrow import get_pyarrow_schema
14
14
  from graphatoms.dataclasses._pydanticMixin import (
@@ -79,9 +79,15 @@ class OurBaseModel(PydanticFactoryMixin, _IndexMaskMixin):
79
79
  """
80
80
 
81
81
  @classmethod
82
- def get_pyarrow_schema(cls) -> Schema:
82
+ def get_pyarrow_schema(cls) -> pa.Schema:
83
83
  """Get the pyarrow schema of this class."""
84
- return get_pyarrow_schema(cls)
84
+ schema: pa.Schema = get_pyarrow_schema(cls)
85
+ if "hashes" not in cls.__pydantic_fields__:
86
+ return schema
87
+ else:
88
+ target_index: int = schema.get_field_index("hashes")
89
+ new_field = schema.field("hashes").with_type(pa.string())
90
+ return schema.set(target_index, new_field)
85
91
 
86
92
  def __repr__(self) -> str:
87
93
  return super().__repr__()
@@ -157,6 +163,6 @@ class OurFrozenModel(OurBaseModel):
157
163
  return hash(self.hash)
158
164
 
159
165
  @cached_property
160
- @abstractmethod
161
166
  def hash(self) -> str:
162
167
  """Get the HASH string of this object."""
168
+ raise NotImplementedError("hash is not implemented for this class.")
@@ -0,0 +1,110 @@
1
+ import os
2
+ from dataclasses import dataclass, field
3
+ from pathlib import Path
4
+ from typing import Any
5
+
6
+ os.environ["HYDRA_FULL_ERROR"] = "1"
7
+ import hydra
8
+ from hydra.core.config_store import ConfigStore
9
+ from omegaconf import MISSING, OmegaConf
10
+
11
+ from .atoms import AseReadAtomsConfig, AtomsConfig
12
+ from .atoms import OctahedronAtomsConfig as OctAtomsConfig
13
+ from .bonds import BondsConfig, RawBondsConfig
14
+ from .calculator import CalcConfig, EMTCalcConfig
15
+ from .calculator import NequipCalcConfig as NequipConfig
16
+
17
+ CONFIG_DIR = Path(__file__).parent
18
+
19
+
20
+ @dataclass
21
+ class SiteConfig:
22
+ method: str = "distance" # or hop
23
+ env_threshold: float = 15 # the environment threshold
24
+ max_moved_threshold: float = 8 # the maximum moved threshold
25
+
26
+
27
+ @dataclass
28
+ class ExplConfig:
29
+ maxtry: int = 1000
30
+ maxconfidence: float = 10
31
+ max_ncore_for_surface: int = 3 # 4, 5, 6
32
+ surface_only_explore_single_core: bool = True
33
+ allow_multiple_adsorption: bool = False
34
+ allow_explore_bulk: bool = False
35
+ thetacutoff: float = -1 # 0-180, -1 means no cutoff
36
+ nfibonacci: int = 200
37
+
38
+
39
+ @dataclass
40
+ class EventConfig:
41
+ db_format: str = "folder"
42
+ check_frequency: bool = True # whether to check the frequency
43
+ max_force: float = 0.05 # eV / Angstrom
44
+ min_frequency: float = 10.0 # cm^-1
45
+ min_frequency_for_ts: float = 20.0 # cm^-1
46
+ simplified_threshold: float = 7.0 # the simplified threshold for event
47
+ gas_sticking: dict[str, float] = field(default_factory=dict)
48
+ gas_pressure: dict[str, float] = field(default_factory=dict)
49
+ default_pressure: float = 101325
50
+ default_sticking: float = 1.0
51
+ temperature: float = 300
52
+
53
+
54
+ @dataclass
55
+ class OptConfig:
56
+ method: str = "lbfgs"
57
+ fmax: float = 0.05
58
+ steps: int = 200
59
+
60
+
61
+ @dataclass
62
+ class Config:
63
+ atoms: AtomsConfig = MISSING
64
+ bonds: BondsConfig = MISSING
65
+ system: Any = MISSING
66
+
67
+ calculator: CalcConfig = MISSING
68
+
69
+ outputs: str = "./zzz"
70
+ max_steps: int = 100000
71
+ max_times: float = 1000.0 # seconds
72
+ run_type: str = "otfkmc" # otfkmc, rxngen
73
+ parallel_workers: int = 0 # 0 means use all cores
74
+ parallel: str = "serial" # serial, multiprocessing, ray, dask, executorlib
75
+ loglevel: str = "info" # Literal["debug", "info", "warning", "error"]
76
+ logfile: str = "log.txt"
77
+ restart: bool = True
78
+ debug: bool = False
79
+
80
+ site: SiteConfig = field(default_factory=SiteConfig)
81
+ exploration: ExplConfig = field(default_factory=ExplConfig)
82
+ event: EventConfig = field(default_factory=EventConfig)
83
+ optimizer: OptConfig = field(default_factory=OptConfig)
84
+
85
+
86
+ cs = ConfigStore.instance()
87
+ cs.store(name="base_config", node=Config)
88
+ cs.store(group="atoms", name="atoms_aseread", node=AseReadAtomsConfig)
89
+ cs.store(group="atoms", name="atoms_octahedron", node=OctAtomsConfig)
90
+ cs.store(group="bonds", name="bonds_raw", node=RawBondsConfig)
91
+ cs.store(group="calculator", name="calc_emt", node=EMTCalcConfig)
92
+ cs.store(group="calculator", name="calc_nequip", node=NequipConfig)
93
+
94
+
95
+ @hydra.main(
96
+ config_path=CONFIG_DIR.as_posix(),
97
+ config_name="run",
98
+ version_base=None,
99
+ )
100
+ def print_config(cfg: Config) -> None:
101
+ from shutil import rmtree
102
+
103
+ print(OmegaConf.to_yaml(cfg))
104
+ print("""
105
+ hydra:
106
+ run:
107
+ dir: ${outputs}
108
+ verbose: ${debug}
109
+ """)
110
+ rmtree(Path(cfg.outputs))
@@ -0,0 +1,24 @@
1
+ from dataclasses import dataclass
2
+
3
+ from omegaconf import MISSING
4
+
5
+
6
+ @dataclass
7
+ class AtomsConfig:
8
+ _target_: str = MISSING
9
+
10
+
11
+ @dataclass
12
+ class OctahedronAtomsConfig(AtomsConfig):
13
+ _target_: str = "ase.cluster.Octahedron"
14
+ symbol: str = MISSING
15
+ length: int = MISSING
16
+ cutoff: int = 0
17
+ alloy: bool = False
18
+
19
+
20
+ @dataclass
21
+ class AseReadAtomsConfig(AtomsConfig):
22
+ _target_: str = "ase.io.read"
23
+ filename: str = MISSING
24
+ index: int = -1
@@ -0,0 +1,5 @@
1
+ defaults:
2
+ - atoms_aseread
3
+
4
+ filename: structure.xyz
5
+
@@ -0,0 +1,7 @@
1
+ defaults:
2
+ - atoms_octahedron
3
+
4
+ _target_: ase.cluster.Octahedron
5
+ symbol: Pd
6
+ length: 8
7
+
@@ -0,0 +1,23 @@
1
+ from dataclasses import dataclass, field
2
+ from typing import Any
3
+
4
+ from omegaconf import MISSING
5
+
6
+
7
+ @dataclass
8
+ class BondsConfig:
9
+ method: str = MISSING
10
+ cfg: Any = MISSING
11
+
12
+
13
+ ####### RAW ########
14
+ @dataclass
15
+ class _RawBondsConfig:
16
+ multiply_factor: float = 1.0
17
+ plus_factor: float = 0.5 # Angstrom
18
+
19
+
20
+ @dataclass
21
+ class RawBondsConfig(BondsConfig):
22
+ method: str = "raw"
23
+ cfg: _RawBondsConfig = field(default_factory=_RawBondsConfig)
@@ -0,0 +1,8 @@
1
+ defaults:
2
+ - bonds_raw
3
+
4
+ method: "raw" # or pymatgen
5
+ cfg:
6
+ multiply_factor: 1.0
7
+ plus_factor: 0.5 # Angstrom
8
+
@@ -0,0 +1,29 @@
1
+ from dataclasses import dataclass, field
2
+
3
+ from omegaconf import MISSING
4
+
5
+
6
+ @dataclass
7
+ class CalcConfig:
8
+ _target_: str = MISSING
9
+
10
+
11
+ @dataclass
12
+ class EMTCalcConfig(CalcConfig):
13
+ _target_: str = "ase.calculators.emt.EMT"
14
+
15
+
16
+ @dataclass
17
+ class _NequipCalcConfig(CalcConfig):
18
+ _target_: str = "os.path.expanduser"
19
+ path: str = MISSING
20
+
21
+
22
+ @dataclass
23
+ class NequipCalcConfig(CalcConfig):
24
+ _target_: str = (
25
+ "nequip.integrations.ase.NequIPCalculator.from_compiled_model"
26
+ )
27
+ chemical_species_to_atom_type_map: bool = True
28
+ compile_path: _NequipCalcConfig = field(default_factory=_NequipCalcConfig)
29
+ device: str = "cpu"
@@ -0,0 +1,4 @@
1
+ defaults:
2
+ - calc_emt
3
+
4
+ _target_: ase.calculators.emt.EMT
@@ -0,0 +1,9 @@
1
+ defaults:
2
+ - calc_nequip
3
+
4
+ _target_: nequip.integrations.ase.NequIPCalculator.from_compiled_model
5
+ chemical_species_to_atom_type_map: true
6
+ compile_path:
7
+ _target_: os.path.expanduser
8
+ path: "~/.local/nequip-oam-0.1/NequIP-OAM-S-0.1.nequip.pth"
9
+ device: cpu