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
#
Base class for NMR Relaxometer devices with frequency and temperature control.
set_frequency
#
Set frequency in MHz (Protocol requirement).
get_frequency_range
#
Get frequency range in MHz (Protocol requirement).
set_frequency_device
#
Set frequency using device-specific units.
get_frequency_device
#
Get frequency with device-specific units.
set_temperature
#
Set temperature (Protocol requirement).
get_target_temperature
#
Get target temperature (Protocol requirement).
get_temperature_range
#
Get temperature range (Protocol requirement).
wait_for_temperature
#
Wait for temperature to stabilize (Protocol requirement).
set_temperature_device
#
Set temperature using device-specific units.
get_temperature_device
#
Get temperature with device-specific units.
Annotation
dataclass
#
Axis
dataclass
#
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.
type
class-attribute
instance-attribute
#
Bar
dataclass
#
A bar series — vertical bars by default, horizontal with orientation="h".
Contour
dataclass
#
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.
Figure
dataclass
#
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
#
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_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 |
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. |
{}
|
Returns:
| Type | Description |
|---|---|
Figure
|
The figure, so calls can be chained. |
to_spec
#
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 |
dict[str, Any]
|
figure. |
Font
dataclass
#
Font styling for titles, axis labels, and annotation text.
Heatmap
dataclass
#
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.
Layout
dataclass
#
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.
Line
dataclass
#
Line styling: color, width, and dash pattern.
dash
class-attribute
instance-attribute
#
Margin
dataclass
#
Plot margins in pixels: left, right, top, bottom.
Marker
dataclass
#
Marker styling for data points (color, size, symbol).
symbol
class-attribute
instance-attribute
#
symbol: (
Literal[
"circle",
"square",
"diamond",
"cross",
"x",
"triangle-up",
"triangle-down",
]
| None
) = None
Scatter
dataclass
#
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=.
mode
class-attribute
instance-attribute
#
mode: (
Literal[
"lines",
"markers",
"lines+markers",
"text",
"lines+markers+text",
]
| None
) = None
fill
class-attribute
instance-attribute
#
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
Shape
dataclass
#
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
#
DeviceState
#
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.)
Scan
#
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).
signal
property
writable
#
Accumulated signal (FID) as a Signal1D/Signal2D.
spectrum
property
writable
#
spectrum: Spectrum1D | Spectrum2D | None
Accumulated spectrum as a Spectrum1D/Spectrum2D.
peaks
property
writable
#
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
#
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
#
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. |
''
|
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,
group_delay: GroupDelaySettings | None = None,
solvent_suppression: SolventSuppressionSettings
| None = None,
) -> Scan
Apply preprocessing to this scan's 1D signal, in memory.
Runs the same pipeline as a normal scan load — solvent suppression,
apodization, zero-fill, FFT, group-delay removal, phase correction, reference
correction, baseline 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
|
group_delay
|
GroupDelaySettings | None
|
Override the group-delay stage. |
None
|
solvent_suppression
|
SolventSuppressionSettings | None
|
Override the solvent-suppression stage. |
None
|
Raises:
| Type | Description |
|---|---|
PreprocessingError
|
If a stage cannot be applied as configured. |
ProcessingParameterError
|
If a stage parameter is out of range. |
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
|
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
|
Returns:
| Type | Description |
|---|---|
GraphResult
|
A |
FunctionAnalysisResult
dataclass
#
SmartFittingResult
dataclass
#
Result from SmartFittingAPI.fit with comprehensive metadata.
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
model_config
class-attribute
instance-attribute
#
get_visualization
#
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 operation duration in nanoseconds.
Default returns 0 - override in operations with duration.
to_struct
#
Serialize this operation to a protobuf Struct.
Used for sending operations over gRPC.
PulseOp
#
RecordOp
#
SilenceOp
#
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 the current save group path.
Returns:
| Type | Description |
|---|---|
str | None
|
Current group path, or None if saving to project root. |
import_scan
#
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_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 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 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
#
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 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 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. |