autoemx.microscope_drivers.PhenomXL module

Electron Microscope Driver

Hardware driver template for controlling an Electron Microscope.

This reference implementation is based on PyPhenom 2.0, but structured for adaptation to other microscope APIs by replacing PyPhenom calls with equivalents.

Purpose

  • Control microscope hardware for autoemx workflows.

  • Provide functions for stage movement, SEM imaging, EDS acquisition, auto-focus/contrast, beam parameter control, and navigation camera operations.

  • Serve as a documented reference for developers adapting to other APIs.

Important

If replacing with another API:
  • Change name of this module so that it corresponds with the employed MicroscopeConfig.ID (autoemx/config/runtime_configs.py), or set it as “driver” in the detector_model.json of the microscopes sharing it (autoemx/calibrations/<ID>/)

  • Maintain function signatures and returned value formats for compatibility.

  • Units in parameters/returns must be consistent across implementations.

  • Error handling should remain explicit and informative (raise EMError).

This code has been tested with the following microscope: - Phenom User Interface Version: 2.0.2-rel - Phenom Type: PhenomXL - Phenom Software Version: 6.8.4.rel.e2fd11083c.28328

Created: Tue Jul 29 13:18:16 2025 Author: Andrea

PyPhenom version:

autoemx.microscope_drivers.PhenomXL.is_microscope_connected() → bool[source]

Return True when driver state indicates a live microscope connection.

autoemx.microscope_drivers.PhenomXL.connect_to_microscope(warn_if_unavailable: bool = True) → bool[source]

Connect to the microscope API on demand.

Returns:

True when connected, False when unavailable.

Return type:

bool

autoemx.microscope_drivers.PhenomXL.frame_rel_to_pixel_coords(pts_rel_coords: ndarray, img_width: int, img_height: int) → ndarray[source]

Convert relative coordinates (normalized by the EM API) into pixel coordinates.

See inline comments for a detailed description of the coordinate system.

Parameters:
  • pts_rel_coords (np.ndarray) – Shape (N, 2) array with (x_rel, y_rel) coordinates. - x_rel in [-0.5, 0.5] - y_rel in [-0.5 * (H / W), 0.5 * (H / W)]

  • img_width (int) – Image width in pixels.

  • img_height (int) – Image height in pixels.

Returns:

Shape (N, 2) array of (x_px, y_px) pixel coordinates.

Return type:

np.ndarray

autoemx.microscope_drivers.PhenomXL.frame_pixel_to_rel_coords(pts_pixel_coords: ndarray, img_width: int, img_height: int) → ndarray[source]

Convert pixel coordinates into relative normalized coordinates compatible with EM API.

See inline comments for a detailed description of the coordinate system.

Parameters:
  • pts_pixel_coords (np.ndarray) – Shape (N, 2) array with (x_px, y_px) pixel coordinates.

  • img_width (int) – Image width in pixels.

  • img_height (int) – Image height in pixels.

Returns:

Shape (N, 2) array of normalized (x_rel, y_rel) coordinates.

Return type:

np.ndarray

autoemx.microscope_drivers.PhenomXL.standby() → None[source]

Put the SEM into standby mode.

autoemx.microscope_drivers.PhenomXL.set_electron_detector_mode(detector_name: str) → None[source]

Set the electron detector mode.

Notes

  • Accepted values of detector names are set at autoemx/config/runtime_configs.py within MicroscopeConfig.detector_type. Ensure ALLOWED_DETECTOR_TYPES is updated when new modes are added.

  • Current version passes the value “BSD”, but PyPhenom requires “All”. This mapping is performed internally.

autoemx.microscope_drivers.PhenomXL.activate() → None[source]

Wake up the instrument from standby mode. Required before sending commands if the SEM is inactive.

autoemx.microscope_drivers.PhenomXL.to_SEM(timeout: int = 120) → None[source]

Switch the instrument to SEM mode.

Parameters:

timeout (int) – Maximum time in seconds to wait for SEM mode activation.

Raises:

TimeoutError – If SEM mode is not reached within timeout seconds.

autoemx.microscope_drivers.PhenomXL.set_high_tension(voltage_keV: float) → None[source]

Set the SEM acceleration voltage.

Parameters:

voltage_keV (float) – Positive value in kiloelectronvolts (keV).

autoemx.microscope_drivers.PhenomXL.set_beam_current(current: float) → None[source]

Set the SEM beam current.

Parameters:

current (float) – Beam current value. Units depend on microscope API requirements.

Notes

Beam current is passed via:

autoemx/config/runtime_configs.py, within MeasurementConfig.beam_current, or predefined in: ~/.autoemx/calibrations/YOUR_MICROSCOPE/Detector_channel_params_calibs/DATE_detector_channel_params_calibs.json using key autoemx.utils.constants.BEAM_CURRENT_KEY.

