def __str__(self): output = self.symbol if self._oxi_state >= 0: output += formula_double_format(self._oxi_state) + "+" else: output += formula_double_format(-self._oxi_state) + "-" return output
def __str__(self): output = self.symbol if self._oxi_state >= 0: output += formula_double_format(self._oxi_state) + "+" else: output += formula_double_format(-self._oxi_state) + "-" for p, v in self._properties.items(): output += "%s=%s" % (p, v) return output
def to_pretty_string(self) -> str: """ :return: Pretty string with proper superscripts. """ str_ = super().reduced_formula if self.charge > 0: str_ += "^+" + formula_double_format(self.charge, False) elif self._charge < 0: str_ += "^" + formula_double_format(self.charge, False) return str_
def __str__(self): output = self.symbol if self.oxi_state is not None: if self.oxi_state >= 0: output += formula_double_format(self.oxi_state) + "+" else: output += formula_double_format(-self.oxi_state) + "-" for p, v in self._properties.items(): output += f",{p}={v}" return output
def alphabetical_formula(self): """ Returns a reduced formula string with appended charge """ alph_formula = super(Ion, self).alphabetical_formula chg_str = "" if self.charge > 0: chg_str = " +" + formula_double_format(self.charge, False) elif self.charge < 0: chg_str = " " + formula_double_format(self.charge, False) return alph_formula + chg_str
def to_pretty_string(self) -> str: """ :return: String without properties. """ output = self.symbol if self.oxi_state is not None: if self.oxi_state >= 0: output += formula_double_format(self.oxi_state) + "+" else: output += formula_double_format(-self.oxi_state) + "-" return output
def alphabetical_formula(self): """ Returns a reduced formula string with appended charge """ alph_formula = self._composition.alphabetical_formula chg_str = "" if self._charge > 0: chg_str = " +" + formula_double_format(self._charge, False) elif self._charge < 0: chg_str = " " + formula_double_format(self._charge, False) return alph_formula + chg_str
def formula(self): """ Returns a formula string, with elements sorted by electronegativity, e.g., Li4 Fe4 P4 O16. """ formula = self._composition.formula chg_str = "" if self._charge > 0: chg_str = " +" + formula_double_format(self._charge, False) elif self._charge < 0: chg_str = " " + formula_double_format(self._charge, False) return formula + chg_str
def formula(self): """ Returns a formula string, with elements sorted by electronegativity, e.g., Li4 Fe4 P4 O16. """ formula = super(Ion, self).formula chg_str = "" if self.charge > 0: chg_str = " +" + formula_double_format(self.charge, False) elif self._charge < 0: chg_str = " " + formula_double_format(self.charge, False) return formula + chg_str
def alphabetical_formula(self): """ Returns a formula string, with elements sorted by alphabetically e.g., Fe4 Li4 O16 P4. """ sym_amt = self.get_el_amt_dict() syms = sorted(sym_amt.keys()) formula = [s + formula_double_format(sym_amt[s], False) for s in syms] return " ".join(formula)
def hill_formula(self): c = self.element_composition elements = sorted([el.symbol for el in c.keys()]) if "C" in elements: elements = ["C"] + [el for el in elements if el != "C"] formula = ["%s%s" % (el, formula_double_format(c[el]) if c[el] != 1 else "") for el in elements] return " ".join(formula)
def formula(self) -> str: """ Returns a formula string, with elements sorted by electronegativity, e.g., Li4 Fe4 P4 O16. """ sym_amt = self.get_el_amt_dict() syms = sorted(sym_amt.keys(), key=lambda sym: get_el_sp(sym).X) formula = [s + formula_double_format(sym_amt[s], False) for s in syms] return " ".join(formula)
def formula(self): """ Returns a formula string, with elements sorted by electronegativity, e.g., Li4 Fe4 P4 O16. """ sym_amt = self.get_el_amt_dict() syms = sorted(sym_amt.keys(), key=lambda sym: get_el_sp(sym).X) formula = [s + formula_double_format(sym_amt[s], False) for s in syms] return " ".join(formula)
def reduced_formula(self): """ Returns a reduced formula string with appended charge. """ reduced_formula = super(Ion, self).reduced_formula charge = self._charge / self.get_reduced_composition_and_factor()[1] if charge > 0: if abs(charge) == 1: chg_str = "[+]" else: chg_str = "[" + formula_double_format(charge, False) + "+]" elif charge < 0: if abs(charge) == 1: chg_str = "[-]" else: chg_str = "[{}-]".format( formula_double_format(abs(charge), False)) else: chg_str = "(aq)" return reduced_formula + chg_str
def reduced_formula(self): """ Returns a reduced formula string with appended charge. """ reduced_formula = super(Ion, self).reduced_formula charge = self._charge / self.get_reduced_composition_and_factor()[1] if charge > 0: if abs(charge) == 1: chg_str = "[+]" else: chg_str = "[" + formula_double_format(charge, False) + "+]" elif charge < 0: if abs(charge) == 1: chg_str = "[-]" else: chg_str = "[{}-]".format(formula_double_format(abs(charge), False)) else: chg_str = "(aq)" return reduced_formula + chg_str
def convert(self, comp: Union[Dict, PMGComp]): elems_, nums_ = [], [] if isinstance(comp, PMGComp): sym_amt = comp.get_el_amt_dict() syms = sorted(sym_amt.keys(), key=lambda sym: get_el_sp(sym).X) comp = {s: formula_double_format(sym_amt[s], False) for s in syms} for e, n in comp.items(): elems_.append(e) nums_.append(n) return self.mix_function(elems_, nums_)
def reduce_formula(sym_amt, iupac_ordering=False): """ Helper method to reduce a sym_amt dict to a reduced formula and factor. Args: sym_amt (dict): {symbol: amount}. 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: (reduced_formula, factor). """ syms = sorted(sym_amt.keys(), key=lambda x: [get_el_sp(x).X, x]) syms = list(filter( lambda x: abs(sym_amt[x]) > Composition.amount_tolerance, syms)) factor = 1 # Enforce integers for doing gcd. if all((int(i) == i for i in sym_amt.values())): factor = abs(gcd(*(int(i) for i in sym_amt.values()))) polyanion = [] # if the composition contains a poly anion if len(syms) >= 3 and get_el_sp(syms[-1]).X - get_el_sp(syms[-2]).X < 1.65: poly_sym_amt = {syms[i]: sym_amt[syms[i]] / factor for i in [-2, -1]} (poly_form, poly_factor) = reduce_formula( poly_sym_amt, iupac_ordering=iupac_ordering) if poly_factor != 1: polyanion.append("({}){}".format(poly_form, int(poly_factor))) syms = syms[:len(syms) - 2 if polyanion else len(syms)] if iupac_ordering: syms = sorted(syms, key=lambda x: [get_el_sp(x).iupac_ordering, x]) reduced_form = [] for s in syms: normamt = sym_amt[s] * 1.0 / factor reduced_form.append(s) reduced_form.append(formula_double_format(normamt)) reduced_form = "".join(reduced_form + polyanion) return reduced_form, factor
def iupac_formula(self) -> str: """ Returns a formula string, with elements sorted by the iupac electronegativity ordering 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. Polyanions are still determined based on the true electronegativity of the elements. e.g. CH2(SO4)2 """ sym_amt = self.get_el_amt_dict() syms = sorted(sym_amt.keys(), key=lambda s: get_el_sp(s).iupac_ordering) formula = [s + formula_double_format(sym_amt[s], False) for s in syms] return " ".join(formula)
def _get_poly_formula( self, geometry: Dict[str, Any], nn_sites: List[Dict[str, Any]], nnn_sites: List[Dict[str, Any]], ) -> Optional[str]: """Gets the polyhedra formula of the nearest neighbor atoms. The polyhedral formula is effectively the sorted nearest neighbor atoms in a reduced format. For example, if the nearest neighbors are 3 I atoms, 2 Br atoms and 1 Cl atom, the polyhedral formula will be "I3Br2Cl". The polyhedral formula will be ``None`` if the site geometry is not in :data:`robocrys.util.connected_geometries`. Args: geometry: The site geometry as produced by :meth:`SiteAnalyzer.get_site_geometry`. nn_sites: The nearest neighbor sites as produced by :meth:`SiteAnalyzer.get_nearest_neighbors`. nnn_sites: The next nearest neighbor sites as produced by :meth:`SiteAnalyzer.get_next_nearest_neighbors`. Returns: The polyhedral formula if the site geometry is in :data:`robocrys.util.connected_geometries` else ``None``. """ def order_elements(el): if self.use_iupac_formula: return [get_el_sp(el).X, el] else: return [get_el_sp(el).iupac_ordering, el] nnn_geometries = [nnn_site["geometry"] for nnn_site in nnn_sites] poly_formula = None if geometry["type"] in connected_geometries and any([ nnn_geometry["type"] in connected_geometries for nnn_geometry in nnn_geometries ]): nn_els = [get_el(nn_site["element"]) for nn_site in nn_sites] comp = Composition("".join(nn_els)) el_amt_dict = comp.get_el_amt_dict() poly_formula = "" for e in sorted(el_amt_dict.keys(), key=order_elements): poly_formula += e poly_formula += formula_double_format(el_amt_dict[e]) return poly_formula
def iupac_formula(self): """ Returns a formula string, with elements sorted by the iupac electronegativity ordering 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. Polyanions are still determined based on the true electronegativity of the elements. e.g. CH2(SO4)2 """ sym_amt = self.get_el_amt_dict() syms = sorted(sym_amt.keys(), key=lambda s: get_el_sp(s).iupac_ordering) formula = [s + formula_double_format(sym_amt[s], False) for s in syms] return " ".join(formula)
def reduce_formula(sym_amt): """ Helper method to reduce a sym_amt dict to a reduced formula and factor. Args: sym_amt (dict): {symbol: amount}. Returns: (reduced_formula, factor). """ syms = sorted(sym_amt.keys(), key=lambda s: get_el_sp(s).X) syms = list( filter(lambda s: abs(sym_amt[s]) > Composition.amount_tolerance, syms)) num_el = len(syms) contains_polyanion = ( num_el >= 3 and get_el_sp(syms[num_el - 1]).X - get_el_sp(syms[num_el - 2]).X < 1.65) factor = 1 # Enforce integers for doing gcd. if all((int(i) == i for i in sym_amt.values())): factor = abs(gcd(*(int(i) for i in sym_amt.values()))) reduced_form = [] n = num_el - 2 if contains_polyanion else num_el for i in range(0, n): s = syms[i] normamt = sym_amt[s] * 1.0 / factor reduced_form.append(s) reduced_form.append(formula_double_format(normamt)) if contains_polyanion: poly_sym_amt = { syms[i]: sym_amt[syms[i]] / factor for i in range(n, num_el) } (poly_form, poly_factor) = reduce_formula(poly_sym_amt) if poly_factor != 1: reduced_form.append("({}){}".format(poly_form, int(poly_factor))) else: reduced_form.append(poly_form) reduced_form = "".join(reduced_form) return reduced_form, factor
def reduce_formula(sym_amt): """ Helper method to reduce a sym_amt dict to a reduced formula and factor. Args: sym_amt (dict): {symbol: amount}. Returns: (reduced_formula, factor). """ syms = sorted(sym_amt.keys(), key=lambda s: [get_el_sp(s).X, s]) syms = list(filter(lambda s: abs(sym_amt[s]) > Composition.amount_tolerance, syms)) num_el = len(syms) contains_polyanion = (num_el >= 3 and get_el_sp(syms[num_el - 1]).X - get_el_sp(syms[num_el - 2]).X < 1.65) factor = 1 # Enforce integers for doing gcd. if all((int(i) == i for i in sym_amt.values())): factor = abs(gcd(*(int(i) for i in sym_amt.values()))) reduced_form = [] n = num_el - 2 if contains_polyanion else num_el for i in range(0, n): s = syms[i] normamt = sym_amt[s] * 1.0 / factor reduced_form.append(s) reduced_form.append(formula_double_format(normamt)) if contains_polyanion: poly_sym_amt = {syms[i]: sym_amt[syms[i]] / factor for i in range(n, num_el)} (poly_form, poly_factor) = reduce_formula(poly_sym_amt) if poly_factor != 1: reduced_form.append("({}){}".format(poly_form, int(poly_factor))) else: reduced_form.append(poly_form) reduced_form = "".join(reduced_form) return reduced_form, factor
def hill_formula(self) -> str: """ :return: Hill formula. The Hill system (or Hill notation) is a system of writing empirical chemical formulas, molecular chemical formulas and components of a condensed formula such that the number of carbon atoms in a molecule is indicated first, the number of hydrogen atoms next, and then the number of all other chemical elements subsequently, in alphabetical order of the chemical symbols. When the formula contains no carbon, all the elements, including hydrogen, are listed alphabetically. """ c = self.element_composition elements = sorted(el.symbol for el in c.keys()) if "C" in elements: elements = ["C"] + [el for el in elements if el != "C"] formula = ["{}{}".format(el, formula_double_format(c[el]) if c[el] != 1 else "") for el in elements] return " ".join(formula)
for i in tqdm(list_name): try: a = json.read_json(i, orient='index', typ='series') cif_str = a["Structure_rlx"] del a["Structure_rlx"] POSCAR = Poscar.from_string(cif_str) ele_den = POSCAR.structure.composition.total_electrons / POSCAR.structure.volume composition_mp = POSCAR.structure.composition ncom = POSCAR.structure.composition.to_data_dict[ 'unit_cell_composition'].values() sym_amt = composition_mp.get_el_amt_dict() syms = sorted(sym_amt.keys(), key=lambda sym: get_el_sp(sym).X) formula = {s: formula_double_format(sym_amt[s], False) for s in syms} departElementProPFeature = DepartElementFeaturizer( elem_data=elemen, n_composition=len(ncom), n_jobs=1, return_type='df') departElement = departElementProPFeature.fit_transform([formula]) ncom = {"ncom" + "_" + str(n): j for n, j in enumerate(ncom)} for k, v in ncom.items(): departElement[k] = v a = pd.DataFrame(a) c = pd.DataFrame(departElement.values.T, index=departElement.columns,
def test_formula_double_format(self): self.assertEqual(formula_double_format(1.00), "") self.assertEqual(formula_double_format(2.00), "2") self.assertEqual(formula_double_format(2.10), "2.1") self.assertEqual(formula_double_format(2.10000000002), "2.1")
def __str__(self): return " ".join([ "{}{}".format(k, formula_double_format(v, ignore_ones=False)) for k, v in self.as_dict().items()])
def __str__(self): return " ".join([ "{}{}".format(k, formula_double_format(v, ignore_ones=False)) for k, v in self.as_dict().items() ])
def get_formula_from_components(components: List[Component], molecules_first: bool = False, use_iupac_formula: bool = True, use_common_formulas: bool = True) -> str: """Reconstructs a chemical formula from structure components. The chemical formulas for the individual components will be grouped together. If two components share the same composition, they will be treated as equivalent. Args: components: A list of structure components, generated using :obj:`pymatgen.analysis.dimensionality.get_structure_components`. molecules_first: Whether to put any molecules (zero-dimensional components) at the beginning of the formula. use_iupac_formula (bool, optional): Whether to order formulas 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. If set to ``False``, the elements will be ordered according to the electronegativity values. use_common_formulas: Whether to use the database of common formulas. The common formula will be used preferentially to the iupac or reduced formula. Returns: The chemical formula. """ def order(comp_formula): composition = Composition(comp_formula) if use_iupac_formula: return (sum( [get_el_sp(s).iupac_ordering for s in composition.elements]) / len(composition.elements)) else: return composition.average_electroneg components = get_formula_inequiv_components( components, use_iupac_formula=use_iupac_formula, use_common_formulas=use_common_formulas) if molecules_first: mol_comps, other_comps = filter_molecular_components(components) else: mol_comps = [] other_comps = components formulas = (sorted([c['formula'] for c in mol_comps], key=order) + sorted([c['formula'] for c in other_comps], key=order)) # if components include special formulas, then the count can be 0.5 # therefore if any non integer amounts we can just use a factor of 2 all_int = all(v['count'] % 1 == 0 for v in components) prefactor = 1 if all_int else 2 form_count_dict = { c['formula']: int(c['count'] * prefactor) for c in components } # the following is based on ``pymatgen.core.composition.reduce_formula`` num_comps = len(formulas) factor = abs(gcd(*(form_count_dict.values()))) reduced_form = [] for i in range(0, num_comps): formula = formulas[i] normamt = form_count_dict[formula] * 1.0 / factor formatted_formula = formula if normamt == 1 else "({})".format(formula) reduced_form.append(formatted_formula) reduced_form.append(formula_double_format(normamt)) reduced_form = "".join(reduced_form) return reduced_form