GraphAtoms 1.2.2__tar.gz → 2.1.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 (99) hide show
  1. {graphatoms-1.2.2 → graphatoms-2.1.0}/PKG-INFO +42 -11
  2. {graphatoms-1.2.2 → graphatoms-2.1.0}/README.md +35 -8
  3. {graphatoms-1.2.2 → graphatoms-2.1.0}/pyproject.toml +23 -9
  4. {graphatoms-1.2.2 → graphatoms-2.1.0}/pyproject.toml.orig +34 -20
  5. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/dataclasses/_numpydantic.py +12 -3
  6. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/dataclasses/_pydanticMixin.py +39 -19
  7. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/dataclasses/_pydanticModel.py +10 -4
  8. graphatoms-2.1.0/src/graphatoms/enterpoint/config/__init__.py +110 -0
  9. graphatoms-2.1.0/src/graphatoms/enterpoint/config/atoms/__init__.py +24 -0
  10. graphatoms-2.1.0/src/graphatoms/enterpoint/config/atoms/aseread.yaml +5 -0
  11. graphatoms-2.1.0/src/graphatoms/enterpoint/config/atoms/octahedron.yaml +7 -0
  12. graphatoms-2.1.0/src/graphatoms/enterpoint/config/bonds/__init__.py +23 -0
  13. graphatoms-2.1.0/src/graphatoms/enterpoint/config/bonds/raw.yaml +8 -0
  14. graphatoms-2.1.0/src/graphatoms/enterpoint/config/calculator/__init__.py +29 -0
  15. graphatoms-2.1.0/src/graphatoms/enterpoint/config/calculator/emt.yaml +4 -0
  16. graphatoms-2.1.0/src/graphatoms/enterpoint/config/calculator/nequip.yaml +9 -0
  17. graphatoms-2.1.0/src/graphatoms/enterpoint/config/example.yaml +72 -0
  18. graphatoms-2.1.0/src/graphatoms/enterpoint/config/run.yaml +25 -0
  19. graphatoms-2.1.0/src/graphatoms/enterpoint/network/__init__.py +217 -0
  20. graphatoms-2.1.0/src/graphatoms/enterpoint/network/_metadata.py +318 -0
  21. graphatoms-2.1.0/src/graphatoms/enterpoint/network/_recorder.py +130 -0
  22. graphatoms-2.1.0/src/graphatoms/enterpoint/network/_scheduler.py +151 -0
  23. graphatoms-2.1.0/src/graphatoms/enterpoint/parallel/__init__.py +66 -0
  24. graphatoms-2.1.0/src/graphatoms/enterpoint/parallel/_base.py +132 -0
  25. graphatoms-2.1.0/src/graphatoms/enterpoint/parallel/_dask.py +48 -0
  26. graphatoms-2.1.0/src/graphatoms/enterpoint/parallel/_executorlib.py +49 -0
  27. graphatoms-2.1.0/src/graphatoms/enterpoint/parallel/_ray.py +70 -0
  28. graphatoms-2.1.0/src/graphatoms/enterpoint/runner/__init__.py +24 -0
  29. graphatoms-2.1.0/src/graphatoms/enterpoint/runner/_base.py +762 -0
  30. graphatoms-2.1.0/src/graphatoms/enterpoint/runner/_errors.py +69 -0
  31. graphatoms-2.1.0/src/graphatoms/enterpoint/runner/_helper.py +554 -0
  32. graphatoms-2.1.0/src/graphatoms/enterpoint/runner/otfkmc.py +200 -0
  33. graphatoms-2.1.0/src/graphatoms/enterpoint/runner/rxngen.py +9 -0
  34. graphatoms-2.1.0/src/graphatoms/enterpoint/view.py +106 -0
  35. graphatoms-2.1.0/src/graphatoms/reaction/__init__.py +17 -0
  36. {graphatoms-1.2.2/src/graphatoms/reaction/event → graphatoms-2.1.0/src/graphatoms/reaction}/_event.py +224 -55
  37. {graphatoms-1.2.2/src/graphatoms/reaction/event → graphatoms-2.1.0/src/graphatoms/reaction}/reaction.py +19 -5
  38. graphatoms-2.1.0/src/graphatoms/reaction/xxsorption.py +198 -0
  39. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/system/__init__.py +1 -5
  40. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/system/atoms.py +81 -15
  41. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/system/bonds.py +32 -34
  42. graphatoms-2.1.0/src/graphatoms/system/database/__init__.py +39 -0
  43. graphatoms-2.1.0/src/graphatoms/system/database/abc.py +79 -0
  44. graphatoms-2.1.0/src/graphatoms/system/database/dict.py +42 -0
  45. graphatoms-2.1.0/src/graphatoms/system/database/dir.py +52 -0
  46. graphatoms-2.1.0/src/graphatoms/system/database/hdf5.py +114 -0
  47. graphatoms-2.1.0/src/graphatoms/system/database/sqliteASE.py +91 -0
  48. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/system/graph.py +176 -108
  49. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/system/sysCluster.py +12 -9
  50. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/system/sysGas.py +34 -14
  51. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/system/system.py +0 -2
  52. graphatoms-2.1.0/src/graphatoms/utils/adsorption.py +790 -0
  53. graphatoms-2.1.0/src/graphatoms/utils/asetools.py +411 -0
  54. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/utils/bytestool.py +21 -15
  55. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/utils/parser.py +4 -1
  56. graphatoms-1.2.2/src/graphatoms/reaction/__init__.py +0 -10
  57. graphatoms-1.2.2/src/graphatoms/reaction/base/__init__.py +0 -9
  58. graphatoms-1.2.2/src/graphatoms/reaction/base/move.py +0 -17
  59. graphatoms-1.2.2/src/graphatoms/reaction/base/rtgp.py +0 -150
  60. graphatoms-1.2.2/src/graphatoms/reaction/database/__init__.py +0 -1
  61. graphatoms-1.2.2/src/graphatoms/reaction/database/base.py +0 -92
  62. graphatoms-1.2.2/src/graphatoms/reaction/database/hdf5.py +0 -136
  63. graphatoms-1.2.2/src/graphatoms/reaction/database/sqliteASE.py +0 -141
  64. graphatoms-1.2.2/src/graphatoms/reaction/event/__init__.py +0 -15
  65. graphatoms-1.2.2/src/graphatoms/reaction/event/adsorption.py +0 -17
  66. graphatoms-1.2.2/src/graphatoms/reaction/event/desorption.py +0 -17
  67. graphatoms-1.2.2/src/graphatoms/reaction/mcmove/__init__.py +0 -5
  68. graphatoms-1.2.2/src/graphatoms/reaction/mcmove/_abc.py +0 -12
  69. graphatoms-1.2.2/src/graphatoms/reaction/mcmove/_base.py +0 -142
  70. graphatoms-1.2.2/src/graphatoms/reaction/mcmove/_moveFB.py +0 -179
  71. graphatoms-1.2.2/src/graphatoms/reaction/mcmove/_moveSP.py +0 -120
  72. graphatoms-1.2.2/src/graphatoms/reaction/mcmove/_moveSwap.py +0 -119
  73. graphatoms-1.2.2/src/graphatoms/reaction/mcmove/_simNVT.py +0 -179
  74. graphatoms-1.2.2/src/graphatoms/reaction/mcmove/test_mmc.py +0 -57
  75. graphatoms-1.2.2/src/graphatoms/reaction/mcmove/test_move.py +0 -23
  76. graphatoms-1.2.2/src/graphatoms/reaction/mcmove/zzz.py +0 -103
  77. graphatoms-1.2.2/src/graphatoms/reaction/mdwarpper/__init__.py +0 -36
  78. graphatoms-1.2.2/src/graphatoms/reaction/network/_base.py +0 -60
  79. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/LICENSE +0 -0
  80. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/__init__.py +0 -0
  81. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/arrayapi/__init__.py +0 -0
  82. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/arrayapi/compat.py +0 -0
  83. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/arrayapi/typing.py +0 -0
  84. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/dataclasses/__init__.py +0 -0
  85. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/dataclasses/_pydantic2pyarrow.py +0 -0
  86. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/dataclasses/graph.py +0 -0
  87. {graphatoms-1.2.2/src/graphatoms/reaction/network → graphatoms-2.1.0/src/graphatoms/enterpoint}/__init__.py +0 -0
  88. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/geometry/__init__.py +0 -0
  89. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/geometry/_bond_list.py +0 -0
  90. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/geometry/_distance_pairs.py +0 -0
  91. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/geometry/_inner_outer.py +0 -0
  92. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/geometry/_neighbor_list.py +0 -0
  93. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/geometry/mic.py +0 -0
  94. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/geometry/rotation.py +0 -0
  95. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/geometry/sample.py +0 -0
  96. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/utils/__init__.py +0 -0
  97. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/utils/logger.py +0 -0
  98. {graphatoms-1.2.2 → graphatoms-2.1.0}/src/graphatoms/utils/rdutils.py +0 -0
  99. {graphatoms-1.2.2 → graphatoms-2.1.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.2
3
+ Version: 2.1.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,9 @@ 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: executorlib
33
+ Requires-Dist: hydra-core
34
+ Requires-Dist: typer
31
35
  Requires-Dist: loguru
32
36
  Requires-Python: >=3.12
33
37
  Project-URL: Homepage, https://github.com/LiuGaoyong/GraphAtoms
@@ -54,6 +58,14 @@ The `graphatoms` is a Python library designed for chemical graph theory analysis
54
58
  - **Dataclasses**: Pydantic-based data models for type-safe data handling
55
59
  - **Array API Compatibility**: Full support for array API standard for cross-framework compatibility (NumPy, PyTorch, JAX, CuPy, etc.)
56
60
  - **Subgraph Operations**: Backend-agnostic subgraph extraction with relabeling support using array-api-compat and array-api-extra
61
+ - **CLI Entry Points**: Three console scripts for configuration, execution, and inspection:
62
+ - `graphatoms-config`: Resolve and print the Hydra/OmegaConf run configuration
63
+ - `graphatoms-run`: Launch a run
64
+ - `run_type=otfkmc` for on-the-fly kinetic Monte Carlo simulation
65
+ - `run_type=rxngen` for reaction network generation
66
+ - `graphatoms-network`: Inspect and visualize a stored reaction network
67
+ - **Hydra-driven Configuration**: Composable, override-friendly config via Hydra/OmegaConf with grouped groups (`atoms`, `bonds`, `calculator`)
68
+ - **Pluggable Parallel Backends**: Switch executors at the config level — `serial`, `multiprocessing`, `ray`, `dask`, `executorlib` — for distributed/on-the-fly KMC workflows
57
69
 
58
70
  ## Module Structure
59
71
 
@@ -61,18 +73,33 @@ The `graphatoms` is a Python library designed for chemical graph theory analysis
61
73
  src/graphatoms/
62
74
  ├── arrayapi/ # Array API compatibility layer
63
75
  ├── dataclasses/ # Pydantic-based data models
76
+ ├── enterpoint/ # Entry points: CLI, config, runners, network, parallel
77
+ │ ├── config/ # Hydra/OmegaConf configuration (atoms, bonds, calculator)
78
+ │ ├── network/ # Reaction network: scheduler, recorder, metadata
79
+ │ ├── parallel/ # Pluggable executors (serial, multiprocessing, ray, dask, executorlib)
80
+ │ ├── runner/ # Runners (otfkmc, rxngen) and helpers
81
+ │ ├── steps/ # Step primitives for runners
82
+ │ └── view.py # CLI viewer for reactions
64
83
  ├── geometry/ # Geometric operations
65
84
  ├── reaction/ # Reaction classes and KMC events
66
- │ ├── base/ # Abstract base classes
67
- │ ├── event/ # KMC events (adsorption, desorption, reaction)
68
- │ ├── mcmove/ # Monte Carlo moves
69
- │ ├── mdwarpper/ # MD wrapper
70
- │ └── network/ # Reaction network
85
+ │ ├── _event.py # Event base and event info
86
+ │ ├── reaction.py # Reaction class
87
+ │ └── xxsorption.py # Adsorption/Desorption events
71
88
  ├── system/ # Core system classes
72
- │ ├── atoms/ # Atomic structure handling
73
- │ ├── database/ # Database storage backends
74
- │ └── graph/ # Graph-based system representation
89
+ │ ├── atoms.py # Atomic structure handling
90
+ │ ├── bonds.py # Bond list operations
91
+ │ ├── graph.py # Graph-based system representation
92
+ │ ├── system.py # System abstract base
93
+ │ ├── sysCluster.py # Cluster system
94
+ │ ├── sysGas.py # Gas molecule system
95
+ │ └── database/ # Database storage backends (HDF5, SQLite, folder)
75
96
  └── utils/ # Utility functions
97
+ ├── adsorption.py # Adsorption site helper
98
+ ├── asetools.py # ASE-related tools
99
+ ├── bytestool.py # Byte-level helpers
100
+ ├── logger.py # Logging setup
101
+ ├── parser.py # Hydra argument parsing
102
+ ├── rdutils.py # RDKit utilities
76
103
  └── subgraph.py # Array API compatible subgraph operations
77
104
  ```
78
105
 
@@ -95,6 +122,10 @@ src/graphatoms/
95
122
  - pydantic >= 2.10
96
123
  - python-snappy >= 0.7.3
97
124
  - loguru
125
+ - pandas >= 2
126
+ - scipy >= 1.10
127
+ - typer
128
+ - executorlib
98
129
 
99
130
  ## Installation
100
131
 
@@ -17,6 +17,14 @@ The `graphatoms` is a Python library designed for chemical graph theory analysis
17
17
  - **Dataclasses**: Pydantic-based data models for type-safe data handling
18
18
  - **Array API Compatibility**: Full support for array API standard for cross-framework compatibility (NumPy, PyTorch, JAX, CuPy, etc.)
19
19
  - **Subgraph Operations**: Backend-agnostic subgraph extraction with relabeling support using array-api-compat and array-api-extra
20
+ - **CLI Entry Points**: Three console scripts for configuration, execution, and inspection:
21
+ - `graphatoms-config`: Resolve and print the Hydra/OmegaConf run configuration
22
+ - `graphatoms-run`: Launch a run
23
+ - `run_type=otfkmc` for on-the-fly kinetic Monte Carlo simulation
24
+ - `run_type=rxngen` for reaction network generation
25
+ - `graphatoms-network`: Inspect and visualize a stored reaction network
26
+ - **Hydra-driven Configuration**: Composable, override-friendly config via Hydra/OmegaConf with grouped groups (`atoms`, `bonds`, `calculator`)
27
+ - **Pluggable Parallel Backends**: Switch executors at the config level — `serial`, `multiprocessing`, `ray`, `dask`, `executorlib` — for distributed/on-the-fly KMC workflows
20
28
 
21
29
  ## Module Structure
22
30
 
@@ -24,18 +32,33 @@ The `graphatoms` is a Python library designed for chemical graph theory analysis
24
32
  src/graphatoms/
25
33
  ├── arrayapi/ # Array API compatibility layer
26
34
  ├── dataclasses/ # Pydantic-based data models
35
+ ├── enterpoint/ # Entry points: CLI, config, runners, network, parallel
36
+ │ ├── config/ # Hydra/OmegaConf configuration (atoms, bonds, calculator)
37
+ │ ├── network/ # Reaction network: scheduler, recorder, metadata
38
+ │ ├── parallel/ # Pluggable executors (serial, multiprocessing, ray, dask, executorlib)
39
+ │ ├── runner/ # Runners (otfkmc, rxngen) and helpers
40
+ │ ├── steps/ # Step primitives for runners
41
+ │ └── view.py # CLI viewer for reactions
27
42
  ├── geometry/ # Geometric operations
28
43
  ├── reaction/ # Reaction classes and KMC events
29
- │ ├── base/ # Abstract base classes
30
- │ ├── event/ # KMC events (adsorption, desorption, reaction)
31
- │ ├── mcmove/ # Monte Carlo moves
32
- │ ├── mdwarpper/ # MD wrapper
33
- │ └── network/ # Reaction network
44
+ │ ├── _event.py # Event base and event info
45
+ │ ├── reaction.py # Reaction class
46
+ │ └── xxsorption.py # Adsorption/Desorption events
34
47
  ├── system/ # Core system classes
35
- │ ├── atoms/ # Atomic structure handling
36
- │ ├── database/ # Database storage backends
37
- │ └── graph/ # Graph-based system representation
48
+ │ ├── atoms.py # Atomic structure handling
49
+ │ ├── bonds.py # Bond list operations
50
+ │ ├── graph.py # Graph-based system representation
51
+ │ ├── system.py # System abstract base
52
+ │ ├── sysCluster.py # Cluster system
53
+ │ ├── sysGas.py # Gas molecule system
54
+ │ └── database/ # Database storage backends (HDF5, SQLite, folder)
38
55
  └── utils/ # Utility functions
56
+ ├── adsorption.py # Adsorption site helper
57
+ ├── asetools.py # ASE-related tools
58
+ ├── bytestool.py # Byte-level helpers
59
+ ├── logger.py # Logging setup
60
+ ├── parser.py # Hydra argument parsing
61
+ ├── rdutils.py # RDKit utilities
39
62
  └── subgraph.py # Array API compatible subgraph operations
40
63
  ```
41
64
 
@@ -58,6 +81,10 @@ src/graphatoms/
58
81
  - pydantic >= 2.10
59
82
  - python-snappy >= 0.7.3
60
83
  - loguru
84
+ - pandas >= 2
85
+ - scipy >= 1.10
86
+ - typer
87
+ - executorlib
61
88
 
62
89
  ## Installation
63
90
 
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "graphatoms"
7
- version = "1.2.2"
7
+ version = "2.1.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,9 @@ dependencies = [
41
42
  "tomli; python_version < '3.11'",
42
43
  "tomli-w",
43
44
  "typing-extensions",
45
+ "executorlib",
46
+ "hydra-core",
47
+ "typer",
44
48
  "loguru",
45
49
  ]
