Skip to content

io#

Load, save, import, and export your data and projects.

Import/export signals and spectra in common file formats, list and load projects / samples / scans from the local library, and save the current data back as a scan. save_group organises newly saved scans into folders, and beep plays a sound to flag an event.

NMRRelaxometer #

NMRRelaxometer(callbacks: DeviceCallbacks | None = None)

Base class for NMR Relaxometer devices with frequency and temperature control.

excluded_capabilities class-attribute #

excluded_capabilities: frozenset[str] = frozenset()

capabilities property #

capabilities: frozenset[str]

String IDs of all capabilities this object implements.

device_type class-attribute #

device_type: str = 'unknown'

provider class-attribute #

provider: str = 'core'

display_name class-attribute #

display_name: str = 'Unknown Device'

hidden class-attribute #

hidden: bool = False

supported_ops class-attribute #

supported_ops: list[type] = []

connected property #

connected: bool

Check if device is connected.

device_state property #

device_state: DeviceState

Current lifecycle state.

kind class-attribute #

kind: DeviceKind = DeviceKind.NMR_RELAXOMETER

dwell_time abstractmethod property #

dwell_time: float

execute_sequence #

execute_sequence(
    sequence: Sequence[SequenceT_contra],
) -> Sequence[Trace]

Execute a sequence.

Parameters:

Name Type Description Default
sequence Sequence[SequenceT_contra]

Sequence in device-specific format

required

Returns:

Type Description
Sequence[Trace]

Execution results in device-specific format

implements #

implements(protocol: type[_P]) -> bool

Check whether this object implements protocol (an isinstance check).

has_capability #

has_capability(capability_id: str) -> bool

has_all_capabilities #

has_all_capabilities(*capability_ids: str) -> bool

has_any_capability #

has_any_capability(*capability_ids: str) -> bool

connect #

connect(config: DeviceConnConfigT) -> bool

Connect to the device.

Parameters:

Name Type Description Default
config DeviceConnConfigT

Device-specific connection configuration (dict or typed model)

required

Returns:

Type Description
bool

True if connection successful

Raises:

Type Description
DeviceError

If connection fails

InvalidTransitionError

If device is not in a connectable state

disconnect #

disconnect(no_error: bool = False) -> bool

Disconnect from the device.

Parameters:

Name Type Description Default
no_error bool

Do nothing if the device is not currently connected.

False

Returns:

Type Description
bool

True if disconnection successful

Raises:

Type Description
DeviceError

If disconnection fails

configure #

configure(config: DeviceConfigT | None = None) -> bool

Configure the device.

Parameters:

Name Type Description Default
config DeviceConfigT | None

Device-specific configuration

None

Returns:

Type Description
bool

True if configuration successful

Raises:

Type Description
DeviceError

If configuration fails or device not connected

halt #

halt() -> bool

Halt any ongoing operations on the device.

Returns:

Type Description
bool

True if halt successful

Raises:

Type Description
DeviceError

If halt fails or device not connected

execute #

execute(
    sequence: list[Any],
    num_accum: int = 1,
    record: bool = True,
    report: bool = True,
) -> list[Any]

Execute a sequence with accumulation and recording options.

This is the main execution method used by DeviceAPI. Subclasses should implement _execute to handle device-specific execution.

Parameters:

Name Type Description Default
sequence list[Any]

List of operations (BaseOp instances)

required
num_accum int

Number of accumulations

1
record bool

Whether to record data

True
report bool

Whether to report progress

True

Returns:

Type Description
list[Any]

List of execution results (typically Trace objects)

validate_sequence #

validate_sequence(sequence: Any) -> tuple[bool, str]

Validate if a sequence can be executed.

Default implementation accepts everything. Override for validation.

Parameters:

Name Type Description Default
sequence Any

Sequence to validate

required

Returns:

Type Description
tuple[bool, str]

Tuple of (is_valid, error_message)

get_supported_ops #

get_supported_ops() -> list[str]

Get list of supported operation IDs.

Extracts op_id from operation classes that were registered via the @operation decorator.

get_supported_op_classes #

get_supported_op_classes() -> list[type]

Get list of supported operation classes.

get_metadata #

get_metadata() -> DeviceMetadata

Get device metadata.

get_device_info #

get_device_info() -> dict

Get device information for gRPC.

get_settings_struct #

get_settings_struct() -> Struct

Get current settings as protobuf Struct.

set_settings_struct #

set_settings_struct(settings: Struct) -> bool

Set settings from protobuf Struct.

get_connection_params_struct #

get_connection_params_struct() -> Struct

Get connection params as Struct for RPC.

Returns connection params used to connect to this device, for persistence in project files.

notify_connection_lost #

notify_connection_lost(reason: str | None = None) -> None

Notify the system that device connection was lost unexpectedly.

Call this method from device implementations when the connection to the physical device is lost (e.g., network failure, device powered off, USB disconnected). This handles cleanup and notifies the frontend.

Parameters:

Name Type Description Default
reason str | None

Optional human-readable reason for the disconnection

None
Example

In your device implementation's connection monitoring:#

if connection_error_detected: self.notify_connection_lost("gRPC connection timed out")

get_connection_schema classmethod #

get_connection_schema() -> dict

Get connection parameters schema as JSON schema.

Auto-extracts from DeviceConnConfigT type parameter. Override only if you need custom schema logic.

Returns:

Type Description
dict

JSON schema dict for connection parameters UI generation

set_frequency #

set_frequency(frequency_mhz: float) -> float

Set frequency in MHz (Protocol requirement).

get_frequency #

get_frequency() -> float

Get frequency in MHz (Protocol requirement).

get_frequency_range #

get_frequency_range() -> tuple[float, float]

Get frequency range in MHz (Protocol requirement).

set_frequency_device #

set_frequency_device(frequency: Frequency) -> bool

Set frequency using device-specific units.

get_frequency_device #

get_frequency_device() -> Frequency

Get frequency with device-specific units.

set_phase #

set_phase(phase_deg: float) -> bool

get_phase #

get_phase() -> float

set_temperature #

set_temperature(temp: Temperature) -> None

Set temperature (Protocol requirement).

get_temperature #

get_temperature() -> Temperature

Get current temperature (Protocol requirement).

get_target_temperature #

get_target_temperature() -> Temperature

Get target temperature (Protocol requirement).

get_temperature_range #

get_temperature_range() -> tuple[Temperature, Temperature]

