From 9f25d6b2ec094cedbee58b33ca7e13b1c1f37774 Mon Sep 17 00:00:00 2001 From: Jason Munro Date: Wed, 26 May 2021 14:42:15 -0700 Subject: [PATCH 1/4] XASDoc bug fix --- emmet-core/emmet/core/xas.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/emmet-core/emmet/core/xas.py b/emmet-core/emmet/core/xas.py index 55a895052d..404e6b0910 100644 --- a/emmet-core/emmet/core/xas.py +++ b/emmet-core/emmet/core/xas.py @@ -65,10 +65,7 @@ class XASDoc(SpectrumDoc): @classmethod def from_spectrum( - cls, - xas_spectrum: XAS, - material_id: MPID, - **kwargs, + cls, xas_spectrum: XAS, material_id: MPID, **kwargs, ): spectrum_type = xas_spectrum.spectrum_type el = xas_spectrum.absorbing_element @@ -92,7 +89,7 @@ def from_spectrum( @classmethod def from_task_docs( cls, all_tasks: List[TaskDocument], material_id: MPID, num_samples: int = 200 - ) -> List[XASDoc]: + ): """ Converts a set of FEFF Task Documents into XASDocs by merging XANES + EXAFS into XAFS spectra first and then merging along equivalent elements to get element averaged spectra @@ -129,10 +126,7 @@ def from_task_docs( # Dictionary of all site to spectra mapping sites_to_spectra = { index: list(group) - for index, group in groupby( - all_spectra, - key=lambda x: x.absorbing_index, - ) + for index, group in groupby(all_spectra, key=lambda x: x.absorbing_index,) } # perform spectra merging @@ -140,8 +134,7 @@ def from_task_docs( type_to_spectra = { index: list(group) for index, group in groupby( - spectra, - key=lambda x: (x.edge, x.spectrum_type), + spectra, key=lambda x: (x.edge, x.spectrum_type), ) } # Make K-edge XAFS spectra by merging XANES + EXAFS From 52b3a0028ef8a646dbb5c60a9df5e3fba95a5b1b Mon Sep 17 00:00:00 2001 From: Jason Munro Date: Wed, 16 Jun 2021 15:44:41 -0700 Subject: [PATCH 2/4] Electronic structure bug fixes --- .../materials/electronic_structure.py | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/emmet-builders/emmet/builders/materials/electronic_structure.py b/emmet-builders/emmet/builders/materials/electronic_structure.py index bfcf40ed4c..cfadc92239 100644 --- a/emmet-builders/emmet/builders/materials/electronic_structure.py +++ b/emmet-builders/emmet/builders/materials/electronic_structure.py @@ -112,6 +112,7 @@ def process_item(self, mat): dos = None bs = {} + structures = {} for bs_type, bs_entry in mat["bandstructure"].items(): if bs_entry.get("object", None) is not None: @@ -119,11 +120,15 @@ def process_item(self, mat): {bs_entry["task_id"]: BandStructureSymmLine.from_dict(bs_entry["object"])} if bs_entry else None ) + structures[bs_entry["task_id"]] = bs_entry["output_structure"] + if mat["dos"]: if mat["dos"]["object"] is not None: self.logger.info("Processing density of states") dos = {mat["dos"]["task_id"]: CompleteDos.from_dict(mat["dos"]["object"])} + structures[mat["dos"]["task_id"]] = mat["dos"]["output_structure"] + if bs: self.logger.info( "Processing band structure types: {}".format([bs_type for bs_type, bs_entry in bs.items() if bs_entry]) @@ -145,7 +150,7 @@ def process_item(self, mat): else: doc = ElectronicStructureDoc.from_bsdos( material_id=mat[self.materials.key], - structure=structure, + structures=structures, dos=dos, is_gap_direct=mat["other"]["is_gap_direct"], is_metal=mat["other"]["is_metal"], @@ -213,14 +218,14 @@ def _update_materials_doc(self, mat_id): "input.is_hubbard", "orig_inputs.kpoints", "input.parameters", - "input.structure", + "output.structure", ], criteria={"task_id": str(task_id)}, ) fs_id = str(task_query["calcs_reversed"][0]["bandstructure_fs_id"]) - structure = Structure.from_dict(task_query["input"]["structure"]) + structure = Structure.from_dict(task_query["output"]["structure"]) kpoints = task_query["orig_inputs"]["kpoints"] labels_dict = { @@ -251,6 +256,7 @@ def _update_materials_doc(self, mat_id): "is_hubbard": int(is_hubbard), "nkpoints": int(nkpoints), "updated_on": lu_dt, + "output_structure": structure, } ) @@ -263,6 +269,7 @@ def _update_materials_doc(self, mat_id): "input.is_hubbard", "orig_inputs.kpoints", "input.parameters", + "output.structure", ], criteria={"task_id": str(task_id)}, ) @@ -271,6 +278,8 @@ def _update_materials_doc(self, mat_id): is_hubbard = task_query["input"]["is_hubbard"] + structure = Structure.from_dict(task_query["output"]["structure"]) + if task_query["orig_inputs"]["kpoints"]["generation_style"] == "Monkhorst": nkpoints = np.prod(task_query["orig_inputs"]["kpoints"]["kpoints"][0], axis=0) else: @@ -287,6 +296,7 @@ def _update_materials_doc(self, mat_id): "nkpoints": int(nkpoints), "nedos": int(nedos), "updated_on": lu_dt, + "output_structure": structure, } ) @@ -298,12 +308,12 @@ def _update_materials_doc(self, mat_id): "input.is_hubbard", "orig_inputs.kpoints", "calcs_reversed", - "input.structure", + "output.structure", ], criteria={"task_id": str(task_id)}, ) - structure = Structure.from_dict(task_query["input"]["structure"]) + structure = Structure.from_dict(task_query["output"]["structure"]) other_mag_ordering = CollinearMagneticStructureAnalyzer(structure).ordering @@ -353,6 +363,8 @@ def _obtain_blessed_calculations(self, materials_doc, bs_calcs, dos_calcs, other materials_doc["bandstructure"][bs_type]["object"] = bs_obj["data"] if bs_obj is not None else None + materials_doc["bandstructure"][bs_type]["output_structure"] = sorted_bs_data[0]["output_structure"] + if dos_calcs: sorted_dos_data = sorted( @@ -366,6 +378,8 @@ def _obtain_blessed_calculations(self, materials_doc, bs_calcs, dos_calcs, other dos_obj = self.dos_fs.query_one(criteria={"fs_id": sorted_dos_data[0]["fs_id"]}) materials_doc["dos"]["object"] = dos_obj["data"] if dos_obj is not None else None + materials_doc["dos"]["output_structure"] = sorted_dos_data[0]["output_structure"] + if other_calcs: sorted_other_data = sorted( From ebffd33dfa899c976c4b5dde9deb9774cb127756 Mon Sep 17 00:00:00 2001 From: Jason Munro Date: Wed, 16 Jun 2021 16:00:50 -0700 Subject: [PATCH 3/4] Fix MPID type hints in ES model --- emmet-core/emmet/core/electronic_structure.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/emmet-core/emmet/core/electronic_structure.py b/emmet-core/emmet/core/electronic_structure.py index b72c2508e9..df971d25f3 100644 --- a/emmet-core/emmet/core/electronic_structure.py +++ b/emmet-core/emmet/core/electronic_structure.py @@ -24,9 +24,7 @@ class ElectronicStructureBaseData(BaseModel): - task_id: Union[MPID, int] = Field( - ..., description="The source calculation (task) ID for the electronic structure data." - ) + task_id: MPID = Field(..., description="The source calculation (task) ID for the electronic structure data.") band_gap: float = Field(..., description="Band gap energy in eV.") @@ -108,14 +106,14 @@ class ElectronicStructureDoc(PropertyDoc, ElectronicStructureSummary): @classmethod def from_bsdos( # type: ignore[override] cls: Type[T], - material_id: Union[MPID, int], - dos: Dict[Union[MPID, int], CompleteDos], + material_id: MPID, + dos: Dict[MPID, CompleteDos], is_gap_direct: bool, is_metal: bool, - structures: Dict[Union[MPID, int], Structure] = None, - setyawan_curtarolo: Dict[Union[MPID, int], BandStructureSymmLine] = None, - hinuma: Dict[Union[MPID, int], BandStructureSymmLine] = None, - latimer_munro: Dict[Union[MPID, int], BandStructureSymmLine] = None, + structures: Dict[MPID, Structure] = None, + setyawan_curtarolo: Dict[MPID, BandStructureSymmLine] = None, + hinuma: Dict[MPID, BandStructureSymmLine] = None, + latimer_munro: Dict[MPID, BandStructureSymmLine] = None, ) -> T: """ Builds a electronic structure document using band structure and density of states data. From ec0815824624fd4f73c3f04d24c18393ddcb0bcd Mon Sep 17 00:00:00 2001 From: Jason Munro Date: Mon, 21 Jun 2021 14:38:41 -0700 Subject: [PATCH 4/4] Insertion electrode fix in electrode model --- emmet-core/emmet/core/electrode.py | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/emmet-core/emmet/core/electrode.py b/emmet-core/emmet/core/electrode.py index 024a11bd6f..8777b256b0 100644 --- a/emmet-core/emmet/core/electrode.py +++ b/emmet-core/emmet/core/electrode.py @@ -27,8 +27,7 @@ class VoltagePairDoc(BaseModel): ) average_voltage: float = Field( - None, - description="The average voltage in V for a particular voltage step.", + None, description="The average voltage in V for a particular voltage step." ) capacity_grav: float = Field(None, description="Gravimetric capacity in mAh/g.") @@ -101,18 +100,15 @@ class InsertionElectrodeDoc(InsertionVoltagePairDoc): ) host_structure: Structure = Field( - None, - description="Host structure (structure without the working ion)", + None, description="Host structure (structure without the working ion)" ) adj_pairs: List[InsertionVoltagePairDoc] = Field( - None, - description="Returns all the Voltage Steps", + None, description="Returns all the Voltage Steps" ) working_ion: Element = Field( - None, - description="The working ion as an Element object", + None, description="The working ion as an Element object" ) num_steps: int = Field( @@ -131,8 +127,7 @@ class InsertionElectrodeDoc(InsertionVoltagePairDoc): ) framework: Composition = Field( - None, - description="The chemical compositions of the host framework", + None, description="The chemical compositions of the host framework" ) elements: List[Element] = Field( @@ -162,9 +157,8 @@ class InsertionElectrodeDoc(InsertionVoltagePairDoc): description="Anonymized representation of the formula (not including the working ion)", ) - electrode_object: Dict = Field( - None, - description="The pymatgen electrode object", + electrode_object: InsertionElectrode = Field( + None, description="The pymatgen electrode object" ) # Make sure that the datetime field is properly formatted @@ -223,13 +217,11 @@ class ConversionElectrodeDoc(ConversionVoltagePairDoc): battery_id: str = Field(None, description="The id for this battery document.") adj_pairs: List[ConversionVoltagePairDoc] = Field( - None, - description="Returns all the adjacent Voltage Steps", + None, description="Returns all the adjacent Voltage Steps" ) working_ion: Element = Field( - None, - description="The working ion as an Element object", + None, description="The working ion as an Element object" ) num_steps: int = Field(