46
50
 
@@ -49,6 +53,11 @@ Homepage = "https://github.com/LiuGaoyong/GraphAtoms"
49
53
  Repository = "https://github.com/LiuGaoyong/GraphAtoms"
50
54
  Issues = "https://github.com/LiuGaoyong/GraphAtoms/issues/"
51
55
 
56
+ [project.scripts]
57
+ graphatoms-config = "graphatoms.enterpoint.config:print_config"
58
+ graphatoms-network = "graphatoms.enterpoint.view:main"
59
+ graphatoms-run = "graphatoms.enterpoint.runner:run"
60
+
52
61
  [[project.authors]]
53
62
  name = "LiuGaoyong"
54
63
  email = "liugaoyong_88@163.com"
@@ -56,19 +65,21 @@ email = "liugaoyong_88@163.com"
56
65
  [dependency-groups]
57
66
  dev = [
58
67
  "ruff>=0.11",
68
+ "openbabel-wheel",
59
69
  "array-api-strict",
60
70
  "pytest>=8.3",
61
71
  "pytest-xdist",
62
- "jupyter",
63
- "sqlmodel",
64
- "openbabel-wheel",
72
+ "jupyterlab",
73
+ "chemiscope",
74
+ "nglview",
75
+ "ray",
65
76
  ]