Get temperature range (Protocol requirement).

wait_for_temperature #

wait_for_temperature(
    target: Temperature, tolerance: float = 0.1
) -> bool

Wait for temperature to stabilize (Protocol requirement).

set_temperature_device #

set_temperature_device(temperature: Temperature) -> bool

Set temperature using device-specific units.

get_temperature_device #

get_temperature_device() -> TemperatureCouple

Get temperature with device-specific units.

resolve_duration #

resolve_duration(direction: NmrPulseDirection) -> Duration

set_duration staticmethod #

set_duration(
    direction: NmrPulseDirection, value: Duration
) -> None

Annotation dataclass #

Annotation(
    x: float | str | None = None,
    y: float | str | None = None,
    text: str | None = None,
    showarrow: bool | None = None,
    textangle: float | None = None,
    xanchor: Literal["auto", "left", "center", "right"]
    | None = None,
    yanchor: Literal["auto", "top", "middle", "bottom"]
    | None = None,
    font: Font | dict[str, Any] | None = None,
    xref: str | None = None,
    yref: str | None = None,
    ax: float | None = None,
    ay: float | None = None,
    arrowcolor: str | None = None,
    arrowwidth: float | None = None,
    bgcolor: str | None = None,
    extras: dict[str, Any] = dict(),
)

A text annotation placed at a point on the plot, optionally with an arrow.

x class-attribute instance-attribute #

x: float | str | None = None

y class-attribute instance-attribute #

y: float | str | None = None

text class-attribute instance-attribute #

text: str | None = None

showarrow class-attribute instance-attribute #

showarrow: bool | None = None

textangle class-attribute instance-attribute #

textangle: float | None = None

xanchor class-attribute instance-attribute #

xanchor: (
    Literal["auto", "left", "center", "right"] | None
) = None

yanchor class-attribute instance-attribute #

yanchor: (
    Literal["auto", "top", "middle", "bottom"] | None
) = None

font class-attribute instance-attribute #

font: Font | dict[str, Any] | None = None

xref class-attribute instance-attribute #

xref: str | None = None

yref class-attribute instance-attribute #

yref: str | None = None

ax class-attribute instance-attribute #

ax: float | None = None

ay class-attribute instance-attribute #

ay: float | None = None

arrowcolor class-attribute instance-attribute #

arrowcolor: str | None = None

arrowwidth class-attribute instance-attribute #

arrowwidth: float | None = None

bgcolor class-attribute instance-attribute #

bgcolor: str | None = None

extras class-attribute instance-attribute #

extras: dict[str, Any] = field(default_factory=dict)

Axis dataclass #

Axis(
    title: str | dict[str, Any] | None = None,
    range: list[float] | tuple[float, float] | None = None,
    autorange: bool | Literal["reversed"] | None = None,
    type: Literal["linear", "log", "date", "category"]
    | None = None,
    showgrid: bool | None = None,
    gridcolor: str | None = None,
    gridwidth: float | None = None,
    zeroline: bool | None = None,
    zerolinecolor: str | None = None,
    zerolinewidth: float | None = None,
    tickformat: str | None = None,
    showticklabels: bool | None = None,
    domain: list[float] | tuple[float, float] | None = None,
    anchor: str | None = None,
    matches: str | None = None,
    nticks: int | None = None,
    extras: dict[str, Any] = dict(),
)

Settings for one axis: title, range, scale, gridlines, and ticks.

Common fields: title, range=[lo, hi] (or autorange=True), type="log" for a logarithmic scale, and showgrid.

title class-attribute instance-attribute #

title: str | dict[str, Any] | None = None

range class-attribute instance-attribute #

range: list[float] | tuple[float, float] | None = None

autorange class-attribute instance-attribute #

autorange: bool | Literal['reversed'] | None = None

type class-attribute instance-attribute #

type: (
    Literal["linear", "log", "date", "category"] | None
) = None

showgrid class-attribute instance-attribute #

showgrid: bool | None = None

gridcolor class-attribute instance-attribute #

gridcolor: str | None = None

gridwidth class-attribute instance-attribute #

gridwidth: float | None = None

zeroline class-attribute instance-attribute #

zeroline: bool | None = None

zerolinecolor class-attribute instance-attribute #

zerolinecolor: str | None = None

zerolinewidth class-attribute instance-attribute #

zerolinewidth: float | None = None

tickformat class-attribute instance-attribute #

tickformat: str | None = None

showticklabels class-attribute instance-attribute #

showticklabels: bool | None = None

domain class-attribute instance-attribute #

domain: list[float] | tuple[float, float] | None = None

anchor class-attribute instance-attribute #

anchor: str | None = None

matches class-attribute instance-attribute #

matches: str | None = None

nticks class-attribute instance-attribute #

nticks: int | None = None

extras class-attribute instance-attribute #

extras: dict[str, Any] = field(default_factory=dict)

Bar dataclass #

Bar(
    x: ArrayLike | None = None,
    y: ArrayLike | None = None,
    name: str | None = None,
    marker: Marker | dict[str, Any] | None = None,
    orientation: Literal["v", "h"] | None = None,
    xaxis: str | None = None,
    yaxis: str | None = None,
    showlegend: bool | None = None,
    visible: bool | None = None,
    type: Literal["bar"] = "bar",
    extras: dict[str, Any] = dict(),
)

A bar series — vertical bars by default, horizontal with orientation="h".

x class-attribute instance-attribute #

x: ArrayLike | None = None

y class-attribute instance-attribute #

y: ArrayLike | None = None

name class-attribute instance-attribute #

name: str | None = None

marker class-attribute instance-attribute #

marker: Marker | dict[str, Any] | None = None

orientation class-attribute instance-attribute #

orientation: Literal['v', 'h'] | None = None

xaxis class-attribute instance-attribute #

xaxis: str | None = None

yaxis class-attribute instance-attribute #

yaxis: str | None = None

showlegend class-attribute instance-attribute #

showlegend: bool | None = None

visible class-attribute instance-attribute #

visible: bool | None = None

type class-attribute instance-attribute #

type: Literal['bar'] = 'bar'

extras class-attribute instance-attribute #

extras: dict[str, Any] = field(default_factory=dict)

Contour dataclass #

