Example #1
0
    def get_integer_formula_and_factor(
        self, max_denominator: int = 10000, iupac_ordering: bool = False
    ) -> Tuple[str, float]:
        """
        Calculates an integer formula and factor.

        Args:
            max_denominator (int): all amounts in the el:amt dict are
                first converted to a Fraction with this maximum denominator
            iupac_ordering (bool, optional): Whether to order the
                formula by the iupac "electronegativity" series, defined in
                Table VI of "Nomenclature of Inorganic Chemistry (IUPAC
                Recommendations 2005)". This ordering effectively follows
                the groups and rows of the periodic table, except the
                Lanthanides, Actinides and hydrogen. Note that polyanions
                will still be determined based on the true electronegativity of
                the elements.

        Returns:
            A pretty normalized formula and a multiplicative factor, i.e.,
            Li0.5O0.25 returns (Li2O, 0.25). O0.25 returns (O2, 0.125)
        """
        el_amt = self.get_el_amt_dict()
        g = gcd_float(list(el_amt.values()), 1 / max_denominator)

        d = {k: round(v / g) for k, v in el_amt.items()}
        (formula, factor) = reduce_formula(d, iupac_ordering=iupac_ordering)
        if formula in Composition.special_formulas:
            formula = Composition.special_formulas[formula]
            factor /= 2
        return formula, factor * g
Example #2
0
    def get_ordered_integer_formula(el_amt, max_denominator=1000):
        """Converts a mapping of {element: stoichiometric value} to a alphabetically ordered string.

        Given a dictionary of {element : stoichiometric value, ..}, returns a string with
        elements ordered alphabetically and stoichiometric values normalized to smallest common
        integer denominator.

        Args:
            el_amt: {element: stoichiometric value} mapping.
            max_denominator: The maximum common denominator of stoichiometric values to use for
                normalization. Smaller stoichiometric fractions will be converted to the same
                integer stoichiometry.

        Returns:
            A material formula string with elements ordered alphabetically and the stoichiometry
            normalized to the smallest integer fractions.
        """
        g = gcd_float(list(el_amt.values()), 1 / max_denominator)
        d = {k: round(v / g) for k, v in el_amt.items()}
        formula = ""
        for k in sorted(d):
            if d[k] > 1:
                formula += k + str(d[k])
            elif d[k] != 0:
                formula += k
        return formula
Example #3
0
    def get_integer_formula_and_factor(self, max_denominator=10000,
                                       iupac_ordering=False):
        """
        Calculates an integer formula and factor.

        Args:
            max_denominator (int): all amounts in the el:amt dict are
                first converted to a Fraction with this maximum denominator
            iupac_ordering (bool, optional): Whether to order the
                formula by the iupac "electronegativity" series, defined in
                Table VI of "Nomenclature of Inorganic Chemistry (IUPAC
                Recommendations 2005)". This ordering effectively follows
                the groups and rows of the periodic table, except the
                Lanthanides, Actanides and hydrogen. Note that polyanions
                will still be determined based on the true electronegativity of
                the elements.

        Returns:
            A pretty normalized formula and a multiplicative factor, i.e.,
            Li0.5O0.25 returns (Li2O, 0.25). O0.25 returns (O2, 0.125)
        """
        el_amt = self.get_el_amt_dict()
        g = gcd_float(list(el_amt.values()), 1 / max_denominator)

        d = {k: round(v / g) for k, v in el_amt.items()}
        (formula, factor) = reduce_formula(
            d, iupac_ordering=iupac_ordering)
        if formula in Composition.special_formulas:
            formula = Composition.special_formulas[formula]
            factor /= 2
        return formula, factor * g
Example #4
0
 def get_ordered_integer_formula(self, el_amt, max_denominator=1000):
     # return alphabetically ordered formula with integer fractions
     g = gcd_float(list(el_amt.values()), 1 / max_denominator)
     d = {k: round(v / g) for k, v in el_amt.items()}
     formula = ""
     for k in sorted(d):
         if d[k] > 1:
             formula += k + str(d[k])
         else:
             formula += k
     return formula