66
77
 
67
78
  [tool.uv]
68
79
  package = true
69
80
 
70
81
  [[tool.uv.index]]
71
- url = "https://mirrors.cernet.edu.cn/pypi/web/simple"
82
+ url = "https://mirrors.nju.edu.cn/pypi/web/simple"
72
83
  default = true
73
84
 
74
85
  [tool.pytest.ini_options]
@@ -76,6 +87,8 @@ filterwarnings = [
76
87
  "error",
77
88
  "ignore::RuntimeWarning",
78
89
  "ignore::DeprecationWarning",
90
+ "ignore::pytest.PytestAssertRewriteWarning",
91
+ "ignore:unclosed file.*:ResourceWarning",
79
92
  ]
80
93
  addopts = "--maxfail=1 -rf"
81
94
  testpaths = ["src/tests"]
@@ -111,6 +124,7 @@ channels = ["conda-forge"]
111
124
  platforms = [
112
125
  "linux-64",
113
126
  "osx-arm64",
127
+ "win-64",
114
128
  ]
115
129
 
116
130
  [tool.pixi.pypi-dependencies.graphatoms]
@@ -149,8 +163,8 @@ h5py = ">=3.16.0,<4"
149
163
  hydra-core = ">=1.3.2,<2"
150
164
  tomli-w = ">=1.2.0,<2"
