Пример #1
0
 def test_init_empty_phaselist(self, empty_input):
     pl = PhaseList(empty_input)
     assert repr(pl) == "No phases."
     pl.add(Phase("al", point_group="m-3m"))
     assert repr(pl) == (
         "Id  Name  Space group  Point group  Proper point group     Color\n"
         " 0    al         None         m-3m                 432  tab:blue")
Пример #2
0
 def test_add_to_phaselist_raises(self):
     """Trying to add a Phase with a name already in the PhaseList
     raises a ValueError.
     """
     pl = PhaseList(names=["a"])
     with pytest.raises(ValueError, match="'a' is already in the phase list"):
         pl.add(Phase("a"))
Пример #3
0
    def test_init_with_single_structure(self):
        structure = Structure()
        names = ["a", "b"]
        pl = PhaseList(names=names, structures=structure)

        assert pl.names == names
        assert pl.structures == [structure] * 2
Пример #4
0
    def test_get_phaselist_size(self, n_names):
        phase_names_pool = "abcd"
        phase_names = [phase_names_pool[i] for i in range(n_names)]

        pl = PhaseList(names=phase_names)

        assert pl.size == n_names
Пример #5
0
    def test_init_with_too_many_phases(
        self, crystal_map_input, phase_names, phase_ids, desired_phase_names
    ):
        """More phases than phase IDs."""
        phase_list = PhaseList(names=phase_names, ids=phase_ids)
        xmap = CrystalMap(phase_list=phase_list, **crystal_map_input)

        assert xmap.phases.names == desired_phase_names
Пример #6
0
    def test_init_phaselist_from_phase(self):
        p = Phase(name="austenite", point_group="432", color="C2")
        pl = PhaseList(p)

        assert pl.names == [p.name]
        assert pl.point_groups == [p.point_group]
        assert pl.space_groups == [p.space_group]
        assert pl.colors == [p.color]
        assert pl.colors_rgb == [p.color_rgb]
Пример #7
0
    def test_add_phaselist_to_phaselist(self):
        """Add a PhaseList to a PhaseList, also ensuring that new IDs are
        given.
        """
        names = ["a", "b"]
        sg_no = [10, 20]
        pl1 = PhaseList(names=names, space_groups=sg_no)
        assert pl1.ids == [0, 1]

        names2 = ["c", "d"]
        sg_no2 = [30, 40]
        ids = [4, 5]
        pl2 = PhaseList(names=names2, space_groups=sg_no2, ids=ids)
        pl1.add(pl2)
        assert pl1.names == names + names2
        assert pl1.space_groups == ([GetSpaceGroup(i) for i in sg_no] +
                                    [GetSpaceGroup(i) for i in sg_no2])
        assert pl1.ids == [0, 1, 2, 3]
Пример #8
0
    def test_get_phaselist_ids(self, n_names, phase_ids, desired_names,
                               desired_phase_ids):
        phase_names_pool = "abc"
        phase_names = [phase_names_pool[i] for i in range(n_names)]

        pl = PhaseList(names=phase_names, ids=phase_ids)

        assert pl.names == desired_names
        assert pl.ids == desired_phase_ids
Пример #9
0
 def test_add_phase_in_empty_phaselist(self):
     """Add Phase to empty PhaseList."""
     sg_no = 10
     name = "a"
     pl = PhaseList()
     pl.add(Phase(name, space_group=sg_no))
     assert pl.ids == [0]
     assert pl.names == [name]
     assert pl.space_groups == [GetSpaceGroup(sg_no)]
     assert pl.structures == [Structure()]
Пример #10
0
    def test_init_set_to_nones(self):
        phase_ids = [1, 2]
        pl = PhaseList(ids=phase_ids)

        assert pl.ids == phase_ids
        assert pl.names == [""] * 2
        assert pl.point_groups == [None] * 2
        assert pl.space_groups == [None] * 2
        assert pl.colors == ["tab:blue", "tab:orange"]
        assert pl.structures == [Structure()] * 2
Пример #11
0
    def test_orientations_symmetry(self, point_group, rotation, expected_orientation):
        r = Rotation(rotation)
        cm = CrystalMap(rotations=r, phase_id=np.array([0]))
        cm.phases = PhaseList(Phase("a", point_group=point_group))

        o = cm.orientations

        assert np.allclose(
            o.data, Orientation(r).set_symmetry(point_group).data, atol=1e-3
        )
        assert np.allclose(o.data, expected_orientation, atol=1e-3)
