Exemple #1
0
 def test_rotate_tsl2bruker(self, r_tsl2bruker):
     s_tilt = 70
     d_tilt = 10
     r_tsl_matrix = detector2sample(sample_tilt=s_tilt, detector_tilt=d_tilt)
     r_tsl = Rotation.from_matrix(r_tsl_matrix)
     r_bruker_matrix = detector2sample(
         sample_tilt=s_tilt, detector_tilt=d_tilt, convention="bruker"
     )
     r_bruker = Rotation.from_matrix(r_bruker_matrix)
     assert np.allclose((~r_tsl2bruker * r_tsl).data, r_bruker.data)
    def test_passing_results_from_get_patterns(self):
        s = nickel_ebsd_small()
        print(s)
        s.remove_static_background()
        s.remove_dynamic_background()

        mp = nickel_ebsd_master_pattern_small(projection="lambert")
        r = Rotation([
            [0.9522, -0.0151, -0.2883, 0.1001],  # Left grain
            [0.9534, 0.0465, -0.2187, -0.2026],  # Right grain
            [0.8876, -0.2312, 0.3364, -0.2131],  # 50th best match
        ])
        detector = EBSDDetector(
            shape=s.axes_manager.signal_shape[::-1],
            pc=[0.421, 0.7794, 0.5049],
            convention="tsl",
            sample_tilt=70,
        )
        sim = mp.get_patterns(rotations=r, detector=detector, energy=20)

        xmap = s.match_patterns(sim, keep_n=1)
        scores = xmap.scores.reshape(xmap.size, )
        sim_idx = xmap.simulation_indices.reshape(xmap.size, )

        assert np.allclose(
            scores,
            [0.197, 0.188, 0.207, 0.198, 0.186, 0.225, 0.191, 0.191, 0.206],
            atol=1e-3,
        )
        assert np.allclose(sim_idx, [0, 1, 1, 0, 1, 1, 0, 1, 1])
Exemple #3
0
    def test_get_item(
        self,
        nickel_ebsd_simulation_generator,
        nav_idx,
        desired_shape,
        desired_pc,
        desired_rotation,
    ):
        """Desired PC and rotation values from __getitem__()."""
        simgen = nickel_ebsd_simulation_generator
        simgen.navigation_shape = (5, 5)
        simgen.detector.pc[nav_idx] = desired_pc
        r = Rotation.from_euler(desired_rotation)
        simgen.rotations[nav_idx] = r

        simgen2 = simgen[nav_idx]
        assert simgen2.navigation_shape == desired_shape
        assert np.allclose(simgen2.detector.pc, desired_pc)
        assert np.allclose(simgen2.rotations.data, r.data)

        new_pc = [
            0.5,
        ] * 3
        simgen2.detector.pc[0] = new_pc
        assert not np.allclose(simgen[nav_idx].detector.pc,
                               simgen2.detector.pc)
Exemple #4
0
    def to_crystal_map(self):
        """
        Exports an indexation result with multiple results per navigation position to
        crystal map with one result per pixel

        Returns
        -------
        orix.CrystalMap
        """
        _s = self.data.map(_get_best_match,inplace=False)

        """ Gets properties """
        phase_id = _s.isig[0].data.flatten()
        alpha = _s.isig[1].data.flatten()
        beta = _s.isig[2].data.flatten()
        gamma = _s.isig[3].data.flatten()
        score = _s.isig[4].data.flatten()

        """ Gets navigation placements """
        xy = np.indices(_s.data.shape[:2])
        x = xy[1].flatten()
        y = xy[0].flatten()

        """ Tidies up so we can put these things into CrystalMap """
        euler = np.vstack((alpha,beta,gamma)).T
        rotations = Rotation.from_euler(euler,convention="bunge", direction="crystal2lab")
        properties = {"score":score}


        return CrystalMap(
                rotations=rotations,
                phase_id=phase_id,
                x=x,
                y=y,
                prop=properties)
Exemple #5
0
    def test_detector_azimuthal(self):
        """Test that setting an azimuthal angle of a detector results in
        different patterns.
        """
        det1 = self.detector

        # Looking from the detector toward the sample, the left part of
        # the detector is closer to the sample than the right part
        det2 = det1.deepcopy()
        det2.azimuthal = 10

        # Looking from the detector toward the sample, the right part of
        # the detector is closer to the sample than the left part
        det3 = det1.deepcopy()
        det3.azimuthal = -10

        mp = nickel_ebsd_master_pattern_small(projection="lambert")
        r = Rotation.identity()

        kwargs = dict(rotations=r, energy=20, compute=True, dtype_out=np.uint8)
        sim1 = mp.get_patterns(detector=det1, **kwargs)
        sim2 = mp.get_patterns(detector=det2, **kwargs)
        sim3 = mp.get_patterns(detector=det3, **kwargs)

        assert not np.allclose(sim1.data, sim2.data)
        assert np.allclose(sim2.data.mean(), 43.56, atol=1e-2)
        assert np.allclose(sim3.data.mean(), 43.39, atol=1e-2)