151
165
  loguru = ">=0.7.3,<0.8"
152
- pytorch = ">=2.10.0,<3"
153
- jax = ">=0.9.0,<0.10"
154
166
  jupyterlab = ">=4.5.8,<5"
155
167
  ovld = ">=0.5.15,<0.6"
156
168
  pytest-xdist = ">=3.8.0,<4"
169
+ executorlib = ">=1.8,<2"
170
+ 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.2"
15
+ version = "2.1.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,40 @@ 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
+ "executorlib",
64
+ "hydra-core",
65
+ "typer",
58
66
  "loguru",
59
67
  ]
60
68
  [dependency-groups]
61
69
  dev = [
62
70
  "ruff>=0.11",
71
+ "openbabel-wheel",
63
72
  "array-api-strict",
64
73
  "pytest>=8.3",
65
74
  "pytest-xdist",
66
- "jupyter",
67
- "sqlmodel", # SQL + pydantic
68
- 'openbabel-wheel',
75
+ "jupyterlab",
76
+ "chemiscope",
77
+ # "playwright>=1.52", # chemiscope [headless]
78
+ "nglview",
79
+ "ray",
69
80
  ]
70
81
 
71
82
  # uv config
72
83
  [tool.uv]
73
84
  package = true
74
85
  [[tool.uv.index]]