autoemx.microscope_drivers.PhenomXL.get_EDS_analyser_object()[source]

Retrieve an EDS analyser object for spectral acquisition.

Returns:

EDS Job Analyzer instance.

Return type:

object

Notes

This analyzer should be passed to acquire_XS_spectral_data() for X-ray acquisition.

autoemx.microscope_drivers.PhenomXL.acquire_XS_spectral_data(analyzer, x: float, y: float, max_collection_time: float, target_counts: int, elements: List[str] | None = None, msa_file_export_path=None) → Tuple[ndarray | None, ndarray | None, float | None, float | None][source]

Acquire an EDS spectrum (and optionally background) at given coordinates.

Parameters:
  • analyzer (object) – EDS Analyzer object from get_EDS_analyser_object().

  • x (float) – Coordinates in API units (typically mm).

  • y (float) – Coordinates in API units (typically mm).

  • max_collection_time (float) – Maximum acquisition time in seconds.

  • target_counts (int) – Target X-ray counts for acquisition.

  • elements (list of str, optional) – Element symbols for quantification. If provided, a background spectrum will be quantified using these elements.

  • msa_file_export_path (str | None, optional) – If a path is provided, it exports a .msa spectral file with all the metadata. Default: None

Returns:

(spectrum_data, background_data, real_time, live_time):
spectrum_datanp.ndarray or None

Spectrum data array.

background_datanp.ndarray or None

Quantified background intensities.

real_timefloat or None

Actual time measurement took (seconds).

live_timefloat or None

Detector live time during measurement (seconds).

Return type:

tuple

Raises:

EMError – If acquisition or quantification fails.

autoemx.microscope_drivers.PhenomXL.auto_focus() → float[source]

Automatically optimize SEM focus.

Returns:

Current working distance in millimeters after focus adjustment.

Return type:

float

autoemx.microscope_drivers.PhenomXL.auto_contrast_brightness() → None[source]

Automatically optimize SEM contrast and brightness.

autoemx.microscope_drivers.PhenomXL.adjust_focus(new_wd: float) → None[source]

Set a new working distance.

Parameters:

new_wd (float) – Desired working distance in millimeters.

autoemx.microscope_drivers.PhenomXL.move_to(x: float, y: float) → None[source]

Move stage to an absolute position.

Parameters:
  • x (float) – X coordinate in millimeters.

  • y (float) – Y coordinate in millimeters.

autoemx.microscope_drivers.PhenomXL.move_by(x: float, y: float) → None[source]

Move stage relative to current position.

Parameters:
  • x (float) – X shift in millimeters.

  • y (float) – Y shift in millimeters.

autoemx.microscope_drivers.PhenomXL.get_position() → Tuple[float, float][source]

Get the current absolute stage position.

Optional driver function: during manual navigation, it is used to record where the user moved the stage. Without it, the sample center position is assumed.

Returns:

(x, y) stage coordinates in millimeters.

Return type:

tuple of float

autoemx.microscope_drivers.PhenomXL.get_frame_width() → float[source]

Get current SEM frame width.

Returns:

Frame width in millimeters.

Return type:

float

autoemx.microscope_drivers.PhenomXL.get_range_frame_width() → Tuple[float, float][source]

Get allowed SEM frame width range.

Returns:

Minimum and maximum frame width in millimeters.

Return type:

tuple(float, float)

autoemx.microscope_drivers.PhenomXL.set_frame_width(frame_width: float) → None[source]

Set SEM horizontal field width.

Parameters:

frame_width (float) – Desired frame width in millimeters.

autoemx.microscope_drivers.PhenomXL.get_image_data(width: int = 1920, height: int = 1200, frame_avg: int = 1) → ndarray[source]

Acquire SEM image data.

Parameters:
  • width (int, default=1920) – Image width in pixels.

  • height (int, default=1200) – Image height in pixels.

  • frame_avg (int, default=1) – Number of frames to average for acquisition.

Returns:

SEM image data as NumPy array (8-bit if thresholds are used).

Return type:

np.ndarray

autoemx.microscope_drivers.PhenomXL.set_brightness(val: float) → None[source]

Set SEM brightness level.

autoemx.microscope_drivers.PhenomXL.set_contrast(val: float) → None[source]

Set SEM contrast level.

autoemx.microscope_drivers.PhenomXL.get_current_wd() → float[source]

Get current SEM working distance.

Returns:

Working distance in millimeters.

Return type:

float

autoemx.microscope_drivers.PhenomXL.to_nav() → bool[source]

Switch instrument to navigation camera (optical) mode.

Returns:

True if successfully switched to navigation mode, False otherwise.

Return type:

bool

autoemx.microscope_drivers.PhenomXL.get_navigation_camera_image() → ndarray | None[source]

Acquire image from navigation camera.

Returns:

RGB navigation camera image, or None if acquisition fails.

Return type:

np.ndarray or None