Exemple #6
0
 def test_get_patterns_navigation_shape_raises(self):
     mp = nickel_ebsd_master_pattern_small(projection="lambert")
     r = Rotation(np.random.uniform(low=0, high=1, size=(1, 2, 3, 4)))
     detector = kp.detectors.EBSDDetector(shape=(60, 60))
     with pytest.raises(ValueError,
                        match="`rotations` can only have one or two "):
         _ = mp.get_patterns(rotations=r, detector=detector, energy=20)
Exemple #7
0
    def rotate(self, axis=None, angle=0):
        """Convenience function for rotating this vector.

        Shapes of 'axis' and 'angle' must be compatible with shape of this
        vector for broadcasting.

        Parameters
        ----------
        axis : Vector3d or array_like, optional
            The axis of rotation. Defaults to the z-vector.
        angle : array_like, optional
            The angle of rotation, in radians.

        Returns
        -------
        Vector3d
            A new vector with entries rotated.

        Examples
        --------
        >>> from math import pi
        >>> v = Vector3d((0, 1, 0))
        >>> axis = Vector3d((0, 0, 1))
        >>> angles = [0, pi/4, pi/2, 3*pi/4, pi]
        >>> v.rotate(axis=axis, angle=angles)
        """
        # Import here to avoid circular import
        from orix.quaternion import Rotation
        from orix.vector.neo_euler import AxAngle

        axis = Vector3d.zvector() if axis is None else axis
        angle = 0 if angle is None else angle
        q = Rotation.from_neo_euler(AxAngle.from_axes_angles(axis, angle))
        return q * self
Exemple #8
0
    def test_get_orientation_similarity_map(self):
        s = nickel_ebsd_small()

        s_dict1 = EBSD(s.data.reshape(-1, 60, 60))
        s_dict2 = EBSD(s.data.reshape(-1, 60, 60))
        n_patterns = s_dict1.axes_manager.navigation_size
        s_dict1._xmap = CrystalMap(Rotation(np.zeros((n_patterns, 4))))
        s_dict2._xmap = CrystalMap(Rotation(np.zeros((n_patterns, 4))))
        s_dict1.xmap.phases[0].name = "a"
        s_dict2.xmap.phases[0].name = "b"

        sd = StaticPatternMatching([s_dict1, s_dict2])
        res = sd(s, keep_n=1, get_orientation_similarity_map=True)
        xmap1, _ = res

        assert np.allclose(xmap1.scores, 1)
        assert np.all(["osm" in xmap.prop for xmap in res])
 def test_orientation_similarity_map(self):
     xmap = CrystalMap(
         rotations=Rotation(np.zeros((100, 4))),
         prop={"simulation_indices": np.tile(np.arange(5), (100, 1))},
         x=np.tile(np.arange(10), 10),
         y=np.tile(np.arange(10), 10),
     )
     assert np.allclose(orientation_similarity_map(xmap), np.ones((10, 10)))
Exemple #10
0
    def test_merging_refined_maps(self):
        ny, nx = (3, 3)
        nav_size = ny * nx
        r = Rotation.from_euler(np.ones((nav_size, 3)))
        x = np.tile(np.arange(ny), nx)
        y = np.repeat(np.arange(nx), ny)

        # Simulation indices
        n_sim_indices = 10
        sim_indices1 = np.random.randint(low=0,
                                         high=1000,
                                         size=n_sim_indices *
                                         nav_size).reshape(
                                             (nav_size, n_sim_indices))
        sim_indices2 = np.random.randint(low=0,
                                         high=1000,
                                         size=n_sim_indices *
                                         nav_size).reshape(
                                             (nav_size, n_sim_indices))

        # Scores
        scores1 = np.ones(nav_size)
        scores1[0] = 3
        scores2 = 2 * np.ones(nav_size)

        xmap1 = CrystalMap(
            rotations=r,
            phase_id=np.ones(nav_size) * 0,
            phase_list=PhaseList(Phase(name="a")),
            x=x,
            y=y,
            prop={
                "simulation_indices": sim_indices1,
                "scores": scores1
            },
        )
        xmap2 = CrystalMap(
            rotations=r,
            phase_id=np.ones(nav_size),
            phase_list=PhaseList(Phase(name="b")),
            x=x,
            y=y,
            prop={
                "simulation_indices": sim_indices2,
                "scores": scores2
            },
        )
        xmap_merged = merge_crystal_maps(crystal_maps=[xmap1, xmap2])

        assert "simulation_indices" not in xmap_merged.prop.keys()
        assert "merged_simulation_indices" not in xmap_merged.prop.keys()

        with pytest.raises(ValueError, match="Cannot merge maps with more"):
            _ = merge_crystal_maps(
                crystal_maps=[xmap1, xmap2],
                simulation_indices_prop="simulation_indices",
            )
Exemple #11
0
 def test_get_patterns_dtype(self):
     r = Rotation.identity()
     mp = nickel_ebsd_master_pattern_small(projection="lambert")
     dtype_out = np.dtype("float64")
     pattern = mp.get_patterns(rotations=r,
                               detector=self.detector,
                               energy=20,
                               dtype_out=dtype_out)
     assert pattern.data.dtype == dtype_out
 def test_n_best_too_great(self):
     xmap = CrystalMap(
         rotations=Rotation(np.zeros((100, 4))),
         prop={"simulation_indices": np.ones((100, 5))},
         x=np.tile(np.arange(10), 10),
         y=np.tile(np.arange(10), 10),
     )
     with pytest.raises(ValueError,
                        match="n_best 6 cannot be greater than"):
         orientation_similarity_map(xmap, n_best=6)