Contour(
    z: Array2D | None = None,
    x: ArrayLike | None = None,
    y: ArrayLike | None = None,
    colorscale: Colorscale | None = None,
    contours: dict[str, Any] | None = None,
    line: Line | dict[str, Any] | None = None,
    ncontours: int | None = None,
    showcolorbar: bool | None = None,
    name: str | None = None,
    xaxis: str | None = None,
    yaxis: str | None = None,
    visible: bool | None = None,
    type: Literal["contour"] = "contour",
    extras: dict[str, Any] = dict(),
)

Contour lines over a 2D grid of values (a topographic-style map).

Like Heatmap, but draws lines joining equal values. ncontours sets roughly how many levels to draw.

z class-attribute instance-attribute #

z: Array2D | None = None

x class-attribute instance-attribute #

x: ArrayLike | None = None

y class-attribute instance-attribute #

y: ArrayLike | None = None

colorscale class-attribute instance-attribute #

colorscale: Colorscale | None = None

contours class-attribute instance-attribute #

contours: dict[str, Any] | None = None

line class-attribute instance-attribute #

line: Line | dict[str, Any] | None = None

ncontours class-attribute instance-attribute #

ncontours: int | None = None

showcolorbar class-attribute instance-attribute #

showcolorbar: bool | None = None

name class-attribute instance-attribute #

name: str | None = None

xaxis class-attribute instance-attribute #

xaxis: str | None = None

yaxis class-attribute instance-attribute #

yaxis: str | None = None

visible class-attribute instance-attribute #

visible: bool | None = None

type class-attribute instance-attribute #

type: Literal['contour'] = 'contour'

extras class-attribute instance-attribute #

extras: dict[str, Any] = field(default_factory=dict)

Figure dataclass #

Figure(
    data: list[_Trace | dict[str, Any]] = list(),
    layout: Layout = Layout(),
)

A complete plot: one or more data series plus a Layout.

Add series with add, draw extra marks with add_shape / add_annotation, and set titles and axes with update_layout. All of these return the figure, so calls can be chained. Pass the finished figure to viz.show_figure(...) or reporting.add_figure(...).

data class-attribute instance-attribute #

data: list[_Trace | dict[str, Any]] = field(
    default_factory=list
)

layout class-attribute instance-attribute #

layout: Layout = field(default_factory=Layout)

add #

add(*traces: _Trace | dict[str, Any]) -> Figure

Add one or more data series (Scatter, Bar, …) to the figure.

Parameters:

Name Type Description Default
*traces _Trace | dict[str, Any]

The series to add.

()

Returns:

Type Description
Figure

The figure, so calls can be chained.

add_shape #

add_shape(shape: Shape | dict[str, Any]) -> Figure

Draw a shape (line, box, circle, …) over the figure.

Parameters:

Name Type Description Default
shape Shape | dict[str, Any]

The Shape to draw.

required

Returns:

Type Description
Figure

The figure, so calls can be chained.

add_annotation #

add_annotation(
    annotation: Annotation | dict[str, Any],
) -> Figure

Add a text label (optionally with an arrow) at a point on the figure.

Parameters:

Name Type Description Default
annotation Annotation | dict[str, Any]

The Annotation to add.

required

Returns:

Type Description
Figure

The figure, so calls can be chained.

update_layout #

update_layout(**kwargs: Any) -> Figure

Set figure-wide options like title and axes by keyword.

For example fig.update_layout(title="...", xaxis=charts.Axis(title="...")). Use the flat form — the xaxis_title= shorthand is not supported; pass xaxis=charts.Axis(title=...) instead.

Parameters:

Name Type Description Default
**kwargs Any

Layout fields to set (e.g. title, xaxis, yaxis, showlegend, height, width).

{}

Returns:

Type Description
Figure

The figure, so calls can be chained.

to_spec #

to_spec() -> dict[str, Any]

Export the figure as a plain dictionary.

You rarely need this directly — viz.show_figure and reporting.add_figure call it for you. Useful if you want to inspect or store the figure's definition. Unset options are dropped and numpy arrays become lists.

Returns:

Type Description
dict[str, Any]

A {"data": [...], "layout": {...}} dictionary describing the

dict[str, Any]

figure.

Font dataclass #

Font(
    size: float | None = None,
    color: str | float | None = None,
    family: str | None = None,
    extras: dict[str, Any] = dict(),
)

Font styling for titles, axis labels, and annotation text.

size class-attribute instance-attribute #

size: float | None = None

color class-attribute instance-attribute #

color: str | float | None = None

family class-attribute instance-attribute #

family: str | None = None

extras class-attribute instance-attribute #

extras: dict[str, Any] = field(default_factory=dict)

Heatmap dataclass #

Heatmap(
    z: Array2D | None = None,
    x: ArrayLike | None = None,
    y: ArrayLike | None = None,
    colorscale: Colorscale | None = None,
    showcolorbar: bool | None = None,
    name: str | None = None,
    xaxis: str | None = None,
    yaxis: str | None = None,
    visible: bool | None = None,
    type: Literal["heatmap"] = "heatmap",
    extras: dict[str, Any] = dict(),
)

A 2D grid of values shown as colours.

z is the grid (rows × columns); optional x and y label the column and row positions. colorscale sets the colour mapping.

z class-attribute instance-attribute #

z: Array2D | None = None

x class-attribute instance-attribute #

x: ArrayLike | None = None

y class-attribute instance-attribute #

y: ArrayLike | None = None

colorscale class-attribute instance-attribute #

colorscale: Colorscale | None = None

showcolorbar class-attribute instance-attribute #

showcolorbar: bool | None = None

name class-attribute instance-attribute #

name: str | None = None

xaxis class-attribute instance-attribute #

xaxis: str | None = None

yaxis class-attribute instance-attribute #

yaxis: str | None = None

visible class-attribute instance-attribute #

visible: bool | None = None

type class-attribute instance-attribute #

type: Literal['heatmap'] = 'heatmap'

extras class-attribute instance-attribute #

extras: dict[str, Any] = field(default_factory=dict)

Layout dataclass #

