Skip to content

device#

Talk to the connected NMR instrument.

Read and set the instrument's temperature, frequency, phase, and pulse durations, and run pulse sequences on it with execute. Methods that need hardware raise an error if no device is connected — guard with is_connected when in doubt.

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]

DEVICE_VENDOR Requires device #

DEVICE_VENDOR() -> str

Name of the connected instrument's vendor/provider (e.g. its make).

DWELL_TIME Requires device #

DWELL_TIME() -> float

Dwell time in seconds — the spacing between acquired sample points.

This is the sampling interval of the digitiser; its inverse is the
spectral width. Available on relaxometer-type devices.

configure Requires device #

configure(config: object) -> bool

Push a settings bundle to the instrument in one call.

Args:
    config: A device configuration object holding the settings to apply.

Returns:
    ``True`` if the instrument accepted the configuration.

execute Requires device #

execute(
    sequence: Sequence[BaseOp],
    return_type: Literal[
        "signal", "spectrum", "both"
    ] = "spectrum",
    num_accum: int = 1,
    report: bool | Literal["auto"] = "auto",
    record: bool = True,
    plot: bool = True,
    manage_run: bool = True,
) -> (
    list[Signal1D]
    | list[Spectrum1D]
    | list[tuple[Signal1D, Spectrum1D]]
)

Run a pulse sequence on the instrument and collect the result.

Executes the given operations, accumulates the requested number of scans,
and (by default) plots the result and saves it into the current state.

Args:
    sequence: The list of operations to run (build them with the ``ops``
        namespace).
    return_type: What to hand back — ``"signal"`` (the time-domain FID),
        ``"spectrum"`` (the transformed spectrum), or ``"both"``.
    num_accum: Number of scans to average together for signal-to-noise.
    report: Whether to generate a report for the run. ``"auto"`` reports
        unless this call is inside a progress-tracked loop.
    record: Whether to record/persist the acquisition.
    plot: Whether to display the result in the UI.
    manage_run: Leave ``True`` to start and finalise the acquisition
        automatically. Set ``False`` only when you are managing the run
        yourself across several calls (e.g. inside a tuning loop).

Returns:
    A list of results matching ``return_type``: ``Signal1D`` items,
    ``Spectrum1D`` items, or ``(Signal1D, Spectrum1D)`` tuples. For 2D
    acquisitions the data is plotted/saved and an empty list is returned.

get_frequency Requires NMRRelaxometer #

get_frequency(
    return_unit: Literal["Hz", "KHz", "MHz", "GHz"] = "Hz",
) -> float

Read the instrument's current spectrometer (carrier) frequency.

Args:
    return_unit: Unit to report in — e.g. ``"Hz"``, ``"kHz"``, ``"MHz"``,
        ``"GHz"``.

Returns:
    The current frequency in ``return_unit``.

get_info Requires device #

get_info() -> DeviceState

Get a snapshot of the connected instrument.

Returns:
    A device-state object with ``connected`` (bool), ``vendor`` (str), and
    ``metadata`` (model/capability details).

get_pulse_duration Requires NMRRelaxometer #

get_pulse_duration(
    pulse_type: Literal[
        "90deg", "180deg", "270deg", "360deg"
    ]
    | Literal["ringing", "echo"]
    | NmrPulseDirection,
    return_unit: Literal[
        "ns", "us", "ms", "s", "m", "h", "d"
    ] = "us",
) -> float

Read the configured duration of a named pulse.

Args:
    pulse_type: Which pulse to read — a calibrated spec such as ``"90deg"``
        or ``"180deg"``, or a pulse direction.
    return_unit: Time unit to report in (e.g. ``"us"``, ``"ms"``).

Returns:
    The pulse duration in ``return_unit``.

get_settings #

get_settings() -> dict

Read all current instrument settings as a plain dictionary.

Returns:

Type Description
dict

The device settings as name→value pairs (empty if the device exposes

dict

none).

get_temperature Requires NMRRelaxometer #

get_temperature(
    return_unit: Literal["C", "F", "K"] = "C",
) -> tuple[float, float]

Read the instrument's current and target sample temperature.

Args:
    return_unit: Unit to report in — ``"C"``, ``"K"``, or ``"F"``.

Returns:
    A ``(current, target)`` tuple in ``return_unit``.

is_connected #

is_connected() -> bool

Check whether an instrument is connected and ready.

Returns:

Type Description
bool

True if a device is present and reports itself connected.

set_frequency Requires NMRRelaxometer #

set_frequency(
    frequency: float,
    unit: Literal["Hz", "KHz", "MHz", "GHz"] = "Hz",
) -> bool

Set the instrument's spectrometer (carrier) frequency.

Args:
    frequency: Target frequency value.
    unit: Unit of ``frequency`` — e.g. ``"Hz"``, ``"kHz"``, ``"MHz"``,
        ``"GHz"``.

Returns:
    ``True`` once the frequency has been sent.

set_phase Requires NMRRelaxometer #

set_phase(phase_deg: float) -> bool

Set the instrument's receiver/transmitter phase.

Args:
    phase_deg: Phase in degrees.

Returns:
    ``True`` once the phase has been sent.

set_pulse_duration Requires NMRRelaxometer #

set_pulse_duration(
    pulse_type: Literal[
        "90deg", "180deg", "270deg", "360deg"
    ]
    | Literal["ringing", "echo"]
    | NmrPulseDirection,
    duration: float,
    unit: Literal[
        "ns", "us", "ms", "s", "m", "h", "d"
    ] = "us",
) -> None

Set the duration of a named pulse on the instrument.

Args:
    pulse_type: Which pulse to set — a calibrated spec such as ``"90deg"``
        or ``"180deg"``, or a pulse direction.
    duration: New pulse length.
    unit: Unit of ``duration`` (e.g. ``"us"``, ``"ms"``).

set_temperature Requires NMRRelaxometer #

set_temperature(
    temperature: float, unit: Literal["C", "F", "K"] = "C"
) -> bool

Set the instrument's target sample temperature.

Args:
    temperature: Target temperature value.
    unit: Unit of ``temperature`` — ``"C"``, ``"K"``, or ``"F"``.

Returns:
    ``True`` once the setpoint has been sent.