1
1
import itertools
2
- from multiprocessing .sharedctypes import Value
3
2
import warnings
4
3
from functools import lru_cache
5
4
from os import environ
6
- from typing import Dict , List , Optional , Tuple , Union
5
+ from typing import Dict , List , Optional , Union
7
6
8
7
from emmet .core .charge_density import ChgcarDataDoc
9
8
from emmet .core .electronic_structure import BSPathType
10
9
from emmet .core .mpid import MPID
11
10
from emmet .core .settings import EmmetSettings
12
- from emmet .core .summary import HasProps
13
- from emmet .core .symmetry import CrystalSystem
14
11
from emmet .core .vasp .calc_types import CalcType
15
- from pymatgen .analysis .magnetism import Ordering
16
12
from pymatgen .analysis .phase_diagram import PhaseDiagram
17
13
from pymatgen .analysis .pourbaix_diagram import IonEntry
18
- from pymatgen .core import Composition , Element , Structure
14
+ from pymatgen .core import Element , Structure
19
15
from pymatgen .core .ion import Ion
20
16
from pymatgen .entries .computed_entries import ComputedEntry , ComputedStructureEntry
21
17
from pymatgen .io .vasp import Chgcar
@@ -132,15 +128,20 @@ def __init__(
132
128
self .session = BaseRester ._create_session (
133
129
api_key = api_key , include_user_agent = include_user_agent
134
130
)
131
+ self .use_document_model = use_document_model
132
+ self .monty_decode = monty_decode
135
133
136
134
try :
137
135
from mpcontribs .client import Client
136
+
138
137
self .contribs = Client (api_key )
139
138
except ImportError :
140
139
self .contribs = None
141
- warnings .warn ("mpcontribs-client not installed. "
142
- "Install the package to query MPContribs data, or construct pourbaix diagrams: "
143
- "'pip install mpcontribs-client'" )
140
+ warnings .warn (
141
+ "mpcontribs-client not installed. "
142
+ "Install the package to query MPContribs data, or construct pourbaix diagrams: "
143
+ "'pip install mpcontribs-client'"
144
+ )
144
145
except Exception as error :
145
146
self .contribs = None
146
147
warnings .warn (f"Problem loading MPContribs client: { error } " )
@@ -186,15 +187,19 @@ def __exit__(self, exc_type, exc_val, exc_tb):
186
187
187
188
def __getattr__ (self , attr ):
188
189
if attr == "alloys" :
189
- raise MPRestError ("Alloy addon package not installed. "
190
- "To query alloy data first install with: 'pip install pymatgen-analysis-alloys'" )
190
+ raise MPRestError (
191
+ "Alloy addon package not installed. "
192
+ "To query alloy data first install with: 'pip install pymatgen-analysis-alloys'"
193
+ )
191
194
elif attr == "charge_density" :
192
- raise MPRestError ("boto3 not installed. "
193
- "To query charge density data first install with: 'pip install boto3'" )
195
+ raise MPRestError (
196
+ "boto3 not installed. "
197
+ "To query charge density data first install with: 'pip install boto3'"
198
+ )
194
199
else :
195
200
raise AttributeError (
196
- f"{ self .__class__ .__name__ !r} object has no attribute { attr !r} "
197
- )
201
+ f"{ self .__class__ .__name__ !r} object has no attribute { attr !r} "
202
+ )
198
203
199
204
def get_task_ids_associated_with_material_id (
200
205
self , material_id : str , calc_types : Optional [List [CalcType ]] = None
@@ -446,7 +451,8 @@ def get_entries(
446
451
inc_structure : bool = None ,
447
452
property_data : List [str ] = None ,
448
453
conventional_unit_cell : bool = False ,
449
- sort_by_e_above_hull = False ,
454
+ sort_by_e_above_hull : bool = False ,
455
+ additional_criteria : dict = None ,
450
456
) -> List [ComputedStructureEntry ]:
451
457
"""
452
458
Get a list of ComputedEntries or ComputedStructureEntries corresponding
@@ -476,14 +482,20 @@ def get_entries(
476
482
conventional unit cell
477
483
sort_by_e_above_hull (bool): Whether to sort the list of entries by
478
484
e_above_hull in ascending order.
485
+ additional_criteria (dict): Any additional criteria to pass. The keys and values should
486
+ correspond to proper function inputs to `MPRester.thermo.search`. For instance,
487
+ if you are only interested in entries on the convex hull, you could pass
488
+ {"energy_above_hull": (0.0, 0.0)} or {"is_stable": True}.
479
489
480
490
Returns:
481
491
List ComputedStructureEntry objects.
482
492
"""
483
493
484
494
if inc_structure is not None :
485
- warnings .warn ("The 'inc_structure' argument is deprecated as structure "
486
- "data is now always included in all returned entry objects." )
495
+ warnings .warn (
496
+ "The 'inc_structure' argument is deprecated as structure "
497
+ "data is now always included in all returned entry objects."
498
+ )
487
499
488
500
if isinstance (chemsys_formula_mpids , str ):
489
501
chemsys_formula_mpids = [chemsys_formula_mpids ]
@@ -497,6 +509,9 @@ def get_entries(
497
509
else :
498
510
input_params = {"formula" : chemsys_formula_mpids }
499
511
512
+ if additional_criteria :
513
+ input_params = {** input_params , ** additional_criteria }
514
+
500
515
entries = []
501
516
502
517
fields = ["entries" ] if not property_data else ["entries" ] + property_data
@@ -514,22 +529,25 @@ def get_entries(
514
529
)
515
530
516
531
for doc in docs :
517
- for entry in doc .entries .values ():
532
+ entry_list = doc .entries .values () if self .use_document_model else doc ["entries" ].values ()
533
+ for entry in entry_list :
534
+ entry_dict = entry .as_dict () if self .monty_decode else entry
518
535
if not compatible_only :
519
- entry . correction = 0.0
520
- entry . energy_adjustments = []
536
+ entry_dict [ " correction" ] = 0.0
537
+ entry_dict [ " energy_adjustments" ] = []
521
538
522
539
if property_data :
523
540
for property in property_data :
524
- entry .data [property ] = doc .dict ()[property ]
541
+ entry_dict ["data" ][property ] = doc .dict ()[property ] if self .use_document_model else doc [
542
+ property ]
525
543
526
544
if conventional_unit_cell :
527
545
528
- s = SpacegroupAnalyzer (entry .structure ).get_conventional_standard_structure ()
529
- site_ratio = (len (s ) / len (entry .structure ))
530
- new_energy = entry .uncorrected_energy * site_ratio
546
+ entry_struct = Structure .from_dict (entry_dict ["structure" ])
547
+ s = SpacegroupAnalyzer (entry_struct ).get_conventional_standard_structure ()
548
+ site_ratio = len (s ) / len (entry_struct )
549
+ new_energy = entry_dict ["energy" ] * site_ratio
531
550
532
- entry_dict = entry .as_dict ()
533
551
entry_dict ["energy" ] = new_energy
534
552
entry_dict ["structure" ] = s .as_dict ()
535
553
entry_dict ["correction" ] = 0.0
@@ -540,7 +558,7 @@ def get_entries(
540
558
for correction in entry_dict ["energy_adjustments" ]:
541
559
correction ["n_atoms" ] *= site_ratio
542
560
543
- entry = ComputedStructureEntry .from_dict (entry_dict )
561
+ entry = ComputedStructureEntry .from_dict (entry_dict ) if self . monty_decode else entry_dict
544
562
545
563
entries .append (entry )
546
564
@@ -575,9 +593,11 @@ def get_pourbaix_entries(
575
593
# imports are not top-level due to expense
576
594
from pymatgen .analysis .pourbaix_diagram import PourbaixEntry
577
595
from pymatgen .entries .compatibility import (
578
- Compatibility , MaterialsProject2020Compatibility ,
596
+ Compatibility ,
597
+ MaterialsProject2020Compatibility ,
579
598
MaterialsProjectAqueousCompatibility ,
580
- MaterialsProjectCompatibility )
599
+ MaterialsProjectCompatibility ,
600
+ )
581
601
from pymatgen .entries .computed_entries import ComputedEntry
582
602
583
603
if solid_compat == "MaterialsProjectCompatibility" :
@@ -638,8 +658,7 @@ def get_pourbaix_entries(
638
658
# could be removed
639
659
if use_gibbs :
640
660
# replace the entries with GibbsComputedStructureEntry
641
- from pymatgen .entries .computed_entries import \
642
- GibbsComputedStructureEntry
661
+ from pymatgen .entries .computed_entries import GibbsComputedStructureEntry
643
662
644
663
ion_ref_entries = GibbsComputedStructureEntry .from_entries (
645
664
ion_ref_entries , temp = use_gibbs
@@ -846,11 +865,14 @@ def get_ion_entries(
846
865
847
866
return ion_entries
848
867
849
- def get_entry_by_material_id (self , material_id : str ,
850
- compatible_only : bool = True ,
851
- inc_structure : bool = None ,
852
- property_data : List [str ] = None ,
853
- conventional_unit_cell : bool = False ,):
868
+ def get_entry_by_material_id (
869
+ self ,
870
+ material_id : str ,
871
+ compatible_only : bool = True ,
872
+ inc_structure : bool = None ,
873
+ property_data : List [str ] = None ,
874
+ conventional_unit_cell : bool = False ,
875
+ ):
854
876
"""
855
877
Get all ComputedEntry objects corresponding to a material_id.
856
878
@@ -877,14 +899,17 @@ def get_entry_by_material_id(self, material_id: str,
877
899
Returns:
878
900
List of ComputedEntry or ComputedStructureEntry object.
879
901
"""
880
- return self .get_entries (material_id ,
881
- compatible_only = compatible_only ,
882
- inc_structure = inc_structure ,
883
- property_data = property_data ,
884
- conventional_unit_cell = conventional_unit_cell )
902
+ return self .get_entries (
903
+ material_id ,
904
+ compatible_only = compatible_only ,
905
+ inc_structure = inc_structure ,
906
+ property_data = property_data ,
907
+ conventional_unit_cell = conventional_unit_cell ,
908
+ )
885
909
886
910
def get_entries_in_chemsys (
887
- self , elements : Union [str , List [str ]],
911
+ self ,
912
+ elements : Union [str , List [str ]],
888
913
use_gibbs : Optional [int ] = None ,
889
914
compatible_only : bool = True ,
890
915
inc_structure : bool = None ,
@@ -924,17 +949,14 @@ def get_entries_in_chemsys(
924
949
input parameters in the 'MPRester.thermo.available_fields' list.
925
950
conventional_unit_cell (bool): Whether to get the standard
926
951
conventional unit cell
927
- additional_criteria (dict): *This is a deprecated argument*. To obtain entry objects
928
- with additional criteria, use the `MPRester.thermo.search` method directly.
952
+ additional_criteria (dict): Any additional criteria to pass. The keys and values should
953
+ correspond to proper function inputs to `MPRester.thermo.search`. For instance,
954
+ if you are only interested in entries on the convex hull, you could pass
955
+ {"energy_above_hull": (0.0, 0.0)} or {"is_stable": True}.
929
956
Returns:
930
957
List of ComputedStructureEntries.
931
958
"""
932
959
933
- if additional_criteria is not None :
934
- warnings .warn ("The 'additional_criteria' argument is deprecated. "
935
- "To obtain entry objects with additional criteria, use "
936
- "the 'MPRester.thermo.search' method directly" )
937
-
938
960
if isinstance (elements , str ):
939
961
elements = elements .split ("-" )
940
962
@@ -945,19 +967,29 @@ def get_entries_in_chemsys(
945
967
946
968
entries = [] # type: List[ComputedEntry]
947
969
948
- entries .extend (self .get_entries (all_chemsyses ,
949
- compatible_only = compatible_only ,
950
- inc_structure = inc_structure ,
951
- property_data = property_data ,
952
- conventional_unit_cell = conventional_unit_cell ))
970
+ entries .extend (
971
+ self .get_entries (
972
+ all_chemsyses ,
973
+ compatible_only = compatible_only ,
974
+ inc_structure = inc_structure ,
975
+ property_data = property_data ,
976
+ conventional_unit_cell = conventional_unit_cell ,
977
+ additional_criteria = additional_criteria ,
978
+ )
979
+ )
980
+
981
+ if not self .monty_decode :
982
+ entries = [ComputedStructureEntry .from_dict (entry ) for entry in entries ]
953
983
954
984
if use_gibbs :
955
985
# replace the entries with GibbsComputedStructureEntry
956
- from pymatgen .entries .computed_entries import \
957
- GibbsComputedStructureEntry
986
+ from pymatgen .entries .computed_entries import GibbsComputedStructureEntry
958
987
959
988
entries = GibbsComputedStructureEntry .from_entries (entries , temp = use_gibbs )
960
989
990
+ if not self .monty_decode :
991
+ entries = [entry .as_dict () for entry in entries ]
992
+
961
993
return entries
962
994
963
995
def get_bandstructure_by_material_id (
@@ -970,7 +1002,7 @@ def get_bandstructure_by_material_id(
970
1002
Get the band structure pymatgen object associated with a Materials Project ID.
971
1003
972
1004
Arguments:
973
- materials_id (str): Materials Project ID for a material
1005
+ material_id (str): Materials Project ID for a material
974
1006
path_type (BSPathType): k-point path selection convention
975
1007
line_mode (bool): Whether to return data for a line-mode calculation
976
1008
@@ -986,7 +1018,7 @@ def get_dos_by_material_id(self, material_id: str):
986
1018
Get the complete density of states pymatgen object associated with a Materials Project ID.
987
1019
988
1020
Arguments:
989
- materials_id (str): Materials Project ID for a material
1021
+ material_id (str): Materials Project ID for a material
990
1022
991
1023
Returns:
992
1024
dos (CompleteDos): CompleteDos object
@@ -1028,6 +1060,7 @@ def submit_structures(self, structures, public_name, public_email):
1028
1060
Args:
1029
1061
structures: A list of Structure objects
1030
1062
1063
+
1031
1064
Returns:
1032
1065
?
1033
1066
"""
@@ -1077,8 +1110,10 @@ def get_charge_density_from_material_id(
1077
1110
"""
1078
1111
1079
1112
if not hasattr (self , "charge_density" ):
1080
- raise MPRestError ("boto3 not installed. "
1081
- "To query charge density data install the boto3 package." )
1113
+ raise MPRestError (
1114
+ "boto3 not installed. "
1115
+ "To query charge density data install the boto3 package."
1116
+ )
1082
1117
1083
1118
# TODO: really we want a recommended task_id for charge densities here
1084
1119
# this could potentially introduce an ambiguity
0 commit comments