Пример #12
0
def phase_list(request):
    names, space_groups, point_group_names, colors, lattices, atoms = request.param
    # Apparently diffpy.structure don't allow iteration over a list of lattices
    structures = [Structure(lattice=lattices[i], atoms=a) for i, a in enumerate(atoms)]
    return PhaseList(
        names=names,
        space_groups=space_groups,
        point_groups=point_group_names,
        colors=colors,
        structures=structures,
    )
Пример #13
0
    def test_make_not_indexed(self):
        phase_names = ["a", "b", "c"]
        phase_colors = ["r", "g", "b"]
        pl = PhaseList(names=phase_names, colors=phase_colors, ids=[-1, 0, 1])

        assert pl.names == phase_names
        assert pl.colors == phase_colors

        pl.add_not_indexed()

        phase_names[0] = "not_indexed"
        phase_colors[0] = "w"
        assert pl.names == phase_names
        assert pl.colors == phase_colors
Пример #14
0
    def phases_in_data(self):
        """List of phases in data.

        Needed because it can be useful to have phases not in data but in
        `self.phases`.
        """
        unique_ids = np.unique(self.phase_id)
        phase_list = self.phases[np.intersect1d(unique_ids, self.phases.ids)]
        if isinstance(phase_list, Phase):  # One phase in data
            # Get phase ID so it carries over to the new `PhaseList` object
            phase = phase_list  # Since it's actually a single phase
            phase_id = self.phases.id_from_name(phase.name)
            return PhaseList(phases=phase, ids=phase_id)
        else:  # Multiple phases in data
            return phase_list
Пример #15
0
    def test_init_phaselist_from_phases(self, phase_collection):
        p1 = Phase(name="austenite", point_group=432, color=None)
        p2 = Phase(name="ferrite", point_group="432", color="C1")
        if phase_collection == "dict":
            phases = {1: p1, 2: p2}
        else:  # phase_collection == "list":
            phases = [p1, p2]

        pl = PhaseList(phases)

        assert pl.names == [p.name for p in [p1, p2]]
        assert pl.point_groups == [p.point_group for p in [p1, p2]]
        assert pl.space_groups == [p.space_group for p in [p1, p2]]
        assert pl.colors == [p.color for p in [p1, p2]]
        assert pl.colors_rgb == [p.color_rgb for p in [p1, p2]]
Пример #16
0
    def test_init_with_phase_list(self, crystal_map_input):
        point_groups = [C2, C3, C4]
        phase_list = PhaseList(point_groups=point_groups)
        cm = CrystalMap(phase_list=phase_list, **crystal_map_input)

        n_point_groups = len(point_groups)
        n_phase_ids = len(cm.phases.ids)
        n_different = n_point_groups - n_phase_ids
        if n_different < 0:
            point_groups += [None] * abs(n_different)
        assert [
            cm.phases.point_groups[i] == point_groups[i] for i in range(n_phase_ids)
        ]

        unique_phase_ids = list(np.unique(crystal_map_input["phase_id"]).astype(int))
        assert cm.phases.ids == unique_phase_ids
Пример #17
0
    def test_add_list_phases_to_phaselist(self):
        """Add a list of Phase objects to PhaseList, also ensuring that
        unique colors are given.
        """
        names = ["a", "b"]
        sg_no = [10, 20]
        colors = ["tab:blue", "tab:orange"]
        pl = PhaseList(names=names, space_groups=sg_no)
        assert pl.colors == colors

        new_names = ["c", "d"]
        new_sg_no = [30, 40]
        pl.add([Phase(name=n, space_group=i) for n, i in zip(new_names, new_sg_no)])
        assert pl.names == names + new_names
        assert pl.space_groups == (
            [GetSpaceGroup(i) for i in sg_no] + [GetSpaceGroup(i) for i in new_sg_no]
        )
        assert pl.colors == colors + ["tab:green", "tab:red"]
Пример #18
0
    def test_iterate_phaselist(self):
        names = ["al", "ni", "sigma"]
        point_groups = [3, 432, "m-3m"]
        colors = ["g", "b", "r"]
        structures = [
            Structure(),
            Structure(lattice=Lattice(1, 2, 3, 90, 90, 90)),
            Structure(),
        ]

        pl = PhaseList(
            names=names, point_groups=point_groups, colors=colors, structures=structures
        )

        for i, ((phase_id, phase), n, s, c, structure) in enumerate(
            zip(pl, names, point_groups, colors, structures)
        ):
            assert phase_id == i
            assert phase.name == n
            assert phase.point_group.name == str(s)
            assert phase.color == c
            assert phase.structure == structure
