pymdkit 1.2.2__tar.gz → 1.2.4__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 (36) hide show
  1. {pymdkit-1.2.2/src/pymdkit.egg-info → pymdkit-1.2.4}/PKG-INFO +1 -1
  2. {pymdkit-1.2.2 → pymdkit-1.2.4}/pyproject.toml +1 -1
  3. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/__init__.py +1 -1
  4. pymdkit-1.2.4/src/pymdkit/commands/stable_entry.py +99 -0
  5. {pymdkit-1.2.2 → pymdkit-1.2.4/src/pymdkit.egg-info}/PKG-INFO +1 -1
  6. pymdkit-1.2.2/src/pymdkit/commands/stable_entry.py +0 -102
  7. {pymdkit-1.2.2 → pymdkit-1.2.4}/LICENSE +0 -0
  8. {pymdkit-1.2.2 → pymdkit-1.2.4}/README.md +0 -0
  9. {pymdkit-1.2.2 → pymdkit-1.2.4}/setup.cfg +0 -0
  10. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/__init__.py +0 -0
  11. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/_fileio.py +0 -0
  12. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/_vasp_output.py +0 -0
  13. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/_vaspset.py +0 -0
  14. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/add_groups.py +0 -0
  15. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/compute_ehull.py +0 -0
  16. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/compute_msd_all_groups.py +0 -0
  17. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/compute_rmsd.py +0 -0
  18. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/electrostatic_energy.py +0 -0
  19. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/final_energy.py +0 -0
  20. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/gather_contcar.py +0 -0
  21. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/nep_rmse.py +0 -0
  22. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/perturb.py +0 -0
  23. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/stru2xyz.py +0 -0
  24. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/submit_vasp.py +0 -0
  25. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/substitute.py +0 -0
  26. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/supercell.py +0 -0
  27. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/symmetrize.py +0 -0
  28. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/vasp2xyz.py +0 -0
  29. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/vasp_relax.py +0 -0
  30. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/commands/vasp_static.py +0 -0
  31. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit/pymdkit_main.py +0 -0
  32. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit.egg-info/SOURCES.txt +0 -0
  33. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit.egg-info/dependency_links.txt +0 -0
  34. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit.egg-info/entry_points.txt +0 -0
  35. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit.egg-info/requires.txt +0 -0
  36. {pymdkit-1.2.2 → pymdkit-1.2.4}/src/pymdkit.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pymdkit
3
- Version: 1.2.2
3
+ Version: 1.2.4
4
4
  Summary: A unified command-line toolkit for atomistic / MD structure workflows.
5
5
  Author-email: Yueda Wang <ydwang0608@ustc.edu.cn>
6
6
  License-Expression: GPL-3.0-or-later
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pymdkit"
7
- version = "1.2.2"
7
+ version = "1.2.4"
8
8
  description = "A unified command-line toolkit for atomistic / MD structure workflows."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -1,3 +1,3 @@
1
1
  """pymdkit -- a unified CLI for atomistic / MD structure workflows."""
2
2
 
