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.
- {emmet_builders-0.87.0.dev0/emmet_builders.egg-info → emmet_builders-0.87.0.dev2}/PKG-INFO +2 -3
- emmet_builders-0.87.0.dev2/emmet/builders/base.py +20 -0
- emmet_builders-0.87.0.dev2/emmet/builders/materials/bonds.py +38 -0
- emmet_builders-0.87.0.dev2/emmet/builders/materials/chemenv.py +34 -0
- emmet_builders-0.87.0.dev2/emmet/builders/materials/corrected_entries.py +107 -0
- emmet_builders-0.87.0.dev2/emmet/builders/materials/oxidation_states.py +34 -0
- emmet_builders-0.87.0.dev2/emmet/builders/materials/robocrys.py +40 -0
- emmet_builders-0.87.0.dev2/emmet/builders/materials/thermo.py +121 -0
- emmet_builders-0.87.0.dev2/emmet/builders/vasp/materials.py +112 -0
- emmet_builders-0.87.0.dev2/emmet/builders/vasp/task_validator.py +48 -0
- {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2/emmet_builders.egg-info}/PKG-INFO +2 -3
- emmet_builders-0.87.0.dev2/emmet_builders.egg-info/SOURCES.txt +29 -0
- {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/emmet_builders.egg-info/requires.txt +1 -2
- {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/pyproject.toml +1 -2
- emmet_builders-0.87.0.dev0/emmet/builders/abinit/phonon.py +0 -853
- emmet_builders-0.87.0.dev0/emmet/builders/abinit/sound_velocity.py +0 -217
- emmet_builders-0.87.0.dev0/emmet/builders/feff/__init__.py +0 -0
- emmet_builders-0.87.0.dev0/emmet/builders/feff/xas.py +0 -67
- emmet_builders-0.87.0.dev0/emmet/builders/materials/__init__.py +0 -0
- emmet_builders-0.87.0.dev0/emmet/builders/materials/absorption_spectrum.py +0 -214
- emmet_builders-0.87.0.dev0/emmet/builders/materials/alloys.py +0 -385
- emmet_builders-0.87.0.dev0/emmet/builders/materials/basic_descriptors.py +0 -166
- emmet_builders-0.87.0.dev0/emmet/builders/materials/bonds.py +0 -55
- emmet_builders-0.87.0.dev0/emmet/builders/materials/chemenv.py +0 -43
- emmet_builders-0.87.0.dev0/emmet/builders/materials/corrected_entries.py +0 -329
- emmet_builders-0.87.0.dev0/emmet/builders/materials/dielectric.py +0 -214
- emmet_builders-0.87.0.dev0/emmet/builders/materials/elasticity.py +0 -499
- emmet_builders-0.87.0.dev0/emmet/builders/materials/electrodes.py +0 -633
- emmet_builders-0.87.0.dev0/emmet/builders/materials/electronic_structure.py +0 -757
- emmet_builders-0.87.0.dev0/emmet/builders/materials/magnetism.py +0 -162
- emmet_builders-0.87.0.dev0/emmet/builders/materials/optimade.py +0 -171
- emmet_builders-0.87.0.dev0/emmet/builders/materials/oxidation_states.py +0 -55
- emmet_builders-0.87.0.dev0/emmet/builders/materials/piezoelectric.py +0 -255
- emmet_builders-0.87.0.dev0/emmet/builders/materials/provenance.py +0 -270
- emmet_builders-0.87.0.dev0/emmet/builders/materials/robocrys.py +0 -44
- emmet_builders-0.87.0.dev0/emmet/builders/materials/similarity.py +0 -151
- emmet_builders-0.87.0.dev0/emmet/builders/materials/substrates.py +0 -183
- emmet_builders-0.87.0.dev0/emmet/builders/materials/summary.py +0 -234
- emmet_builders-0.87.0.dev0/emmet/builders/materials/thermo.py +0 -299
- emmet_builders-0.87.0.dev0/emmet/builders/matscholar/missing_compositions.py +0 -223
- emmet_builders-0.87.0.dev0/emmet/builders/mobility/__init__.py +0 -0
- emmet_builders-0.87.0.dev0/emmet/builders/mobility/migration_graph.py +0 -102
- emmet_builders-0.87.0.dev0/emmet/builders/vasp/__init__.py +0 -0
- emmet_builders-0.87.0.dev0/emmet/builders/vasp/materials.py +0 -360
- emmet_builders-0.87.0.dev0/emmet/builders/vasp/task_validator.py +0 -89
- emmet_builders-0.87.0.dev0/emmet_builders.egg-info/SOURCES.txt +0 -69
- emmet_builders-0.87.0.dev0/tests/__init__.py +0 -0
- emmet_builders-0.87.0.dev0/tests/conftest.py +0 -7
- emmet_builders-0.87.0.dev0/tests/test_absorption.py +0 -43
- emmet_builders-0.87.0.dev0/tests/test_basic_descriptors.py +0 -30
- emmet_builders-0.87.0.dev0/tests/test_chemenv.py +0 -40
- emmet_builders-0.87.0.dev0/tests/test_corrected_entries_thermo.py +0 -78
- emmet_builders-0.87.0.dev0/tests/test_dielectric.py +0 -43
- emmet_builders-0.87.0.dev0/tests/test_elasticity.py +0 -43
- emmet_builders-0.87.0.dev0/tests/test_electronic_structure.py +0 -66
- emmet_builders-0.87.0.dev0/tests/test_magnetism.py +0 -55
- emmet_builders-0.87.0.dev0/tests/test_materials.py +0 -46
- emmet_builders-0.87.0.dev0/tests/test_mobility.py +0 -31
- emmet_builders-0.87.0.dev0/tests/test_oxidation.py +0 -37
- emmet_builders-0.87.0.dev0/tests/test_piezoelectric.py +0 -44
- emmet_builders-0.87.0.dev0/tests/test_similarity.py +0 -43
- emmet_builders-0.87.0.dev0/tests/test_summary.py +0 -193
- emmet_builders-0.87.0.dev0/tests/test_utils.py +0 -105
- emmet_builders-0.87.0.dev0/tests/test_vasp.py +0 -30
- {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/MANIFEST.in +0 -0
- {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/emmet/builders/__init__.py +0 -0
- {emmet_builders-0.87.0.dev0/emmet/builders/abinit → emmet_builders-0.87.0.dev2/emmet/builders/materials}/__init__.py +0 -0
- {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/emmet/builders/py.typed +0 -0
- {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/emmet/builders/settings.py +0 -0
- {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/emmet/builders/utils.py +0 -0
- {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/emmet/builders/vasp/mp_potcar_stats.json.gz +0 -0
- {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/emmet_builders.egg-info/dependency_links.txt +0 -0
- {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/emmet_builders.egg-info/top_level.txt +0 -0
- {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/requirements/deployment.txt +0 -0
- {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/requirements/ubuntu-latest_py3.11.txt +0 -0
- {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/requirements/ubuntu-latest_py3.11_extras.txt +0 -0
- {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/requirements/ubuntu-latest_py3.12.txt +0 -0
- {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/requirements/ubuntu-latest_py3.12_extras.txt +0 -0
- {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/requirements/ubuntu-latest_py3.13.txt +0 -0
- {emmet_builders-0.87.0.dev0 → emmet_builders-0.87.0.dev2}/requirements/ubuntu-latest_py3.13_extras.txt +0 -0
- {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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|