Exemple #13
0
def compute_refine_orientation_projection_center_results(
    results: list,
    detector,
    xmap: CrystalMap,
    master_pattern,
):
    """Compute the results from
    :meth:`~kikuchipy.signals.EBSD.refine_orientation_projection_center`
    and return the :class:`~orix.crystal_map.CrystalMap` and
    :class:`~kikuchipy.detectors.EBSDDetector`.

    Parameters
    ----------
    results
        Results returned from `refine_orientation_projection_center()`,
        which is a list of :class:`~dask.delayed.Delayed`.
    detector : ~kikuchipy.detectors.EBSDDetector
        Detector passed to `refine_orientation_projection_center()` to
        obtain `results`.
    xmap
        Crystal map passed to `refine_orientation_projection_center()`
        to obtain `results`.
    master_pattern : ~kikuchipy.signals.EBSDMasterPattern
        Master pattern passed to
        `refine_orientation_projection_center()` to obtain `results`.

    Returns
    -------
    xmap_refined : :class:`~orix.crystal_map.CrystalMap`
        Crystal map with refined orientations and scores.
    new_detector : :class:`~kikuchipy.detectors.EBSDDetector`
        EBSD detector with refined projection center parameters.
    """
    n_patterns = len(results)
    nav_shape = xmap.shape
    with ProgressBar():
        print(
            f"Refining {n_patterns} orientation(s) and projection center(s):",
            file=sys.stdout,
        )
        computed_results = dask.compute(*results)
        computed_results = np.array(computed_results)
        # (n, score, phi1, Phi, phi2, PCx, PCy, PCz)
        xmap_refined = CrystalMap(
            rotations=Rotation.from_euler(computed_results[:, 1:4]),
            phase_id=np.zeros(n_patterns),
            x=xmap.x,
            y=xmap.y,
            phase_list=PhaseList(phases=master_pattern.phase),
            prop=dict(scores=computed_results[:, 0]),
            scan_unit=xmap.scan_unit,
        )
        new_detector = detector.deepcopy()
        new_detector.pc = computed_results[:, 4:].reshape(nav_shape + (3, ))
    return xmap_refined, new_detector
Exemple #14
0
    def test_signal_varying_dimensions(self, dummy_signal, slices,
                                       desired_xmap_shape):
        s = dummy_signal.inav[slices]
        sig_shape = dummy_signal.axes_manager.signal_shape
        s_dict1 = EBSD(dummy_signal.data.reshape((-1, ) + sig_shape))
        n_sim = s_dict1.axes_manager.navigation_size
        s_dict1._xmap = CrystalMap(Rotation(np.zeros((n_sim, 4))))
        sd = StaticPatternMatching(s_dict1)
        res = sd(s)

        assert res.shape == desired_xmap_shape
Exemple #15
0
    def to_crystal_map(self):
        """Obtain a crystallographic map specifying the best matching phase and
        orientation at each probe position with corresponding metrics.

        Raises
        -------
        ValueError("Currently under development")
        """

        raise ValueError("Currently under development")

        _s = self.map(
            crystal_from_vector_matching, inplace=False)

        """ Gets phase, the easy bit """
        phase_id = _s.isig[0].data.flatten()

        """ Deals with the properties, hard coded as of v0.13 """
        # need to invert an array of dicts into a dict of arrays
        def _map_to_get_property(prop):
            return d[prop]

        # assume same properties at every point of the signal
        key_list = []
        for key in _s.inav[0,0].isig[2]:
            key_list.append(key)

        properties = {}
        for key in key_list:
            _key_signal = _s.isig[2].map(_map_to_get_property,prop=key,inplace=False)
            properties[key] = _key_signal

        """ Deal with the rotations """
        def _map_for_alpha_beta_gamma(ix):
            return z[ix]

        alpha = _s.isig[1].map(_map_for_alpha_beta_gamma,ix=0,inplace=False)
        beta =  _s.isig[1].map(_map_for_alpha_beta_gamma,ix=1,inplace=False)
        gamma = _s.isig[1].map(_map_for_alpha_beta_gamma,ix=2,inplace=False)

        euler = np.vstack((alpha,beta,gamma)).T
        rotations = Rotation.from_euler(euler,convention="bunge", direction="crystal2lab")

        """ Gets navigation placements """
        xy = np.indices(_s.data.shape[:2])
        x = xy[1].flatten()
        y = xy[0].flatten()

        return CrystalMap(
                rotations=rotations,
                phase_id=phase_id,
                x=x,
                y=y,
                prop=properties)
 def test_from_n_best(self):
     sim_idx_prop = "simulated_indices"
     xmap = CrystalMap(
         rotations=Rotation(np.zeros((100, 4))),
         prop={sim_idx_prop: np.ones((100, 5))},
         x=np.tile(np.arange(10), 10),
         y=np.tile(np.arange(10), 10),
     )
     osm = orientation_similarity_map(xmap,
                                      simulation_indices_prop=sim_idx_prop,
                                      from_n_best=2)
     assert osm.shape == (10, 10, 4)
