示例#1
0
    def __init__(
        self,
        structure: Structure,
        energy: float,
        correction: float = 0.0,
        composition: Composition = None,
        energy_adjustments: list = None,
        parameters: dict = None,
        data: dict = None,
        entry_id: object = None,
    ):
        """
        Initializes a ComputedStructureEntry.

        Args:
            structure (Structure): The actual structure of an entry.
            energy (float): Energy of the entry. Usually the final calculated
                energy from VASP or other electronic structure codes.
            energy_adjustments: An optional list of EnergyAdjustment to
                be applied to the energy. This is used to modify the energy for
                certain analyses. Defaults to None.
            parameters: An optional dict of parameters associated with
                the entry. Defaults to None.
            data: An optional dict of any additional data associated
                with the entry. Defaults to None.
            entry_id: An optional id to uniquely identify the entry.
        """

        if composition:
            composition = Composition(composition)
            if (
                composition.get_integer_formula_and_factor()[0]
                != structure.composition.get_integer_formula_and_factor()[0]
            ):
                raise ValueError("Mismatching composition provided.")
        else:
            composition = structure.composition

        super().__init__(
            composition,
            energy,
            correction=correction,
            energy_adjustments=energy_adjustments,
            parameters=parameters,
            data=data,
            entry_id=entry_id,
        )
        self._structure = structure
示例#2
0
def _composition_prototype(composition):
    """
    Guess the phase prototype from the integer anonymized_composition.
    Args:
        composition (str): a given composition.
    Returns:
        prototype:
            double_perovskites: 1
            unknown: 0
            ...to be continued

    """
    c = Composition(composition)
    c_int = Composition(c.get_integer_formula_and_factor()[0])
    f_int_anynomous = c_int.anonymized_formula
    prototype = 0
    if f_int_anynomous is "ABCDE6" and Element("O") in Composition(
            composition).elements:
        prototype = 1
    # to be continued
    return prototype
		def get_ionic_properties(row):
			# getting oxidation state of fractional formula is not implemented yet in pymatgen
			# round the fractional formular to 1 decimal place in order to speed up guessed_oxidation_state calculation in pymatgen
			# sum of fractions is preserved (=1)
			elem_frac = {row.A1:row.A1_frac, row.A2:row.A2_frac, row.B1:row.B1_frac, row.B2:row.B2_frac, row.O:row.O_frac}
			# _=elem_frac.pop('_', None)
			elem_frac_red = { k:v for k, v in elem_frac.items() if (v<1 and v>0)}	# remove empty cation and oxygen anion
			# ceil and floor to 1 decimal places and create list
			frac_list=[(k,math.ceil(v*10)/10.0) if v==min(list(elem_frac_red.values())) else (k,math.floor(v*10)/10.0) for k, v in elem_frac_red.items()]
			frac_dict = {k:v for k,v in frac_list}
			elem_frac_copy = elem_frac.copy()	# make a copy so that original element fractions are not updated
			elem_frac_copy.update(frac_dict)	# update the dictionary with 1 decimal precision {Element: fraction} where fraction ceiled/floored for 1 decimal place

			# get fractional formula with 1 decimal point rounded fractions
			l=[]
			[l.append(k+str(v)) for k,v in elem_frac_copy.items() if k!='_'][0]
			formula_1deci = ''.join(l)
			
			comp = Composition(formula_1deci) # create pymatgen Composition object
			int_comp = Composition(comp.get_integer_formula_and_factor()[0]) # get integer formular
			elem_ionic_radius = {}
			# try:
			
			if len(int_comp.oxi_state_guesses())>0:
				ox_state_dict = int_comp.oxi_state_guesses()[0] # get the best oxidation state guess / pymatgen outputs fractional oxidation states where necessary
				for (elem,ox_st) in list(ox_state_dict.items()):
					if not ox_st.is_integer() or ox_st not in ElementSym(elem).ox_st_dict[elem]:	
						avg_ionic_radius = get_avg_ionic_radius(elem, int(int_comp.get(elem)), ox_st)
						if avg_ionic_radius == -1:	# oxidation states cannot be solved with all available oxidation states 
							break

						elem_ionic_radius[elem] = avg_ionic_radius
					else:
						ionic_radius = ElementSym(elem).ionic_radii(ox_st)
						elem_ionic_radius[elem] = ionic_radius
				if len(elem_ionic_radius)==4:
					# now update the first elem_frac dict with the found ionic radius values (some oinic radii may be averages because of fractional oxidation state)
					elem_radii = elem_frac.copy() # for clarity
					elem_radii.update(elem_ionic_radius)

					rA_avg = (elem_frac[row.A1]*elem_radii[row.A1] + elem_frac[row.A2]*elem_radii[row.A2])
					rB_avg = (elem_frac[row.B1]*elem_radii[row.B1] + elem_frac[row.B2]*elem_radii[row.B2])
					rO = ElementSym('O').ionic_radii(-2)	# oxygen's oxidation state is always -2

					ox_st_dict_copy = elem_frac.copy()	# to find nA, nB, nO
					ox_st_dict_copy.update(ox_state_dict)

					nA = elem_frac[row.A1]*ox_st_dict_copy[row.A1] + elem_frac[row.A2]*ox_st_dict_copy[row.A2]
					nB = elem_frac[row.B1]*ox_st_dict_copy[row.B1] + elem_frac[row.B2]*ox_st_dict_copy[row.B2]
					nO = -2 # Oxygent oxidation state

				# to make it easy to understand that these materials are discarded, the else statements are added below // not necessary if Ra_avg, Rb_avg etc. were initialized with -1 at the top
				else:
					rA_avg = -1	# discard these materials / oxidation states could not be solved by the algorithm
					rB_avg = -1
					rO = ElementSym('O').ionic_radii(-2)

					nA = -1
					nB = -1
					nO = -2 # Oxygen oxidation state

			else:
				rA_avg = -1	# discard these materials where the ions show unknown oxidation states/ typically higher that the max oxi_state of a particular element
				rB_avg = -1	# pymatgen's oxi_state_guesses() couldn't solve these even with fractional oxidation states
				rO = ElementSym('O').ionic_radii(-2)

				nA = -1	# discard
				nB = -1	# discard
				nO = -2 # Oxygent oxidation state


			return nA, nB, nO, rA_avg, rB_avg, rO
