GraphAtoms 2.3.1__tar.gz → 2.3.2__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.2}/PKG-INFO +1 -1
- {graphatoms-2.3.1 → graphatoms-2.3.2}/pyproject.toml +1 -1
- {graphatoms-2.3.1 → graphatoms-2.3.2}/pyproject.toml.orig +1 -1
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/dataclasses/_pydanticMixin.py +38 -20
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/network/_clsnetwork.py +15 -7
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/network/_metadata.py +5 -1
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/network/_scheduler.py +9 -2
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/common/_base.py +6 -3
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/common/_helper.py +7 -5
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/general/otfkmc.py +5 -1
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/geometry/sample.py +7 -1
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/system/database/abc.py +8 -5
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/utils/adsorption.py +6 -2
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/utils/bytestool.py +52 -1
- {graphatoms-2.3.1 → graphatoms-2.3.2}/README.md +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/LICENSE +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/arrayapi/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/arrayapi/compat.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/arrayapi/typing.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/dataclasses/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/dataclasses/_numpydantic.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/dataclasses/_pydantic2pyarrow.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/dataclasses/_pydanticModel.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/dataclasses/graph.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/config/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/config/atoms/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/config/atoms/aseread.yaml +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/config/atoms/octahedron.yaml +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/config/bonds/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/config/bonds/raw.yaml +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/config/calculator/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/config/calculator/emt.yaml +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/config/calculator/nequip.yaml +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/config/example.yaml +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/config/run.yaml +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/network/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/network/_commands.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/network/_recorder.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/parallel/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/parallel/_base.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/parallel/_dask.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/parallel/_executorlib.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/parallel/_ray.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/common/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/common/_errors.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/general/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/general/_expl.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/general/rxngen.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/v2/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/v2/_helperv2.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/v2/general/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/v2/general/_expl.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/v2/general/otfkmc.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/v2/general/rxngen.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/v2/ray/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/v2/ray/_expl.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/v2/ray/_helper.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/v2/ray/otfkmc.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/v2/ray/rxngen.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/geometry/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/geometry/_bond_list.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/geometry/_distance_pairs.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/geometry/_inner_outer.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/geometry/_neighbor_list.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/geometry/mic.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/geometry/rotation.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/reaction/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/reaction/_event.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/reaction/reaction.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/reaction/xxsorption.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/system/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/system/atoms.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/system/bonds.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/system/database/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/system/database/dict.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/system/database/dir.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/system/database/hdf5.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/system/database/sqliteASE.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/system/graph.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/system/sysCluster.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/system/sysGas.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/system/system.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/utils/__init__.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/utils/aseqhull.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/utils/asetools.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/utils/logger.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/utils/parser.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/utils/rdutils.py +0 -0
- {graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/utils/subgraph.py +0 -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.2"
|
|
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" }]
|
|
@@ -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",
|
|
@@ -10,6 +10,7 @@ from graphatoms.dataclasses import OurBaseModel
|
|
|
10
10
|
from graphatoms.enterpoint.config import Config, EventConfig
|
|
11
11
|
from graphatoms.reaction import EventBase, EventInfo
|
|
12
12
|
from graphatoms.system.bonds import matchmode2nmatch
|
|
13
|
+
from graphatoms.utils.bytestool import atomic_write
|
|
13
14
|
|
|
14
15
|
__all__ = ["MetaData"]
|
|
15
16
|
|
|
@@ -187,7 +188,10 @@ class MetaData(BaseModel):
|
|
|
187
188
|
|
|
188
189
|
def persistence(self, path: Path | str) -> None:
|
|
189
190
|
self.basic.write_json(Path(path) / "metadata-basic.json")
|
|
190
|
-
|
|
191
|
+
atomic_write(
|
|
192
|
+
Path(path) / "metadata-table.feather",
|
|
193
|
+
writer=lambda p: self.table.dataframe.to_feather(p),
|
|
194
|
+
)
|
|
191
195
|
|
|
192
196
|
@classmethod
|
|
193
197
|
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,7 +36,10 @@ 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
|
|
@@ -151,5 +155,8 @@ if __name__ == "__main__":
|
|
|
151
155
|
plt.title("Blue: Keep; Red: Skip")
|
|
152
156
|
|
|
153
157
|
p = Path(__file__).with_suffix(".png")
|
|
154
|
-
|
|
158
|
+
atomic_write(
|
|
159
|
+
p,
|
|
160
|
+
writer=lambda p: plt.savefig(p),
|
|
161
|
+
)
|
|
155
162
|
obj.write_npz(p.with_suffix(".npz"))
|
|
@@ -26,6 +26,7 @@ from graphatoms.enterpoint.config.atoms import AseReadAtomsConfig
|
|
|
26
26
|
from graphatoms.enterpoint.network import ReactionNetwork
|
|
27
27
|
from graphatoms.enterpoint.parallel import get_executor
|
|
28
28
|
from graphatoms.system import Cluster, Gas, System
|
|
29
|
+
from graphatoms.utils.bytestool import atomic_write_text
|
|
29
30
|
from graphatoms.utils.parser import hydra_parse
|
|
30
31
|
|
|
31
32
|
from ._helper import helper_optimization
|
|
@@ -241,8 +242,10 @@ class RunnerABC:
|
|
|
241
242
|
|
|
242
243
|
def persist_gas_number_dct(self) -> None:
|
|
243
244
|
"""Persist the gas number dct to file."""
|
|
244
|
-
|
|
245
|
-
|
|
245
|
+
atomic_write_text(
|
|
246
|
+
self.__gas_number_path,
|
|
247
|
+
json.dumps(self.gas_number_dct, indent=4),
|
|
248
|
+
)
|
|
246
249
|
|
|
247
250
|
def load_gas_number_dct(self) -> None:
|
|
248
251
|
"""Load the gas number dct from file."""
|
|
@@ -376,7 +379,7 @@ class RunnerABC:
|
|
|
376
379
|
values: list[Cluster] = []
|
|
377
380
|
keys: list[tuple[bool, int, str]] = []
|
|
378
381
|
for core in system.get_site_core(max_ncore=max_ncore): # type: ignore
|
|
379
|
-
idx_core = np.unique(np.where(core)).astype(int)
|
|
382
|
+
idx_core = np.unique(np.where(core)).astype(int) # type: ignore
|
|
380
383
|
values.append(
|
|
381
384
|
Cluster.from_select(
|
|
382
385
|
system,
|
|
@@ -4,12 +4,14 @@ These helper functions only run calculation, and check the result.
|
|
|
4
4
|
They do not check whether the calculation is necessary and output logger.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
from pathlib import Path
|
|
7
8
|
from time import perf_counter
|
|
8
9
|
from typing import Any, Literal
|
|
9
10
|
|
|
10
11
|
import numpy as np
|
|
11
12
|
from ase import Atoms
|
|
12
13
|
from ase.calculators.calculator import Calculator
|
|
14
|
+
from ase.io.extxyz import write_xyz as write_extxyz
|
|
13
15
|
|
|
14
16
|
from graphatoms.enterpoint.config import Config
|
|
15
17
|
from graphatoms.enterpoint.network import ReactionNetwork
|
|
@@ -18,6 +20,7 @@ from graphatoms.system import Cluster, Gas, SysGraph, System
|
|
|
18
20
|
from graphatoms.system.atoms import Structure
|
|
19
21
|
from graphatoms.utils import asetools
|
|
20
22
|
from graphatoms.utils.adsorption import Helper
|
|
23
|
+
from graphatoms.utils.bytestool import atomic_write
|
|
21
24
|
from graphatoms.utils.parser import hydra_parse
|
|
22
25
|
|
|
23
26
|
from ._errors import CheckVibrationFailed, HelperException, OptimizationFailed
|
|
@@ -178,11 +181,10 @@ def helper_optimization(
|
|
|
178
181
|
deep=deep_copy,
|
|
179
182
|
)
|
|
180
183
|
except Exception as e:
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
lst
|
|
184
|
-
|
|
185
|
-
)
|
|
184
|
+
atomic_write(
|
|
185
|
+
Path(f"debug-{graph_label}.xyz"),
|
|
186
|
+
writer=lambda p: write_extxyz(p, lst),
|
|
187
|
+
)
|
|
186
188
|
raise e
|
|
187
189
|
if (not allow_not_connected) and (not result.is_connected):
|
|
188
190
|
e = HelperException(
|
|
@@ -17,6 +17,7 @@ from graphatoms.enterpoint.runner.common._helper import (
|
|
|
17
17
|
helper_match,
|
|
18
18
|
)
|
|
19
19
|
from graphatoms.reaction import Adsorption, Desorption, Reaction
|
|
20
|
+
from graphatoms.utils.bytestool import atomic_write
|
|
20
21
|
|
|
21
22
|
from ._expl import ExplorationBase
|
|
22
23
|
|
|
@@ -92,7 +93,10 @@ class OTFKMC(ExplorationBase):
|
|
|
92
93
|
# -------------------------------------------
|
|
93
94
|
system = self.get_system_for(atoms)
|
|
94
95
|
data = [i.model_dump() for i in df_data]
|
|
95
|
-
|
|
96
|
+
atomic_write(
|
|
97
|
+
self.__info_path,
|
|
98
|
+
writer=lambda p: pd.DataFrame(data).to_csv(p),
|
|
99
|
+
)
|
|
96
100
|
self.__traj.write(system.to_ase())
|
|
97
101
|
if df_data[-1].time > float(self.config.max_times):
|
|
98
102
|
self.logger.info(
|
|
@@ -56,6 +56,8 @@ if __name__ == "__main__":
|
|
|
56
56
|
from matplotlib import pyplot as plt
|
|
57
57
|
from matplotlib.axes import Axes
|
|
58
58
|
|
|
59
|
+
from graphatoms.utils.bytestool import atomic_write
|
|
60
|
+
|
|
59
61
|
N = 100
|
|
60
62
|
|
|
61
63
|
fig, axes = plt.subplots(1, 2, figsize=(8, 4.5), dpi=150)
|
|
@@ -76,4 +78,8 @@ if __name__ == "__main__":
|
|
|
76
78
|
ax.set_xticks([])
|
|
77
79
|
ax.set_yticks([])
|
|
78
80
|
plt.tight_layout()
|
|
79
|
-
|
|
81
|
+
|
|
82
|
+
atomic_write(
|
|
83
|
+
Path(__file__).with_suffix(".png"),
|
|
84
|
+
writer=lambda p: fig.savefig(p),
|
|
85
|
+
)
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
from abc import abstractmethod
|
|
2
2
|
from collections.abc import Mapping, MutableSet
|
|
3
|
+
from pathlib import Path
|
|
3
4
|
from typing import override
|
|
4
5
|
|
|
5
6
|
import numpy as np
|
|
6
7
|
from ase import Atoms
|
|
8
|
+
from ase.io.extxyz import write_xyz as write_extxyz
|
|
7
9
|
|
|
8
10
|
from graphatoms.system import SysGraph
|
|
11
|
+
from graphatoms.utils.bytestool import atomic_write
|
|
9
12
|
|
|
10
13
|
|
|
11
14
|
class DatabaseABC(Mapping[str, Atoms], MutableSet[str]):
|
|
@@ -63,11 +66,11 @@ class DatabaseABC(Mapping[str, Atoms], MutableSet[str]):
|
|
|
63
66
|
if not np.all(np.abs(vdiff) < check_threshold):
|
|
64
67
|
# Save some files for debug.
|
|
65
68
|
old = SysGraph.from_ase(old_value)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
(
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
lst = [old_value, value.to_ase()]
|
|
70
|
+
atomic_write(
|
|
71
|
+
Path(f"{key}-debug.xyz"),
|
|
72
|
+
writer=lambda p: write_extxyz(p, lst),
|
|
73
|
+
)
|
|
71
74
|
value.write_npz(f"{key}-new.npz") # type: ignore
|
|
72
75
|
old.write_npz(f"{key}-old.npz") # type: ignore
|
|
73
76
|
raise ValueError(
|
|
@@ -23,10 +23,11 @@ from scipy.spatial.transform import Rotation
|
|
|
23
23
|
from graphatoms.geometry import neighbor_list
|
|
24
24
|
from graphatoms.geometry.sample import fibonacci_lattice
|
|
25
25
|
from graphatoms.system import Cluster, Gas, System
|
|
26
|
+
from graphatoms.utils.asetools import call_optimization as optimize
|
|
27
|
+
from graphatoms.utils.bytestool import atomic_write
|
|
26
28
|
from graphatoms.utils.rdutils import rdmol2ase, smiles2rdmol
|
|
27
29
|
|
|
28
30
|
matplotlib.use("Agg")
|
|
29
|
-
from .asetools import call_optimization as optimize
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
#########################################
|
|
@@ -786,5 +787,8 @@ def plot(atoms: Atoms, pngfname: Path) -> None:
|
|
|
786
787
|
)
|
|
787
788
|
ax.set_xticks([])
|
|
788
789
|
ax.set_yticks([])
|
|
789
|
-
|
|
790
|
+
atomic_write(
|
|
791
|
+
pngfname.with_suffix(".png"),
|
|
792
|
+
writer=lambda p: fig.savefig(p),
|
|
793
|
+
)
|
|
790
794
|
plt.close(fig)
|
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
import gzip
|
|
4
4
|
import hashlib
|
|
5
|
+
import os
|
|
5
6
|
import string
|
|
7
|
+
import uuid
|
|
6
8
|
import zlib
|
|
7
9
|
from collections.abc import Callable
|
|
8
10
|
from functools import partial
|
|
9
|
-
from
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Annotated, Any
|
|
10
13
|
|
|
11
14
|
from numpy.random import choice
|
|
12
15
|
from pydantic import Field, validate_call
|
|
@@ -179,6 +182,54 @@ def random_string(n: int) -> str:
|
|
|
179
182
|
return "".join(choice(pool, size=int(n)))
|
|
180
183
|
|
|
181
184
|
|
|
185
|
+
def _fsync_dir(path: Path) -> None:
|
|
186
|
+
"""Best-effort fsync of a directory so a rename is durable (POSIX)."""
|
|
187
|
+
try:
|
|
188
|
+
fd = os.open(str(path), os.O_RDONLY)
|
|
189
|
+
except OSError:
|
|
190
|
+
return
|
|
191
|
+
try:
|
|
192
|
+
os.fsync(fd)
|
|
193
|
+
except OSError:
|
|
194
|
+
pass
|
|
195
|
+
finally:
|
|
196
|
+
os.close(fd)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def atomic_write(target: Path, writer: Callable[[Path], Any]) -> None:
|
|
200
|
+
"""Write `target` atomically.
|
|
201
|
+
|
|
202
|
+
The `writer` callback receives a temporary path in the same
|
|
203
|
+
directory and must create/write the file there. The temp file is
|
|
204
|
+
fsynced and then os.replace()d onto `target`. Because both paths
|
|
205
|
+
live in the same directory, os.replace is atomic on POSIX.
|
|
206
|
+
|
|
207
|
+
The temp file keeps `target.suffix`, so callers such as
|
|
208
|
+
``np.savez`` that auto-append ".npz" behave correctly.
|
|
209
|
+
"""
|
|
210
|
+
target = Path(target)
|
|
211
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
212
|
+
file_stem = f".{target.stem}.tmp.{os.getpid()}{uuid.uuid4().hex}"
|
|
213
|
+
tmp = target.parent / f"{file_stem}{target.suffix}"
|
|
214
|
+
try:
|
|
215
|
+
writer(tmp)
|
|
216
|
+
# ensure the file is synced to disk
|
|
217
|
+
with open(tmp, "rb") as f:
|
|
218
|
+
os.fsync(f.fileno())
|
|
219
|
+
os.replace(tmp, target)
|
|
220
|
+
_fsync_dir(target.parent)
|
|
221
|
+
except Exception:
|
|
222
|
+
try:
|
|
223
|
+
tmp.unlink()
|
|
224
|
+
except FileNotFoundError:
|
|
225
|
+
pass
|
|
226
|
+
raise
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def atomic_write_text(target: Path, text: str, encoding="utf-8") -> None:
|
|
230
|
+
atomic_write(target, lambda p: p.write_text(text, encoding=encoding))
|
|
231
|
+
|
|
232
|
+
|
|
182
233
|
#######################################################################
|
|
183
234
|
# Test
|
|
184
235
|
#######################################################################
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/config/atoms/octahedron.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/config/calculator/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/config/calculator/nequip.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphatoms-2.3.1 → graphatoms-2.3.2}/src/graphatoms/enterpoint/runner/v2/general/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|