コード例 #1
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)
コード例 #2
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)
コード例 #3
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",
            )
コード例 #4
0
ファイル: _refinement.py プロジェクト: hakonanes/kikuchipy
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
コード例 #5
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)
コード例 #6
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
コード例 #7
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
コード例 #8
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
コード例 #9
0
ファイル: _refinement.py プロジェクト: hakonanes/kikuchipy
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
コード例 #10
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]
コード例 #11
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)
コード例 #12
0
ファイル: test_indexation_utils.py プロジェクト: pyxem/pyxem
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())
コード例 #13
0
ファイル: emsoft_ebsd.py プロジェクト: hakonanes/kikuchipy
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]
コード例 #14
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)