emmet-builders 0.87.0.dev0__tar.gz → 0.87.0.dev2__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 (81) hide show
  1. {emmet_builders-0.87.0.dev0/emmet_builders.egg-info → emmet_builders-0.87.0.dev2}/PKG-INFO +2 -3
  2. emmet_builders-0.87.0.dev2/emmet/builders/base.py +20 -0
  3. emmet_builders-0.87.0.dev2/emmet/builders/materials/bonds.py +38 -0
  4. emmet_builders-0.87.0.dev2/emmet/builders/materials/chemenv.py +34 -0
  5. emmet_builders-0.87.0.dev2/emmet/builders/materials/corrected_entries.py +107 -0
  6. emmet_builders-0.87.0.dev2/emmet/builders/materials/oxidation_states.py +34 -0
  7. emmet_builders-0.87.0.dev2/emmet/builders/materials/robocrys.py +40 -0
  8. emmet_builders-0.87.0.dev2/emmet/builders/materials/thermo.py +121 -0
  9. emmet_builders-0.87.0.dev2/emmet/builders/vasp/materials.py +112 -0
  10. emmet_builders-0.87.0.dev2/emmet/builders/vasp/task_validator.py +48 -0
  11. {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2/emmet_builders.egg-info}/PKG-INFO +2 -3
  12. emmet_builders-0.87.0.dev2/emmet_builders.egg-info/SOURCES.txt +29 -0
  13. {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/emmet_builders.egg-info/requires.txt +1 -2
  14. {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/pyproject.toml +1 -2
  15. emmet_builders-0.87.0.dev0/emmet/builders/abinit/phonon.py +0 -853
  16. emmet_builders-0.87.0.dev0/emmet/builders/abinit/sound_velocity.py +0 -217
  17. emmet_builders-0.87.0.dev0/emmet/builders/feff/__init__.py +0 -0
  18. emmet_builders-0.87.0.dev0/emmet/builders/feff/xas.py +0 -67
  19. emmet_builders-0.87.0.dev0/emmet/builders/materials/__init__.py +0 -0
  20. emmet_builders-0.87.0.dev0/emmet/builders/materials/absorption_spectrum.py +0 -214
  21. emmet_builders-0.87.0.dev0/emmet/builders/materials/alloys.py +0 -385
  22. emmet_builders-0.87.0.dev0/emmet/builders/materials/basic_descriptors.py +0 -166
  23. emmet_builders-0.87.0.dev0/emmet/builders/materials/bonds.py +0 -55
  24. emmet_builders-0.87.0.dev0/emmet/builders/materials/chemenv.py +0 -43
  25. emmet_builders-0.87.0.dev0/emmet/builders/materials/corrected_entries.py +0 -329
  26. emmet_builders-0.87.0.dev0/emmet/builders/materials/dielectric.py +0 -214
  27. emmet_builders-0.87.0.dev0/emmet/builders/materials/elasticity.py +0 -499
  28. emmet_builders-0.87.0.dev0/emmet/builders/materials/electrodes.py +0 -633
  29. emmet_builders-0.87.0.dev0/emmet/builders/materials/electronic_structure.py +0 -757
  30. emmet_builders-0.87.0.dev0/emmet/builders/materials/magnetism.py +0 -162
  31. emmet_builders-0.87.0.dev0/emmet/builders/materials/optimade.py +0 -171
  32. emmet_builders-0.87.0.dev0/emmet/builders/materials/oxidation_states.py +0 -55
  33. emmet_builders-0.87.0.dev0/emmet/builders/materials/piezoelectric.py +0 -255
  34. emmet_builders-0.87.0.dev0/emmet/builders/materials/provenance.py +0 -270
  35. emmet_builders-0.87.0.dev0/emmet/builders/materials/robocrys.py +0 -44
  36. emmet_builders-0.87.0.dev0/emmet/builders/materials/similarity.py +0 -151
  37. emmet_builders-0.87.0.dev0/emmet/builders/materials/substrates.py +0 -183
  38. emmet_builders-0.87.0.dev0/emmet/builders/materials/summary.py +0 -234
  39. emmet_builders-0.87.0.dev0/emmet/builders/materials/thermo.py +0 -299
  40. emmet_builders-0.87.0.dev0/emmet/builders/matscholar/missing_compositions.py +0 -223
  41. emmet_builders-0.87.0.dev0/emmet/builders/mobility/__init__.py +0 -0
  42. emmet_builders-0.87.0.dev0/emmet/builders/mobility/migration_graph.py +0 -102
  43. emmet_builders-0.87.0.dev0/emmet/builders/vasp/__init__.py +0 -0
  44. emmet_builders-0.87.0.dev0/emmet/builders/vasp/materials.py +0 -360
  45. emmet_builders-0.87.0.dev0/emmet/builders/vasp/task_validator.py +0 -89
  46. emmet_builders-0.87.0.dev0/emmet_builders.egg-info/SOURCES.txt +0 -69
  47. emmet_builders-0.87.0.dev0/tests/__init__.py +0 -0
  48. emmet_builders-0.87.0.dev0/tests/conftest.py +0 -7
  49. emmet_builders-0.87.0.dev0/tests/test_absorption.py +0 -43
  50. emmet_builders-0.87.0.dev0/tests/test_basic_descriptors.py +0 -30
  51. emmet_builders-0.87.0.dev0/tests/test_chemenv.py +0 -40
  52. emmet_builders-0.87.0.dev0/tests/test_corrected_entries_thermo.py +0 -78
  53. emmet_builders-0.87.0.dev0/tests/test_dielectric.py +0 -43
  54. emmet_builders-0.87.0.dev0/tests/test_elasticity.py +0 -43
  55. emmet_builders-0.87.0.dev0/tests/test_electronic_structure.py +0 -66
  56. emmet_builders-0.87.0.dev0/tests/test_magnetism.py +0 -55
  57. emmet_builders-0.87.0.dev0/tests/test_materials.py +0 -46
  58. emmet_builders-0.87.0.dev0/tests/test_mobility.py +0 -31
  59. emmet_builders-0.87.0.dev0/tests/test_oxidation.py +0 -37
  60. emmet_builders-0.87.0.dev0/tests/test_piezoelectric.py +0 -44
  61. emmet_builders-0.87.0.dev0/tests/test_similarity.py +0 -43
  62. emmet_builders-0.87.0.dev0/tests/test_summary.py +0 -193
  63. emmet_builders-0.87.0.dev0/tests/test_utils.py +0 -105
  64. emmet_builders-0.87.0.dev0/tests/test_vasp.py +0 -30
  65. {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/MANIFEST.in +0 -0
  66. {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/emmet/builders/__init__.py +0 -0
  67. {emmet_builders-0.87.0.dev0/emmet/builders/abinit → emmet_builders-0.87.0.dev2/emmet/builders/materials}/__init__.py +0 -0
  68. {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/emmet/builders/py.typed +0 -0
  69. {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/emmet/builders/settings.py +0 -0
  70. {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/emmet/builders/utils.py +0 -0
  71. {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/emmet/builders/vasp/mp_potcar_stats.json.gz +0 -0
  72. {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/emmet_builders.egg-info/dependency_links.txt +0 -0
  73. {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/emmet_builders.egg-info/top_level.txt +0 -0
  74. {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/requirements/deployment.txt +0 -0
  75. {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/requirements/ubuntu-latest_py3.11.txt +0 -0
  76. {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/requirements/ubuntu-latest_py3.11_extras.txt +0 -0
  77. {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/requirements/ubuntu-latest_py3.12.txt +0 -0
  78. {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/requirements/ubuntu-latest_py3.12_extras.txt +0 -0
  79. {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/requirements/ubuntu-latest_py3.13.txt +0 -0
  80. {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/requirements/ubuntu-latest_py3.13_extras.txt +0 -0
  81. {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/setup.cfg +0 -0
@@ -1,14 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: emmet-builders
3
- Version: 0.87.0.dev0
3
+ Version: 0.87.0.dev2
4
4
  Summary: Builders for the Emmet Library
5
5
  Author-email: The Materials Project <feedback@materialsproject.org>
6
6
  License: Modified BSD
7
7
  Project-URL: Homepage, https://github.com/materialsproject/emmet/tree/main/emmet-builders/
8
8
  Project-URL: Documentation, https://materialsproject.github.io/emmet/
9
9
  Requires-Python: >=3.11
10
- Requires-Dist: emmet-core[all]>=0.85
11
- Requires-Dist: maggma>=0.57.6
10
+ Requires-Dist: emmet-core[all]>=0.86.1
12
11
  Requires-Dist: matminer>=0.9.1
13
12
  Requires-Dist: pymatgen-io-validation>=0.1.1
14
13
  Provides-Extra: test
@@ -0,0 +1,20 @@
1
+ from pydantic import Field
2
+ from pymatgen.core import Structure
3
+
4
+ from emmet.core.base import EmmetBaseModel
5
+ from emmet.core.types.typing import IdentifierType
6
+
7
+
8
+ class BaseBuilderInput(EmmetBaseModel):
9
+ """
10
+ Document model with the minimum inputs required
11
+ to run builders that only require a Pymatgen structure
12
+ object for property analysis.
13
+
14
+ A material_id and builder_meta information may be optionally
15
+ included.
16
+ """
17
+
18
+ deprecated: bool = Field(False)
19
+ material_id: IdentifierType | None = Field(None)
20
+ structure: Structure
@@ -0,0 +1,38 @@
1
+ from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
2
+
3
+ from emmet.builders.base import BaseBuilderInput
4
+ from emmet.core.bonds import BondingDoc
5
+
6
+
7
+ def build_bonding_docs(
8
+ input_documents: list[BaseBuilderInput],
9
+ ) -> list[BondingDoc]:
10
+ """
11
+ Generate bonding documents from input structures.
12
+
13
+ Transforms a list of BaseBuilderInput documents containing
14
+ Pymatgen structures into corresponding BondingDoc instances by
15
+ analyzing the bonding environment of each structure.
16
+
17
+ Caller is responsible for creating BaseBuilderInput instances
18
+ within their data pipeline context.
19
+
20
+ Args:
21
+ input_documents: List of BaseBuilderInput documents to process.
22
+
23
+ Returns:
24
+ list[BondingDoc]
25
+ """
26
+ return list(
27
+ map(
28
+ lambda x: BondingDoc.from_structure(
29
+ builder_meta=x.builder_meta,
30
+ deprecated=x.deprecated,
31
+ material_id=x.material_id,
32
+ structure=SpacegroupAnalyzer(
33
+ x.structure
34
+ ).get_conventional_standard_structure(),
35
+ ),
36
+ input_documents,
37
+ )
38
+ )
@@ -0,0 +1,34 @@
1
+ from emmet.builders.base import BaseBuilderInput
2
+ from emmet.core.chemenv import ChemEnvDoc
3
+
4
+
5
+ def build_chemenv_docs(
6
+ input_documents: list[BaseBuilderInput],
7
+ ) -> list[ChemEnvDoc]:
8
+ """
9
+ Generate chemical environment documents from input structures.
10
+
11
+ Transforms a list of BaseBuilderInput documents containing
12
+ Pymatgen structures into corresponding ChemEnvDoc instances by
13
+ analyzing the chemical environment of each structure.
14
+
15
+ Caller is responsible for creating BaseBuilderInput instances
16
+ within their data pipeline context.
17
+
18
+ Args:
19
+ input_documents: List of BaseBuilderInput documents to process.
20
+
21
+ Returns:
22
+ list[ChemEnvDoc]
23
+ """
24
+ return list(
25
+ map(
26
+ lambda x: ChemEnvDoc.from_structure(
27
+ builder_meta=x.builder_meta,
28
+ deprecated=x.deprecated,
29
+ material_id=x.material_id,
30
+ structure=x.structure,
31
+ ),
32
+ input_documents,
33
+ )
34
+ )
@@ -0,0 +1,107 @@
1
+ import copy
2
+ import warnings
3
+
4
+ from pydantic import BaseModel, Field
5
+ from pymatgen.entries.compatibility import Compatibility
6
+
7
+ from emmet.builders.utils import HiddenPrints
8
+ from emmet.core.corrected_entries import CorrectedEntriesDoc
9
+ from emmet.core.thermo import ThermoType
10
+ from emmet.core.types.pymatgen_types.computed_entries_adapter import (
11
+ ComputedStructureEntryType,
12
+ )
13
+
14
+
15
+ class CorrectedEntriesBuilderInput(BaseModel):
16
+ entries: list[ComputedStructureEntryType] = Field(
17
+ ...,
18
+ description="""
19
+ List of computed structure entries to apply corrections to.
20
+ Entries MUST belong to a single chemical system (chemsys).
21
+ """,
22
+ )
23
+
24
+
25
+ def build_corrected_entries_doc(
26
+ input: CorrectedEntriesBuilderInput,
27
+ compatibilities: list[Compatibility | None] = [None],
28
+ ) -> CorrectedEntriesDoc:
29
+ """
30
+ Process computed structure entries using corrections defined in pymatgen
31
+ compatibility classes. Ensures compatibility of energies for entries for
32
+ different thermodynamic hulls.
33
+
34
+ Input entries must all belong to the same chemical system. Caller is
35
+ responsible for constructing CorrectedEntriesBuilderInput instances within
36
+ their data pipeline context.
37
+
38
+ Args:
39
+ input: CorrectedEntriesBuilderInput with an aggregated list of computed
40
+ structure entries for a single chemical system.
41
+ compatibilities: List of pymatgen compatibility classes to apply to
42
+ input entries.
43
+
44
+ Returns:
45
+ CorrectedEntriesDoc: if no Compatibility class(es) are provided, and all
46
+ entries have the same functional, no corrections will be applied and
47
+ entries will simply be passed through to CorrectedEntriesDoc constructor.
48
+ """
49
+ all_entry_types = {str(e.data["run_type"]) for e in input.entries}
50
+
51
+ elements = sorted(
52
+ set([el.symbol for e in input.entries for el in e.composition.elements])
53
+ )
54
+ chemsys = "-".join(elements)
55
+
56
+ corrected_entries = {}
57
+
58
+ for compatibility in compatibilities:
59
+ if compatibility is not None:
60
+ with warnings.catch_warnings():
61
+ warnings.simplefilter("ignore")
62
+ with HiddenPrints():
63
+ if compatibility.name == "MP DFT mixing scheme":
64
+ thermo_type = ThermoType.GGA_GGA_U_R2SCAN
65
+
66
+ if "R2SCAN" in all_entry_types:
67
+ only_scan_pd_entries = [
68
+ e
69
+ for e in input.entries
70
+ if str(e.data["run_type"]) == "R2SCAN"
71
+ ]
72
+ corrected_entries["R2SCAN"] = only_scan_pd_entries
73
+
74
+ pd_entries = compatibility.process_entries(
75
+ copy.deepcopy(input.entries),
76
+ verbose=False,
77
+ )
78
+
79
+ else:
80
+ corrected_entries["R2SCAN"] = None
81
+ pd_entries = None
82
+
83
+ elif compatibility.name == "MP2020":
84
+ thermo_type = ThermoType.GGA_GGA_U
85
+ pd_entries = compatibility.process_entries(
86
+ copy.deepcopy(input.entries), verbose=False
87
+ )
88
+ else:
89
+ thermo_type = ThermoType.UNKNOWN
90
+ pd_entries = compatibility.process_entries(
91
+ copy.deepcopy(input.entries), verbose=False
92
+ )
93
+
94
+ corrected_entries[str(thermo_type)] = pd_entries
95
+
96
+ else:
97
+ if len(all_entry_types) > 1:
98
+ # TODO: logging over raising
99
+ raise ValueError(
100
+ "More than one functional type has been provided without a mixing scheme!"
101
+ )
102
+ else:
103
+ thermo_type = all_entry_types.pop()
104
+
105
+ corrected_entries[str(thermo_type)] = copy.deepcopy(input.entries)
106
+
107
+ return CorrectedEntriesDoc(chemsys=chemsys, entries=corrected_entries)
@@ -0,0 +1,34 @@
1
+ from emmet.builders.base import BaseBuilderInput
2
+ from emmet.core.oxidation_states import OxidationStateDoc
3
+
4
+
5
+ def build_oxidation_states_docs(
6
+ input_documents: list[BaseBuilderInput],
7
+ ) -> list[OxidationStateDoc]:
8
+ """
9
+ Generate oxidation state documents from input structures.
10
+
11
+ Transforms a list of BaseBuilderInput documents containing
12
+ Pymatgen structures into corresponding OxidationStateDoc instances by
13
+ analyzing the oxidation states of each structure.
14
+
15
+ Caller is responsible for creating BaseBuilderInput instances
16
+ within their data pipeline context.
17
+
18
+ Args:
19
+ input_documents: List of BaseBuilderInput documents to process.
20
+
21
+ Returns:
22
+ list[OxidationStateDoc]
23
+ """
24
+ return list(
25
+ map(
26
+ lambda x: OxidationStateDoc.from_structure(
27
+ builder_meta=x.builder_meta,
28
+ deprecated=x.deprecated,
29
+ material_id=x.material_id,
30
+ structure=x.structure,
31
+ ),
32
+ input_documents,
33
+ )
34
+ )
@@ -0,0 +1,40 @@
1
+ from robocrys import __version__ as __robocrys_version__
2
+ from robocrys.condense.mineral import MineralMatcher
3
+
4
+ from emmet.builders.base import BaseBuilderInput
5
+ from emmet.core.robocrys import RobocrystallogapherDoc
6
+
7
+
8
+ def build_robocrys_docs(
9
+ input_documents: list[BaseBuilderInput],
10
+ ) -> list[RobocrystallogapherDoc]:
11
+ """
12
+ Generate robocrystallographer descriptions from input structures.
13
+
14
+ Transforms a list of BaseBuilderInput documents containing
15
+ Pymatgen structures into corresponding RobocrystallogapherDoc instances by
16
+ using robocrys' StructureCondenser and StructureDescriber classes.
17
+
18
+ Caller is responsible for creating BaseBuilderInput instances
19
+ within their data pipeline context.
20
+
21
+ Args:
22
+ input_documents: List of BaseBuilderInput documents to process.
23
+
24
+ Returns:
25
+ list[RobocrystallogapherDoc]
26
+ """
27
+ mineral_matcher = MineralMatcher()
28
+ return list(
29
+ map(
30
+ lambda x: RobocrystallogapherDoc.from_structure(
31
+ builder_meta=x.builder_meta,
32
+ deprecated=x.deprecated,
33
+ material_id=x.material_id,
34
+ mineral_matcher=mineral_matcher,
35
+ robocrys_version=__robocrys_version__,
36
+ structure=x.structure,
37
+ ),
38
+ input_documents,
39
+ )
40
+ )
@@ -0,0 +1,121 @@
1
+ import logging
2
+ import warnings
3
+
4
+ from pydantic import BaseModel, Field
5
+ from pymatgen.analysis.phase_diagram import PhaseDiagram, PhaseDiagramError
6
+ from pymatgen.entries.computed_entries import ComputedStructureEntry
7
+
8
+ from emmet.builders.utils import HiddenPrints
9
+ from emmet.core.thermo import PhaseDiagramDoc, ThermoDoc
10
+ from emmet.core.types.enums import ThermoType
11
+ from emmet.core.types.pymatgen_types.computed_entries_adapter import (
12
+ ComputedStructureEntryType,
13
+ )
14
+ from emmet.core.vasp.calc_types.enums import RunType
15
+
16
+
17
+ class ThermoBuilderInput(BaseModel):
18
+ """
19
+ Minimum inputs required to build ThermoDocs and PhaseDiagramDocs
20
+ for a chemical system.
21
+ """
22
+
23
+ chemsys: str = Field(
24
+ ...,
25
+ description="Dash-delimited string of elements in the material.",
26
+ )
27
+
28
+ entries: dict[RunType | ThermoType, list[ComputedStructureEntryType]] = Field(
29
+ ...,
30
+ description="""
31
+ List of all computed entries for 'chemsys' that are valid for the specified thermo type.
32
+ Entries for elemental endpoints of 'chemsys' are required.
33
+ """,
34
+ )
35
+
36
+
37
+ class ThermoBuilderOutput(BaseModel):
38
+ """Output of build_thermo_docs_and_phase_diagram_docs function"""
39
+
40
+ chemsys: str
41
+ thermo_docs: dict[RunType | ThermoType, list[ThermoDoc] | None]
42
+ phase_diagram_docs: dict[RunType | ThermoType, PhaseDiagramDoc | None]
43
+
44
+
45
+ ThermoPDPair = tuple[list[ThermoDoc] | None, PhaseDiagramDoc | None]
46
+
47
+ logger = logging.getLogger()
48
+
49
+
50
+ def build_thermo_docs_and_phase_diagram_docs(
51
+ thermo_input: ThermoBuilderInput,
52
+ ) -> ThermoBuilderOutput:
53
+ chemsys = thermo_input.chemsys
54
+
55
+ thermo_docs = dict()
56
+ phase_diagram_docs = dict()
57
+ for thermo_type, entry_list in thermo_input.entries.items():
58
+ logger.debug(
59
+ f"Processing {len(entry_list)} entries for: {chemsys} and thermo type: {thermo_type}"
60
+ )
61
+
62
+ with warnings.catch_warnings():
63
+ warnings.simplefilter("ignore")
64
+ with HiddenPrints():
65
+ _thermo_docs, _phase_diagram_doc = _produce_pair(
66
+ entry_list, thermo_type
67
+ )
68
+ thermo_docs[thermo_type] = _thermo_docs
69
+ phase_diagram_docs[thermo_type] = _phase_diagram_doc
70
+
71
+ return ThermoBuilderOutput(
72
+ chemsys=chemsys,
73
+ thermo_docs=thermo_docs,
74
+ phase_diagram_docs=phase_diagram_docs,
75
+ )
76
+
77
+
78
+ def _produce_pair(
79
+ computed_structure_entries: list[ComputedStructureEntry],
80
+ thermo_type: RunType | ThermoType,
81
+ ) -> ThermoPDPair:
82
+ phase_diagram_doc = None
83
+ try:
84
+ phase_diagram: PhaseDiagram = ThermoDoc.construct_phase_diagram(
85
+ computed_structure_entries
86
+ )
87
+ thermo_docs: list[ThermoDoc] = ThermoDoc.from_entries(
88
+ computed_structure_entries,
89
+ thermo_type,
90
+ phase_diagram,
91
+ use_max_chemsys=True,
92
+ deprecated=False,
93
+ )
94
+
95
+ if phase_diagram:
96
+ chemsys = "-".join(
97
+ sorted(set([el.symbol for el in phase_diagram.elements]))
98
+ )
99
+ phase_diagram_id = f"{chemsys}_{thermo_type.value}"
100
+ phase_diagram_doc = PhaseDiagramDoc(
101
+ phase_diagram_id=phase_diagram_id,
102
+ chemsys=chemsys,
103
+ phase_diagram=phase_diagram,
104
+ thermo_type=thermo_type,
105
+ )
106
+
107
+ if not thermo_docs:
108
+ return None, phase_diagram_doc
109
+
110
+ return thermo_docs, phase_diagram_doc
111
+
112
+ except PhaseDiagramError as p:
113
+ elsyms = []
114
+ for entry in computed_structure_entries:
115
+ elsyms.extend([el.symbol for el in entry.composition.elements])
116
+
117
+ logger.error(
118
+ f"Phase diagram error in chemsys {'-'.join(sorted(set(elsyms)))}: {p}"
119
+ )
120
+
121
+ return None, None
@@ -0,0 +1,112 @@
1
+ from itertools import groupby
2
+ from typing import Iterator
3
+
4
+ from emmet.builders.settings import EmmetBuildSettings
5
+ from emmet.core.tasks import CoreTaskDoc
6
+ from emmet.core.utils import group_structures, undeform_structure
7
+ from emmet.core.vasp.calc_types import TaskType
8
+ from emmet.core.vasp.material import MaterialsDoc
9
+ from pydantic import Field
10
+
11
+
12
+ class ValidationTaskDoc(CoreTaskDoc):
13
+ """
14
+ Wrapper for TaskDoc to ensure compatiblity with validation checks
15
+ in MaterialsDoc.from_tasks(...) if validation builder is skipped
16
+ """
17
+
18
+ is_valid: bool = Field(True)
19
+
20
+
21
+ def build_material_docs(
22
+ input_documents: list[ValidationTaskDoc],
23
+ settings: EmmetBuildSettings = EmmetBuildSettings(),
24
+ ) -> list[MaterialsDoc]:
25
+ """
26
+ Aggregate ValidationTaskDocs into MaterialsDocs by chemical formula.
27
+ Caller is responsible for creating ValidationTaskDoc instances within
28
+ their data pipeline context.
29
+
30
+ Groups input documents by formula_pretty, performs structure matching
31
+ on each formula group, and constructs a MaterialsDoc for each group of
32
+ task documents with matching structures within each formula group.
33
+
34
+ Args:
35
+ input_documents: List of ValidationTaskDoc objects to process. Must contain
36
+ ALL documents for each unique formula_pretty value to avoid incorrect
37
+ material splitting. Documents for the same formula should not be split
38
+ across multiple function calls.
39
+ settings: Builder configuration settings, defaults defined in EmmetBuildSettings.
40
+ Relevant settings: VASP_STRUCTURE_QUALITY_SCORES, VASP_USE_STATICS,
41
+ VASP_ALLOWED_VASP_TYPES, LTOL, STOL, ANGLE_TOL, and SYMPREC.
42
+
43
+ Returns:
44
+ list[MaterialsDoc]
45
+ """
46
+
47
+ input_documents.sort(key=lambda x: x.formula_pretty)
48
+ materials = []
49
+ for _, group in groupby(input_documents, key=lambda x: x.formula_pretty):
50
+ # TODO: logging - task_ids = [task.task_id for task in group]
51
+ group = list(group)
52
+ task_transformations = [task.transformations for task in group]
53
+ grouped_tasks = filter_and_group_tasks(group, task_transformations, settings)
54
+ for group in grouped_tasks:
55
+ try:
56
+ doc = MaterialsDoc.from_tasks(
57
+ group,
58
+ structure_quality_scores=settings.VASP_STRUCTURE_QUALITY_SCORES,
59
+ use_statics=settings.VASP_USE_STATICS,
60
+ )
61
+ materials.append(doc)
62
+ except Exception as e:
63
+ # TODO: logging - failed_ids = list({t_.task_id for t_ in group})
64
+ doc = MaterialsDoc.construct_deprecated_material(group)
65
+ doc.warnings.append(str(e))
66
+ materials.append(doc)
67
+
68
+ return materials
69
+
70
+
71
+ def filter_and_group_tasks(
72
+ tasks: list[ValidationTaskDoc],
73
+ task_transformations: list[dict | None],
74
+ settings: EmmetBuildSettings,
75
+ ) -> Iterator[list[ValidationTaskDoc]]:
76
+ """Groups tasks by structure matching"""
77
+
78
+ filtered_tasks = []
79
+ filtered_transformations = []
80
+ for task, transformations in zip(tasks, task_transformations):
81
+ if any(
82
+ allowed_type == task.task_type
83
+ for allowed_type in settings.VASP_ALLOWED_VASP_TYPES
84
+ ):
85
+ filtered_tasks.append(task)
86
+ filtered_transformations.append(transformations)
87
+ structures = []
88
+ for idx, (task, transformations) in enumerate(
89
+ zip(filtered_tasks, filtered_transformations)
90
+ ):
91
+ if task.task_type == TaskType.Deformation:
92
+ if transformations is None:
93
+ # Do not include deformed tasks without transformation information
94
+ continue
95
+ else:
96
+ s = undeform_structure(task.input.structure, transformations)
97
+ else:
98
+ s = task.output.structure
99
+
100
+ s.index = idx
101
+ structures.append(s)
102
+
103
+ grouped_structures = group_structures(
104
+ structures,
105
+ ltol=settings.LTOL,
106
+ stol=settings.STOL,
107
+ angle_tol=settings.ANGLE_TOL,
108
+ symprec=settings.SYMPREC,
109
+ )
110
+ for group in grouped_structures:
111
+ grouped_tasks = [filtered_tasks[struct.index] for struct in group]
112
+ yield grouped_tasks
@@ -0,0 +1,48 @@
1
+ from typing import Any
2
+
3
+ from emmet.builders.settings import EmmetBuildSettings
4
+ from emmet.builders.utils import get_potcar_stats
5
+ from emmet.core.tasks import CoreTaskDoc, TaskDoc
6
+ from emmet.core.types.enums import DeprecationMessage
7
+ from emmet.core.vasp.task_valid import TaskDocument
8
+ from emmet.core.vasp.validation_legacy import ValidationDoc
9
+
10
+
11
+ def build_validation_doc(
12
+ input: CoreTaskDoc | TaskDoc | TaskDocument,
13
+ settings: EmmetBuildSettings = EmmetBuildSettings(),
14
+ potcar_stats: dict[str, Any] = get_potcar_stats(method="stored"),
15
+ ) -> ValidationDoc:
16
+ """
17
+ Build a ValidationDoc from a CoreTaskDoc by checking CoreTaskDoc
18
+ parameters against reference values.
19
+
20
+ Args:
21
+ input: Parsed task document to validate.
22
+ settings: Reference values used in validation, defaults defined in EmmetBuildSettings.
23
+ Relevant settings: VASP_KSPACING_TOLERANCE, VASP_DEFAULT_INPUT_SETS, VASP_CHECKED_LDAU_FIELDS,
24
+ VASP_MAX_SCF_GRADIENT, and DEPRECATED_TAGS.
25
+ potcar_stats: POTCAR stats used to validate POTCARs used for the source calculation
26
+ for 'input'. Defaults to compiled values in 'emmet.builders.vasp.mp_potcar_stats.json.gz'
27
+
28
+ Returns:
29
+ ValidationDoc
30
+ """
31
+ validation_doc = ValidationDoc.from_task_doc(
32
+ task_doc=input,
33
+ kpts_tolerance=0.4 if "mp_production_old" in input.tags else 0.9,
34
+ kspacing_tolerance=settings.VASP_KSPACING_TOLERANCE,
35
+ input_sets=settings.VASP_DEFAULT_INPUT_SETS,
36
+ LDAU_fields=settings.VASP_CHECKED_LDAU_FIELDS,
37
+ max_allowed_scf_gradient=settings.VASP_MAX_SCF_GRADIENT,
38
+ potcar_stats=potcar_stats,
39
+ )
40
+
41
+ bad_tags = list(set(input.tags).intersection(settings.DEPRECATED_TAGS))
42
+
43
+ if len(bad_tags) > 0:
44
+ validation_doc.warnings.append(f"Manual Deprecation by tags: {bad_tags}")
45
+ validation_doc.valid = False
46
+ validation_doc.reasons.append(DeprecationMessage.MANUAL)
47
+
48
+ return validation_doc
@@ -1,14 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: emmet-builders
3
- Version: 0.87.0.dev0
3
+ Version: 0.87.0.dev2
4
4
  Summary: Builders for the Emmet Library
5
5
  Author-email: The Materials Project <feedback@materialsproject.org>
6
6
  License: Modified BSD
7
7
  Project-URL: Homepage, https://github.com/materialsproject/emmet/tree/main/emmet-builders/
8
8
  Project-URL: Documentation, https://materialsproject.github.io/emmet/
9
9
  Requires-Python: >=3.11
10
- Requires-Dist: emmet-core[all]>=0.85
11
- Requires-Dist: maggma>=0.57.6
10
+ Requires-Dist: emmet-core[all]>=0.86.1
12
11
  Requires-Dist: matminer>=0.9.1
13
12
  Requires-Dist: pymatgen-io-validation>=0.1.1
14
13
  Provides-Extra: test
@@ -0,0 +1,29 @@
1
+ MANIFEST.in
2
+ pyproject.toml
3
+ emmet/builders/__init__.py
4
+ emmet/builders/base.py
5
+ emmet/builders/py.typed
6
+ emmet/builders/settings.py
7
+ emmet/builders/utils.py
8
+ emmet/builders/materials/__init__.py
9
+ emmet/builders/materials/bonds.py
10
+ emmet/builders/materials/chemenv.py
11
+ emmet/builders/materials/corrected_entries.py
12
+ emmet/builders/materials/oxidation_states.py
13
+ emmet/builders/materials/robocrys.py
14
+ emmet/builders/materials/thermo.py
15
+ emmet/builders/vasp/materials.py
16
+ emmet/builders/vasp/mp_potcar_stats.json.gz
17
+ emmet/builders/vasp/task_validator.py
18
+ emmet_builders.egg-info/PKG-INFO
19
+ emmet_builders.egg-info/SOURCES.txt
20
+ emmet_builders.egg-info/dependency_links.txt
21
+ emmet_builders.egg-info/requires.txt
22
+ emmet_builders.egg-info/top_level.txt
23
+ requirements/deployment.txt
24
+ requirements/ubuntu-latest_py3.11.txt
25
+ requirements/ubuntu-latest_py3.11_extras.txt
26
+ requirements/ubuntu-latest_py3.12.txt
27
+ requirements/ubuntu-latest_py3.12_extras.txt
28
+ requirements/ubuntu-latest_py3.13.txt
29
+ requirements/ubuntu-latest_py3.13_extras.txt
@@ -1,5 +1,4 @@
1
- emmet-core[all]>=0.85
2
- maggma>=0.57.6
1
+ emmet-core[all]>=0.86.1
3
2
  matminer>=0.9.1
4
3
  pymatgen-io-validation>=0.1.1
5
4
 
@@ -27,8 +27,7 @@ authors = [
27
27
  ]
28
28
  license = { text = "Modified BSD" }
29
29
  dependencies = [
30
- "emmet-core[all]>=0.85",
31
- "maggma>=0.57.6",
30
+ "emmet-core[all]>=0.86.1",
32
31
  "matminer>=0.9.1",
33
32
  "pymatgen-io-validation>=0.1.1",
34
33
  ]