Пример #19
0
    def test_init_phaselist_from_strings(
        self,
        names,
        space_groups,
        point_groups,
        colors,
        phase_ids,
        desired_names,
        desired_space_groups,
        desired_point_groups,
        desired_colors,
        desired_phase_ids,
    ):
        pl = PhaseList(
            names=names,
            space_groups=space_groups,
            point_groups=point_groups,
            colors=colors,
            ids=phase_ids,
        )

        actual_point_group_names = []
        actual_space_group_names = []
        for _, p in pl:
            if p.point_group is None:
                actual_point_group_names.append(None)
            else:
                actual_point_group_names.append(p.point_group.name)
            if p.space_group is None:
                actual_space_group_names.append(None)
            else:
                actual_space_group_names.append(p.space_group.short_name)

        assert pl.names == desired_names
        assert actual_space_group_names == desired_space_groups
        assert actual_point_group_names == desired_point_groups
        assert pl.colors == desired_colors
        assert pl.ids == desired_phase_ids
Пример #20
0
    def test_phase_legend(self, crystal_map, phase_names, phase_colors,
                          legend_properties):
        cm = crystal_map
        cm[0, 0].phase_id = 1
        cm.phases = PhaseList(names=phase_names,
                              point_groups=[3, 3],
                              colors=phase_colors)

        fig = plt.figure()
        ax = fig.add_subplot(projection=PLOT_MAP)
        _ = ax.plot_map(cm, legend_properties=legend_properties)

        legend = ax.legend_

        assert legend._fontsize == 11.0
        assert [i._text for i in legend.texts] == phase_names

        frame_alpha = legend_properties.pop("framealpha", 0.6)
        assert legend.get_frame().get_alpha() == frame_alpha

        for k, v in legend_properties.items():
            assert legend.__getattribute__(k) == v

        plt.close("all")
Пример #21
0
 def test_init_with_single_point_group(self, crystal_map_input):
     point_group = O
     phase_list = PhaseList(point_groups=point_group)
     cm = CrystalMap(phase_list=phase_list, **crystal_map_input)
     assert np.allclose(cm.phases.point_groups[0].data, point_group.data)
Пример #22
0
 def test_get_item_not_indexed(self, phase_slice):
     ids = np.arange(-1, 9)  # [-1, 0, 1, 2, ...]
     pl = PhaseList(ids=ids)  # [-1, 0, 1, 2, ...]
     pl.add_not_indexed()  # [-1, 0, 1, 2, ...]
     assert np.allclose(pl[phase_slice].ids, ids[phase_slice])
