This page was generated from doc/user_guide/kikuchi_pattern_simulations.ipynb. Interactive online version: Binder badge.

Kikuchi pattern simulations#

This section explains how to inspect and visualize the results from EBSD indexing by plotting Kikuchi lines and zone axes onto an EBSD signal. We consider this a geometrical EBSD simulation, since it’s only positions of Kikuchi lines and zone axes that are computed. These simulations are based on the work by Aimo Winkelmann in the supplementary material to [BJG+16].

We’ll also show how to perform kinematical Kikuchi pattern simulations.

Let’s import the necessary libraries and a small (3, 3) Nickel EBSD test data set

[1]:
# Exchange inline for notebook or qt5 (from pyqt) for interactive plotting
%matplotlib inline

import tempfile

from diffpy.structure import Atom, Lattice, Structure
from diffsims.crystallography import ReciprocalLatticeVector
import hyperspy.api as hs
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
from orix.crystal_map import Phase
from orix.quaternion import Rotation
import kikuchipy as kp
import pyvista


# Plotting parameters
plt.rcParams.update(
    {"figure.figsize": (10, 10), "font.size": 20, "lines.markersize": 10}
)
pyvista.global_theme.window_size = [700, 700]
pyvista.set_jupyter_backend("pythreejs")

s = kp.data.nickel_ebsd_small()  # Use kp.load("data.h5") to load your own data
s
[1]:
<EBSD, title: patterns My awes0m4 ..., dimensions: (3, 3|60, 60)>

Geometrical simulations#

Let’s enhance the Kikuchi bands by removing the static and dynamic backgrounds