75
- url = "https://mirrors.cernet.edu.cn/pypi/web/simple" # CERNET
86
+ # url = "https://mirrors.cernet.edu.cn/pypi/web/simple" # CERNET
87
+ url = "https://mirrors.nju.edu.cn/pypi/web/simple" # NJU
76
88
  default = true
77
89
  # [[tool.uv.index]]
78
90
  # name = "pytorch-cpu"
@@ -87,13 +99,15 @@ default = true
87
99
  filterwarnings = [
88
100
  "error", # All other warnings are transformed into errors.
89
101
  # ignore the following warnings that matching a regex
90
- # example: 'ignore:function ham\(\) is deprecated:DeprecationWarning',
102
+ # example: "ignore:function ham\(\) is deprecated:DeprecationWarning",
91
103
  "ignore::RuntimeWarning",
92
104
  "ignore::DeprecationWarning",
105
+ "ignore::pytest.PytestAssertRewriteWarning",
106
+ "ignore:unclosed file.*:ResourceWarning",
93
107
 
94
108
  ]
95
- addopts = '--maxfail=1 -rf' # exit after 1 failures, report fail info
96
- testpaths = ['src/tests']
109
+ addopts = "--maxfail=1 -rf" # exit after 1 failures, report fail info
110
+ testpaths = ["src/tests"]
97
111
 