Layout(
    title: str | dict[str, Any] | None = None,
    xaxis: Axis | dict[str, Any] | None = None,
    yaxis: Axis | dict[str, Any] | None = None,
    xaxis2: Axis | dict[str, Any] | None = None,
    xaxis3: Axis | dict[str, Any] | None = None,
    xaxis4: Axis | dict[str, Any] | None = None,
    yaxis2: Axis | dict[str, Any] | None = None,
    yaxis3: Axis | dict[str, Any] | None = None,
    yaxis4: Axis | dict[str, Any] | None = None,
    showlegend: bool | None = None,
    legend: dict[str, Any] | None = None,
    margin: Margin | dict[str, Any] | None = None,
    shapes: list[Shape | dict[str, Any]] = list(),
    annotations: list[Annotation | dict[str, Any]] = list(),
    paper_bgcolor: str | None = None,
    plot_bgcolor: str | None = None,
    height: float | None = None,
    width: float | None = None,
    font: Font | dict[str, Any] | None = None,
    hovermode: Literal[
        "x", "y", "closest", "x unified", "y unified", False
    ]
    | None = None,
    extras: dict[str, Any] = dict(),
)

The figure's overall look: title, axes, legend, margins, shapes, annotations.

Usually set through Figure.update_layout rather than constructed directly. xaxis2/yaxis2 (and …3/…4) support extra axes for multi-panel figures.

title class-attribute instance-attribute #

title: str | dict[str, Any] | None = None

xaxis class-attribute instance-attribute #

xaxis: Axis | dict[str, Any] | None = None

yaxis class-attribute instance-attribute #

yaxis: Axis | dict[str, Any] | None = None

xaxis2 class-attribute instance-attribute #

xaxis2: Axis | dict[str, Any] | None = None

xaxis3 class-attribute instance-attribute #

xaxis3: Axis | dict[str, Any] | None = None

xaxis4 class-attribute instance-attribute #

xaxis4: Axis | dict[str, Any] | None = None

yaxis2 class-attribute instance-attribute #

yaxis2: Axis | dict[str, Any] | None = None

yaxis3 class-attribute instance-attribute #

yaxis3: Axis | dict[str, Any] | None = None

yaxis4 class-attribute instance-attribute #

yaxis4: Axis | dict[str, Any] | None = None

showlegend class-attribute instance-attribute #

showlegend: bool | None = None

legend class-attribute instance-attribute #

legend: dict[str, Any] | None = None

margin class-attribute instance-attribute #

margin: Margin | dict[str, Any] | None = None

shapes class-attribute instance-attribute #

shapes: list[Shape | dict[str, Any]] = field(
    default_factory=list
)

annotations class-attribute instance-attribute #

annotations: list[Annotation | dict[str, Any]] = field(
    default_factory=list
)

paper_bgcolor class-attribute instance-attribute #

paper_bgcolor: str | None = None

plot_bgcolor class-attribute instance-attribute #

plot_bgcolor: str | None = None

height class-attribute instance-attribute #

height: float | None = None

width class-attribute instance-attribute #

width: float | None = None

font class-attribute instance-attribute #

font: Font | dict[str, Any] | None = None

hovermode class-attribute instance-attribute #

hovermode: (
    Literal[
        "x", "y", "closest", "x unified", "y unified", False
    ]
    | None
) = None

extras class-attribute instance-attribute #

extras: dict[str, Any] = field(default_factory=dict)

Line dataclass #

Line(
    color: str | None = None,
    width: float | None = None,
    dash: Literal[
        "solid",
        "dot",
        "dash",
        "longdash",
        "dashdot",
        "longdashdot",
    ]
    | None = None,
    extras: dict[str, Any] = dict(),
)

Line styling: color, width, and dash pattern.

color class-attribute instance-attribute #

color: str | None = None

width class-attribute instance-attribute #

width: float | None = None

dash class-attribute instance-attribute #

dash: (
    Literal[
        "solid",
        "dot",
        "dash",
        "longdash",
        "dashdot",
        "longdashdot",
    ]
    | None
) = None

extras class-attribute instance-attribute #

extras: dict[str, Any] = field(default_factory=dict)

Margin dataclass #

Margin(
    l: float | None = None,
    r: float | None = None,
    t: float | None = None,
    b: float | None = None,
    extras: dict[str, Any] = dict(),
)

Plot margins in pixels: left, right, top, bottom.

l class-attribute instance-attribute #

l: float | None = None

r class-attribute instance-attribute #

r: float | None = None

t class-attribute instance-attribute #

t: float | None = None

b class-attribute instance-attribute #

b: float | None = None

extras class-attribute instance-attribute #

extras: dict[str, Any] = field(default_factory=dict)

Marker dataclass #

Marker(
    color: str | list[str] | list[float] | None = None,
    size: float | list[float] | None = None,
    symbol: Literal[
        "circle",
        "square",
        "diamond",
        "cross",
        "x",
        "triangle-up",
        "triangle-down",
    ]
    | None = None,
    line: Line | dict[str, Any] | None = None,
    extras: dict[str, Any] = dict(),
)

Marker styling for data points (color, size, symbol).

color class-attribute instance-attribute #

color: str | list[str] | list[float] | None = None

size class-attribute instance-attribute #

size: float | list[float] | None = None

symbol class-attribute instance-attribute #

symbol: (
    Literal[
        "circle",
        "square",
        "diamond",
        "cross",
        "x",
        "triangle-up",
        "triangle-down",
    ]
    | None
) = None

line class-attribute instance-attribute #

line: Line | dict[str, Any] | None = None

extras class-attribute instance-attribute #

extras: dict[str, Any] = field(default_factory=dict)

Scatter dataclass #

Scatter(
    x: ArrayLike | None = None,
    y: ArrayLike | None = None,
    mode: Literal[
        "lines",
        "markers",
        "lines+markers",
        "text",
        "lines+markers+text",
    ]
    | None = None,
    name: str | None = None,
    line: Line | dict[str, Any] | None = None,
    marker: Marker | dict[str, Any] | None = None,
    fill: Literal[
        "none",
        "tozeroy",
        "tozerox",
        "tonexty",
        "tonextx",
        "toself",
    ]
    | None = None,
    fillcolor: str | None = None,
    xaxis: str | None = None,
    yaxis: str | None = None,
    text: list[str] | str | None = None,
    textfont: Font | dict[str, Any] | None = None,
    textposition: Literal[
        "top left",
        "top center",
        "top right",
        "middle left",
        "middle center",
        "middle right",
        "bottom left",
        "bottom center",
        "bottom right",
    ]
    | None = None,
    showlegend: bool | None = None,
    visible: bool | None = None,
    type: Literal["scatter"] = "scatter",
    extras: dict[str, Any] = dict(),
)

A line and/or point series — the most common plot type.