Example #5
0
 def _str_from_comp(cls, coeffs, compositions, reduce=False):
     r_coeffs = np.zeros(len(coeffs))
     r_formulas = []
     for i, (amt, comp) in enumerate(zip(coeffs, compositions)):
         formula, factor = comp.get_reduced_formula_and_factor()
         r_coeffs[i] = amt * factor
         r_formulas.append(formula)
     if reduce:
         factor = 1 / gcd_float(np.abs(r_coeffs))
         r_coeffs *= factor
     else:
         factor = 1
     return cls._str_from_formulas(r_coeffs, r_formulas), factor
Example #6
0
 def _str_from_comp(cls, coeffs, compositions, reduce=False):
     r_coeffs = np.zeros(len(coeffs))
     r_formulas = []
     for i, (amt, comp) in enumerate(zip(coeffs, compositions)):
         formula, factor = comp.get_reduced_formula_and_factor()
         r_coeffs[i] = amt * factor
         r_formulas.append(formula)
     if reduce:
         factor = 1 / gcd_float(np.abs(r_coeffs))
         r_coeffs *= factor
     else:
         factor = 1
     return cls._str_from_formulas(r_coeffs, r_formulas), factor
Example #7
0
 def get_ordered_integer_formula(el_amt, max_denominator=1000):
     """
     Given a dictionary of {element : stoichiometric value, ..}, returns a string with
     elements ordered alphabetically and stoichiometric values normalized to smallest common
     ingeger denominator
     :param el_amt:
     :param max_denominator:
     :return:
     """
     # return alphabetically ordered formula with integer fractions
     g = gcd_float(list(el_amt.values()), 1 / max_denominator)
     d = {k: round(v / g) for k, v in el_amt.items()}
     formula = ""
     for k in sorted(d):
         if d[k] > 1:
             formula += k + str(d[k])
         elif d[k] != 0:
             formula += k
     return formula
Example #8
0
    def get_integer_formula_and_factor(self, max_denominator=10000):
        """
        Calculates an integer formula and factor.

        Args:
            max_denominator (int): all amounts in the el:amt dict are
                first converted to a Fraction with this maximum denominator

        Returns:
            A pretty normalized formula and a multiplicative factor, i.e.,
            Li0.5O0.25 returns (Li2O, 0.25). O0.25 returns (O2, 0.125)
        """
        el_amt = self.get_el_amt_dict()
        g = gcd_float(list(el_amt.values()), 1 / max_denominator)

        d = {k: round(v / g) for k, v in el_amt.items()}
        (formula, factor) = reduce_formula(d)
        if formula in Composition.special_formulas:
            formula = Composition.special_formulas[formula]
            factor /= 2
        return formula, factor * g
Example #9
0
    def get_integer_formula_and_factor(self, max_denominator=10000):
        """
        Calculates an integer formula and factor.

        Args:
            max_denominator (int): all amounts in the el:amt dict are
                first converted to a Fraction with this maximum denominator

        Returns:
            A pretty normalized formula and a multiplicative factor, i.e.,
            Li0.5O0.25 returns (Li2O, 0.25). O0.25 returns (O2, 0.125)
        """
        el_amt = self.get_el_amt_dict()
        g = gcd_float(list(el_amt.values()), 1 / max_denominator)

        d = {k: round(v / g) for k, v in el_amt.items()}
        (formula, factor) = reduce_formula(d)
        if formula in Composition.special_formulas:
            formula = Composition.special_formulas[formula]
            factor /= 2
        return formula, factor * g
Example #10
0
 def test_gcd_float(self):
     vs = [6.2, 12.4, 15.5 + 5e-9]
     self.assertAlmostEqual(gcd_float(vs, 1e-8), 3.1)
Example #11
0
 def test_gcd_float(self):
     vs = [6.2, 12.4, 15.5 + 5e-9]
     self.assertAlmostEqual(gcd_float(vs, 1e-8), 3.1)