Chapter 2: Diffraction
HOLZ Lines¶
part of
MSE672: Introduction to Transmission Electron Microscopy
Spring 2026
by Gerd Duscher
Microscopy Facilities
Institute of Advanced Materials & Manufacturing
Materials Science & Engineering
The University of Tennessee, Knoxville
Background and methods to analysis and quantification of data acquired with transmission electron microscopes
import sys
import importlib.metadata
def test_package(package_name):
"""Test if package exists and returns version or -1"""
try:
version = importlib.metadata.version(package_name)
except importlib.metadata.PackageNotFoundError:
version = '-1'
return version
if test_package('pyTEMlib') < '0.2026.1.2':
print('installing pyTEMlib')
!{sys.executable} -m pip install pyTEMlib -q --upgrade
print('done')Import numerical and plotting python packages¶
Import the python packages that we will use:
Beside the basic numerical (numpy) and plotting (pylab of matplotlib) libraries,
and some libraries from the book
kinematic scattering library.
%matplotlib widget
import matplotlib.pyplot as plt
import numpy as np
import sys
if 'google.colab' in sys.modules:
from google.colab import output
output.enable_custom_widget_manager()
# Import libraries from pyTEMlib
import pyTEMlib
__notebook_version__ = '2026.01.11'
print('pyTEM version: ', pyTEMlib.__version__)
print('notebook version: ', __notebook_version__)pyTEM version: 0.2026.1.3
notebook version: 2026.01.11
Define crystal¶
### Please choose another crystal like: Silicon, Aluminium, GaAs , ZnO
atoms = pyTEMlib.crystal_tools.structure_by_name('silicon')
atomsLattice(symbols='Si8', pbc=True, cell=[5.43088, 5.43088, 5.43088])Plot the unit cell¶
from ase.visualize.plot import plot_atoms
plot_atoms(atoms, radii=0.3, rotation=('0x,4y,0z'))<Axes: >Parameters for Diffraction Calculation¶
tags = {}
tags['acceleration_voltage_V'] = 99 *1000.0 #V
tags['convergence_angle_mrad'] = 0
tags['zone_hkl'] = np.array([2,2,1]) # incident neares zone axis: defines Laue Zones!!!!
tags['Sg_max'] = .01 # 1/Ang maximum allowed excitation error ; This parameter is related to the thickness
tags['hkl_max'] = 36 # Highest evaluated Miller indices
Kinematic Scattering Calculation¶
diff_dict = pyTEMlib.diffraction_tools.get_bragg_reflections(atoms, tags, verbose=True)Of the 724 possible reflection 152 are allowed.
Of those, there are 2 in ZOLZ and 150 in HOLZ
Of the 10 forbidden reflection in ZOLZ 0 can be dynamically activated.
Plot Selected Area Electron Diffraction Pattern¶
#####################
# Plot ZOLZ SAED Pattern #
#####################
#We plot only the allowed diffraction spots
g = diff_dict['allowed']['g']
# we sort them by order of Laue zone
ZOLZ = diff_dict['allowed']['ZOLZ']
HOLZ = diff_dict['allowed']['HOLZ']
rotation = 0
x = g[:, 0] * np.cos(g[:, 1]+np.pi+rotation)*10
y = g[:, 0] * np.sin(g[:, 1]+np.pi+rotation)*10
slope = np.tan(g[:, 1]+rotation-np.pi/2)
# Plot
fig = plt.figure()
ax = fig.add_subplot(111)
# We plot the x,y axis only; the z -direction is set to zero - this is our projection
ax.scatter(x[ZOLZ], y[ZOLZ], c='red', s=20)
ax.scatter(x[HOLZ], y[HOLZ], c='green', s=20)
# zero spot plotting
ax.scatter(0,0, c='red', s=100)
ax.scatter(0,0, c='white', s=40)
ax.set_aspect('equal')
FOV = 4
plt.ylim(-FOV,FOV); plt.xlim(-FOV,FOV); plt.show()Origin of HOLZ Line¶
In convergent beam electron-diffraction (CBED) the zero disk contains deficient lines from HOLZ reflections in exact Bragg condition.
These HOLZ deficient lines are only visible with a convergent beam.
To undestand the position from the center of the disk, consider first the beam in the center of the disk, the one in exact zone axis.
Because of the many different angles in CBED, one is cutting the HOLZ reflection in exact Bragg condition (remove the # from the second animate code-line).
The Exald sphere has to be shifted back to the common origin (our electron source).
The distance from the center of the disk is then clearly visible as (remove the # from the third animate code-line)
import pyTEMlib.animation as animate
plt.figure()
animate.deficient_holz_line(exact_bragg=False, laue_zone=1)
animate.deficient_holz_line(exact_bragg='True', laue_zone=1, color='blue')
animate.deficient_holz_line(exact_bragg='True', laue_zone=1, color='red', shift=True)
HOLZ Line Construction¶
Position of deficient HOLZ line
What is :¶
Consider the angles that make up the 90 from ZOLZ to zone axis
then:
For exact Bragg position in ZOLZ
then
with:
Because is the same as we can now calculate the deficient HOLZ lines
For exact Bragg position in ZOLZ then
This is our Kikuchi line equation
#Calculate angle between K0 and deficient cone vector
#For dynamic calculations K0 is replaced by Kg
K0 = diff_dict['K_0']
g_allowed = diff_dict['allowed']['g']
g_norm_allowed = g_allowed[:, 0]
dtheta = g_allowed[:,0]/2-np.arcsin(g_allowed[:,2]/g_allowed[:,3])
#calculate length of distance of deficient cone to K0 in ZOLZ plane
gd_length =2*np.sin((dtheta)/2 )*K0
#Calculate nearest point of HOLZ and Kikuchi lines
gd = g_allowed.copy()
gd[:,0] = -gd[:,0]*gd_length/g_norm_allowed
gd[:,1] = -gd[:,1]*gd_length/g_norm_allowed
gd[:,2] = 0.
###calculate and save line in Hough space coordinates (distance and theta)
slope = gd[:,0]/(gd[:,1]+1e-20)
distance = gd_length
theta = np.arctan(slope)
Now everything together in a single cell¶
We change the lattice parameter (Vegard’s law of alloys) by a few pm and observe the effect on the pattern.
# ----- Input -----------
unit_cell_change_pm = 0.0
# -----------------------
atoms = pyTEMlib.crystal_tools.structure_by_name('Silicon')
cell = atoms.cell.lengths()
atoms.set_cell(cell+unit_cell_change_pm/100, scale_atoms=True)
atoms
tags = {'crystal_name': 'silicon',
'acceleration_voltage_V': 100.8*1000.0, #V
'convergence_angle_mrad': 5.,
'Sg_max': .03, # 1/Ang maximum allowed excitation error ; This parameter is related to the thickness
'hkl_max': 9, # Highest evaluated Miller indices
'zone_hkl': np.array([1, 2, -2]),
'mistilt_alpha degree': 0., # -45#-35-0.28-1+2.42
'mistilt_beta degree': 0.,
'plot_FOV': .5}
diff_dict ={}
diff_dict = pyTEMlib.diffraction_tools.get_bragg_reflections(atoms, tags, verbose=True)
diff_dict['output']=pyTEMlib.diffraction_tools.plot_holz_parameter()
diff_dict['output']['plot_reflections']=False
diff_dict['output']['plot_Kikuchi']=False
diff_dict['output']['linewidth_HOLZ'] = 3
diff_dict['output']['plot_HOLZ']=True
pyTEMlib.diffraction_tools.plot_diffraction_pattern(diff_dict)
plt.gca().scatter(0, 0, c='red')
plt.gca().set_xlim(-20,20)
plt.gca().set_ylim(-20,20)Of the 156 possible reflection 28 are allowed.
Of those, there are 4 in ZOLZ and 24 in HOLZ
Of the 46 forbidden reflection in ZOLZ 0 can be dynamically activated.
(-20.0, 20.0)Now for graphite and low acceleration voltages.¶
Change the acceleration voltage and see what happens.
Tip: 61.29keV and 59.68 keV are especially interesting
### Please choose another crystal like: Silicon, Aluminium, GaAs , ZnO
# ----- Input -----------
crystal_name = 'graphite'
acceleration_voltage = 61.29 * 1000.0
# -----------------------
atoms = pyTEMlib.crystal_tools.structure_by_name(crystal_name)
tags = {'crystal_name': crystal_name,
'acceleration_voltage': acceleration_voltage, #V
'convergence_angle': 7.,
'Sg_max': .03, # 1/Ang maximum allowed excitation error ; This parameter is related to the thickness
'hkl_max': 9, # Highest evaluated Miller indices
'zone_hkl': np.array([0, 0, 1]),
'mistilt_alpha': .0, # -45#-35-0.28-1+2.42
'mistilt_beta': 0.,
'plot_FOV': .5}
diff_dict ={}
diff_dict = pyTEMlib.diffraction_tools.get_bragg_reflections(atoms, tags, verbose=True)
diff_dict['output']=pyTEMlib.diffraction_tools.plot_holz_parameter()
diff_dict['output']['plot_reflections']=True
diff_dict['output']['plot_Kikuchi']=False
diff_dict['output']['linewidth_HOLZ'] = 2
diff_dict['output']['plot_HOLZ']=True
pyTEMlib.diffraction_tools.plot_diffraction_pattern(diff_dict)
plt.title(crystal_name + ': ' + str(tags['zone_hkl']))
plt.gca().set_xlim(-1.7, 1.7)
plt.gca().set_ylim(-1.7, 1.7)
plt.gca().set_aspect('equal')
Of the 138 possible reflection 118 are allowed.
Of those, there are 18 in ZOLZ and 100 in HOLZ
Of the 0 forbidden reflection in ZOLZ 0 can be dynamically activated.
Navigation¶
Back: Kikuchi Lines
Chapter 2: Diffraction
List of Content: Front