98
112
  # ruff config
99
113
  [tool.ruff]
@@ -114,7 +128,7 @@ backend = { name = "pixi-build-python", version = "*" }
114
128
  [tool.pixi.workspace]
115
129
  preview = ["pixi-build"]
116
130
  channels = ["conda-forge"]
117
- platforms = ["linux-64", "osx-arm64"]
131
+ platforms = ["linux-64", "osx-arm64", "win-64"]
118
132
 
119
133
  [tool.pixi.pypi-dependencies]
120
134
  graphatoms = { path = ".", editable = true }
@@ -125,7 +139,7 @@ dev = { features = ["dev"], solve-group = "default" }
125
139
 
126
140
  [tool.pixi.tasks]
127
141
  test = "pytest -s -vv"
128
- benchmark = 'pytest -s src/tests-benchmark/*.py'
142
+ benchmark = "pytest -s src/tests-benchmark/*.py"
129
143
 
130
144
  [tool.pixi.dependencies]
131
145
  python = ">=3.12"
@@ -148,8 +162,8 @@ h5py = ">=3.16.0,<4"
148
162
  hydra-core = ">=1.3.2,<2"
149
163
  tomli-w = ">=1.2.0,<2"
150
164
  loguru = ">=0.7.3,<0.8"
151
- pytorch = ">=2.10.0,<3"
152
- jax = ">=0.9.0,<0.10"
153
165
  jupyterlab = ">=4.5.8,<5"
154
166
  ovld = ">=0.5.15,<0.6"
155
167
  pytest-xdist = ">=3.8.0,<4"
168
+ executorlib = ">=1.8,<2"
169
+ 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))