Contents
Simple TEM Imaging and Diffraction
Imports¶
import abtem
import ase
import matplotlib.pyplot as plt
import numpy as np
abtem.config.set({"visualize.cmap": "viridis"})
abtem.config.set({"visualize.continuous_update": True})
abtem.config.set({"visualize.autoscale": True})
#abtem.config.set({"visualize.reciprocal_space_units": "mrad"})
abtem.config.set({"device": "cpu"})
abtem.config.set({"fft": "fftw"});
from matplotlib.patches import Circle
from ipywidgets import HBox, VBox, widgets, interact, Dropdown, Label, Layout
unit_cell = ase.build.bulk("Au", cubic=True)
atoms = unit_cell * (1, 1, 30)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))
abtem.show_atoms(atoms, ax=ax1, title="Beam view")
abtem.show_atoms(atoms, ax=ax2, plane="xz", title="Side view", linewidth=0);

plane_wave = abtem.PlaneWave(energy=200e3)
potential = abtem.Potential(atoms, slice_thickness=4.08 / 4, sampling=0.04, exit_planes=1, projection='finite')
exit_wave = plane_wave.multislice(potential).compute()
[########################################] | 100% Completed | 1.15 ss
Cs = -20e-6 * 1e10
ctf = abtem.CTF(Cs=Cs, energy=200e3)
ctf.scherzer_defocus
ctf.defocus = ctf.scherzer_defocus
ctf.semiangle_cutoff = ctf.crossover_angle
ctf.focal_spread = 10
ctf.angular_spread = 1
image = exit_wave.apply_ctf(ctf).intensity().compute()
%matplotlib ipympl
with plt.ioff():
dpi = 72
fig, axs = plt.subplots(1,3, figsize=(675/dpi, 400/dpi), dpi=dpi)
im0_vmax = potential[:].array.sum(0).max()/2
im0_vmin = 0
im1_vmax = (np.abs(exit_wave[1:][:].array)**2).max()/2
im1_vmin = 0
im2_vmax = image[1:][:].array.max()
im2_vmin = image[1:][:].array.min()
potential.build().compute()
exit_wave.compute()
image.compute()
pots = potential.to_images()[0].show(ax=axs[0], vmin = im0_vmin, vmax = im0_vmax)
wavs = exit_wave[1:][0].show(ax=axs[1], vmin = im1_vmin, vmax = im1_vmax)
imgs = image[1:][0].show(ax=axs[2], vmin = im2_vmin, vmax = im2_vmax)
#pots = axs[0].imshow(potential[0].array[0])
#wavs = axs[1].imshow(exit_wave[1:][0].intensity().array)
#imgs = axs[2].imshow(image[1:][0].array)
axs[0].set_title('Cumulative potential')
axs[1].set_title('Exit wave')
axs[2].set_title('Image')
axs[1].set_yticks([])
axs[2].set_yticks([])
axs[1].set_ylabel("")
axs[2].set_ylabel("")
plt.tight_layout()
im0 = axs[0].get_images()[0]
im1 = axs[1].get_images()[0]
im2 = axs[2].get_images()[0]
# interact
def update_images(plane):
# axs[0].cla()
# axs[1].cla()
# axs[2].cla()
# pots._artists[0,0].set_data(potential[plane].array)
# wavs._artists[0,0].set_data(exit_wave[1:][plane].array)
# imgs._artists[0,0].set_data(image[1:][plane].array)
#pots.set_data(potential[plane].array[0])
#wavs.set_data(exit_wave[1:][plane].intensity().array)
#imgs.set_data(image[1:][plane].array)
im0.set_data(potential[0:plane].array.sum(0))
im1.set_data(np.abs(exit_wave[:-1][plane].array)**2)
im2.set_data(image[:-1][plane].array)
im0.set_clim(vmax = im0_vmax, vmin = im0_vmin)
im1.set_clim(vmax = im1_vmax, vmin = im1_vmin)
im2.set_clim(vmax = im2_vmax, vmin = im1_vmin)
fig.canvas.draw_idle()
style = {
'description_width': 'initial',
}
layout = Layout(width='250px',height='30px')
plane = widgets.IntSlider(
value = 0, max = len(potential),
step = 1,
description = "Slice",
style = style,
layout = layout,
)
widgets.interactive_output(
update_images,
{
'plane':plane,
},
)
fig.canvas.resizable = False
fig.canvas.header_visible = False
fig.canvas.footer_visible = False
fig.canvas.toolbar_visible = True
fig.canvas.layout.width = '675px'
fig.canvas.layout.height = '400px'
fig.canvas.toolbar_position = 'bottom'
widget = widgets.VBox(
[
fig.canvas,
HBox(
[plane]
)
],
)
[########################################] | 100% Completed | 1.05 ss
[########################################] | 100% Completed | 1.05 ss
display(widget);
VBox(children=(Canvas(footer_visible=False, header_visible=False, layout=Layout(height='400px', width='675px')…
diffraction = exit_wave.diffraction_patterns()
indexed_spots = diffraction[1:].crop(120).index_diffraction_spots(cell=unit_cell)
%matplotlib ipympl
diffraction.compute()
indexed_spots.compute()
with plt.ioff():
dpi = 72
fig, axs = plt.subplots(1,2, figsize=(675/dpi, 375/dpi), dpi=dpi)
diff = diffraction[1:].block_direct().crop(120).show(ax=axs[0])#, cbar=True)
spts = indexed_spots[1:].block_direct().crop(120).show(ax=axs[1],
scale=0.15,
#cbar=True,
annotation_kwargs={"threshold": 0.01, "fontsize": 7},
vmin = 0,
vmax = 0.01,
)
axs[0].set_title('Diffraction pattern')
axs[1].set_title('Indexed reflections')
#axs[1].set_yticks([])
axs[1].set_ylabel("")
plt.tight_layout()
# ax0_loc = fig.axes[0].get_position()
# ax1_loc = fig.axes[1].get_position()
# interact
def update_images(plane):
axs[0].cla()
axs[1].cla()
#for ax in list(fig.axes):
# if ax.get_label() == '<colorbar>':
# fig.delaxes(ax)
# fig.axes[0].set_position(ax0_loc)
# fig.axes[1].set_position(ax1_loc)
diff = diffraction[(plane+1):].block_direct().crop(120).show(ax=axs[0])
spts = indexed_spots[plane:].block_direct().crop(120).show(
ax=axs[1],
scale=0.15,
#cbar=True,
annotation_kwargs={"threshold": 0.001, "fontsize": 7},
vmin = 0,
vmax = 0.01,
figsize = (8,8)
)
axs[1].set_yticks([])
axs[1].set_ylabel("")
axs[0].set_title('Diffraction pattern')
axs[1].set_title('Indexed reflections')
fig.canvas.draw_idle()
return None
style = {
'description_width': 'initial',
}
layout = Layout(width='250px',height='30px')
plane = widgets.IntSlider(
value = 0, max = len(potential)-1,
step = 4,
description = "Slice",
style = style,
layout = layout,
)
widgets.interactive_output(
update_images,
{
'plane':plane,
},
)
fig.canvas.resizable = False
fig.canvas.header_visible = False
fig.canvas.footer_visible = False
fig.canvas.toolbar_visible = True
fig.canvas.layout.width = '675px'
fig.canvas.layout.height = '375px'
fig.canvas.toolbar_position = 'bottom'
widget2 = widgets.VBox(
[
fig.canvas,
HBox(
[plane]
)
],
)
OMP: Info #276: omp_set_nested routine deprecated, please use omp_set_max_active_levels instead.
display(widget2);
VBox(children=(Canvas(footer_visible=False, header_visible=False, layout=Layout(height='375px', width='675px')…