Exemple #17
0
    def test_keep_n(self, n_rot_in, n_rot_out, keep_n):
        s = nickel_ebsd_small()
        s_dict = EBSD(np.random.random((n_rot_in, 60, 60)).astype(np.float32))
        s_dict._xmap = CrystalMap(Rotation(np.zeros((n_rot_in, 4))))
        sd = StaticPatternMatching(s_dict)
        xmap = sd(s)

        assert xmap.rotations_per_point == n_rot_out

        xmap2 = sd(s, keep_n=keep_n)

        assert xmap2.rotations_per_point == keep_n
Exemple #18
0
    def test_n_slices_input(self, dummy_signal):
        sig_shape = dummy_signal.axes_manager.signal_shape
        n_px = np.prod(sig_shape)
        n_sim = 13500 + 1
        rand_data = (np.random.randint(
            0, 255,
            n_sim * n_px).reshape((n_sim, ) + sig_shape).astype(np.uint8))
        s_dict1 = EBSD(rand_data)
        s_dict1._xmap = CrystalMap(Rotation(np.zeros((n_sim, 4))))
        sd = StaticPatternMatching(s_dict1)

        with replace_stdin(io.StringIO("y")):
            res = sd(dummy_signal, n_slices=1)
            assert isinstance(res, CrystalMap)

        with replace_stdin(io.StringIO("n")):
            res = sd(dummy_signal, n_slices=1)
            assert res is None
Exemple #19
0
    def test_simulated_patterns_xmap_detector(self):
        mp = nickel_ebsd_master_pattern_small(projection="lambert")
        r = Rotation.from_euler([[0, 0, 0], [0, np.pi / 2, 0]])
        detector = EBSDDetector(
            shape=(60, 60),
            pc=[0.5, 0.5, 0.5],
            sample_tilt=70,
            convention="tsl",
        )
        s = mp.get_patterns(rotations=r, detector=detector, energy=20)

        assert np.allclose(s.xmap.rotations.to_euler(), r.to_euler())
        assert s.xmap.phases.names == [mp.phase.name]
        assert s.xmap.phases[0].point_group.name == mp.phase.point_group.name

        assert s.detector.shape == detector.shape
        assert np.allclose(s.detector.pc, detector.pc)
        assert s.detector.sample_tilt == detector.sample_tilt
Exemple #20
0
async def preview_dictionary(req: DictionaryIndexingIn):
    if req.ebsd_info.uid not in kp_signals:
        raise HTTPException(status_code=404, detail="Patterns not found")
    s = kp_signals[req.ebsd_info.uid]

    detector = kp.detectors.EBSDDetector(
        shape=s.axes_manager.signal_shape[::-1],
        pc=req.detector.pc,
        sample_tilt=req.detector.sample_tilt,
        convention=req.detector.pc_convention,
        tilt=req.detector.camera_tilt,
    )
    res = PreviewDictionary(patterns=[])
    if req.preview_angles:
        euler = np.array(req.preview_angles)
    else:
        euler = np.array([0.0, 0.0, 0.0])
    for mp_req in req.masterpatterns:
        mp = kp.load(
            mp_req.filepath,
            projection=mp_req.projection,
            hemisphere="both",
            energy=mp_req.energy,
        )
        sim = mp.get_patterns(
            rotations=Rotation.from_euler(np.deg2rad(euler)),
            detector=detector,
            energy=mp_req.energy,
            compute=True,
        )
        svg_string = io.StringIO()
        plt.figure()
        plt.imshow(sim.data[0], cmap="gray")
        plt.title(
            f"{mp.phase.name.capitalize()}\n($\phi_1, \Phi, \phi_2)$ = {np.array_str(euler, precision=1)}"
        )
        plt.axis("off")
        plt.savefig(svg_string,
                    format="svg",
                    bbox_inches="tight",
                    transparent=True)
        svg_string.seek(0)
        res.patterns.append(svg_string.getvalue())
    return res
Exemple #21
0
    def test_get_patterns_chunk(self):
        r = Rotation.from_euler(((0, 0, 0), (1, 1, 1), (2, 2, 2)))
        dc = _get_direction_cosines(self.detector)

        mpn = np.empty((1001, 1001))
        mps = mpn
        npx = 1001
        npy = npx
        out = _get_patterns_chunk(
            rotations_array=r.data,
            dc=dc,
            master_north=mpn,
            master_south=mps,
            npx=npx,
            npy=npy,
            scale=(npx - 1) / 2,
            rescale=False,
        )

        assert out.shape == r.shape + dc.shape
