Recording Class API¶
The Recording class is the main class in biosigIO for working with biosignal data. It encapsulates signals, channel information, and metadata, and provides methods for data manipulation and export.
Class Documentation¶
biosigio.core.emg.Recording
¶
Core biosignal recording: signals + channels + events + metadata.
Modality-agnostic container for EEG / EMG / iEEG / MEG / stim / marker data imported from any supported format.
Attributes: signals (pd.DataFrame): Raw signal data with time as index. metadata (dict): Metadata dictionary containing recording information. channels (dict): Channel information including type, unit, sampling frequency. events (pd.DataFrame): Annotations or events associated with the signals, with columns 'onset', 'duration', 'description'.
__init__()
¶
Initialize an empty recording.
from_file(filepath, importer=None, force_csv=False, bids_channels='auto', **kwargs)
classmethod
¶
The method to create a Recording object from file.
Args: filepath: Path to the input file importer: Name of the importer to use. Can be one of the following: - 'trigno': Delsys Trigno EMG system (CSV) - 'otb': OTB/OTB+ EMG system (OTB, OTB+) - 'eeglab': EEGLAB .set files (SET) - 'edf': EDF/EDF+/BDF/BDF+ format (EDF, BDF) - 'csv': Generic CSV (or TXT) files with columnar data - 'wfdb': Waveform Database (WFDB) - 'xdf': XDF format (multi-stream Lab Streaming Layer files) - 'meg': MEG via MNE (.fif and CTF .ds; requires the 'meg' extra) - 'brainvision': BrainVision .vhdr via MNE (requires the 'meg' extra) - 'tabular': biosigIO Parquet/Arrow/Feather (requires the 'arrow' extra) - 'neo': proprietary electrophysiology formats via python-neo (Intan, Blackrock, Spike2, Plexon, Micromed, Neuralynx, ...; requires the 'neo' extra) - 'zarr': biosigIO Zarr serving store (requires the 'zarr' extra) If None, the importer will be inferred from the file extension. Automatic import is supported for CSV/TXT files. force_csv: If True and importer is 'csv', forces using the generic CSV importer even if the file appears to match a specialized format. bids_channels: When 'auto' (default), look for a sibling BIDS _channels.tsv next to the file and apply its per-channel type/units over the importer's inferred values. Pass 'off' to disable. **kwargs: Additional arguments passed to the importer. For XDF files, useful kwargs include: - stream_names: List of stream names to import - stream_types: List of stream types to import (e.g., ["EMG", "EXG"]) - stream_ids: List of stream IDs to import
Returns: Recording: New Recording object with loaded data
add_channel(label, data, sample_frequency, physical_dimension, channel_type, *, modality=None, prefilter='n/a')
¶
Add a new channel to the recording.
Args:
label: Channel label or name (as per EDF specification)
data: Channel data
sample_frequency: Sampling frequency in Hz (as per EDF specification)
physical_dimension: Physical dimension/unit of measurement (as per EDF specification)
channel_type: BIDS channel type ('EEG', 'EMG', 'ECG', 'ACC', 'SEEG', ...).
Required; validated against the modality vocabulary. There is no
default (a missing type must be explicit, e.g. 'OTHER'/'MISC').
modality: Coarse modality ('EEG', 'EMG', 'IEEG', 'MEG', 'BEH', 'MISC').
If None, it is inferred from channel_type.
prefilter: Pre-filtering applied to the channel (keyword-only).
add_event(onset, duration, description)
¶
Add an event/annotation to the recording.
Args: onset: Event onset time in seconds. duration: Event duration in seconds. description: Event description string.
select_channels(channels=None, channel_type=None, inplace=False, *, modality=None)
¶
Select specific channels from the data and return a new Recording object.
Args: channels: Channel name or list of channel names to select. If None and channel_type is specified, selects all channels of that type. channel_type: Type of channels to select ('EMG', 'ACC', 'GYRO', etc.). If specified with channels, filters the selection to only channels of this type.
Returns: Recording: A new Recording object containing only the selected channels
Examples: # Select specific channels new_rec = rec.select_channels(['EMG1', 'ACC1'])
# Select all EMG channels
emg_only = rec.select_channels(channel_type='EMG')
# Select specific EMG channels only, this example does not select ACC channels
emg_subset = rec.select_channels(['EMG1', 'ACC1'], channel_type='EMG')
get_channel_types()
¶
Get list of unique channel types in the data.
Returns: List of channel types (e.g., ['EMG', 'ACC', 'GYRO'])
get_channels_by_type(channel_type)
¶
Get list of channels of a specific type.
Args: channel_type: Type of channels to get ('EMG', 'ACC', 'GYRO', etc.)
Returns: List of channel names of the specified type
set_metadata(key, value)
¶
Set metadata value.
Args: key: Metadata key value: Metadata value
get_metadata(key)
¶
Get metadata value.
Args: key: Metadata key
Returns: Value associated with the key
to_edf(filepath, method='both', fft_noise_range=None, svd_rank=None, precision_threshold=0.01, format='auto', bypass_analysis=None, verify=False, verify_tolerance=1e-06, verify_channel_map=None, verify_plot=False, events_df=None, create_channels_tsv=True, clip_outliers='auto', **kwargs)
¶
Export the recording to EDF/BDF format, optionally including events.
Args:
filepath: Path to save the EDF/BDF file
method: Method for signal analysis ('svd', 'fft', or 'both')
'svd': Uses Singular Value Decomposition for noise floor estimation
'fft': Uses Fast Fourier Transform for noise floor estimation
'both': Uses both methods and takes the minimum noise floor (default)
fft_noise_range: Optional tuple (min_freq, max_freq) specifying frequency range for noise in FFT method
svd_rank: Optional manual rank cutoff for signal/noise separation in SVD method
precision_threshold: Maximum acceptable precision loss percentage (default: 0.01%)
format: Format to use ('auto', 'edf', or 'bdf'). Default is 'auto'.
If 'edf' or 'bdf' is specified, that format will be used directly.
If 'auto', the format (EDF/16-bit or BDF/24-bit) is chosen based
on signal analysis to minimize precision loss while preferring EDF
if sufficient.
bypass_analysis: If True, skip signal analysis step when format is explicitly
set to 'edf' or 'bdf'. If None (default), analysis is skipped
automatically when format is forced. Set to False to force
analysis even with a specified format. Ignored if format='auto'.
verify: If True, reload the exported file and compare signals with the original
to check for data integrity loss. Results are printed. (default: False)
verify_tolerance: Absolute tolerance used when comparing signals during verification. (default: 1e-6)
verify_channel_map: Optional dictionary mapping original channel names (keys)
to reloaded channel names (values) for verification.
Used if verify is True and channel names might differ.
verify_plot: If True and verify is True, plots a comparison of original vs reloaded signals.
events_df: Optional DataFrame with events ('onset', 'duration', 'description').
If None, uses self.events. (This provides flexibility)
create_channels_tsv: If True, create a BIDS-compliant channels.tsv file (default: True)
clip_outliers: Singularity handling for the per-channel physical window.
'auto' (default) keeps the full range losslessly but clips rare extreme
outliers to a robust window only when keeping them would crater the bulk
signal's resolution at the chosen format (with a warning); True always
clips to the robust window; False never clips. See EDFExporter.export for
the advanced outlier_sigmas / min_effective_bits knobs.
**kwargs: Additional arguments for the EDF exporter
Returns: Union[str, None]: If verify is True, returns a string with verification results. Otherwise, returns None.
Raises: ValueError: If no signals are loaded
plot_signals(channels=None, time_range=None, offset_scale=0.8, uniform_scale=True, detrend=False, grid=True, title=None, show=True, plt_module=None)
¶
Plot signals in a single plot with vertical offsets.
Args: channels: List of channels to plot. If None, plot all channels. time_range: Tuple of (start_time, end_time) to plot. If None, plot all data. offset_scale: Portion of allocated space each signal can use (0.0 to 1.0). uniform_scale: Whether to use the same scale for all signals. detrend: Whether to remove mean from signals before plotting. grid: Whether to show grid lines. title: Optional title for the figure. show: Whether to display the plot. plt_module: Matplotlib pyplot module to use.
Attributes¶
Details about the main attributes:
signals¶
pandas.DataFrame: Contains the raw signal data. The index is typically time in seconds (if available from the source file or calculated), and columns represent the different channels.
metadata¶
dict: A dictionary holding metadata about the recording session (e.g., subject ID, recording date, device info). Keys and values depend on the source file.
channels¶
dict: A dictionary where keys are channel labels (strings) and values are dictionaries containing channel-specific information (e.g., sample_frequency, physical_dimension, channel_type, prefilter).
events¶
pandas.DataFrame: Contains time-stamped annotations or events loaded from the file (e.g., from EDF+ or WFDB annotations) or added manually. It has the columns onset, duration, and description.
Key Methods Summary¶
Data Loading¶
from_file(): Load biosignal data from a file (class method)add_channel(): Append a channel (data + metadata) to a Recording
Data Access¶
get_sampling_frequency(): Get the sampling frequency of the dataget_n_samples(): Get the number of samplesget_n_channels(): Get the number of channelsget_duration(): Get the duration of the recording in secondsget_channel_types(): Get the unique channel typesget_channels_by_type(): Get channel names of a specific type
Data Manipulation¶
select_channels(): Create a new Recording object with selected channelsset_metadata(): Set a single metadata fieldget_metadata(): Get a single metadata fieldhas_metadata(): Check if a metadata field exists
Visualization¶
plot_signals(): Plot EMG signals with customizable options
Export¶
to_edf(): Export data to EDF/BDF format with optional verification
Usage Examples¶
Loading Data¶
from biosigio import Recording
# Load from file with automatic importer selection
rec = Recording.from_file("data.otb+")
# Load with explicit importer
rec = Recording.from_file("data.otb+", importer="otb")
# Generic CSV/TXT supports automatic importer selection, but a Delsys Trigno
# export is best loaded with its dedicated importer
rec = Recording.from_file("data.csv", importer='trigno')
Building a Recording Programmatically¶
import numpy as np
from biosigio import Recording
# Start from an empty Recording and add channels
rec = Recording()
rec.add_channel(
label='EMG1',
data=np.array([1.0, 2.0, 3.0, 4.0, 5.0]),
sample_frequency=1000,
physical_dimension='µV',
channel_type='EMG',
)
rec.add_channel(
label='EMG2',
data=np.array([5.0, 4.0, 3.0, 2.0, 1.0]),
sample_frequency=1000,
physical_dimension='µV',
channel_type='EMG',
)
Selecting Channels¶
# Select by channel names
subset = rec.select_channels(['EMG1', 'EMG2'])
# Select by channel type
emg_only = rec.select_channels(channel_type='EMG')
Metadata Handling¶
# Set metadata
rec.set_metadata('subject', 'S001')
# Get metadata
subject = rec.get_metadata('subject')
# Check if metadata exists
if rec.has_metadata('condition'):
condition = rec.get_metadata('condition')
Plotting¶
# Plot all channels
rec.plot_signals()
# Plot specific channels with time range
rec.plot_signals(['EMG1', 'EMG2'], time_range=(0, 5))
# Customize plot
rec.plot_signals(
channels=['EMG1', 'EMG2'],
time_range=(0, 5),
title='EMG Signals',
grid=True,
detrend=False,
offset_scale=0.8
)
Verification¶
from biosigio.analysis.verification import compare_signals, report_verification_results
from biosigio.visualization.static import plot_comparison
import matplotlib.pyplot as plt
# Export with built-in verification
rec_original.to_edf('output', verify=True, verify_tolerance=0.001)
# Export and verify with custom channel mapping
channel_map = {'EMG1': 'CH1', 'EMG2': 'CH2'}
rec_original.to_edf('output', verify=True, verify_channel_map=channel_map)
# Export, verify, and generate verification plot
rec_original.to_edf('output', verify=True, verify_plot=True)
# Manual verification (alternative approach). With the default format='auto',
# to_edf may write either output.edf or output.bdf; reload the path it wrote.
rec_original.to_edf('output')
rec_reloaded = Recording.from_file('output.edf') # or 'output.bdf' if BDF was selected
# Compare signals
results = compare_signals(rec_original, rec_reloaded, tolerance=0.001)
is_identical = report_verification_results(results, verify_tolerance=0.001)
# Plot comparison for visual verification
plot_comparison(rec_original, rec_reloaded, channels=['EMG1', 'EMG2'])
plt.show()