Пример #23
0
    def __init__(
        self,
        rotations,
        phase_id=None,
        x=None,
        y=None,
        z=None,
        phase_list=None,
        prop=None,
        scan_unit=None,
        is_in_data=None,
    ):
        """
        Parameters
        ----------
        rotations : orix.quaternion.rotation.Rotation
            Rotation of each data point. Must be passed with all spatial
            dimensions in the first array axis (flattened). May contain
            multiple rotations per point, included in the second array
            axes. Crystal map data size is set equal to the first array
            axis' size.
        phase_id : numpy.ndarray, optional
            Phase ID of each pixel. IDs equal to -1 are considered not
            indexed. If None is passed (default), all points are
            considered to belong to one phase with ID 0.
        x : numpy.ndarray, optional
            Map x coordinate of each data point. If None is passed,
            the map is assumed to be 1D, and it is set to an array of
            increasing integers from 0 to the length of the `phase_id`
            array.
        y : numpy.ndarray, optional
            Map y coordinate of each data point. If None is passed,
            the map is assumed to be 1D, and it is set to None.
        z : numpy.ndarray, optional
            Map z coordinate of each data point. If None is passed, the
            map is assumed to be 2D or 1D, and it is set to None.
        phase_list : PhaseList, optional
            A list of phases in the data with their with names,
            space groups, point groups, and structures. The order in which
            the phases appear in the list is important, as it is this, and
            not the phases' IDs, that is used to link the phases to the
            input `phase_id` if the IDs aren't exactly the same as in
            `phase_id`. If None (default), a phase list with as many
            phases as there are unique phase IDs in `phase_id` is created.
        prop : dict of numpy.ndarray, optional
            Dictionary of properties of each data point.
        scan_unit : str, optional
            Length unit of the data. If None (default), "px" is used.
        is_in_data : np.ndarray, optional
            Array of booleans signifying whether a point is in the data.

        Examples
        --------
        >>> from diffpy.structure import Atom, Lattice, Structure
        >>> import numpy as np
        >>> from orix.crystal_map import CrystalMap
        >>> from orix.quaternion.rotation import Rotation
        >>> euler1, euler2, euler3, x, y, iq, dp, phase_id = np.loadtxt(
        ...     "/some/file.ang", unpack=True)
        >>> euler_angles = np.column_stack((euler1, euler2, euler3))
        >>> rotations = Rotation.from_euler(euler_angles)
        >>> properties = {"iq": iq, "dp": dp}
        >>> structures = [
        ...     Structure(
        ...         title="austenite",
        ...         atoms=[Atom("fe", [0] * 3)],
        ...         lattice=Lattice(0.360, 0.360, 0.360, 90, 90, 90)
        ...     ),
        ...     Structure(
        ...         title="ferrite",
        ...         atoms=[Atom("fe", [0] * 3)],
        ...         lattice=Lattice(0.287, 0.287, 0.287, 90, 90, 90)
        ...     )
        ... ]
        >>> pl = PhaseList(space_groups=[225, 229], structures=structures)
        >>> cm = CrystalMap(
        ...     rotations=rotations,
        ...     phase_id=phase_id,
        ...     x=x,
        ...     y=y,
        ...     phase_list=pl,
        ...     prop=properties,
        ... )
        """
        # Set rotations
        if not isinstance(rotations, Rotation):
            raise ValueError(
                f"rotations must be of type {Rotation}, not {type(rotations)}."
            )
        self._rotations = rotations

        # Set data size
        data_size = rotations.shape[0]

        # Set phase IDs
        if phase_id is None:  # Assume single phase data
            phase_id = np.zeros(data_size)
        phase_id = phase_id.astype(int)
        self._phase_id = phase_id

        # Set data point IDs
        point_id = np.arange(data_size)
        self._id = point_id

        # Set spatial coordinates
        if x is None and y is None and z is None:
            x = np.arange(data_size)
        self._x = x
        self._y = y
        self._z = z

        # Create phase list
        # Sorted in ascending order
        unique_phase_ids = np.unique(phase_id)
        include_not_indexed = False
        if unique_phase_ids[0] == -1:
            include_not_indexed = True
            unique_phase_ids = unique_phase_ids[1:]
        # Also sorted in ascending order
        if phase_list is None:
            self.phases = PhaseList(ids=unique_phase_ids)
        else:
            phase_list = copy.deepcopy(phase_list)
            phase_ids = phase_list.ids
            n_different = len(phase_ids) - len(unique_phase_ids)
            if n_different > 0:
                # Remove superfluous phases by removing the phases whose
                # ID is not in the ID array, in descending list order
                for i in phase_ids[::-1]:
                    if i not in unique_phase_ids:
                        del phase_list[i]
                        n_different -= 1
                    if n_different == 0:
                        break
            elif n_different < 0:
                # Create new phase list adding the missing phases with
                # default initial values
                phase_list = PhaseList(
                    names=phase_list.names,
                    space_groups=phase_list.space_groups,
                    point_groups=phase_list.point_groups,
                    colors=phase_list.colors,
                    structures=phase_list.structures,
                    ids=unique_phase_ids,
                )
            # Ensure phase list IDs correspond to IDs in phase_id array
            new_ids = list(unique_phase_ids.astype(int))
            phase_list._dict = dict(zip(new_ids, phase_list._dict.values()))
            self.phases = phase_list

        # Set whether measurements are indexed
        is_indexed = np.ones(data_size, dtype=bool)
        is_indexed[np.where(phase_id == -1)] = False

        # Add "not_indexed" to phase list and ensure not indexed points
        # have correct phase ID
        if include_not_indexed:
            self.phases.add_not_indexed()
            self._phase_id[~is_indexed] = -1

        # Set array with True for points in data
        if is_in_data is None:
            is_in_data = np.ones(data_size, dtype=bool)
        self.is_in_data = is_in_data

        # Set scan unit
        if scan_unit is None:
            scan_unit = "px"
        self.scan_unit = scan_unit

        # Set properties
        if prop is None:
            prop = {}
        self._prop = CrystalMapProperties(prop, id=point_id)

        # Set original data shape (needed if data shape changes in
        # __getitem__())
        self._original_shape = self._data_shape_from_coordinates()
Пример #24
0
    def test_get_phaselist_colors_rgb(self):
        pl = PhaseList(names=["a", "b", "c"], colors=["r", "g", (0, 0, 1)])

        assert pl.colors == ["r", "g", "b"]
        assert np.allclose(pl.colors_rgb, [(1.0, 0.0, 0.0), [0, 0.5, 0], (0, 0, 1)])