Exemple #22
0
def compute_refine_orientation_results(results: list, xmap: CrystalMap,
                                       master_pattern):
    """Compute the results from
    :meth:`~kikuchipy.signals.EBSD.refine_orientation` and return the
    :class:`~orix.crystal_map.CrystalMap`.

    Parameters
    ----------
    results
        Results returned from `refine_orientation()`, which is a list of
        :class:`~dask.delayed.Delayed`.
    xmap
        Crystal map passed to `refine_orientation()` to obtain
        `results`.
    master_pattern : ~kikuchipy.signals.EBSDMasterPattern
        Master pattern passed to `refine_orientation()` to obtain
        `results`.

    Returns
    -------
    refined_xmap : :class:`~orix.crystal_map.CrystalMap`
        Crystal map with refined orientations and scores.
    """
    n_patterns = len(results)
    with ProgressBar():
        print(f"Refining {n_patterns} orientation(s):", file=sys.stdout)
        computed_results = dask.compute(*results)
        # (n, score, phi1, Phi, phi2)
        computed_results = np.array(computed_results)
        xmap_refined = CrystalMap(
            rotations=Rotation.from_euler(computed_results[:, 1:]),
            phase_id=np.zeros(n_patterns),
            x=xmap.x,
            y=xmap.y,
            phase_list=PhaseList(phases=master_pattern.phase),
            prop=dict(scores=computed_results[:, 0]),
            scan_unit=xmap.scan_unit,
        )
    return xmap_refined
Exemple #23
0
    def test_project_patterns_from_master_pattern(self):
        """Make sure the Numba function is covered."""
        r = Rotation.from_euler(((0, 0, 0), (1, 1, 1), (2, 2, 2)))
        dc = _get_direction_cosines_for_single_pc_from_detector(self.detector)

        npx = npy = 101
        mpn = mps = np.zeros((npy, npx))
        patterns = _project_patterns_from_master_pattern.py_func(
            rotations=r.data,
            direction_cosines=dc,
            master_north=mpn,
            master_south=mps,
            npx=npx,
            npy=npy,
            scale=float((npx - 1) / 2),
            dtype_out=mpn.dtype,
            rescale=False,
            # Aren't used
            out_min=1,
            out_max=2,
        )

        assert patterns.shape == r.shape + dc.shape[:-1]
Exemple #24
0
    def test_return_merged_crystal_map(self, return_merged_xmap,
                                       desired_n_xmaps_out):
        s = nickel_ebsd_small()
        s_dict1 = EBSD(s.data.reshape(-1, 60, 60))
        s_dict2 = s_dict1.deepcopy()
        n_patterns = s_dict1.axes_manager.navigation_size
        s_dict1._xmap = CrystalMap(Rotation(np.zeros((n_patterns, 4))))
        s_dict2._xmap = s_dict1.xmap.deepcopy()
        s_dict1.xmap.phases[0].name = "a"
        s_dict2.xmap.phases[0].name = "b"

        sd = StaticPatternMatching([s_dict1, s_dict2])
        res1 = sd(s, return_merged_crystal_map=return_merged_xmap)

        assert len(res1) == desired_n_xmaps_out

        sd.dictionaries.pop(-1)
        res2 = sd(s, return_merged_crystal_map=True)

        assert isinstance(res2, CrystalMap)

        res3 = sd(s)

        assert isinstance(res3, CrystalMap)
Exemple #25
0
    def test_get_patterns(self):
        # Ni Test
        EMSOFT_EBSD_FILE = os.path.join(
            DIR_PATH, "../../data/emsoft_ebsd/EBSD_TEST_Ni.h5")
        emsoft_key = load(EMSOFT_EBSD_FILE)
        emsoft_key = emsoft_key.data[0]

        angles = np.array((120, 45, 60))
        r = Rotation.from_euler(np.radians(angles))
        kp_mp = nickel_ebsd_master_pattern_small(projection="lambert",
                                                 hemisphere="both")
        kp_pattern = kp_mp.get_patterns(rotations=r,
                                        detector=self.detector,
                                        energy=20,
                                        dtype_out=np.uint8)
        kp_pat = kp_pattern.data[0].compute()

        ncc1 = ncc(kp_pat, emsoft_key)
        ndp1 = ndp(kp_pat, emsoft_key)

        assert ncc1 >= 0.935
        assert ndp1 >= 0.935

        detector_shape = self.detector.shape
        r2 = Rotation.from_euler(((0, 0, 0), (1, 1, 1), (2, 2, 2)))
        mp_a = EBSDMasterPattern(np.zeros((2, 10, 11, 11)))
        print(mp_a.axes_manager)
        mp_a.axes_manager[0].name = "hemisphere"
        mp_a.axes_manager[1].name = "energy"
        mp_a.projection = "lambert"
        mp_a.phase = Phase("Ni", 225)
        out_a = mp_a.get_patterns(r2, self.detector, 5)

        assert isinstance(out_a, LazyEBSD)
        desired_data_shape = (3, ) + detector_shape[::-1]
        assert out_a.axes_manager.shape == desired_data_shape

        mp_b = EBSDMasterPattern(np.zeros((10, 11, 11)))
        mp_b.axes_manager[0].name = "energy"
        mp_b.projection = "lambert"
        mp_b.phase = Phase("Ni", 225)
        out_b = mp_b.get_patterns(r2, self.detector, 5)

        assert isinstance(out_b, LazyEBSD)
        assert out_b.axes_manager.shape == desired_data_shape

        mp_c = EBSDMasterPattern(np.zeros((11, 11)))
        mp_c.projection = "lambert"
        mp_c.phase = Phase("Ni", 225)
        out_c = mp_c.get_patterns(r2, self.detector, 5)
        out_c_2 = mp_c.get_patterns(r2, self.detector, 5, compute=True)

        assert isinstance(out_c, LazyEBSD)
        assert isinstance(out_c_2, EBSD)
        assert out_c.axes_manager.shape == desired_data_shape

        mp_c2 = EBSDMasterPattern(np.zeros((11, 11)))
        mp_c2.projection = "lambert"
        mp_c2.phase = Phase("!Ni", 220)
        with pytest.raises(AttributeError):
            mp_c2.get_patterns(r2, self.detector, 5)

        mp_d = EBSDMasterPattern(np.zeros((2, 11, 11)))
        with pytest.raises(NotImplementedError):
            mp_d.get_patterns(r2, self.detector, 5)

        mp_e = EBSDMasterPattern(np.zeros((10, 11, 11)))
        mp_e.axes_manager[0].name = "energy"
        mp_e.projection = "lambert"
        mp_e.phase = Phase("!Ni", 220)
        with pytest.raises(AttributeError):
            mp_e.get_patterns(r2, self.detector, 5)

        # More than one Projection center is currently not supported so
        # it should fail
        d2 = EBSDDetector(
            shape=(10, 10),
            px_size=50,
            pc=((0, 0, 15000), (0, 0, 15000)),
            convention="emsoft4",
            tilt=0,
            sample_tilt=70,
        )
        with pytest.raises(NotImplementedError):
            mp_c.get_patterns(r2, d2, 5)
