LabKit MATLAB Workbench

reference

Biosignal API

Public API index | App guide

labkit.biosignal.* provides GUI-free import and processing functions for physiological and wearable time-series data. Use it to build a MATLAB script from the same recording, channel, event, segment, template, and measurement structures used by LabKit apps.

labkit.biosignal.version() returns biosignal-library version and compatibility information used by labkit.contract requirement checks.

ECG peak detection is the only modality-specific detector in the current module. Import, filtering, segmentation, template construction, measurement, and group comparison use generic biosignal structures.

Public Surface

Current app-facing functions:

[recording, status] = labkit.biosignal.readRecording(filepath);
names = labkit.biosignal.listChannels(recording);
signal = labkit.biosignal.getChannel(recording, channel);
cropped = labkit.biosignal.cropSignal(signal, [startSec endSec]);
filtered = labkit.biosignal.filterSignal(signal, filterSpec);
ecgPeakOptions = labkit.biosignal.defaultEcgPeakOptions("qrs-streaming");
events = labkit.biosignal.detectEcgPeaks(signal, ecgPeakOptions);
segments = labkit.biosignal.segmentByEvents(signal, events, windowSec);
template = labkit.biosignal.buildTemplate(segments, templateOptions);
measurements = labkit.biosignal.measureSegments(segments, template, measureOptions);
comparison = labkit.biosignal.compareGroups(values, groups);

readRecording accepts MAT files containing timetable variables and delimited text tables such as CSV and TSV.

For delimited text tables, time handling is deliberately conservative. The reader does not treat an arbitrary monotonic numeric column as seconds. It uses a table column as time only when the column is datetime/duration, when the column name is time-like such as time_s or time_ms, or when the caller explicitly passes timeColumn and optionally timeUnit. Otherwise the recording uses a synthetic sample-index time axis and keeps numeric columns as signal channels.

CSV and TXT files from wearable workflows can contain preamble rows, headerless numeric data, I0/I1-style Arduino columns, sec/channel tables with per-column count rows, epoch timestamps, footer metadata rows, gaps, duplicated rows, or time axes that jump backward. The table reader tries to handle the common cases automatically and records import choices in recording.metadata. Backward or duplicate time steps are stitched forward with a nominal sample interval; large positive gaps are preserved and counted in metadata.timeRepair. If auto-detection is ambiguous, the app or caller should pass explicit import options rather than relying on inference.

Example explicit text-table time options:

opts = struct('timeColumn', 'timestamp', 'timeUnit', 'milliseconds');
[recording, status] = labkit.biosignal.readRecording(filepath, opts);

Useful delimited-table options include headerLine, hasHeader, timeColumn, timeUnit, signalColumns, fallbackFs, and timeRepair.

readRecording Options

OptionTypeDefaultValid values / meaning
headerLinepositive integerautoHeader line for text tables, or first data line when hasHeader=false.
hasHeaderlogicalautoWhether the detected/explicit line contains column names.
timeColumnname or 1-based indexautoExplicit time column. Use this when auto-detection is ambiguous.
timeUnitstringinferseconds, milliseconds, microseconds, nanoseconds, or sample/index aliases.
signalColumnsnames or 1-based indicesall numeric non-time columnsRestricts imported signal channels.
fallbackFspositive scalar HznoneUsed for synthetic sample-index time or timestamp repair fallback.
timeRepairstringautoauto stitches duplicate/backward time steps; none/off disables repair.
gapFactorpositive scalar20Positive gaps larger than this multiple of nominal dt are counted as large gaps.
useFirstNumericColumnAsTimelogicalfalseOpt-in fallback for ambiguous text tables.

Data Structures

Functions exchange ordinary MATLAB structures with these principal fields:

recording.sourcePath, recording.name, recording.signals, recording.metadata
signal.time, signal.values, signal.fs, signal.name, signal.displayName, signal.metadata
events.index, events.time, events.amplitude, events.score, events.label
segments.values, segments.timeOffset, segments.eventIndex, segments.eventTime, segments.fs
template.values, template.timeOffset, template.keptSegmentIndex, template.score
measurements.perSegment, measurements.summary

Open an individual function page for required fields, row/column orientation, units, empty-result behavior, and errors.

Processing Provided By This Module

The public functions cover:

detectEcgPeaks supports qrs-streaming, pan-tompkins, and local methods. Select the method through its options; no detector-specific helper call is required.

detectEcgPeaks Options

Start from labkit.biosignal.defaultEcgPeakOptions(method) and override only the fields the app exposes:

opts = labkit.biosignal.defaultEcgPeakOptions("pan-tompkins");
opts.polarity = "positive";
opts.minDistanceSec = 0.35;
events = labkit.biosignal.detectEcgPeaks(signal, opts);
OptionTypeDefaultValid values / meaning
methodstringqrs-streamingqrs-streaming, pan-tompkins, or local.
polaritystringautoauto, positive, negative, or absolute.
minDistanceSecpositive scalar0.25 for ECG methods, 0.05 for localMinimum accepted peak spacing.
thresholdStdscalar3Local method robust-threshold multiplier.
smoothSecpositive scalar0.01Local method score smoothing window.
integrationWindowSecpositive scalar0.150Pan-Tompkins moving-integration window.
refineSearchSecpositive scalar0.120 Pan-Tompkins, 0.090 streamingDetector-trace peak snap search half-window.
rawRefineSearchSecpositive scalar0.020Final raw-signal peak snap half-window for Pan-Tompkins and streaming.
baselineWindowSecpositive scalar0.600Streaming causal baseline window.
envelopeWindowSecpositive scalar0.080Streaming slope-envelope window.
lookaheadSecpositive scalar0.080Streaming local-maximum lookahead.
minTemplateScorescalar0.45Streaming rolling-template QC threshold.
medianPolarityCorrectionlogicaltrueStreaming post-pass for auto/positive polarity: reviews recent anchors against the signal median and re-snaps inverted anchors.
medianReviewPeakCountpositive integer3Number of latest streaming peaks considered by the median polarity review.

Other Processing Options

FunctionOptions / parameters
filterSignal(signal, spec)spec.type: bandpass, lowpass, highpass, none, off; spec.cutoffHz: scalar or [low high]; spec.edgeMode: reflect default or none; spec.edgePadSec: padding seconds, auto by default; spec.edgeTaperSec: padded-edge taper seconds, default 1.
segmentByEvents(signal, events, windowSec)windowSec: [start end] seconds relative to event, default [-0.35 0.35].
buildTemplate(segments, opts)opts.topN: positive integer, default min(30, segmentCount).
measureSegments(segments, template, opts)opts.signalWindowSec: [start end], default [-0.06 0.06]; opts.noiseWindowsSec: N-by-2 matrix, default [-0.30 -0.20; 0.40 0.50].

Applications decide:

These application choices are intentionally not parameters of the generic biosignal functions.

Reference Contract

The generated page for every labkit.biosignal function documents its exact input structure, implemented options, defaults, legal values, empty-result and error behavior, and related functions. The repository documentation contract discovers the whole public package rather than relying on a hand-maintained function list, and executes every block labeled Example:.

Change history