Set mode to "lines", "markers", or "lines+markers" to choose between a connected line, scattered points, or both. Style with line= and marker=.

x class-attribute instance-attribute #

x: ArrayLike | None = None

y class-attribute instance-attribute #

y: ArrayLike | None = None

mode class-attribute instance-attribute #

mode: (
    Literal[
        "lines",
        "markers",
        "lines+markers",
        "text",
        "lines+markers+text",
    ]
    | None
) = None

name class-attribute instance-attribute #

name: str | None = None

line class-attribute instance-attribute #

line: Line | dict[str, Any] | None = None

marker class-attribute instance-attribute #

marker: Marker | dict[str, Any] | None = None

fill class-attribute instance-attribute #

fill: (
    Literal[
        "none",
        "tozeroy",
        "tozerox",
        "tonexty",
        "tonextx",
        "toself",
    ]
    | None
) = None

fillcolor class-attribute instance-attribute #

fillcolor: str | None = None

xaxis class-attribute instance-attribute #

xaxis: str | None = None

yaxis class-attribute instance-attribute #

yaxis: str | None = None

text class-attribute instance-attribute #

text: list[str] | str | None = None

textfont class-attribute instance-attribute #

textfont: Font | dict[str, Any] | None = None

textposition class-attribute instance-attribute #

textposition: (
    Literal[
        "top left",
        "top center",
        "top right",
        "middle left",
        "middle center",
        "middle right",
        "bottom left",
        "bottom center",
        "bottom right",
    ]
    | None
) = None

showlegend class-attribute instance-attribute #

showlegend: bool | None = None

visible class-attribute instance-attribute #

visible: bool | None = None

type class-attribute instance-attribute #

type: Literal['scatter'] = 'scatter'

extras class-attribute instance-attribute #

extras: dict[str, Any] = field(default_factory=dict)

Shape dataclass #

Shape(
    type: Literal[
        "line", "rect", "circle", "path", "triangle"
    ]
    | None = None,
    x0: float | str | None = None,
    x1: float | str | None = None,
    y0: float | str | None = None,
    y1: float | str | None = None,
    path: str | None = None,
    xref: str | None = None,
    yref: str | None = None,
    line: Line | dict[str, Any] | None = None,
    fillcolor: str | None = None,
    opacity: float | None = None,
    layer: Literal["above", "below"] | None = None,
    tipX: float | None = None,
    tipY: float | None = None,
    dx: float | None = None,
    dy: float | None = None,
    lengthPx: float | None = None,
    widthPx: float | None = None,
    label: str | None = None,
    labelColor: str | None = None,
    labelFontSize: float | None = None,
    extras: dict[str, Any] = dict(),
)

A shape drawn over the plot to highlight a region or point.

Set type to "line", "rect", "circle", or "path" and give its corners with x0/y0/x1/y1. A "triangle" type is also available as a peak marker (positioned with tipX/tipY and sized with the dx/ dy/lengthPx/widthPx/label fields).

type class-attribute instance-attribute #

type: (
    Literal["line", "rect", "circle", "path", "triangle"]
    | None
) = None

x0 class-attribute instance-attribute #

x0: float | str | None = None

x1 class-attribute instance-attribute #

x1: float | str | None = None

y0 class-attribute instance-attribute #

y0: float | str | None = None

y1 class-attribute instance-attribute #

y1: float | str | None = None

path class-attribute instance-attribute #

path: str | None = None

xref class-attribute instance-attribute #

xref: str | None = None

yref class-attribute instance-attribute #

yref: str | None = None

line class-attribute instance-attribute #

line: Line | dict[str, Any] | None = None

fillcolor class-attribute instance-attribute #

fillcolor: str | None = None

opacity class-attribute instance-attribute #

opacity: float | None = None

layer class-attribute instance-attribute #

layer: Literal['above', 'below'] | None = None

tipX class-attribute instance-attribute #

tipX: float | None = None

tipY class-attribute instance-attribute #

tipY: float | None = None

dx class-attribute instance-attribute #

dx: float | None = None

dy class-attribute instance-attribute #

dy: float | None = None

lengthPx class-attribute instance-attribute #

lengthPx: float | None = None

widthPx class-attribute instance-attribute #

widthPx: float | None = None

label class-attribute instance-attribute #

label: str | None = None

labelColor class-attribute instance-attribute #

labelColor: str | None = None

labelFontSize class-attribute instance-attribute #

labelFontSize: float | None = None

extras class-attribute instance-attribute #

extras: dict[str, Any] = field(default_factory=dict)

DeviceState #

connected instance-attribute #

connected: bool

vendor instance-attribute #

vendor: str

metadata instance-attribute #

metadata: DeviceMetadata

GraphResult #

GraphResult(
    results: dict[str, object],
    nodes: list[PostprocessingNode],
)

What a processing graph produced when run over one scan.

Read-only. signal and spectrum give the graph's final results; the outputs mapping holds every final output keyed by the step that produced it. ("Final" steps are the ones whose output nothing else in the graph feeds into.)

outputs property #

outputs: dict[str, object]

Each final step's id mapped to the value it produced.

signal property #

signal: SignalNd | None

The graph's final signal output (the first one, if there are several).

spectrum property #

spectrum: SpectrumNd | None

The graph's final spectrum output (the first one, if there are several).

Scan #

Scan(ref: AnalysisScanRef, scan: Scan | None = None)

One stored scan, with friendly access to its data.

Read its signal, spectrum, peaks, and metadata; the heavy data is loaded from disk only when first accessed, then kept in memory. Assigning to signal/spectrum/peaks changes the scan in memory only — call save to write it back to its own file on disk.

This is what every scans method hands back; you work with it instead of the raw stored record (still reachable via .raw if you ever need it).

id property #

id: str

Scan id (UUID).

project property #

project: str

Name of the project this scan belongs to.

label property #

label: str | None

User/UI-assigned label for this scan within the working set.

group property #

group: str | None

Group/folder path of the scan, if any.

name property #

name: str

Display name (falls back to the scan id).

timestamp property #

timestamp: object

Acquisition timestamp.

experiment_type property #

experiment_type: object

Detected experiment type (COSY, T1_IR, …).

sample property #

sample: object | None

Sample snapshot taken at acquisition time, if any.

metadata property #

metadata: object | None

Acquisition metadata (pulse program, gains, …).

is_loaded property #

is_loaded: bool

Whether the full scan is currently materialized in memory.