def _get_patterns_chunk(
    rotations_array: np.ndarray,
    dc: Vector3d,
    master_north: np.ndarray,
    master_south: np.ndarray,
    npx: int,
    npy: int,
    scale: Union[int, float],
    rescale: bool,
    dtype_out: Optional[type] = np.float32,
) -> np.ndarray:
    """Get the EBSD patterns on the detector for each rotation in the
    chunk. Each pattern is found by a bi-quadratic interpolation of the
    master pattern as described in EMsoft.

    Parameters
    ----------
    rotations_array
        Array of rotations of shape (..., 4) for a given chunk in
        quaternions.
    dc
        Direction cosines unit vector between detector and sample.
    master_north
        Northern hemisphere of the master pattern.
    master_south
        Southern hemisphere of the master pattern.
    npx
        Number of pixels in the x-direction on the master pattern.
    npy
        Number of pixels in the y-direction on the master pattern.
    scale
        Factor to scale up from square Lambert projection to the master
        pattern.
    rescale
        Whether to call rescale_intensities() or not.
    dtype_out
        Data type of the returned patterns, by default np.float32.

    Returns
    -------
    numpy.ndarray
        3D or 4D array with simulated patterns.
    """
    rotations = Rotation(rotations_array)
    rotations_shape = rotations_array.shape[:-1]
    simulated = np.empty(shape=rotations_shape + dc.shape, dtype=dtype_out)
    for i in np.ndindex(rotations_shape):
        rotated_dc = rotations[i] * dc
        (
            nii,
            nij,
            niip,
            nijp,
            di,
            dj,
            dim,
            djm,
        ) = _get_lambert_interpolation_parameters(
            rotated_direction_cosines=rotated_dc, npx=npx, npy=npy, scale=scale,
        )
        pattern = np.where(
            rotated_dc.z >= 0,
            (
                master_north[nii, nij] * dim * djm
                + master_north[niip, nij] * di * djm
                + master_north[nii, nijp] * dim * dj
                + master_north[niip, nijp] * di * dj
            ),
            (
                master_south[nii, nij] * dim * djm
                + master_south[niip, nij] * di * djm
                + master_south[nii, nijp] * dim * dj
                + master_south[niip, nijp] * di * dj
            ),
        )
        if rescale:
            pattern = rescale_intensity(pattern, dtype_out=dtype_out)
        simulated[i] = pattern
    return simulated
