コード例 #1
0
 def test_htmlify(self):
     self.assertEqual(
         htmlify("Li3Fe2(PO4)3"),
         "Li<sub>3</sub>Fe<sub>2</sub>(PO<sub>4</sub>)<sub>3</sub>",
     )
     self.assertEqual(htmlify("Li0.2Na0.8Cl"),
                      "Li<sub>0.2</sub>Na<sub>0.8</sub>Cl")
コード例 #2
0
    def _get_xaxis_title(self, latex: bool = True) -> str:
        """Returns the formatted title of the x axis (using either html/latex)"""
        if latex:
            f1 = latexify(self.c1.reduced_formula)
            f2 = latexify(self.c2.reduced_formula)
            title = f"$x$ in $x${f1} + $(1-x)${f2}"
        else:
            f1 = htmlify(self.c1.reduced_formula)
            f2 = htmlify(self.c2.reduced_formula)
            title = f"<i>x</i> in <i>x</i>{f1} + (1-<i>x</i>){f2}"

        return title
コード例 #3
0
 def _get_annotation(ann_loc: np.ndarray,
                     formula: str) -> Dict[str, Union[str, float]]:
     """Returns a Plotly annotation dict given a formula and location"""
     formula = htmlify(formula)
     annotation = plotly_layouts["default_annotation_layout"].copy()
     annotation.update({"x": ann_loc[0], "y": ann_loc[1], "text": formula})
     if len(ann_loc) == 3:
         annotation.update({"z": ann_loc[2]})
     return annotation
コード例 #4
0
 def _get_plotly_annotations(x: List[float], y: List[float], reactions: List[Reaction]):
     """Returns dictionary of annotations for the Plotly figure layout"""
     annotations = []
     for x_coord, y_coord, rxn in zip(x, y, reactions):
         products = ", ".join(
             [htmlify(p.reduced_formula) for p in rxn.products if not np.isclose(rxn.get_coeff(p), 0)]
         )
         annotation = dict(x=x_coord, y=y_coord, text=products, font=dict(size=18), ax=-25, ay=55)
         annotations.append(annotation)
     return annotations
コード例 #5
0
    def get_all_component_descriptions(self) -> str:
        """Gets the descriptions of all components in the structure.

        Returns:
            A description of all components in the structure.
        """
        if len(self._da.components) == 1:
            return self.get_component_description(
                self._da.get_component_groups()[0].components[0].index,
                single_component=True,
            )

        else:
            component_groups = self._da.get_component_groups()

            component_descriptions = []
            for group in component_groups:
                for component in group.components:

                    if group.molecule_name:
                        # don't describe known molecules
                        continue

                    formula = group.formula
                    group_count = group.count
                    component_count = component.count
                    shape = dimensionality_to_shape[group.dimensionality]

                    if self.fmt == "latex":
                        formula = latexify(formula)
                    elif self.fmt == "unicode":
                        formula = unicodeify(formula)
                    elif self.fmt == "html":
                        formula = htmlify(formula)

                    if group_count == component_count:
                        s_filler = "the" if group_count == 1 else "each"
                    else:
                        s_filler = "{} of the".format(
                            en.number_to_words(component_count)
                        )
                        shape = en.plural(shape)

                    desc = f"In {s_filler} {formula} {shape}, "
                    desc += self.get_component_description(component.index)

                    component_descriptions.append(desc)

            return " ".join(component_descriptions)
コード例 #6
0
    def get_mineral_description(self) -> str:
        """Gets the mineral name and space group description.

        If the structure is a perfect match for a known prototype (e.g.
        the distance parameter is -1, the mineral name is the prototype name.
        If a structure is not a perfect match but similar to a known mineral,
        "-like" will be added to the mineral name. If the structure is a good
        match to a mineral but contains a different number of element types than
        the mineral prototype, "-derived" will be added to the mineral name.

        Returns:
            The description of the mineral name.
        """
        spg_symbol = self._da.spg_symbol
        formula = self._da.formula
        if self.fmt == "latex":
            spg_symbol = latexify_spacegroup(self._da.spg_symbol)
            formula = latexify(formula)

        elif self.fmt == "unicode":
            spg_symbol = unicodeify_spacegroup(self._da.spg_symbol)
            formula = unicodeify(formula)

        elif self.fmt == "html":
            spg_symbol = htmlify_spacegroup(self._da.spg_symbol)
            formula = htmlify(formula)

        mineral_name = get_mineral_name(self._da.mineral)

        if mineral_name:
            desc = f"{formula} is {mineral_name} structured and"
        else:
            desc = f"{formula}"

        desc += " crystallizes in the {} {} space group.".format(
            self._da.crystal_system, spg_symbol
        )
        return desc