signal property writable #

signal: Signal1D | Signal2D | None

Accumulated signal (FID) as a Signal1D/Signal2D.

spectrum property writable #

spectrum: Spectrum1D | Spectrum2D | None

Accumulated spectrum as a Spectrum1D/Spectrum2D.

peaks property writable #

peaks: list[PeakInfo] | list[PeakInfo2D]

Picked peaks for the scan.

Returns the manually picked peaks stored on the scan if present; otherwise the peaks from the most recent explicit perform_analysis call (empty if none). Peaks are not auto-detected on access — call perform_analysis to run detection.

integration_regions property #

integration_regions: list[IntegrationRegion]

Integration regions defined on the scan.

raw property #

raw: Scan

The underlying stored scan record, for advanced use.

Loads from disk on first access. Prefer the friendly accessors above (signal, spectrum, peaks, metadata); reach for this only when you need a field they don't expose.

perform_analysis #

perform_analysis(
    *,
    settings: PeakDetectionSettings | None = None,
    adaptive: bool | None = None,
    min_distance_hz: float | None = None,
    min_height_ratio: float | None = None,
    prominence: float | None = None,
    integration_width_hz: float | None = None,
    normalize_to_peak: int | None = None,
    multiplet_search_width_hz: float | None = None,
) -> list[PeakInfo]

Detect peaks and compute their integrals on this scan's 1D spectrum.

Runs the same analysis the app performs (adaptive detection + integration). Any setting not provided falls back to the user's global peak-detection settings (project display settings), then the app defaults. The result is stored and returned (also reflected by .peaks when there are no manual peaks). Returns an empty list for non-1D spectra.

Parameters:

Name Type Description Default
settings PeakDetectionSettings | None

A full settings object to start from (overrides the global settings as the base); individual keyword args below still win.

None
adaptive bool | None

Noise-adaptive detection.

None
min_distance_hz float | None

Minimum spacing between peaks.

None
min_height_ratio float | None

Minimum height as a fraction of the max (manual mode).

None
prominence float | None

Minimum prominence (manual mode).

None
integration_width_hz float | None

Fixed integration width (0/None = auto).

None
normalize_to_peak int | None

Peak index to normalize areas to (<0 = none).

None
multiplet_search_width_hz float | None

Multiplet clustering window.

None

save #

save(
    *,
    signed: bool = False,
    password: str | None = None,
    comment: str = "",
) -> None

Write modifications back to this scan's own file on disk.

Targets the scan by id/project, so persisting an analysis scan never touches the current/active scan.

Parameters:

Name Type Description Default
signed bool

Use a CFR-21-Part-11 signed save (authorship signature).

False
password str | None

Profile password (required for admin signed saves only).

None
comment str

Optional signing comment.

''

reload #

reload() -> Scan

Drop the cached data so the next access re-reads from disk.

preprocess #

preprocess(
    *,
    settings: PreprocessingSettings | None = None,
    phase_correction: PhaseCorrectionSettings | None = None,
    baseline_correction: BaselineCorrectionSettings
    | None = None,
    apodization: ApodizationSettings | None = None,
    zero_fill: ZeroFillSettings | None = None,
    fft: FftSettings | None = None,
    reference_correction: ReferenceCorrectionSettings
    | None = None,
) -> Scan

Apply preprocessing to this scan's 1D signal, in memory.

Runs the same pipeline as a normal scan load — apodization, zero-fill, FFT, phase correction, baseline correction, reference correction — producing a processed signal and spectrum. Each stage not provided falls back to the user's global preprocessing settings (project.preprocessing_settings). Updates .signal/.spectrum (and invalidates cached peaks) without touching current_scan. No-op for non-1D signals. Returns self.

Parameters:

Name Type Description Default
settings PreprocessingSettings | None

A full settings object to start from (the global settings are the base otherwise); the per-stage args below still win.

None
phase_correction PhaseCorrectionSettings | None

Override the phase-correction stage.

None
baseline_correction BaselineCorrectionSettings | None

Override the baseline-correction stage.

None
apodization ApodizationSettings | None

Override the apodization (window) stage.

None
zero_fill ZeroFillSettings | None

Override the zero-fill stage.

None
fft FftSettings | None

Override the FFT stage.

None
reference_correction ReferenceCorrectionSettings | None

Override the reference-correction stage.

None

analyze #

analyze(*, with_preprocessing: bool | None = None) -> Scan

Run the app's automatic processing on this scan (in memory).

Convenience bundle: optionally preprocess (phase correction, baseline, etc.) then refresh peak analysis — matching what the app does on a normal scan load, without touching current_scan. Returns self.

Parameters:

Name Type Description Default
with_preprocessing bool | None

Whether to preprocess first. Defaults to the project's load_with_preprocessing setting.

None

process #

process(graph: GraphSpec | None = None) -> GraphResult

Run a processing graph over this scan and return its outputs.

Processes this scan's signal/spectrum in the background, without changing the active scan (scans.current) or the processor shown in the UI.

Parameters:

Name Type Description Default
graph GraphSpec | None

Which graph to run — None for the project's current processing graph, the name of a saved processor, or an explicit list of processing nodes.

None

Returns:

Type Description
GraphResult

A GraphResult holding the graph's final outputs.

FunctionAnalysisResult dataclass #

FunctionAnalysisResult(
    function_name: str = "unknown",
    parameter_count: int = 0,
    function_type: str = "unknown",
    confidence: float = 0.0,
    recommended_algorithm: str = "scipy",
    algorithm_confidence: float = 0.0,
    characteristics: dict[str, Any] = dict(),
    analysis_methods: list[str] = list(),
    recommendation_reason: str = "",
    signature: SignatureInfo = SignatureInfo(),
    source_analysis: SourceAnalysis | None = None,
    name_analysis: NameAnalysis = NameAnalysis(),
    numerical_analysis: NumericalAnalysis | None = None,
)

function_name class-attribute instance-attribute #

function_name: str = 'unknown'

parameter_count class-attribute instance-attribute #

parameter_count: int = 0

function_type class-attribute instance-attribute #

function_type: str = 'unknown'

confidence class-attribute instance-attribute #

confidence: float = 0.0

recommended_algorithm class-attribute instance-attribute #

recommended_algorithm: str = 'scipy'

algorithm_confidence class-attribute instance-attribute #

algorithm_confidence: float = 0.0

characteristics class-attribute instance-attribute #