Exemple #27
0
def file_reader(
    filename: str,
    scan_size: Union[None, int, Tuple[int, ...]] = None,
    lazy: bool = False,
    **kwargs,
) -> List[dict]:
    """Read dynamically simulated electron backscatter diffraction
    patterns from EMsoft's format produced by their EMEBSD.f90 program.

    Parameters
    ----------
    filename
        Full file path of the HDF file.
    scan_size
        Scan size in number of patterns in width and height.
    lazy
        Open the data lazily without actually reading the data from disk
        until requested. Allows opening datasets larger than available
        memory. Default is False.
    kwargs :
        Keyword arguments passed to h5py.File.

    Returns
    -------
    signal_dict_list: list of dicts
        Data, axes, metadata and original metadata.
    """
    mode = kwargs.pop("mode", "r")
    f = File(filename, mode=mode, **kwargs)

    _check_file_format(f)

    # Read original metadata
    omd = hdf5group2dict(f["/"],
                         data_dset_names=["EBSDPatterns"],
                         recursive=True)

    # Set metadata and original metadata dictionaries
    md = _get_metadata(omd)
    md.update({
        "Signal": {
            "signal_type": "EBSD",
            "record_by": "image"
        },
        "General": {
            "title": f.filename.split("/")[-1].split(".")[0],
            "original_filename": f.filename.split("/")[-1],
        },
    })
    scan = {"metadata": md, "original_metadata": omd}

    # Read patterns
    dataset = f["EMData/EBSD/EBSDPatterns"]
    if lazy:
        chunks = "auto" if dataset.chunks is None else dataset.chunks
        patterns = da.from_array(dataset, chunks=chunks)
    else:
        patterns = np.asanyarray(dataset)

    # Reshape data if desired
    sy = omd["NMLparameters"]["EBSDNameList"]["numsy"]
    sx = omd["NMLparameters"]["EBSDNameList"]["numsx"]
    if scan_size is not None:
        if isinstance(scan_size, int):
            new_shape = (scan_size, sy, sx)
        else:
            new_shape = scan_size + (sy, sx)
        patterns = patterns.reshape(new_shape)

    scan["data"] = patterns

    # Set navigation and signal axes
    pixel_size = omd["NMLparameters"]["EBSDNameList"]["delta"]
    ndim = patterns.ndim
    units = ["px", "um", "um"]
    names = ["x", "dy", "dx"]
    scales = np.array([1, pixel_size, pixel_size])
    if ndim == 4:
        units = ["px"] + units
        names = ["y"] + names
        scales = np.append([1], scales)
    scan["axes"] = [{
        "size": patterns.shape[i],
        "index_in_array": i,
        "name": names[i],
        "scale": scales[i],
        "offset": 0,
        "units": units[i],
    } for i in range(patterns.ndim)]

    # Get crystal map
    phase = _crystaldata2phase(hdf5group2dict(f["CrystalData"]))
    xtal_fname = f["EMData/EBSD/xtalname"][()][0].decode().split("/")[-1]
    phase.name, _ = os.path.splitext(xtal_fname)
    scan["xmap"] = CrystalMap(
        rotations=Rotation.from_euler(f["EMData/EBSD/EulerAngles"][()]),
        phase_list=PhaseList(phase),
    )

    if not lazy:
        f.close()

    return [scan]
