Skip to content

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 data
  • get_n_samples(): Get the number of samples
  • get_n_channels(): Get the number of channels
  • get_duration(): Get the duration of the recording in seconds
  • get_channel_types(): Get the unique channel types
  • get_channels_by_type(): Get channel names of a specific type

Data Manipulation

  • select_channels(): Create a new Recording object with selected channels
  • set_metadata(): Set a single metadata field
  • get_metadata(): Get a single metadata field
  • has_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()

Exporting

# Export with automatic format selection
rec.to_edf('output')

# Force EDF format
rec.to_edf('output', format='edf')

# Control format selection method
rec.to_edf('output', method='svd')