Python SDK

Imaging Capabilities

After attaching an ImagingDevice to a session, you can control the chamber, acquire images, manage ROIs, move the stage, adjust focus parameters, and more. Each call blocks until the device completes the operation (or reports failure).

Device types

ImagingDevice — Use for SEMs and other imaging instruments. Construct with ImagingDevice(client, device_slug="tescan-001") or device_id=.... Exposes .chamber, .imaging, and .stage.

DeformationDevice — Use for tensile stages, load frames, etc. Construct with DeformationDevice(client, device_slug="kammweis-001"). High-level APIs (load, displacement) can be extended later; for now you attach it to sessions and invoke capabilities as needed.

from semphony.systems import ImagingDevice, DeformationDevice

tescan = ImagingDevice(client, device_slug="tescan-001")
kamm = DeformationDevice(client, device_slug="kammweis-001")
with run.session() as s:
    tescan.attach(s)
    kamm.attach(s)

Chamber (vacuum)

The .chamber interface provides vacuum control for the SEM chamber. Use chamber.vent() to vent the chamber (e.g. before loading a sample) and chamber.pump() to evacuate it afterwards.

When guardrails are enabled, the SDK enforces safety rules automatically (e.g. beam must be off before venting).

tescan.chamber.vent()
# ... load sample, then ...
tescan.chamber.pump()

Image acquisition

Acquire an image with the given AcquisitionConfig. Use download=True to fetch the image bytes via the API. Provide target_path to save the file to disk. The call blocks until the device completes and returns an AcquisitionResult.

You can call tescan.acquire(...) (convenience alias) or tescan.imaging.acquire(...). The SDK retries up to 2 times on 504 (acquisition timeout), since timeouts can be transient.

from semphony.models import AcquisitionConfig

result = tescan.acquire(
    AcquisitionConfig(fov_um=100, resolution=(1024, 1024)),
    download=True,
    target_path="acquired.png",
)
# result.image_id, result.local_path, result.correlation_id

Fix beam for EDS (point scan)

For EDS or other point analyses, fix the beam to a single pixel or small region, then collect the spectrum (e.g. via your EDS detector/software), then stop the scan. fix_beam_at(x, y) uses scan/pixel coordinates for the current view; default 1×1 pixel, or use width=3, height=3 for a small region (better stability). Always call stop_scan() when done.

# Fix beam at pixel (512, 512), then collect EDS for N seconds, then stop
tescan.imaging.fix_beam_at(512, 512)
# ... collect spectrum with EDS detector/software for N seconds ...
tescan.imaging.stop_scan()

# Optional: 3×3 region for stability
tescan.imaging.fix_beam_at(512, 512, width=3, height=3)

Save ROI

Capture a pyramidal ROI at the current stage position. The SDK acquires images at multiple zoom levels (ROI, L2, L1, L0) as specified by the RoiSpec. Only levels with FOV > 0 are acquired. Optionally save the images and manifest to disk with target_dir.

from semphony.models import RoiSpec

spec = RoiSpec(name="my_roi", roi_fov_um=50, l0_fov_um=1500, l1_fov_um=300, l2_fov_um=150)
saved = tescan.imaging.save_roi("my_roi", spec, target_dir="./rois")
# saved.name, saved.levels, saved.spec

Find ROI

Navigate the stage back to a previously saved ROI using correlative image matching. The algorithm acquires live images at each zoom level and compares them to the saved pyramid using template matching, iteratively correcting stage position, rotation, and field of view. Requires semphony[find-roi].

result = tescan.imaging.find_roi(
    "./rois/my_roi",
    stage_mode="same_session",
)
# result.found, result.final_pose, result.iterations, result.level_history

Key parameters: stage_mode ("same_session" or "cross_session"), max_iters, px_tol (pixel tolerance), gain_xy / gain_rot / gain_fov (correction gains). See the API reference for all parameters.

Autofocus (DeepFocus)

Run DeepFocus iterative autofocus: acquire two perturbed images (WD +/- sigma), predict working distance and stigmation corrections with a trained CNN, apply and repeat until convergence. Requires semphony[autofocus] and a trained TorchScript model. See the DeepFocus autofocus guide for training, recalibration, and usage.

from semphony.autofocus import AutofocusConfig

result = tescan.imaging.autofocus(AutofocusConfig(
    model_path="./deepfocus_model.pt",
    use_gpu=True,
))
# result.converged, result.iterations, result.final_wd_mm

Stage control

The .stage interface provides absolute and relative stage movement. Coordinates are in millimetres (x, y, z) and degrees (r for rotation, t for tilt).

Get position

stage.get_pos() queries the device SDK for the live stage position. stage.get_latest_pos() returns the last server-stored position (faster, but may be stale).

pos = tescan.stage.get_pos()
# pos: {"x": 10.5, "y": 8.2, "z": 5.0, "r": 0.0, "t": 0.0}

Absolute move

stage.move_to(x, y, z=..., r=...) moves the stage to an absolute position. Only x and y are required.

tescan.stage.move_to(10.5, 8.2, r=45.0)

Relative move (delta)

stage.move_delta(dx=..., dy=..., dz=..., dr=..., dt=...) moves the stage by a relative offset. When guardrails are active, the max move may be limited to a percentage of the current FOV.

tescan.stage.move_delta(dx=0.1, dy=-0.05)

Geometric transformations

The .imaging.geometric_transformations interface provides access to SharkSEM-style geometry parameters (beam shift, tilt correction, rotation, etc.). You can list, get, set, or reset all transformations.

geoms = tescan.imaging.geometric_transformations.list()
value = tescan.imaging.geometric_transformations.get("tilt_correction")
tescan.imaging.geometric_transformations.set("tilt_correction", x=0.0)
tescan.imaging.geometric_transformations.reset()  # zero all

Centerings

The .imaging.centerings interface provides access to SharkSEM-style centering parameters (beam shift, aperture alignment, etc.). The API mirrors geometric transformations: list(), get(name_or_index), and set(name_or_index, x=..., y=...).

centerings = tescan.imaging.centerings.list()
value = tescan.imaging.centerings.get("beam_shift")
tescan.imaging.centerings.set("beam_shift", x=0.0, y=0.0)

Focus parameters & beam control

Focus parameters

Read or write the working distance (mm) and stigmation values. These are also used internally by the autofocus algorithm.

focus = tescan.imaging.get_focus_params()
# {"wd_mm": 10.5, "stigm_x": 0.0, "stigm_y": 0.0}

tescan.imaging.set_focus_params(wd_mm=10.6, stigm_x=0.01)

View field

Set the field of view (in micrometres) without acquiring an image.

tescan.imaging.set_view_field(fov_um=500)

Beam control

Turn the electron beam on or off. Guardrails enforce that vacuum must be present before enabling the beam.

tescan.imaging.set_beam(enabled=True)
tescan.imaging.set_beam(enabled=False)

Device metrics

Return the full device metrics snapshot (beam status, stage, vacuum, stigmator, etc.).

metrics = tescan.imaging.get_metrics()

Human-in-the-loop

Use imaging.await_human(message) to pause the workflow and display a message in the Semphony UI. The call blocks until the operator clicks Continue. Use it for sample loading, ROI selection, manual focus adjustments, or any step that requires human interaction.

tescan.imaging.await_human("Load sample and close chamber.")
# blocks until human clicks Continue in the UI

tescan.imaging.await_human("Navigate to ROI of interest, then continue.")