コード例 #7
0
    def _get_poly_site_description(self, site_index: int):
        """Gets a description of a connected polyhedral site.

        If the site likeness (order parameter) is less than ``distorted_tol``,
        "distorted" will be added to the geometry description.

        Args:
            site_index: An inequivalent site index.

        Returns:
            A description the a polyhedral site, including connectivity.
        """
        site = self._da.sites[site_index]
        nnn_details = self._da.get_next_nearest_neighbor_details(
            site_index, group=not self.describe_symmetry_labels
        )

        from_element = get_formatted_el(
            site["element"],
            self._da.sym_labels[site_index],
            use_oxi_state=self.describe_oxidation_state,
            use_sym_label=self.describe_symmetry_labels,
            fmt=self.fmt,
        )

        from_poly_formula = site["poly_formula"]
        if self.fmt == "latex":
            from_poly_formula = latexify(from_poly_formula)
        elif self.fmt == "unicode":
            from_poly_formula = unicodeify(from_poly_formula)
        elif self.fmt == "html":
            from_poly_formula = htmlify(from_poly_formula)

        s_from_poly_formula = get_el(site["element"]) + from_poly_formula

        if site["geometry"]["likeness"] < self.distorted_tol:
            s_distorted = "distorted "
        else:
            s_distorted = ""
        s_polyhedra = geometry_to_polyhedra[site["geometry"]["type"]]
        s_polyhedra = polyhedra_plurals[s_polyhedra]

        nn_desc = self._get_nearest_neighbor_description(site_index)
        desc = f"{from_element} is bonded to {nn_desc} to form "

        # handle the case we were are connected to the same type of polyhedra
        if (
            nnn_details[0].element == site["element"]
            and len(
                {(nnn_site.element, nnn_site.poly_formula) for nnn_site in nnn_details}
            )
        ) == 1:
            connectivities = list({nnn_site.connectivity for nnn_site in nnn_details})
            s_mixture = "a mixture of " if len(connectivities) != 1 else ""
            s_connectivities = en.join(connectivities)

            desc += "{}{}{}-sharing {} {}".format(
                s_mixture,
                s_distorted,
                s_connectivities,
                s_from_poly_formula,
                s_polyhedra,
            )
            return desc

        # otherwise loop through nnn connectivities and describe individually
        desc += "{}{} {} that share ".format(
            s_distorted, s_from_poly_formula, s_polyhedra
        )
        nnn_descriptions = []
        for nnn_site in nnn_details:
            to_element = get_formatted_el(
                nnn_site.element,
                nnn_site.sym_label,
                use_oxi_state=False,
                use_sym_label=self.describe_symmetry_labels,
            )

            to_poly_formula = nnn_site.poly_formula
            if self.fmt == "latex":
                to_poly_formula = latexify(to_poly_formula)
            elif self.fmt == "unicode":
                to_poly_formula = unicodeify(to_poly_formula)
            elif self.fmt == "html":
                to_poly_formula = htmlify(to_poly_formula)

            to_poly_formula = to_element + to_poly_formula
            to_shape = geometry_to_polyhedra[nnn_site.geometry]

            if len(nnn_site.sites) == 1 and nnn_site.count != 1:
                s_equivalent = " equivalent "
            else:
                s_equivalent = " "

            if nnn_site.count == 1:
                s_an = f" {en.an(nnn_site.connectivity)}"
            else:
                s_an = ""
                to_shape = polyhedra_plurals[to_shape]

            nnn_descriptions.append(
                "{}{} with {}{}{} {}".format(
                    s_an,
                    en.plural(nnn_site.connectivity, nnn_site.count),
                    en.number_to_words(nnn_site.count),
                    s_equivalent,
                    to_poly_formula,
                    to_shape,
                )
            )

        return desc + en.join(nnn_descriptions)
コード例 #8
0
    def get_component_makeup_summary(self) -> str:
        """Gets a summary of the makeup of components in a structure.

        Returns:
            A description of the number of components and their dimensionalities
            and orientations.
        """
        component_groups = self._da.get_component_groups()

        if (
            len(component_groups) == 1
            and component_groups[0].count == 1
            and component_groups[0].dimensionality == 3
        ):
            desc = ""

        else:
            if self._da.dimensionality == 3:
                desc = "The structure consists of "
            else:
                desc = "The structure is {}-dimensional and consists of " "".format(
                    en.number_to_words(self._da.dimensionality)
                )

            component_makeup_summaries = []
            nframeworks = len(
                [
                    c
                    for g in component_groups
                    for c in g.components
                    if c.dimensionality == 3
                ]
            )
            for component_group in component_groups:
                if nframeworks == 1 and component_group.dimensionality == 3:
                    s_count = "a"
                else:
                    s_count = en.number_to_words(component_group.count)

                dimensionality = component_group.dimensionality

                if component_group.molecule_name:
                    if component_group.nsites == 1:
                        shape = "atom"
                    else:
                        shape = "molecule"
                    shape = en.plural(shape, s_count)
                    formula = component_group.molecule_name
                else:
                    shape = en.plural(dimensionality_to_shape[dimensionality], s_count)
                    formula = component_group.formula

                if self.fmt == "latex":
                    formula = latexify(formula)
                elif self.fmt == "unicode":
                    formula = unicodeify(formula)
                    print(formula)
                elif self.fmt == "html":
                    formula = htmlify(formula)

                comp_desc = f"{s_count} {formula} {shape}"

                if component_group.dimensionality in [1, 2]:
                    orientations = list(
                        {c.orientation for c in component_group.components}
                    )
                    s_direction = en.plural("direction", len(orientations))
                    comp_desc += " oriented in the {} {}".format(
                        en.join(orientations), s_direction
                    )

                component_makeup_summaries.append(comp_desc)

            if nframeworks == 1 and len(component_makeup_summaries) > 1:
                # when there is a single framework, make the description read
                # "... and 8 Sn atoms inside a SnO2 framework" instead of
                # "..., 8 Sn atoms and one SnO2 framework"
                # This works because the component summaries are sorted by
                # dimensionality
                desc += en.join(component_makeup_summaries[:-1])
                desc += f" inside {component_makeup_summaries[-1]}."
            else:
                desc += en.join(component_makeup_summaries) + "."
        return desc
コード例 #9
0
ファイル: test_string_utils.py プロジェクト: ExpHP/pymatgen
 def test_htmlify(self):
     self.assertEqual(htmlify("Li3Fe2(PO4)3"),
                      "Li<sub>3</sub>Fe<sub>2</sub>(PO<sub>4</sub>)<sub>3</sub>")
     self.assertEqual(htmlify("Li0.2Na0.8Cl"),
                      "Li<sub>0.2</sub>Na<sub>0.8</sub>Cl")