示例#4
0
    def query(
        self,
        formula: str = Query(
            ...,
            description="Human readable chemical formula.",
        ),
        limit: int = Query(
            10,
            description="Maximum number of matches to show. Defaults to 10.",
        ),
    ) -> STORE_PARAMS:

        self.formula = formula
        self.limit = limit

        try:
            comp = Composition(formula)
        except CompositionError:
            raise HTTPException(
                status_code=400,
                detail="Invalid formula provided.",
            )

        ind_str = []
        eles = []

        if len(comp) == 1:
            d = comp.get_integer_formula_and_factor()

            s = d[0] + str(int(d[1])) if d[1] != 1 else d[0]

            ind_str.append(s)
            eles.append(d[0])
        else:

            comp_red = comp.reduced_composition.items()

            for (i, j) in comp_red:

                if j != 1:
                    ind_str.append(i.name + str(int(j)))
                else:
                    ind_str.append(i.name)

                eles.append(i.name)

        final_terms = ["".join(entry) for entry in permutations(ind_str)]

        pipeline = [
            {
                "$search": {
                    "index": "formula_autocomplete",
                    "text": {
                        "path": "formula_pretty",
                        "query": final_terms
                    },
                }
            },
            {
                "$project": {
                    "_id": 0,
                    "formula_pretty": 1,
                    "elements": 1,
                    "length": {
                        "$strLenCP": "$formula_pretty"
                    },
                }
            },
            {
                "$match": {
                    "length": {
                        "$gte": len(final_terms[0])
                    },
                    "elements": {
                        "$all": eles
                    },
                }
            },
            {
                "$limit": limit
            },
            {
                "$sort": {
                    "length": 1
                }
            },
            {
                "$project": {
                    "elements": 0,
                    "length": 0
                }
            },
        ]

        return {"pipeline": pipeline}