---
jupytext:
  formats: md:myst
  text_representation:
    extension: .md
    format_name: myst
    format_version: 0.13
    jupytext_version: 1.11.5
kernelspec:
  display_name: Python 3
  language: python
  name: python3
---

# MSO

The `MSO` class is the main interface for interacting with a Saleae Logic MSO device. It provides methods for capturing data and managing device settings.

## Overview

The `MSO` class handles:
- Device connection and initialization
- Analog capture operations
- Device configuration and settings

## Classes

### `MSO`

```python
class MSO:
    def __init__(self, serial_number: Optional[str] = None)
```

**Parameters:**
- `serial_number`: Optional serial number to connect to a specific device. If not provided, connects to the first available device.

**Properties:**
- `part_number`: The Saleae Part Number for the attached MSO. Supplies information like maximum sample rates and buffer sizes.

## Methods

### `MSO.capture()`

```python
def capture(self,
            capture_config: mso_api.CaptureConfig,
            save_dir: pathlib.Path,
            timeout_secs: Optional[float] = None) -> mso_api.Capture
```

Captures data from the device according to the specified configuration.

**Parameters:**
- `capture_config`: Configuration for the capture (channels, sample rate, etc.)
- `save_dir`: Directory to save capture data
- `timeout_secs`: Optional timeout for the capture operation

**Returns:**
- A `Capture` object containing the captured data

**Note:** This method will:
1. Create the save directory if it doesn't exist
2. Save the record options to `record_options.json`
3. Execute the capture command
4. Save the record result to `record_result.json`
5. Load the captured data into a `Capture` object

**Example Usage:**

```{code-cell} python
from pathlib import Path
from saleae.mso_api import MSO, CaptureConfig, AnalogChannel, AnalogSettings, TimedCapture

# Initialize the MSO
mso = MSO()

# Configure the capture
config = CaptureConfig(
    enabled_channels=[AnalogChannel(channel=0, name="clock")],
    analog_settings=AnalogSettings(sample_rate=100e6),
    capture_settings=TimedCapture(capture_length_seconds=0.1),
)

# Perform the capture
save_dir = Path("my-capture")
capture = mso.capture(config, save_dir=save_dir)

# Access the captured data and inspect the actual (effective) capture settings
print(f"Captured {capture.analog_data['clock'].num_samples} samples at a "
      f"{capture.config.analog_settings.sample_rate/1e6:.1f} MHz sample rate")
```

## Error Handling

The `MSO` class can raise the following exceptions, which are all subclasses of `MsoApiError`:
- `CaptureTimeoutError` when capture operations timeout
- `MsoCommandError` when device commands otherwise fail
- `SmartCableNotReadyError` when a digital capture is initiated on a Smart Cable that's not plugged in
- `SaleaeCommsProcessError` when something has broken in the low-level communications layer, or the device has been unplugged from USB during a capture.

If either of these conditions arise, the directory you requested your capture to be saved in
will contain a file called `traceback.txt` with debug information from your own program
as well as the underlying capture executable.

### `CaptureTimeoutError`

```python
class CaptureTimeoutError(MsoApiError):
    def __init__(self, timeout_seconds: Optional[float] = None):
        self.timeout_seconds = timeout_seconds
```

Exception raised when a capture operation times out. This can occur in two scenarios:
- No trigger condition was found during a triggered capture
- The actual capturing and uploading did not complete within the specified timeout period

If you're running into a lot of these, try the following:
 - check that your trigger condition is actually occurring on the channel you've configured within the trigger timeout
 - consider increasing (or dropping) the overall command timeout (`timeout_secs`), as that includes upload time from
   the device.

**Attributes:**
- `timeout_seconds`: The timeout duration that was exceeded

### `MsoCommandError`

```python
class MsoCommandError(MsoApiError):
    def __init__(self, command: str, stdout: str):
        self.command = command
        self.stdout = stdout
        super().__init__(f"Command {command} failed, stdout was: {stdout}")
```

Exception raised when device commands otherwise fail.

**Attributes:**
- `command`: The command that failed
- `stdout`: The stdout output from the command

### `SmartCableNotReadyError`

```python
class SmartCableNotReadyError(MsoApiError):
    def __init__(self, command: str, stdout: str):
        self.command = command
        self.stdout = stdout
        super().__init__(f"Smart cable was not connected or initialized in time. {command} failed, stdout was: {stdout}")
```

Exception raised when a smart cable is not ready or not connected. This typically occurs when:
- The smart cable is not properly connected to the MSO device
- The smart cable has not been initialized in time for the capture operation
- There are communication issues with the smart cable hardware

**Attributes:**
- `command`: The command that failed
- `stdout`: The stdout output from the command

**Common Solutions:**
- Ensure the smart cable is properly connected to the MSO device
- Try unplugging and replugging the smart cable
- Verify that the smart cable is being detected by the system by opening Logic2 and attempting to capture data from it

### `SaleaeCommsProcessError`

```python
class SaleaeCommsProcessError(MsoApiError):
    def __init__(self, args: list[str], stdout: str, stderr: str, returncode: int, env: Optional[dict[str, str]] = None):
        self.msoexe_args = args
        self.stdout = stdout
        self.stderr = stderr
        self.returncode = returncode
        self.env = env
```

Exception raised when there are low-level communication issues with the MSO device. This typically occurs when:
- The device is disconnected from USB during a capture operation
- There are fundamental communication problems with the device

**Attributes:**
- `msoexe_args`: The command arguments that were passed to the MSO executable
- `stdout`: The stdout output from the command
- `stderr`: The stderr output from the command
- `returncode`: The return code from the MSO executable
- `env`: The environment variables used during execution

**Note:** If you encounter this error outside of obvious scenarios like disconnecting the USB cable during capture, please contact Saleae support with the error details and your system information. We'd like to get the problem fixed as soon as possible.