characteristics: dict[str, Any] = field(
    default_factory=dict
)

analysis_methods class-attribute instance-attribute #

analysis_methods: list[str] = field(default_factory=list)

recommendation_reason class-attribute instance-attribute #

recommendation_reason: str = ''

signature class-attribute instance-attribute #

signature: SignatureInfo = field(
    default_factory=SignatureInfo
)

source_analysis class-attribute instance-attribute #

source_analysis: SourceAnalysis | None = None

name_analysis class-attribute instance-attribute #

name_analysis: NameAnalysis = field(
    default_factory=NameAnalysis
)

numerical_analysis class-attribute instance-attribute #

numerical_analysis: NumericalAnalysis | None = None

SmartFittingResult dataclass #

SmartFittingResult(
    success: bool,
    parameters: tuple[float, ...],
    loss: float,
    message: str,
    execution_time: float,
    model_name: str,
    n_iterations: int,
    initial_guess: tuple[float, ...],
    algorithm_used: str,
    model_info: FunctionAnalysisResult,
    data_info: DataAnalysisInfo,
    auto_selected: bool,
)

Result from SmartFittingAPI.fit with comprehensive metadata.

success instance-attribute #

success: bool

parameters instance-attribute #

parameters: tuple[float, ...]

loss instance-attribute #

loss: float

message instance-attribute #

message: str

execution_time instance-attribute #

execution_time: float

model_name instance-attribute #

model_name: str

n_iterations instance-attribute #

n_iterations: int

initial_guess instance-attribute #

initial_guess: tuple[float, ...]

algorithm_used instance-attribute #

algorithm_used: str

model_info instance-attribute #

data_info instance-attribute #

data_info: DataAnalysisInfo

auto_selected instance-attribute #

auto_selected: bool

BaseOp #

Base class for all operations.

Operations are pure data models (Pydantic) that define their parameters. Devices are responsible for interpreting and executing operations.

Example

@operation # Decorator will register and assign ID class PulseOp(BaseOp): phase: rpc.NmrPulseDirection duration: rpc.Duration

op_id class-attribute #

op_id: str

display_name class-attribute instance-attribute #

display_name: str | None = None

category class-attribute instance-attribute #

category: str | None = None

model_config class-attribute instance-attribute #

model_config = ConfigDict(arbitrary_types_allowed=True)

get_visualization #

get_visualization() -> dict[str, Any] | None

Get visualization data for this operation.

Returns a dict with visualization info or None if no visualization. Default implementation returns None - override in subclasses.

get_duration_ns #

get_duration_ns() -> float

Get operation duration in nanoseconds.

Default returns 0 - override in operations with duration.

to_struct #

to_struct() -> Struct

Serialize this operation to a protobuf Struct.

Used for sending operations over gRPC.

from_struct classmethod #

from_struct(struct: Struct) -> BaseOp

Deserialize an operation from a protobuf Struct.

This is a factory method that finds the right operation class based on the op_id stored in the struct.

PulseOp #

op_id class-attribute #

op_id: str

display_name class-attribute instance-attribute #

display_name: str | None = None

category class-attribute instance-attribute #

category: str | None = None

model_config class-attribute instance-attribute #

model_config = ConfigDict(arbitrary_types_allowed=True)

phase instance-attribute #

phase: NmrPulseDirection

duration instance-attribute #

duration: Duration

to_struct #

to_struct() -> Struct

Serialize this operation to a protobuf Struct.

Used for sending operations over gRPC.

from_struct classmethod #

from_struct(struct: Struct) -> BaseOp

Deserialize an operation from a protobuf Struct.

This is a factory method that finds the right operation class based on the op_id stored in the struct.

get_duration_ns #

get_duration_ns() -> float

get_visualization #

get_visualization() -> dict[str, Any]

RecordOp #

op_id class-attribute #

op_id: str

display_name class-attribute instance-attribute #

display_name: str | None = None

category class-attribute instance-attribute #

category: str | None = None

model_config class-attribute instance-attribute #

model_config = ConfigDict(arbitrary_types_allowed=True)

duration instance-attribute #

duration: Duration

to_struct #

to_struct() -> Struct

Serialize this operation to a protobuf Struct.

Used for sending operations over gRPC.

from_struct classmethod #

from_struct(struct: Struct) -> BaseOp

Deserialize an operation from a protobuf Struct.

This is a factory method that finds the right operation class based on the op_id stored in the struct.

get_duration_ns #

get_duration_ns() -> float

get_visualization #

get_visualization() -> dict[str, Any]

SilenceOp #

op_id class-attribute #

op_id: str

display_name class-attribute instance-attribute #

display_name: str | None = None

category class-attribute instance-attribute #

category: str | None = None

model_config class-attribute instance-attribute #

model_config = ConfigDict(arbitrary_types_allowed=True)

duration instance-attribute #

duration: Duration

to_struct #

to_struct() -> Struct

Serialize this operation to a protobuf Struct.

Used for sending operations over gRPC.

from_struct classmethod #

from_struct(struct: Struct) -> BaseOp

Deserialize an operation from a protobuf Struct.

This is a factory method that finds the right operation class based on the op_id stored in the struct.

get_duration_ns #

get_duration_ns() -> float

get_visualization #

get_visualization() -> dict[str, Any]

beep #

beep(
    mode: Literal[
        "success", "warning", "error", "info"
    ] = "info",
    theme: Literal[
        "big-sur",
        "chime",
        "mario",
        "material",
        "pokemon",
        "sonic",
        "zelda",
    ] = "material",
) -> None

Plays an audio signal ("beep"). Can be used to indicate an important event or an error.

Parameters:

Name Type Description Default
mode Literal['success', 'warning', 'error', 'info']

The tone of the signal. Default: "info".

'info'
theme Literal['big-sur', 'chime', 'mario', 'material', 'pokemon', 'sonic', 'zelda']

Variation of the signal. Default: "material".

'material'

export_signal #

export_signal(
    path: str | Path,
    format_id: str | None = None,
    signal: Signal1D | Signal2D | None = None,
) -> bool

Export signal data to file.

Parameters:

Name Type Description Default
path str | Path

Output file path.

required
format_id str | None

Export format ID (e.g., 'csv'). Auto-detected from extension if None.

None
signal Signal1D | Signal2D | None

Signal to export. Uses current state signal if None.

None

Returns:

Type Description
bool