[2]:
s.remove_static_background()
s.remove_dynamic_background()
Removing the static background:
[########################################] | 100% Completed |  0.1s
[########################################] | 100% Completed |  0.1s
Removing the dynamic background:
[########################################] | 100% Completed |  0.1s
[########################################] | 100% Completed |  0.1s
[3]:
_ = hs.plot.plot_images(
    s, axes_decor=None, label=None, colorbar=False, tight_layout=True
)
../_images/user_guide_kikuchi_pattern_simulations_6_0.png

To project Kikuchi lines and zone axes onto our detector, we need

  1. a description of the crystal phase

  2. the set of Kikuchi bands to consider, e.g. the sets of planes {111}, {200}, {220}, and {311}

  3. the crystal orientations with respect to the reference frame

  4. the position of the detector with respect to the sample, in the form of a sample-detector model which includes the sample and detector tilt and the projection center (shortes distance from the source point on the sample to the detector), given here as (PC:math:_x, PC\(_y\), PC\(_z\))

We’ll store the crystal phase information in an orix.crystal_map.Phase instance

[4]:
phase = Phase(
    space_group=225,
    structure=Structure(
        atoms=[Atom("Ni", [0, 0, 0])], lattice=Lattice(3.52, 3.52, 3.52, 90, 90, 90)
    ),
)

print(phase)
print(phase.structure)
<name: . space group: Fm-3m. point group: m-3m. proper point group: 432. color: tab:blue>
lattice=Lattice(a=3.52, b=3.52, c=3.52, alpha=90, beta=90, gamma=90)
Ni   0.000000 0.000000 0.000000 1.0000

We’ll build up the reflector list using diffsims.crystallography.ReciprocalLatticeVector

[5]:
ref = ReciprocalLatticeVector(
    phase=phase, hkl=[[1, 1, 1], [2, 0, 0], [2, 2, 0], [3, 1, 1]]
)
ref
[5]:
ReciprocalLatticeVector (4,),  (m-3m)
[[1. 1. 1.]
 [2. 0. 0.]
 [2. 2. 0.]
 [3. 1. 1.]]

We’ll obtain the symmetrically equivalent vectors and plot each family of vectors in a distinct colour in the stereographic projection

[6]:
ref = ref.symmetrise().unique()
ref.size
[6]:
50
[7]:
ref.print_table()
 h k l      d     |F|_hkl   |F|^2   |F|^2_rel   Mult
 3 1 1    1.061     nan      nan       nan       24
 1 1 1    2.032     nan      nan       nan       8
 2 2 0    1.245     nan      nan       nan       12
 2 0 0    1.760     nan      nan       nan       6
[8]:
# Dictionary with {hkl} as key and indices into `ref` as values
hkl_sets = ref.get_hkl_sets()
hkl_sets
[8]:
defaultdict(tuple,
            {(2.0, 0.0, 0.0): (array([ 8,  9, 10, 11, 12, 13]),),
             (2.0,
              2.0,
              0.0): (array([14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]),),
             (1.0, 1.0, 1.0): (array([0, 1, 2, 3, 4, 5, 6, 7]),),
             (3.0,
              1.0,
              1.0): (array([26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
                     43, 44, 45, 46, 47, 48, 49]),)})
[9]:
hkl_colors = np.zeros((ref.size, 3))
for idx, color in zip(
    hkl_sets.values(),
    [[1, 0, 0], [0, 1, 0], [0, 0, 1], [1, 1, 0]],  # Red, green, blue, yellow
):
    hkl_colors[idx] = color
[10]:
hkl_labels = []
for hkl in ref.hkl.round(0).astype(int):
    hkl_labels.append(str(hkl).replace("[", "(").replace("]", ")"))
[11]:
ref.scatter(c=hkl_colors, grid=True, ec="k", vector_labels=hkl_labels)
../_images/user_guide_kikuchi_pattern_simulations_17_0.png

We can also plot the plane traces, i.e. the Kikuchi lines, in both hemispheres (they are identical for Ni)

[12]:
ref.draw_circle(
    color=hkl_colors, hemisphere="both", figure_kwargs=dict(figsize=(15, 10))
)
../_images/user_guide_kikuchi_pattern_simulations_19_0.png

We know from pattern matching of these nine patterns to dynamically simulated patterns of orientations uniformly distributed in the orientation space of the proper point group \(432\), that they come from two grains with orientations of about \((\phi_1, \Phi, \phi_2) = (80^{\circ}, 34^{\circ}, -90^{\circ})\) and \((\phi_1, \Phi, \phi_2) = (115^{\circ}, 27^{\circ}, -95^{\circ})\). We store these orientations in an orix.quaternion.Rotation instance

[13]:
grain1 = np.deg2rad((80, 34, -90))
grain2 = np.deg2rad((115, 27, -95))
rot = Rotation.from_euler(
    [[grain1, grain2, grain2], [grain1, grain2, grain2], [grain1, grain2, grain2]]
)
rot
[13]:
Rotation (3, 3)
[[[ 0.9527 -0.0255 -0.2913  0.0833]
  [ 0.9576  0.0604 -0.2255 -0.1689]
  [ 0.9576  0.0604 -0.2255 -0.1689]]

 [[ 0.9527 -0.0255 -0.2913  0.0833]
  [ 0.9576  0.0604 -0.2255 -0.1689]
  [ 0.9576  0.0604 -0.2255 -0.1689]]

 [[ 0.9527 -0.0255 -0.2913  0.0833]
  [ 0.9576  0.0604 -0.2255 -0.1689]
  [ 0.9576  0.0604 -0.2255 -0.1689]]]

We describe the sample-detector model in an kikuchipy.detectors.EBSDDetector instance. From Hough indexing we know the projection center to be, in the EDAX TSL convention (see the reference frame guide for the various conventions and more details on the use of the sample-detector model), \((x^{*}, y^{*}, z^{*}) = (0.421, 0.7794, 0.5049)\). The sample was tilted \(70^{\circ}\) about the microscope X direction towards the detector, and the detector normal was orthogonal to the optical axis (beam direction)

[14]:
detector = kp.detectors.EBSDDetector(
    shape=s.axes_manager.signal_shape[::-1],
    sample_tilt=70,
    pc=[0.421, 0.7794, 0.5049],
    convention="edax",
)
detector
[14]:
EBSDDetector (60, 60), px_size 1 um, binning 1, tilt 0, azimuthal 0, pc (0.421, 0.221, 0.505)

Note that the projection center gets converted internally to the Bruker convention.

Now we’re ready to create geometrical simulations. We create simulations using the kikuchipy.simulations.KikuchiPatternSimulator, which takes the reflectors as input

[15]:
simulator = kp.simulations.KikuchiPatternSimulator(ref)
[16]:
sim = simulator.on_detector(detector, rot)
Finding bands that are in some pattern:
[########################################] | 100% Completed |  0.1s
Finding zone axes that are in some pattern:
[########################################] | 100% Completed |  0.1s
Calculating detector coordinates for bands and zone axes:
[########################################] | 100% Completed |  0.1s

By passing the detector and crystal orientations to KikuchiPatternSimulator.on_detector(), we’ve obtained a kikuchipy.simulations.GeometricalKikuchiPatternSimulation, which stores the detector and gnomonic coordinates of the Kikuchi lines and zone axes for each crystal orientation

[17]:
sim
[17]:
GeometricalKikuchiPatternSimulation (3, 3):
ReciprocalLatticeVector (27,),  (m-3m)
[[ 1.  1.  1.]
 [-1.  1.  1.]
 [-1. -1.  1.]
 [ 1. -1.  1.]
 [ 0.  2.  0.]
 [-2.  0.  0.]
 [ 0. -2.  0.]
 [ 0.  0.  2.]
 [-2.  2.  0.]
 [-2. -2.  0.]
 [ 2. -2.  0.]
 [ 0.  2.  2.]
 [-2.  0.  2.]
 [ 0. -2.  2.]
 [ 2.  0.  2.]
 [ 3.  1.  1.]
 [-1.  3.  1.]
 [-3. -1.  1.]
 [ 1. -3.  1.]
 [ 1.  3.  1.]
 [-3.  1.  1.]
 [-1. -3.  1.]
 [ 3. -1.  1.]
 [ 1. -1.  3.]
 [ 1.  1.  3.]
 [-1.  1.  3.]
 [-1. -1.  3.]]

We see that not all 50 of the reflectors in the reflector list are present in some pattern.

These geometrical simulations can be plotted one-by-one by themselves

[18]:
sim.plot()
../_images/user_guide_kikuchi_pattern_simulations_30_0.png

Or, they be plotted on top of patterns in three ways: passing a pattern to GeometricalKikuchiPatternSimulation.plot()

[19]:
sim.plot(index=(1, 2), pattern=s.inav[2, 1].data)
../_images/user_guide_kikuchi_pattern_simulations_32_0.png

Or obtaining a collection of lines, zone axes and zone axes labels as Matplotlib objects via GeometricalKikuchiPatternSimulation.as_collections() and adding them to an existing Matplotlib axis

[20]:
fig, ax = plt.subplots(ncols=3, nrows=3, figsize=(15, 15))

for idx in np.ndindex(s.axes_manager.navigation_shape[::-1]):
    ax[idx].imshow(s.data[idx], cmap="gray")
    ax[idx].axis("off")

    lines, zone_axes, zone_axes_labels = sim.as_collections(
        idx,
        zone_axes=True,
        zone_axes_labels=True,
        zone_axes_labels_kwargs=dict(fontsize=12),
    )
    ax[idx].add_collection(lines)
    ax[idx].add_collection(zone_axes)
    for label in zone_axes_labels:
        ax[idx].add_artist(label)

fig.tight_layout()
../_images/user_guide_kikuchi_pattern_simulations_34_0.png

Or obtaining the lines, zone axes, zone axes labels and PCs as HyperSpy markers via GeometricalKikuchiPatternSimulation.as_markers() and adding them to a signal of the same navigation shape as the simulation instance. This enables navigating the patterns with the geometrical simulations

[21]:
markers = sim.as_markers()

# To delete previously added permanent markers, do
# del s.metadata.Markers

s.add_marker(markers, plot_marker=False, permanent=True)
[22]:
s.plot()
../_images/user_guide_kikuchi_pattern_simulations_37_0.png
../_images/user_guide_kikuchi_pattern_simulations_37_1.png

Kinematical simulations#

We can obtain kinematical master patterns using KikuchiPatternSimulator.calculate_master_pattern(), provided that the simulator is created from a ReciprocalLatticeVector instance that satisfy these conditions:

  1. The unit cell, i.e. the structure used to create the phase used in ReciprocalLatticeVector, must have all asymmetric atom positions filled, which can either be done by creating a Phase instance from a valid CIF file with Phase.from_cif() or calling ReciprocalLatticeVector.sanitise_phase()

  2. The atoms in the structure have their elements described by the symbol (Ni), not by the atomic number (28)

  3. The lattice parameters are in given in Ångström.

  4. Kinematical structure factors \(F_{hkl}\) have been calculated with ReciprocalLatticeVector.calculate_structure_factor()

  5. Bragg angles \(\theta_B\) have been calculated with ReciprocalLatticeVector.calculate_theta()

Let’s simulate three master patterns:

  • nickel

  • variant of the \(\sigma\)-phase (Fe, Cr) in steels

  • silicon carbide 6H.

Nickel#

We’ll compare our kinematical simulations to dynamical simulations performed with EMsoft (see [CDeGraef13]), since we have a Ni master pattern available in the kikuchipy.data module

[23]:
mp_ni_dyn = kp.data.nickel_ebsd_master_pattern_small(projection="stereographic")

Inspect phase

[24]:
phase_ni = mp_ni_dyn.phase.deepcopy()

print(phase_ni)
print(phase_ni.structure.lattice)
<name: ni/ni. space group: Fm-3m. point group: m-3m. proper point group: 432. color: tab:blue>
Lattice(a=0.35236, b=0.35236, c=0.35236, alpha=90, beta=90, gamma=90)

Change lattice parameters from nm to Ångström

[25]:
lat_ni = phase_ni.structure.lattice  # Shallow copy
lat_ni.setLatPar(lat_ni.a * 10, lat_ni.b * 10, lat_ni.c * 10)

print(phase_ni.structure.lattice)
Lattice(a=3.5236, b=3.5236, c=3.5236, alpha=90, beta=90, gamma=90)

We’ll build up the reflector list by:

  1. Finding all reflectors with a minimal interplanar spacing \(d\)

  2. Keeping those that have a structure factor above 0.5% of the reflector with the highest structure factor

[26]:
ref_ni = ReciprocalLatticeVector.from_min_dspacing(phase_ni, 0.5)

ref_ni = ref_ni[
    ref_ni.allowed
]  # Exclude non-allowed reflectors (not available for hexagonal or trigonal phases!)
ref_ni = ref_ni.unique(use_symmetry=True).symmetrise()

Sanitise phase

[27]:
ref_ni.phase.structure
[27]:
[28   0.000000 0.000000 0.000000 1.0000]
[28]:
ref_ni.sanitise_phase()
ref_ni.phase.structure
[28]:
[Ni   0.000000 0.000000 0.000000 1.0000,
 Ni   0.000000 0.500000 0.500000 1.0000,
 Ni   0.500000 0.000000 0.500000 1.0000,
 Ni   0.500000 0.500000 0.000000 1.0000]

We can now calculate the structure factors. Two parametrizations are available, from [Kir98] ("xtables", the default) or [LVanDyck14] ("lobato")

[29]:
ref_ni.calculate_structure_factor()
[30]:
structure_factor_ni = abs(ref_ni.structure_factor)
ref_ni = ref_ni[structure_factor_ni > 0.05 * structure_factor_ni.max()]

ref_ni.print_table()
 h k l      d     |F|_hkl   |F|^2   |F|^2_rel   Mult
 1 1 1    2.034    11.8     140.0     100.0      8
 2 0 0    1.762    10.4     108.2      77.3      6
 2 2 0    1.246     7.4     55.0       39.3      12
 3 1 1    1.062     6.2     38.6       27.6      24
 2 2 2    1.017     5.9     34.7       24.8      8
 4 0 0    0.881     4.9     23.9       17.1      6
 3 3 1    0.808     4.3     18.8       13.4      24
 4 2 0    0.788     4.2     17.4       12.5      24
 4 2 2    0.719     3.6     13.3       9.5       24
 5 1 1    0.678     3.3     11.1       8.0       24
 3 3 3    0.678     3.3     11.1       8.0       8
 4 4 0    0.623     2.9      8.6       6.1       12
 5 3 1    0.596     2.7      7.4       5.3       48
 4 4 2    0.587     2.7      7.1       5.1       24
 6 0 0    0.587     2.7      7.1       5.1       6
 6 2 0    0.557     2.4      6.0       4.3       24
 5 3 3    0.537     2.3      5.3       3.8       24
 6 2 2    0.531     2.3      5.1       3.7       24
 4 4 4    0.509     2.1      4.4       3.2       8
[31]:
ref_ni.calculate_theta(20e3)

We can now create our simulator and plot the simulation

[32]:
simulator_ni = kp.simulations.KikuchiPatternSimulator(ref_ni)
simulator_ni.reflectors.size
[32]:
338

Plotting the band centers with intensities scaled by the structure factor

[33]:
simulator_ni.plot()
../_images/user_guide_kikuchi_pattern_simulations_57_0.png

Or no scaling (scaling="square" for the structure factor squared)

[34]:
simulator_ni.plot(scaling=None)
../_images/user_guide_kikuchi_pattern_simulations_59_0.png

We can also plot the Kikuchi bands, showing both hemispheres, also adding the crystal axes alignment

[35]:
fig = simulator_ni.plot(hemisphere="both", mode="bands", return_figure=True)

ax = fig.axes[0]
ax.scatter(simulator_ni.phase.a_axis, c="r")
ax.scatter(simulator_ni.phase.b_axis, c="g")
ax.scatter(simulator_ni.phase.c_axis, c="b")
../_images/user_guide_kikuchi_pattern_simulations_61_0.png

The simulation can be plotted in spherical projection as well using Matplotlib, or PyVista provided that it is installed

[36]:
simulator_ni.plot("spherical", mode="bands")
../_images/user_guide_kikuchi_pattern_simulations_63_0.png
[37]:
# Intensity scaling is not available when plotting in a notebook
simulator_ni.plot("spherical", mode="bands", backend="pyvista")  # Interactive!

When we’re happy with the reflector list in the simulator, we can generate our kinematical master pattern

[38]:
mp_ni_kin = simulator_ni.calculate_master_pattern(half_size=200)
[########################################] | 100% Completed |  3.7s

The returned master pattern is an instance of EBSDMasterPattern in the stereographic projection.

[39]:
mp_ni_kin
[39]:
<EBSDMasterPattern, title: , dimensions: (|401, 401)>
[40]:
mp_ni_kin.plot_spherical(style="points")  # Interactive!

Comparing kinematical and dynamical simulations

[41]:
# Exclude outside equator
ni_dyn_data = mp_ni_dyn.data.astype(np.float32)
ni_kin_data = mp_ni_kin.data.astype(np.float32)
mask = ni_dyn_data == 0
ni_dyn_data[mask] = np.nan
ni_kin_data[mask] = np.nan

fig, ax = plt.subplots(ncols=2)
ax[0].imshow(ni_kin_data, cmap="gray")
ax[1].imshow(ni_dyn_data, cmap="gray")
ax[0].axis("off")
ax[1].axis("off")
ax[0].set_title("Ni kinematical 20 kV")
ax[1].set_title("Ni dynamical 20 kV")
fig.tight_layout()
../_images/user_guide_kikuchi_pattern_simulations_71_0.png

Warning

Use dynamical simulations when performing pattern matching, not kinematical simulations. The latter intensities are not realistic, as demonstrated in the above comparison.

Finally, we can transform the master pattern in the stereographic projection to one in the Lambert projection

[42]:
mp_ni_kin_lp = mp_ni_kin.as_lambert()
100%|██████████| 1/1 [00:00<00:00,  6.96it/s]
[43]:
mp_ni_kin_lp.plot()
../_images/user_guide_kikuchi_pattern_simulations_74_0.png

We can then project parts of this pattern onto our EBSD detector using get_patterns()

[44]:
s_kin = mp_ni_kin_lp.get_patterns(rot, detector, energy=20, compute=True)
Creating a dictionary of (3, 3) simulated patterns:
[########################################] | 100% Completed |  0.1s
[45]:
_ = hs.plot.plot_images(
    s_kin, axes_decor=None, label=None, colorbar=False, tight_layout=True
)
../_images/user_guide_kikuchi_pattern_simulations_77_0.png

Compare these to the ones the first plot!

\(\sigma\)-phase#

[46]:
phase_sigma = Phase(
    name="sigma",
    space_group=136,
    structure=Structure(
        atoms=[
            Atom("Cr", [0, 0, 0], 0.5),
            Atom("Fe", [0, 0, 0], 0.5),
            Atom("Cr", [0.31773, 0.31773, 0], 0.5),
            Atom("Fe", [0.31773, 0.31773, 0], 0.5),
            Atom("Cr", [0.06609, 0.26067, 0], 0.5),
            Atom("Fe", [0.06609, 0.26067, 0], 0.5),
            Atom("Cr", [0.13122, 0.53651, 0], 0.5),
            Atom("Fe", [0.13122, 0.53651, 0], 0.5),
        ],
        lattice=Lattice(8.802, 8.802, 4.548, 90, 90, 90),
    ),
)
phase_sigma
[46]:
<name: sigma. space group: P42/mnm. point group: 4/mmm. proper point group: 422. color: tab:blue>
[47]:
ref_sigma = ReciprocalLatticeVector.from_min_dspacing(phase_sigma, 1)

ref_sigma.sanitise_phase()

ref_sigma.calculate_structure_factor("lobato")

structure_factor = abs(ref_sigma.structure_factor)
ref_sigma = ref_sigma[structure_factor > 0.05 * structure_factor.max()]

ref_sigma.calculate_theta(20e3)

ref_sigma.print_table()
 h k l      d     |F|_hkl   |F|^2   |F|^2_rel   Mult
 0 0 2    2.274    143.1   20470.3    100.0      2
 0 0 4    1.137    70.5    4970.7      24.3      2
 3 3 0    2.075    66.2    4381.5      21.4      4
 4 1 0    2.135    64.6    4170.3      20.4      8
 4 1 1    1.932    63.5    4027.8      19.7      16
 3 3 1    1.888    56.4    3185.6      15.6      8
 3 3 2    1.533    49.6    2461.7      12.0      8
 1 1 1    3.672    48.6    2361.2      11.5      8
 4 1 2    1.556    48.0    2299.3      11.2      16
 5 5 1    1.201    47.3    2232.9      10.9      8
 8 2 0    1.067    42.1    1775.5      8.7       8
 5 0 1    1.642    41.1    1688.5      8.2       8
 4 1 3    1.236    40.0    1599.1      7.8       16
 1 1 0    6.224    37.3    1391.3      6.8       4
 7 2 0    1.209    36.6    1337.2      6.5       8
 2 2 1    2.568    36.0    1297.3      6.3       8
 3 3 3    1.224    35.9    1290.3      6.3       8
 7 2 1    1.168    32.4    1048.0      5.1       16
 7 2 2    1.068    31.3     977.7      4.8       16
 6 6 0    1.037    31.3     977.4      4.8       4
 5 5 0    1.245    28.6     816.9      4.0       4
 4 1 4    1.004    28.5     814.4      4.0       16
 5 0 3    1.149    27.7     764.7      3.7       8
 3 2 0    2.441    27.4     748.8      3.7       8
 1 0 1    4.041    25.4     642.9      3.1       8
 5 5 2    1.092    24.3     590.9      2.9       8
 3 2 1    2.151    23.7     561.8      2.7       16
 6 4 1    1.179    22.9     522.5      2.6       16
 6 6 1    1.011    22.8     520.7      2.5       8
 1 1 3    1.473    22.5     504.7      2.5       8
 4 0 0    2.200    21.8     476.3      2.3       4
 4 4 1    1.472    21.8     475.6      2.3       8
 7 3 1    1.120    21.0     439.9      2.1       16
 2 2 3    1.363    19.9     394.7      1.9       8
 3 2 2    1.664    19.4     375.4      1.8       16
 8 2 1    1.039    19.3     374.0      1.8       16
 1 1 2    2.136    19.1     364.2      1.8       8
 4 3 1    1.642    18.3     336.3      1.6       16
 2 2 0    3.112    18.1     327.6      1.6       4
 5 1 0    1.726    17.1     292.8      1.4       8
 2 1 1    2.976    16.3     265.8      1.3       16
 4 0 2    1.581    16.0     257.3      1.3       8
 4 4 0    1.556    15.7     245.6      1.2       4
 3 1 0    2.783    15.5     241.3      1.2       8
 5 2 1    1.538    15.4     236.3      1.2       16
 4 4 3    1.086    15.3     233.2      1.1       8
 6 1 0    1.447    15.0     223.5      1.1       8
 7 0 1    1.212    14.5     211.4      1.0       8
 3 2 3    1.288    14.2     202.8      1.0       16
 2 0 0    4.401    14.2     202.6      1.0       4
 5 1 2    1.375    13.5     183.3      0.9       16
 8 3 0    1.030    12.8     164.7      0.8       8
 4 4 2    1.284    12.7     161.9      0.8       8
 4 3 3    1.149    12.3     152.3      0.7       16
 6 1 2    1.221    12.3     152.2      0.7       16
 6 1 1    1.379    11.7     136.8      0.7       16
 3 0 1    2.465    11.7     136.0      0.7       8
 2 2 2    1.836    11.7     135.9      0.7       8
 1 0 3    1.494    11.2     126.0      0.6       8
 3 2 4    1.031    11.2     125.0      0.6       16
 5 2 3    1.112    10.6     112.3      0.5       16
 3 1 2    1.761    10.5     109.4      0.5       16
 1 1 4    1.118     9.7     94.6       0.5       8
 8 3 1    1.005     9.6     91.2       0.4       16
 4 0 4    1.010     9.5     89.8       0.4       8
 6 2 1    1.331     9.2     84.6       0.4       16
 4 2 0    1.968     9.0     81.0       0.4       8
 4 3 0    1.760     8.7     75.7       0.4       8
 3 1 1    2.374     8.7     75.0       0.4       16
 6 1 3    1.047     8.4     70.2       0.3       16
 2 1 3    1.415     8.4     69.8       0.3       16
 2 0 2    2.020     8.0     64.7       0.3       8
 8 1 1    1.062     7.6     57.7       0.3       16
 6 5 0    1.127     7.5     56.6       0.3       8
 6 3 1    1.261     7.4     55.4       0.3       16
[48]:
simulator_sigma = kp.simulations.KikuchiPatternSimulator(ref_sigma)
simulator_sigma
[48]:
KikuchiPatternSimulator:
ReciprocalLatticeVector (788,), sigma (4/mmm)
[[ 8.  3.  1.]
 [ 8.  3.  0.]
 [ 8.  3. -1.]
 ...
 [-8. -3.  1.]
 [-8. -3.  0.]
 [-8. -3. -1.]]
[49]:
fig = simulator_sigma.plot(hemisphere="both", mode="bands", return_figure=True)

ax = fig.axes[0]
ax.scatter(simulator_sigma.phase.a_axis, c="r")
ax.scatter(simulator_sigma.phase.b_axis, c="g")
ax.scatter(simulator_sigma.phase.c_axis, c="b")
fig.tight_layout()
../_images/user_guide_kikuchi_pattern_simulations_83_0.png
[50]:
simulator_sigma.plot("spherical", mode="bands", backend="pyvista")
[51]:
mp_sigma = simulator_sigma.calculate_master_pattern()
[########################################] | 100% Completed | 18.5s
[52]:
mp_sigma.plot()
../_images/user_guide_kikuchi_pattern_simulations_86_0.png
[53]:
mp_sigma.plot_spherical(style="points")  # Interactive!

Silicon carbide 6H#

[54]:
phase_sic = Phase(
    name="sic_6h",
    space_group=186,
    structure=Structure(
        atoms=[
            Atom("Si", [1 / 3, 2 / 3, 0.20778]),
            Atom("C", [1 / 3, 2 / 3, 0.33298]),
            Atom("Si", [1 / 3, 2 / 3, 0.54134]),
            Atom("C", [1 / 3, 2 / 3, 0.66647]),
            Atom("C", [0, 0, 0]),
            Atom("Si", [0, 0, 0.37461]),
        ],
        lattice=Lattice(3.081, 3.081, 15.2101, 90, 90, 120),
    ),
)
phase_sic
[54]:
<name: sic_6h. space group: P63mc. point group: 6mm. proper point group: 6. color: tab:blue>
[55]:
ref_sic = ReciprocalLatticeVector.from_min_dspacing(phase_sic)  # 0.7 Å, default
ref_sic.sanitise_phase()

ref_sic.calculate_structure_factor()

structure_factor = abs(ref_sic.structure_factor)
ref_sic = ref_sic[structure_factor > 0.05 * structure_factor.max()]

ref_sic.calculate_theta(20e3)

ref_sic.print_table()
 h k l      d     |F|_hkl   |F|^2   |F|^2_rel   Mult
0   0   6  2.535    18.1     328.7     100.0      1
0   0  -6  2.535    18.1     328.7     100.0      1
1   0   0  2.668    10.4     108.9      33.1      10
2   0   0  1.334     9.6     92.7       28.2      6
1   0  -1  2.628     7.7     58.8       17.9      10
1   0   1  2.628     7.7     58.8       17.9      10
1   0  -9  1.428     7.1     50.7       15.4      10
1   0   9  1.428     7.1     50.7       15.4      10
1   0  -3  2.361     6.7     45.5       13.8      10
1   0   3  2.361     6.7     45.5       13.8      10
2  -1   2  1.510     5.9     34.7       10.6      6
2  -1  -2  1.510     5.9     34.7       10.6      6
2   0   6  1.181     5.9     34.4       10.4      6
2   0  -6  1.181     5.9     34.3       10.4      6
1   0   2  2.518     5.8     33.5       10.2      10
1   0  -2  2.518     5.8     33.5       10.2      10
2  -1   8  1.197     5.7     32.9       10.0      6
2  -1  -8  1.197     5.7     32.9       10.0      6
1   0  -6  1.838     5.0     25.1       7.6       10
1   0   6  1.838     5.0     25.0       7.6       10
1   0  -7  1.685     4.5     20.2       6.2       10
1   0   7  1.685     4.5     20.2       6.2       10
1   0   8  1.548     4.3     18.8       5.7       10
1   0  -8  1.548     4.3     18.7       5.7       10
3   0   0  0.889     4.1     17.1       5.2       6
0   0 -18  0.845     4.0     15.7       4.8       1
0   0  18  0.845     4.0     15.7       4.8       1
1   0 -15  0.948     3.9     14.9       4.5       10
1   0  15  0.948     3.9     14.9       4.5       10
2  -1  10  1.082     3.5     12.5       3.8       6
2  -1 -10  1.082     3.5     12.5       3.8       6
3  -1   0  1.008     3.4     11.7       3.6       12
2  -1   0  1.541     3.4     11.6       3.5       6
2   2   0  0.770     3.3     11.0       3.3       6
2  -1  16  0.809     3.1      9.9       3.0       6
2  -1 -16  0.809     3.1      9.9       3.0       6
3   0  -6  0.839     2.8      8.0       2.4       6
3   0   6  0.839     2.8      8.0       2.4       6
1   0   5  2.006     2.8      7.7       2.4       10
1   0  -5  2.006     2.8      7.7       2.4       10
2   0  18  0.714     2.8      7.7       2.3       6
2   0 -18  0.714     2.8      7.6       2.3       6
2  -1  14  0.888     2.7      7.5       2.3       6
2  -1 -14  0.888     2.7      7.5       2.3       6
3  -1  -8  0.891     2.6      6.7       2.1       12
3  -1   9  0.866     2.6      6.7       2.0       12
3  -1  -9  0.866     2.6      6.7       2.0       12
3  -1   8  0.891     2.6      6.7       2.0       12
0   0  12  1.268     2.5      6.2       1.9       1
0   0 -12  1.268     2.5      6.2       1.9       1
1   0  10  1.321     2.5      6.1       1.9       10
1   0 -10  1.321     2.5      6.1       1.8       10
2  -1  -9  1.138     2.4      5.9       1.8       6
2  -1   9  1.138     2.4      5.9       1.8       6
2   2   6  0.737     2.3      5.4       1.6       6
2   2  -6  0.737     2.3      5.4       1.6       6
3  -1   6  0.937     2.3      5.2       1.6       12
3  -1  -6  0.937     2.3      5.1       1.6       12
3  -1  -2  1.000     2.3      5.1       1.5       12
3  -1   2  1.000     2.3      5.1       1.5       12
3   0  -9  0.787     2.2      5.0       1.5       6
3   0   9  0.787     2.2      5.0       1.5       6
2   0   9  1.047     2.1      4.6       1.4       6
2   0  -9  1.047     2.1      4.6       1.4       6
2  -1   6  1.316     2.0      3.8       1.2       6
2  -1  -6  1.316     2.0      3.8       1.2       6
3  -1  15  0.715     1.9      3.7       1.1       12
3  -1 -15  0.715     1.9      3.7       1.1       12
1   0  16  0.895     1.9      3.6       1.1       10
2  -1  -1  1.533     1.9      3.6       1.1       6
2  -1   1  1.533     1.9      3.6       1.1       6
1   0 -16  0.895     1.9      3.6       1.1       10
2  -1  -4  1.428     1.8      3.3       1.0       6
2  -1   4  1.428     1.8      3.3       1.0       6
1   0  -4  2.184     1.8      3.2       1.0       10
3   1  -2  0.737     1.8      3.2       1.0       12
3   1   2  0.737     1.8      3.2       1.0       12
1   0   4  2.184     1.8      3.2       1.0       10
2   2  -8  0.714     1.8      3.1       0.9       6
3  -1 -10  0.841     1.7      3.0       0.9       12
2   2   8  0.714     1.7      3.0       0.9       6
3  -1  10  0.841     1.7      3.0       0.9       12
2  -1  -3  1.474     1.7      3.0       0.9       6
2  -1   3  1.474     1.7      3.0       0.9       6
1   0  14  1.006     1.7      2.9       0.9       10
1   0 -14  1.006     1.7      2.8       0.9       10
1   0  17  0.848     1.7      2.8       0.8       10
1   0 -17  0.848     1.7      2.8       0.8       10
2   0 -12  0.919     1.7      2.7       0.8       6
2   0  12  0.919     1.7      2.7       0.8       6
3  -1   1  1.006     1.6      2.6       0.8       12
3  -1  -1  1.006     1.6      2.6       0.8       12
2  -1 -15  0.847     1.6      2.5       0.8       6
2  -1  15  0.847     1.6      2.5       0.8       6
3  -1   3  0.989     1.6      2.5       0.8       12
3  -1  -3  0.989     1.6      2.5       0.8       12
2   0   1  1.329     1.5      2.4       0.7       6
2   0  -1  1.329     1.5      2.4       0.7       6
1   0 -18  0.806     1.5      2.2       0.7       10
3  -1 -14  0.739     1.5      2.2       0.7       12
1   0  18  0.806     1.5      2.2       0.7       10
3  -1  14  0.739     1.5      2.2       0.7       12
2   0  15  0.807     1.5      2.1       0.7       6
2   0 -15  0.807     1.5      2.1       0.7       6
2   2  -2  0.766     1.5      2.1       0.6       6
2   2   2  0.766     1.5      2.1       0.6       6
2   0   3  1.290     1.4      2.0       0.6       6
2   0  -3  1.290     1.4      2.0       0.6       6
2  -1  -7  1.257     1.4      2.0       0.6       6
2  -1   7  1.257     1.4      2.0       0.6       6
3  -1   7  0.915     1.4      1.9       0.6       12
3  -1  -7  0.915     1.4      1.9       0.6       12
1   0  11  1.228     1.4      1.9       0.6       10
1   0 -11  1.228     1.4      1.9       0.6       10
3   0  -3  0.876     1.4      1.8       0.6       6
3   0   3  0.876     1.4      1.8       0.6       6
3   0  -1  0.888     1.3      1.8       0.5       6
3   0   1  0.888     1.3      1.8       0.5       6
3   0   8  0.806     1.3      1.6       0.5       6
2   0  -8  1.092     1.2      1.6       0.5       6
3   0  -8  0.806     1.2      1.5       0.5       6
2   0   8  1.092     1.2      1.5       0.4       6
2   0   7  1.137     1.2      1.5       0.4       6
2   0  -7  1.137     1.2      1.5       0.4       6
3   0  -7  0.823     1.2      1.4       0.4       6
3   0   7  0.823     1.2      1.4       0.4       6
2   0  -2  1.314     1.2      1.4       0.4       6
2   0   2  1.314     1.2      1.4       0.4       6
2   2   9  0.701     1.2      1.4       0.4       6
2   2  -9  0.701     1.2      1.4       0.4       6
1   0 -13  1.072     1.1      1.3       0.4       10
1   0  13  1.072     1.1      1.3       0.4       10
3   0  12  0.728     1.1      1.2       0.4       6
3   1   3  0.732     1.1      1.2       0.4       12
3   1  -3  0.732     1.1      1.2       0.4       12
3   0 -12  0.728     1.1      1.2       0.4       6
3   0   2  0.883     1.1      1.1       0.3       6
3   0  -2  0.883     1.1      1.1       0.3       6
3   1   1  0.739     1.0      1.0       0.3       12
3   1  -1  0.739     1.0      1.0       0.3       12
3   1   7  0.701     0.9      0.9       0.3       12
3   1  -7  0.701     0.9      0.9       0.3       12
[56]:
simulator_sic = kp.simulations.KikuchiPatternSimulator(ref_sic)
simulator_sic
[56]:
KikuchiPatternSimulator:
ReciprocalLatticeVector (896,), sic_6h (6mm)
[[ 3.  1.  7.]
 [ 3.  1.  3.]
 [ 3.  1.  2.]
 ...
 [-3. -1. -2.]
 [-3. -1. -3.]
 [-3. -1. -7.]]
[57]:
fig = simulator_sic.plot(hemisphere="both", mode="bands", return_figure=True)

ax = fig.axes[0]
ax.scatter(simulator_sic.phase.a_axis, c="r")
ax.scatter(simulator_sic.phase.b_axis, c="g")
ax.scatter(simulator_sic.phase.c_axis, c="b")
../_images/user_guide_kikuchi_pattern_simulations_92_0.png
[58]:
simulator_sic.plot("spherical", mode="bands", backend="pyvista")
[59]:
mp_sic = simulator_sic.calculate_master_pattern(hemisphere="both", half_size=200)
[########################################] | 100% Completed |  9.9s
[60]:
mp_sic
[60]:
<EBSDMasterPattern, title: , dimensions: (2|401, 401)>
[61]:
mp_sic.plot(navigator=None)
../_images/user_guide_kikuchi_pattern_simulations_96_0.png
[62]:
mp_sic.plot_spherical(style="points")  # Interactive!