ShowCIF: from crystal to projected phase#

Open in Colab

Inspect unit cells, columns, specimen tilt, and depth slabs before planning an experiment. This notebook uses a small idealized cubic BaTiO₃ model, built below; it is not a refinement of an experimental sample. No private data or download is required for the model.

Run the cells in order in JupyterLab. Use a WebGPU-capable browser on localhost or HTTPS. Install quantem.widget[crystal] (abTEM, for the potential preview) in the notebook environment first; see installation. This tutorial requires a build that includes ShowCIF. For a source checkout, use the developer installation below rather than assuming an older wheel contains it.

python -m pip install -e '.[crystal]'
npm ci
npm run build

Demo route · API and physical conventions

# @title Install QuantEM { display-mode: "form" }
if get_ipython().__class__.__module__.startswith("google.colab"):
    !wget -q https://raw.githubusercontent.com/electronmicroscopy/quantem.widget/main/scripts/install_colab.py -O install_quantem.py
    %run install_quantem.py
    %pip install -q abtem
import quantem.widget as qw
qw.profile()

from ase import Atoms

crystal = Atoms(
    "BaTiO3",
    scaled_positions=[
        (0, 0, 0), (0.5, 0.5, 0.5),
        (0.5, 0.5, 0), (0.5, 0, 0.5), (0, 0.5, 0.5),
    ],
    cell=[4.0, 4.0, 4.0],
    pbc=True,
)
quantem.widget  0.0.1rc44.dev0
  install       editable checkout
  commit        2d009a7f61ee (dirty checkout)
quantem.gpu     0.0.1rc18.dev0
  install       local build
  commit        not recorded
quantem         0.1.10
  install       installed package
  commit        not recorded
webgpu kernels  fa4a86c (fa4a86cfee85), pinned fa4a86cfee85ea719be2dd98206d2098f0dd3344
torch           2.14.1+cu130  device=cpu
python          3.12.15

Inspect the columns#

Start along [001]. Drag the 3D view to rotate the camera; the beam direction stays fixed. Change Unit Cells to see the specimen grow. Hide oxygen with the species control, then restore it. The projected dots show atomic positions, not scattering strength.

The settings gear exposes column, orthogonal, and slice views. Try [110], then return to [001]. The row/column tilt sliders rotate the specimen relative to that nominal beam direction; they are independent of camera rotation.

atoms = qw.ShowCIF(crystal, repeats=(4, 4, 8), zone_axis=(0, 0, 1))
atoms

Inspect potential and expected phase#

This second view uses the same model and 16 depth slabs. Open the settings gear to show the potential maps if hidden. Switch Quantity between integrated potential (V Å), thickness average (V), and expected phase (rad). Change Color and Columns to compare the planes comfortably.

Use Potential Depth to scrub, Avg 3 for a centered three-plane mean, and Play to scan depth. Atom slicing is separate. With 16 planes, centers 0 and 1 both average planes 0–2; center 2 averages 1–3. The full projection still includes all planes. Optional Blur σ is a display filter; it does not change the stored potential.

At 300 keV, expected phase is σ(E) times integrated potential. It is not the exit-wave phase of a thick crystal: this preview omits multislice propagation, channeling, thermal motion, and partial coherence. The neutral independent-atom model uses infinite atomic projections assigned to slabs by site depth, not finite-z integrals. Do not infer reconstruction quality or experimental resolution from the preview.

potential = qw.ShowCIF(
    crystal,
    repeats=(4, 4, 8),
    potential=True,
    num_slices=16,
    energy_keV=300,
    potential_quantity="phase",
    potential_colormap="magma",
)
potential

Change a physical view from Python#

These settings update the existing widget. A microscope FOV changes the framing, not the atom count. The scale bars remain calibrated. Magnification needs a measured reference FOV for your own instrument; no universal calibration is assumed.

potential.view_mode = "microscope"
potential.field_of_view_A = 24
potential.specimen_tilt_mrad = [5.0, -3.0]  # (row, col), mrad

Use your own CIF and share the view#

Replace the model with a fully occupied CIF in the same constructor:

viewer = qw.ShowCIF("my_crystal.cif", repeats=(4, 4, 8), potential=True)
viewer

ASE expands the CIF symmetry. Mixed or partially occupied sites need an explicitly ordered model. Start with a small inspection cell: atom views support up to 250,000 atoms and potential previews up to 8,192 atoms. Increasing the FOV does not create missing material.

Export when ready:

potential.export_html("crystal-inspection.html")

The HTML embeds the structure and synced physical settings. It needs a WebGPU browser and network access for the widget manager; temporary camera, playback, blur, and slice selections reset on reopen. To inspect a reconstructed volume, use Show3D and Show3DSlices.