Show5DSTEM — Quick Demo#

Load multiple 4D-STEM scans with IO.arina_folder() and visualize as a 5D time/tilt series in Show4DSTEM.

[1]:
try:
    %load_ext autoreload
    %autoreload 2
    %env ANYWIDGET_HMR=1
except Exception:
    pass
env: ANYWIDGET_HMR=1
[2]:
import numpy as np
from quantem.widget import Show4DSTEM

Synthetic 5D-STEM data#

Simulate a time series of 4D-STEM scans: each frame is a (scan_r, scan_c, det_r, det_c) dataset with Bragg spots that shift over time (e.g. beam-induced strain evolution).

[3]:
rng = np.random.default_rng(42)
n_frames = 6
scan_r, scan_c = 32, 32
det_r, det_c = 48, 48
center = (det_r // 2, det_c // 2)
dr, dc = np.mgrid[:det_r, :det_c]
data_5d = np.zeros((n_frames, scan_r, scan_c, det_r, det_c), dtype=np.float32)
for t in range(n_frames):
    # Direct beam with time-varying center shift
    shift_r = 0.5 * np.sin(2 * np.pi * t / n_frames)
    shift_c = 0.3 * np.cos(2 * np.pi * t / n_frames)
    beam = np.exp(-((dr - center[0] - shift_r)**2 + (dc - center[1] - shift_c)**2) / (2 * 3.0**2))
    # Bragg spots at different g-vectors
    for gr, gc in [(8, 0), (-8, 0), (0, 8), (0, -8), (6, 6), (-6, -6)]:
        spot_r = center[0] + gr + shift_r * 0.5
        spot_c = center[1] + gc + shift_c * 0.5
        beam += 0.3 * np.exp(-((dr - spot_r)**2 + (dc - spot_c)**2) / (2 * 1.5**2))
    # Add position-dependent intensity variation (thickness wedge)
    sr, sc = np.mgrid[:scan_r, :scan_c]
    thickness = 1.0 + 0.3 * sr / scan_r
    data_5d[t] = beam[None, None, :, :] * thickness[:, :, None, None]
    data_5d[t] += rng.poisson(0.5, (scan_r, scan_c, det_r, det_c)).astype(np.float32)
print(f"5D-STEM shape: {data_5d.shape}")
print(f"Memory: {data_5d.nbytes / 1e6:.0f} MB")
5D-STEM shape: (6, 32, 32, 48, 48)
Memory: 57 MB

View with Show4DSTEM#

Pass 5D data directly — Show4DSTEM auto-detects the leading frame dimension and adds a time slider.

[4]:
Show4DSTEM(data_5d, frame_dim_label="Time", title="Strain Evolution")
[4]:

From IOResult (real data workflow)#

With real arina data, use IO.arina_folder() to load all master files in a session folder:

[5]:
from quantem.widget.io import IOResult
# Simulate what IO.arina_folder() returns
result = IOResult(
    data=data_5d,
    title="Korea_Sample_C1",
    labels=[f"scan_{i:02d}" for i in range(n_frames)],
)
print(result)
# Show4DSTEM accepts IOResult directly
Show4DSTEM(result, frame_dim_label="Scan")
IOResult
  shape:      6 x 32 x 32 x 48 x 48
  dtype:      float32
  title:      Korea_Sample_C1
  labels:     ['scan_00', 'scan_01', 'scan_02', ...] (6 total)
[5]: