Skip to content

Provenance

Acquisition provenance: which instrument produced a waveform, configured how

Acquisition provenance: which instrument produced a waveform, configured how.

Snapshots are taken at acquisition time so the recorded settings reflect the state that actually produced the trace. Every field is Optional: a model that cannot answer a query records None instead of failing the acquisition.

AcquisitionProvenance dataclass

AcquisitionProvenance(schema_version: int = SCHEMA_VERSION, instrument: Optional[InstrumentInfo] = None, channels: Dict[int, ChannelSettings] = dict(), trigger: Optional[TriggerSettings] = None, timebase: Optional[float] = None, sample_rate: Optional[float] = None, acquired_at: Optional[str] = None, address: Optional[str] = None, dialect: Optional[str] = None, library_version: Optional[str] = None)

from_scope classmethod

from_scope(scope: Any, channels: Optional[List[int]] = None) -> AcquisitionProvenance

Snapshot the scope's current state. Never raises: unavailable settings become None.

Source code in scpi_control/provenance.py
@classmethod
def from_scope(cls, scope: Any, channels: Optional[List[int]] = None) -> "AcquisitionProvenance":
    """Snapshot the scope's current state. Never raises: unavailable settings become None."""
    instrument = None
    info = getattr(scope, "device_info", None)
    if info:
        instrument = InstrumentInfo(manufacturer=info.get("manufacturer"), model=info.get("model"), serial=info.get("serial"), firmware=info.get("firmware"))

    channel_settings: Dict[int, ChannelSettings] = {}
    for n in channels or []:
        config = None
        try:
            ch = scope.get_channel(n)
            if ch is not None:
                config = ch.get_configuration()
        except Exception:
            logger.debug("Provenance: channel %s configuration unavailable", n, exc_info=True)
        if config is None:
            channel_settings[n] = ChannelSettings(channel=n)
        else:
            channel_settings[n] = ChannelSettings(
                channel=n,
                enabled=config.get("enabled"),
                coupling=config.get("coupling"),
                voltage_scale=config.get("voltage_scale"),
                voltage_offset=config.get("voltage_offset"),
                probe_ratio=config.get("probe_ratio"),
                bandwidth_limit=config.get("bandwidth_limit"),
                unit=config.get("unit"),
            )

    trigger = None
    try:
        tconf = scope.trigger.get_configuration()
        trigger = TriggerSettings(
            mode=tconf.get("mode"),
            trigger_type=tconf.get("type"),
            source=tconf.get("source"),
            level=tconf.get("level"),
            slope=tconf.get("slope"),
            coupling=tconf.get("coupling"),
            holdoff=tconf.get("holdoff"),
        )
    except Exception:
        logger.debug("Provenance: trigger configuration unavailable", exc_info=True)

    timebase = None
    try:
        timebase = scope.timebase
    except Exception:
        logger.debug("Provenance: timebase unavailable", exc_info=True)

    sample_rate = None
    try:
        sample_rate = scope.waveform._get_sample_rate()
    except Exception:
        logger.debug("Provenance: sample rate unavailable", exc_info=True)

    address = None
    host = getattr(scope, "host", None)
    if host:
        address = "{0}:{1}".format(host, getattr(scope, "port", ""))

    from scpi_control import __version__

    return cls(
        instrument=instrument,
        channels=channel_settings,
        trigger=trigger,
        timebase=timebase,
        sample_rate=sample_rate,
        acquired_at=datetime.now(timezone.utc).isoformat(),
        address=address,
        dialect=getattr(scope, "dialect", None),
        library_version=__version__,
    )

See Also

  • Waveform - Waveform acquisition and data handling
  • Waveform I/O - Read saved waveform files back, including their provenance