3
- __version__ = "1.2.2"
3
+ __version__ = "1.2.4"
@@ -0,0 +1,99 @@
1
+ """Download stable Materials Project structures for a chemical system."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import re
7
+ from pathlib import Path
8
+
9
+ COMMAND = "stable-entry"
10
+ HELP = "Download stable Materials Project structures for a chemical system."
11
+
12
+
13
+ def safe_formula(formula):
14
+ return re.sub(r"[^A-Za-z0-9_.-]+", "", str(formula))
15
+
16
+
17
+ def entry_id_text(entry):
18
+ entry_id = getattr(entry, "entry_id", "")
19
+ if isinstance(entry_id, dict):
20
+ for key in ("material_id", "task_id", "entry_id", "id"):
21
+ if entry_id.get(key):
22
+ return str(entry_id[key])
23
+ return "-".join(f"{k}-{v}" for k, v in sorted(entry_id.items()))
24
+ if entry_id:
25
+ return str(entry_id)
26
+ data = getattr(entry, "data", {}) or {}
27
+ for key in ("material_id", "task_id", "entry_id", "id"):
28
+ if data.get(key):
29
+ return str(data[key])
30
+ return "unknown"
31
+
32
+
33
+ def entry_sort_key(entry):
34
+ formula = str(entry.composition.reduced_formula)
35
+ return (len(entry.composition.elements), formula, entry_id_text(entry))
36
+
37
+
38
+ def add_arguments(parser: argparse.ArgumentParser) -> None:
39
+ parser.add_argument("-s", nargs="+", required=True,
40
+ help="Chemical system elements, e.g. -s Li La Ta Cl.")
41
+ parser.add_argument("-mp-api-key", default=None,
42
+ help="Materials Project API key.")
43
+
44
+
45
+ def fetch_stable_entries(elements, api_key=None):
46
+ """Fetch stable thermo entries matching the Materials Project phase diagram."""
47
+ from pymatgen.ext.matproj import MPRester
48
+
49
+ with MPRester(api_key) as mpr:
50
+ entries = mpr.get_entries_in_chemsys(
51
+ elements,
52
+ inc_structure=True,
53
+ additional_criteria={
54
+ "thermo_types": ["GGA_GGA+U"],
55
+ "is_stable": True,
56
+ },
57
+ )
58
+ by_mpid = {}
59
+ for entry in entries:
60
+ by_mpid[entry_id_text(entry)] = entry
61
+ return list(by_mpid.values())
62
+
63
+
64
+ def run(args) -> int:
65
+ from pymatgen.io.cif import CifWriter
66
+
67
+ elements = list(dict.fromkeys(args.s))
68
+ label = "-".join(elements)
69
+ out_dir = Path(f"{label}-stable-entries")
70
+ out_dir.mkdir(parents=True, exist_ok=True)
71
+
72
+ try:
73
+ entries = fetch_stable_entries(elements, args.mp_api_key)
74
+ except ModuleNotFoundError as exc:
75
+ if exc.name == "emmet":
76
+ raise SystemExit(
77
+ "Error: stable-entry requires emmet models from mp-api. "
78
+ "Reinstall pymdkit or run `pip install mp-api`."
79
+ ) from exc
80
+ raise
81
+
82
+ entries = sorted(entries, key=entry_sort_key)
83
+ written = 0
84
+ for entry in entries:
85
+ mpid = safe_formula(entry_id_text(entry).split(" ")[0])
86
+ formula = safe_formula(entry.composition.reduced_formula)
87
+ path = out_dir / f"{mpid}-{formula}.cif"
88
+ CifWriter(entry.structure).write_file(str(path))
89
+ print(f"{mpid}\t{entry.composition.reduced_formula}\t-> {path}")
90
+ written += 1
91
+
92
+ print(f"Wrote {written} stable entr{'y' if written == 1 else 'ies'} to {out_dir}")
93
+ return 0 if written else 1
94
+
95
+
96
+ if __name__ == "__main__":
97
+ _parser = argparse.ArgumentParser(description=__doc__)
98
+ add_arguments(_parser)
99
+ raise SystemExit(run(_parser.parse_args()))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pymdkit
3
- Version: 1.2.2
3
+ Version: 1.2.4
4
4
  Summary: A unified command-line toolkit for atomistic / MD structure workflows.
5
5
  Author-email: Yueda Wang <ydwang0608@ustc.edu.cn>
6
6
  License-Expression: GPL-3.0-or-later
@@ -1,102 +0,0 @@
1
- """Download stable Materials Project structures for a chemical system."""
2
-
3
- from __future__ import annotations
4
-
5
- import argparse
6
- import re
7
- from dataclasses import dataclass
8
- from pathlib import Path
9
-
10
- COMMAND = "stable-entry"
11
- HELP = "Download stable Materials Project structures for a chemical system."
12
-
13
-
14
- @dataclass
15
- class StableStructure:
16
- material_id: str
17
- formula: str
18
- structure: object
19
-
20
-
21
- def safe_formula(formula):
22
- return re.sub(r"[^A-Za-z0-9_.-]+", "", str(formula))
23
-
24
-
25
- def doc_get(doc, name, default=None):
26
- if isinstance(doc, dict):
27
- return doc.get(name, default)
28
- return getattr(doc, name, default)
29
-
30
-
31
- def normalize_doc(doc):
32
- material_id = str(doc_get(doc, "material_id", "unknown"))
33
- formula = doc_get(doc, "formula_pretty") or doc_get(doc, "formula")
34
- structure = doc_get(doc, "structure")
35
- if formula is None and structure is not None:
36
- formula = structure.composition.reduced_formula
37
- if structure is None:
38
- raise ValueError(f"MP document {material_id} has no structure field")
39
- return StableStructure(material_id=material_id, formula=str(formula), structure=structure)
40
-
41
-
42
- def entry_sort_key(entry):
43
- return (len(entry.structure.composition.elements), entry.formula, entry.material_id)
44
-
45
-
46
- def add_arguments(parser: argparse.ArgumentParser) -> None:
47
- parser.add_argument("-s", nargs="+", required=True,
48
- help="Chemical system elements, e.g. -s Li La Ta Cl.")
49
- parser.add_argument("-mp-api-key", default=None,
50
- help="Materials Project API key.")
51
-
52
-
53
- def fetch_stable_structures(elements, api_key=None):
54
- from mp_api.client import MPRester
55
-
56
- chemsys = "-".join(elements)
57
- fields = ["material_id", "formula_pretty", "structure"]
58
- with MPRester(api_key) as mpr:
59
- docs = mpr.materials.summary.search(
60
- chemsys=chemsys,
61
- is_stable=True,
62
- fields=fields,
63
- )
64
- return [normalize_doc(doc) for doc in docs]
65
-
66
-
67
- def run(args) -> int:
68
- from pymatgen.io.cif import CifWriter
69
-
70
- elements = list(dict.fromkeys(args.s))
71
- label = "-".join(elements)
72
- out_dir = Path(f"{label}-stable-entries")
73
- out_dir.mkdir(parents=True, exist_ok=True)
74
-
75
- try:
76
- entries = fetch_stable_structures(elements, args.mp_api_key)
77
- except ModuleNotFoundError as exc:
78
- if exc.name == "mp_api":
79
- raise SystemExit(
80
- "Error: stable-entry requires mp-api. Reinstall pymdkit 1.2.2+ "
81
- "or run `pip install mp-api`."
82
- ) from exc
83
- raise
84
-
85
- entries = sorted(entries, key=entry_sort_key)
86
- written = 0
87
- for entry in entries:
88
- mpid = safe_formula(entry.material_id)
89
- formula = safe_formula(entry.formula)
90
- path = out_dir / f"{mpid}-{formula}.cif"
91
- CifWriter(entry.structure).write_file(str(path))
92
- print(f"{mpid}\t{entry.formula}\t-> {path}")
93
- written += 1
94
-
95
- print(f"Wrote {written} stable entr{'y' if written == 1 else 'ies'} to {out_dir}")
96
- return 0 if written else 1
97
-
98
-
99
- if __name__ == "__main__":
100
- _parser = argparse.ArgumentParser(description=__doc__)
101
- add_arguments(_parser)
102
- raise SystemExit(run(_parser.parse_args()))
File without changes
File without changes
File without changes