True if export succeeded, False otherwise.

export_spectrum #

export_spectrum(
    path: str | Path,
    format_id: str | None = None,
    spectrum: Spectrum1D | Spectrum2D | None = None,
) -> bool

Export spectrum data to file.

Parameters:

Name Type Description Default
path str | Path

Output file path.

required
format_id str | None

Export format ID (e.g., 'csv'). Auto-detected from extension if None.

None
spectrum Spectrum1D | Spectrum2D | None

Spectrum to export. Uses current state spectrum if None.

None

Returns:

Type Description
bool

True if export succeeded, False otherwise.

get_save_group #

get_save_group() -> str | None

Get the current save group path.

Returns:

Type Description
str | None

Current group path, or None if saving to project root.

import_scan #

import_scan(
    path: str | Path, format_id: str | None = None
) -> bool

Import a scan from file.

The imported data is loaded into State.signal and State.spectrum.

Parameters:

Name Type Description Default
path str | Path

Input file path.

required
format_id str | None

Import format ID. Auto-detected if None.

None

Returns:

Type Description
bool

True if import succeeded, False otherwise.

list_export_formats #

list_export_formats() -> list[str]

List available export format IDs.

Returns:

Type Description
list[str]

List of format IDs (e.g., ['csv', 'jcamp_dx', 'nmrpipe']).

list_import_formats #

list_import_formats() -> list[str]

List available import format IDs.

Returns:

Type Description
list[str]

List of format IDs (e.g., ['jcamp_dx', 'bruker', 'varian']).

list_projects #

list_projects() -> list[str]

List all available project names.

Returns:

Type Description
list[str]

List of project names.

list_samples #

list_samples() -> list[str]

List all available sample names.

Returns:

Type Description
list[str]

List of sample names.

list_scans #

list_scans(project_name: str | None = None) -> list[str]

List all scan IDs in a project.

Parameters:

Name Type Description Default
project_name str | None

Project to list scans from. Uses current project if None.

None

Returns:

Type Description
list[str]

List of scan IDs.

load_project #

load_project(
    name: str, update_state: bool = True
) -> Project | None

Load a project from the repository.

Parameters:

Name Type Description Default
name str

Project name to load.

required
update_state bool

If True, sets as current project in State. Default: True.

True

Returns:

Type Description
Project | None

The loaded Project, or None if not found.

load_sample #

load_sample(
    name: str, update_state: bool = True
) -> Sample | None

Load a sample from the repository.

Parameters:

Name Type Description Default
name str

Sample name to load.

required
update_state bool

If True, sets as current sample in State.project. Default: True.

True

Returns:

Type Description
Sample | None

The loaded Sample, or None if not found.

load_scan #

load_scan(
    scan_id: str,
    project_name: str | None = None,
    update_state: bool = True,
) -> tuple[
    Signal1D | Signal2D | None,
    Spectrum1D | Spectrum2D | None,
]

Load a scan from the repository.

Parameters:

Name Type Description Default
scan_id str

Scan ID to load.

required
project_name str | None

Project containing the scan. Uses current project if None.

None
update_state bool

If True, updates State.signal/spectrum/current_scan. Default: True.

True

Returns:

Type Description
tuple[Signal1D | Signal2D | None, Spectrum1D | Spectrum2D | None]

Tuple of (signal, spectrum), either may be None.

save_as_scan #

save_as_scan(
    signal: Signal1D | Signal2D | None = None,
    spectrum: Spectrum1D | Spectrum2D | None = None,
    name: str = "user_saved",
    project_name: str | None = None,
    group: str | None = None,
) -> str | None

Save provided signal/spectrum as a new scan in the repository.

Parameters:

Name Type Description Default
signal Signal1D | Signal2D | None

Signal data to save (optional).

None
spectrum Spectrum1D | Spectrum2D | None

Spectrum data to save (optional).

None
name str

Name/label for the scan. Default: "user_saved".

'user_saved'
project_name str | None

Project to save to. Uses current project if None.

None
group str | None

Optional group/folder within the project.

None

Returns:

Type Description
str | None

The scan ID if successful, None otherwise.

save_group #

save_group(group_path: str) -> Iterator[None]

Context manager to set the save group for scans.

All scans saved within this context will go to the specified group. The group is created automatically if it doesn't exist.

Parameters:

Name Type Description Default
group_path str

Group path relative to project (e.g., "January/SampleA"). Use empty string "" to save to project root.

required
Example
# Scans acquired in this block go to "Experiment1/Run1" folder
with io.save_group("Experiment1/Run1"):
    acquire()  # Saved to Project/Experiment1/Run1/scan.nscan
    acquire()  # Also saved there

# Back to project root
acquire()  # Saved to Project/scan.nscan

# Nested groups work too
with io.save_group("January"):
    with io.save_group("January/Week1"):  # Absolute path
        acquire()  # Saved to Project/January/Week1/scan.nscan

save_project #

save_project(
    project: Project | None = None, name: str | None = None
) -> bool

Save a project to the repository.

Parameters:

Name Type Description Default
project Project | None

Project to save. Uses State.project if None.

None
name str | None

Override name for the project. Uses project.name if None.

None

Returns:

Type Description
bool

True if successful, False otherwise.

save_sample #

save_sample(
    sample: Sample | None = None, name: str | None = None
) -> bool

Save a sample to the repository.

Parameters:

Name Type Description Default
sample Sample | None

Sample to save. Uses State.project.sample if None.

None
name str | None

Override name for the sample. Uses sample.name if None.

None

Returns:

Type Description
bool

True if successful, False otherwise.

save_state_as_scan #

save_state_as_scan(
    name: str = "user_saved",
    project_name: str | None = None,
    group: str | None = None,
) -> str | None

Save current State.signal and State.spectrum as a new scan.

Parameters:

Name Type Description Default
name str

Name/label for the scan. Default: "user_saved".

'user_saved'
project_name str | None

Project to save to. Uses current project if None.

None
group str | None

Optional group/folder within the project.

None

Returns:

Type Description
str | None

The scan ID if successful, None otherwise.

set_save_group #

set_save_group(group_path: str | None) -> None

Set the save group for subsequent scans (non-context-manager version).

Parameters:

Name Type Description Default
group_path str | None

Group path, or None to reset to project root.

required
Example
io.set_save_group("MyGroup")
acquire()  # Goes to MyGroup
io.set_save_group(None)  # Reset