# ScopeDriverBase

## class ScopeDriverBase[source]

Bases: [`ABC`](https://docs.python.org/3/library/abc.html#abc.ABC "(in Python v3.15)")

Vendor scope driver contract. Concrete drivers compose a transport (typically `VisaDriver`).

Channels are 1-indexed analog input numbers throughout — the wrapper
instrument (`InstroScope`) is responsible for range-checking against the
declared `num_channels`.

Methods

| [`check_errors`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.check_errors "instro.scope.ScopeDriverBase.check_errors") | Drain the vendor's error queue; raise `RuntimeError` if any error is pending. |
| --- | --- |
| [`close`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.close "instro.scope.ScopeDriverBase.close") | Close the underlying transport. |
| [`digitize`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.digitize "instro.scope.ScopeDriverBase.digitize") | Arm a single acquisition and block until the trigger fires and the capture completes. |
| [`fetch_waveform`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.fetch_waveform "instro.scope.ScopeDriverBase.fetch_waveform") | Fetch the most recently acquired waveform from `channel`. |
| [`force_trigger`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.force_trigger "instro.scope.ScopeDriverBase.force_trigger") | Force a trigger event immediately, regardless of the configured conditions. |
| [`get_acquisition_mode`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.get_acquisition_mode "instro.scope.ScopeDriverBase.get_acquisition_mode") | Read back the current acquisition mode. |
| [`get_acquisition_state`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.get_acquisition_state "instro.scope.ScopeDriverBase.get_acquisition_state") | Read back the acquisition run state (RUNNING / STOPPED). |
| [`get_average_count`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.get_average_count "instro.scope.ScopeDriverBase.get_average_count") | Read back the waveforms-to-average count. |
| [`get_coupling`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.get_coupling "instro.scope.ScopeDriverBase.get_coupling") | Read back input coupling on `channel`. |
| [`get_horizontal_scale`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.get_horizontal_scale "instro.scope.ScopeDriverBase.get_horizontal_scale") | Read back the timebase (seconds/div). |
| [`get_probe_attenuation`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.get_probe_attenuation "instro.scope.ScopeDriverBase.get_probe_attenuation") | Read back `channel`'s probe attenuation ratio. |
| [`get_sample_rate`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.get_sample_rate "instro.scope.ScopeDriverBase.get_sample_rate") | Read back the current sample rate (samples per second). |
| [`get_trigger_status`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.get_trigger_status "instro.scope.ScopeDriverBase.get_trigger_status") | Read back the trigger status (ARMED / READY / TRIGGERED / …). |
| [`get_vertical_offset`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.get_vertical_offset "instro.scope.ScopeDriverBase.get_vertical_offset") | Read back `channel`'s vertical offset (volts). |
| [`get_vertical_scale`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.get_vertical_scale "instro.scope.ScopeDriverBase.get_vertical_scale") | Read back `channel`'s vertical scale (V/div). |
| [`load_settings`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.load_settings "instro.scope.ScopeDriverBase.load_settings") | Recall a scope setup from `name`. |
| [`measure`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.measure "instro.scope.ScopeDriverBase.measure") | Read a built-in measurement (VPP, VMAX, VMIN, VAVG, VRMS, …) on `channel`. |
| [`open`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.open "instro.scope.ScopeDriverBase.open") | Open the underlying transport. |
| [`run`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.run "instro.scope.ScopeDriverBase.run") | Start continuous (free-running) acquisition. |
| [`save_screenshot`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.save_screenshot "instro.scope.ScopeDriverBase.save_screenshot") | Capture a screenshot. |
| [`save_settings`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.save_settings "instro.scope.ScopeDriverBase.save_settings") | Save the current scope setup. |
| [`set_acquisition_mode`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.set_acquisition_mode "instro.scope.ScopeDriverBase.set_acquisition_mode") | Set the acquisition mode. |
| [`set_average_count`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.set_average_count "instro.scope.ScopeDriverBase.set_average_count") | Set the number of waveforms to average. |
| [`set_coupling`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.set_coupling "instro.scope.ScopeDriverBase.set_coupling") | Set AC/DC input coupling on `channel`. |
| [`set_horizontal_scale`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.set_horizontal_scale "instro.scope.ScopeDriverBase.set_horizontal_scale") | Set the timebase to `seconds_per_div`. |
| [`set_probe_attenuation`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.set_probe_attenuation "instro.scope.ScopeDriverBase.set_probe_attenuation") | Set `channel`'s probe attenuation ratio (e.g. 1, 10, 100, 1000). |
| [`set_trigger_level`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.set_trigger_level "instro.scope.ScopeDriverBase.set_trigger_level") | Set the trigger threshold to `level` (volts). |
| [`set_trigger_mode`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.set_trigger_mode "instro.scope.ScopeDriverBase.set_trigger_mode") | Set the trigger sweep mode (AUTO / NORMAL). |
| [`set_trigger_slope`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.set_trigger_slope "instro.scope.ScopeDriverBase.set_trigger_slope") | Set the trigger edge slope (RISING / FALLING / EITHER). |
| [`set_trigger_source`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.set_trigger_source "instro.scope.ScopeDriverBase.set_trigger_source") | Set the trigger source to analog `channel`. |
| [`set_trigger_type`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.set_trigger_type "instro.scope.ScopeDriverBase.set_trigger_type") | Set the trigger type (EDGE, PULSE, …). |
| [`set_vertical_offset`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.set_vertical_offset "instro.scope.ScopeDriverBase.set_vertical_offset") | Set `channel`'s vertical offset to `offset` (volts). |
| [`set_vertical_scale`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.set_vertical_scale "instro.scope.ScopeDriverBase.set_vertical_scale") | Set `channel`'s vertical scale to `volts_per_div` (V/div). |
| [`setup_measurement`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.setup_measurement "instro.scope.ScopeDriverBase.setup_measurement") | Ensure a measurement slot exists for `measurement_type`/`channel` before the scope triggers. |
| [`single`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.single "instro.scope.ScopeDriverBase.single") | Arm a single-shot acquisition. |
| [`stop`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.stop "instro.scope.ScopeDriverBase.stop") | Stop acquisition. |

### abstractmethod open() → None[source]

Open the underlying transport. Idempotent.

Concrete drivers also perform any one-shot instrument setup here
(e.g. `*CLS`, remote-mode handshake).

### abstractmethod close() → None[source]

Close the underlying transport. Idempotent.

### abstractmethod check_errors() → None[source]

Drain the vendor’s error queue; raise `RuntimeError` if any error is pending.

Used between setup commands and any blocking query — calling a data
query while the scope’s error queue holds a syntax error would hang.

### abstractmethod set_vertical_scale( volts_per_div: float, channel: int, ) → None[source]

Set `channel`’s vertical scale to `volts_per_div` (V/div).

Drivers may snap to the nearest hardware-supported step. Callers that
need the actual applied value should `get_vertical_scale()` afterward.

### abstractmethod get_vertical_scale(channel: int) → float[source]

Read back `channel`’s vertical scale (V/div).

### abstractmethod set_vertical_offset(offset: float, channel: int) → None[source]

Set `channel`’s vertical offset to `offset` (volts).

### abstractmethod get_vertical_offset(channel: int) → float[source]

Read back `channel`’s vertical offset (volts).

### abstractmethod set_coupling( coupling: Coupling, channel: int, ) → None[source]

Set AC/DC input coupling on `channel`.

### abstractmethod get_coupling( channel: int, ) → Coupling[source]

Read back input coupling on `channel`.

### abstractmethod set_probe_attenuation( factor: float, channel: int, ) → None[source]

Set `channel`’s probe attenuation ratio (e.g. 1, 10, 100, 1000).

### abstractmethod get_probe_attenuation(channel: int) → float[source]

Read back `channel`’s probe attenuation ratio.

### abstractmethod set_horizontal_scale(seconds_per_div: float) → None[source]

Set the timebase to `seconds_per_div`. Applies globally to all channels.

### abstractmethod get_horizontal_scale() → float[source]

Read back the timebase (seconds/div).

### abstractmethod get_sample_rate() → float[source]

Read back the current sample rate (samples per second).

This is the effective hardware rate the scope is acquiring at; it
depends on the timebase, memory depth, and interpolation settings.

### abstractmethod set_acquisition_mode( mode: AcquisitionMode, ) → None[source]

Set the acquisition mode.

Drivers should raise `NotImplementedError` for `AcquisitionMode`
values their scope doesn’t support (e.g. Keysight 1200X has no
ENVELOPE mode).

### abstractmethod get_acquisition_mode() → AcquisitionMode[source]

Read back the current acquisition mode.

### abstractmethod set_average_count(count: int) → None[source]

Set the number of waveforms to average. Only takes effect in `AcquisitionMode.AVERAGE`.

### abstractmethod get_average_count() → int[source]

Read back the waveforms-to-average count.

### abstractmethod run() → None[source]

Start continuous (free-running) acquisition.

### abstractmethod stop() → None[source]

Stop acquisition. Leaves the captured data intact for `fetch_waveform` / `measure`.

### abstractmethod single() → None[source]

Arm a single-shot acquisition.

Non-blocking — use `get_acquisition_state` to poll for STOPPED, or
prefer `digitize()` which combines arming and waiting.

### abstractmethod digitize(timeout: float) → None[source]

Arm a single acquisition and block until the trigger fires and the capture completes.

Acquisition is global — all enabled channels capture simultaneously. On
success the scope is left stopped with valid data ready for readout.

Parameters:
:   **timeout**

    Maximum seconds to wait for the trigger to fire.

Raises:
:   [**TimeoutError**](https://docs.python.org/3/builtins/exceptions.html#TimeoutError "(in Python v3.15)") – Trigger did not fire within `timeout`. The driver
    clears any pending operation so the session stays usable.

### abstractmethod get_acquisition_state() → AcquisitionState[source]

Read back the acquisition run state (RUNNING / STOPPED).

### abstractmethod fetch_waveform( channel: int, ) → WaveformData[source]

Fetch the most recently acquired waveform from `channel`.

Returns:
:   `WaveformData` with `times` in nanoseconds relative to the
    trigger point (negative = pre-trigger) and `voltages` already
    scaled through the configured probe attenuation.

### setup_measurement( measurement_type: ScopeMeasurementType, channel: int, ) → None[source]

Ensure a measurement slot exists for `measurement_type`/`channel` before the scope triggers.

Required for instruments (e.g. Tektronix) that compute measurements
during acquisition — the slot must be present at trigger time or the
first `measure()` returns stale/invalid data. Default is a no-op for
instruments (e.g. Keysight 1200X) that compute on demand.

### abstractmethod measure( measurement_type: ScopeMeasurementType, channel: int, ) → float[source]

Read a built-in measurement (VPP, VMAX, VMIN, VAVG, VRMS, …) on `channel`.

Returns `math.nan` when the scope reports its invalid-measurement
sentinel (no valid acquisition yet, channel off, etc.).

### abstractmethod set_trigger_source(channel: int) → None[source]

Set the trigger source to analog `channel`.

Drivers typically cache this value because the trigger-level SCPI on
some scopes requires the source channel in the same command.

### abstractmethod set_trigger_type( trigger_type: TriggerType, ) → None[source]

Set the trigger type (EDGE, PULSE, …).

### abstractmethod set_trigger_level(level: float) → None[source]

Set the trigger threshold to `level` (volts). Applies to the configured trigger source.

### abstractmethod set_trigger_slope( slope: TriggerSlope, ) → None[source]

Set the trigger edge slope (RISING / FALLING / EITHER).

### abstractmethod set_trigger_mode( mode: TriggerMode, ) → None[source]

Set the trigger sweep mode (AUTO / NORMAL).

AUTO forces an acquisition if no trigger fires within the timeout;
NORMAL waits indefinitely for a real trigger.

### abstractmethod force_trigger() → None[source]

Force a trigger event immediately, regardless of the configured conditions.

### abstractmethod get_trigger_status() → TriggerStatus[source]

Read back the trigger status (ARMED / READY / TRIGGERED / …).

### abstractmethod save_screenshot( filepath: str, to_instrument: bool = False, ) → bytes[source]

Capture a screenshot.

Parameters:
:   - **filepath**

      Output path. When `to_instrument=False` this is a host
      path; when `True` it is a path on the scope’s filesystem
      (USB stick, internal storage).
    - **to_instrument**

      When `True`, the scope writes the file itself and
      this returns `b""`. When `False`, the image is transferred
      to the host, written to `filepath`, and the raw bytes are
      returned for in-memory use.

### abstractmethod save_settings( name: str, to_instrument: bool = False, ) → bytes[source]

Save the current scope setup. Path semantics mirror [`save_screenshot()`](https://dev.nominal.io/instro/ref/instruments/instro.scope.ScopeDriverBase.md#instro.scope.ScopeDriverBase.save_screenshot "instro.scope.ScopeDriverBase.save_screenshot").

### abstractmethod load_settings( name: str, from_instrument: bool = False, ) → None[source]

Recall a scope setup from `name`.

With `from_instrument=True` the scope reads from its own filesystem;
otherwise the host reads `name` and pushes the bytes to the scope.
After loading, the calling `InstroScope` should invalidate its
tracked `ScopeState` and resync if a fresh view is needed.