Exemple #28
0
def test_results_dict_to_crystal_map(test_library_phases_multi, test_lib_gen):
    """Test getting a :class:`orix.crystal_map.CrystalMap` from returns
    from :func:`index_dataset_with_template_rotation`.
    """
    # Map and signal shapes
    nav_shape = (2, 3)
    sig_shape = (80, 80)
    test_set = np.zeros(nav_shape + sig_shape)

    # Diffraction conditions
    diff_lib = test_lib_gen.get_diffraction_library(
        test_library_phases_multi,
        calibration=0.015,
        reciprocal_radius=1.18,
        half_shape=tuple(np.array(sig_shape) // 2),
        with_direct_beam=False,
    )

    # Simulate multi-phase results
    phase_id = np.zeros(nav_shape, dtype=int)
    phase_id[:, [0, 2]] = 1
    phase_names = list(diff_lib.keys())

    # Simulate patterns
    sim_kwargs = dict(size=sig_shape[0], sigma=4)
    for idx in np.ndindex(*nav_shape):
        i = phase_id[idx]
        j = int(idx[1] / 2)
        test_pattern = diff_lib[phase_names[i]]["simulations"][j].\
            get_diffraction_pattern(**sim_kwargs)
        test_set[idx] = test_pattern

    # Perform template matching
    n_best = 3
    results, phase_dict = index_dataset_with_template_rotation(
        Signal2D(test_set),
        diff_lib,
        phases=phase_names,
        n_best=n_best,
    )

    # Extract various results once
    phase_id = results["phase_index"].reshape((-1, n_best))
    ori = np.deg2rad(results["orientation"].reshape((-1, n_best, 3)))

    # Property names in `results`
    prop_names = ["correlation", "mirrored_template", "template_index"]

    # Only get the bast match when multiple phases match best to some
    # patterns
    xmap = results_dict_to_crystal_map(results,
                                       phase_dict,
                                       diffraction_library=diff_lib)
    assert np.allclose(xmap.phase_id, phase_id[:, 0])
    assert xmap.rotations_per_point == 1
    assert xmap.phases.names == phase_names
    assert (xmap.phases.structures[0].lattice.abcABG() ==
            test_library_phases_multi.structures[0].lattice.abcABG())

    # Raise warning when a property is not present as expected
    del results[prop_names[0]]
    with pytest.warns(UserWarning,
                      match=f"Property '{prop_names[0]}' was expected"):
        xmap2 = results_dict_to_crystal_map(results,
                                            phase_dict,
                                            diffraction_library=diff_lib)
    assert list(xmap2.prop.keys()) == prop_names[1:]

    # Raise error when trying to access a best match which isn't
    # available
    with pytest.raises(ValueError, match="`index` cannot be higher than 2"):
        _ = results_dict_to_crystal_map(results, phase_dict, index=3)
    # Get second best match
    i = 1
    xmap3 = results_dict_to_crystal_map(results, phase_dict, index=i)
    assert xmap3.rotations_per_point == 1
    assert np.allclose(xmap3.phase_id, phase_id[:, i])
    assert np.allclose(xmap3.rotations.data,
                       Rotation.from_euler(ori[:, i]).data)
    assert np.allclose(xmap3.prop[prop_names[1]],
                       results[prop_names[1]][:, :, i].flatten())

    # Make map single-phase and get all matches per point
    results["phase_index"][..., 0] = 0
    xmap4 = results_dict_to_crystal_map(results, phase_dict)
    assert np.all(xmap4.phase_id == 0)
    assert xmap4.phases.names[0] == phase_names[0]
    assert xmap4.rotations_per_point == 3

    # Get only best match even though map is single-phase
    i = 0
    xmap5 = results_dict_to_crystal_map(results, phase_dict, index=i)
    assert xmap5.rotations_per_point == 1
    assert np.allclose(xmap5.rotations.data,
                       Rotation.from_euler(ori[:, i]).data)
    assert np.allclose(xmap5.prop[prop_names[1]],
                       results[prop_names[1]][:, :, i].flatten())
Exemple #29
0
 def test_get_patterns_navigation_shape(self, nav_shape):
     mp = nickel_ebsd_master_pattern_small(projection="lambert")
     r = Rotation(np.random.uniform(low=0, high=1, size=nav_shape + (4, )))
     detector = EBSDDetector(shape=(60, 60))
     sim = mp.get_patterns(rotations=r, detector=detector, energy=20)
     assert sim.axes_manager.navigation_shape[::-1] == nav_shape
Exemple #30
0
    def test_get_patterns(self):
        emsoft_key = load(EMSOFT_EBSD_FILE)
        emsoft_key = emsoft_key.data[0]

        r = Rotation.from_euler(np.radians([120, 45, 60]))
        mp1 = nickel_ebsd_master_pattern_small(projection="lambert",
                                               hemisphere="both")
        kp_pattern = mp1.get_patterns(rotations=r,
                                      detector=self.detector,
                                      energy=20,
                                      dtype_out=emsoft_key.dtype)
        kp_pat = kp_pattern.data[0].compute()
        assert kp_pat.dtype == emsoft_key.dtype

        ncc = NormalizedCrossCorrelationMetric(1, 1)
        ncc1 = ncc(kp_pat, emsoft_key)
        assert ncc1 >= 0.935

        ndp = NormalizedDotProductMetric(1, 1)
        ndp1 = ndp(kp_pat, emsoft_key)
        assert ndp1 >= 0.935

        detector_shape = self.detector.shape
        r2 = Rotation.from_euler(((0, 0, 0), (1, 1, 1), (2, 2, 2)))
        mp2 = kp.signals.EBSDMasterPattern(np.zeros((2, 10, 11, 11)))
        mp2.axes_manager[0].name = "hemisphere"
        mp2.axes_manager[1].name = "energy"
        mp2.projection = "lambert"
        mp2.phase = Phase("Ni", 225)
        out2 = mp2.get_patterns(r2, self.detector, 5)
        assert isinstance(out2, kp.signals.LazyEBSD)
        desired_data_shape = (3, ) + detector_shape[::-1]
        assert out2.axes_manager.shape == desired_data_shape

        mp3 = kp.signals.EBSDMasterPattern(np.zeros((10, 11, 11)))
        mp3.axes_manager[0].name = "energy"
        mp3.projection = "lambert"
        mp3.phase = Phase("Ni", 225)
        out3 = mp3.get_patterns(r2, self.detector, 5)
        assert isinstance(out3, kp.signals.LazyEBSD)
        assert out3.axes_manager.shape == desired_data_shape

        mp4 = kp.signals.EBSDMasterPattern(np.zeros((11, 11)))
        mp4.projection = "lambert"
        mp4.phase = Phase("Ni", 225)
        out41 = mp4.get_patterns(r2, self.detector, 5)
        out42 = mp4.get_patterns(r2, self.detector, 5, compute=True)

        assert isinstance(out41, kp.signals.LazyEBSD)
        assert isinstance(out42, kp.signals.EBSD)
        assert out41.axes_manager.shape == desired_data_shape

        mp5 = kp.signals.EBSDMasterPattern(np.zeros((11, 11)))
        mp5.projection = "lambert"
        mp5.phase = Phase("!Ni", 220)
        with pytest.raises(AttributeError):
            _ = mp5.get_patterns(r2, self.detector, 5)

        mp6 = kp.signals.EBSDMasterPattern(np.zeros((2, 11, 11)))
        with pytest.raises(AttributeError,
                           match="Master pattern `phase` attribute"):
            _ = mp6.get_patterns(r2, self.detector, 5)

        mp7 = kp.signals.EBSDMasterPattern(np.zeros((10, 11, 11)))
        mp7.axes_manager[0].name = "energy"
        mp7.projection = "lambert"
        mp7.phase = Phase("!Ni", 220)
        with pytest.raises(AttributeError,
                           match="For point groups without inversion"):
            _ = mp7.get_patterns(r2, self.detector, 5)

        # More than one PC is currently not supported so should fail
        d2 = kp.detectors.EBSDDetector(
            shape=(10, 10),
            px_size=50,
            pc=((0, 0, 15000), (0, 0, 15000)),
            convention="emsoft4",
            sample_tilt=70,
        )
        with pytest.raises(NotImplementedError):
            _ = mp4.get_patterns(r2, d2, 5)