Trigno Examples¶
This page demonstrates how to work with EMG data from the Delsys Trigno wireless EMG system. Trigno data is exported as CSV files with a metadata preamble followed by a data table. The importer reads per-channel Label: ... Sampling frequency: ... Unit: ... lines from the preamble, then locates the data header line (the one containing the X[s] time column) and reads the samples below it. Per-channel sampling frequency comes from each channel's Sampling frequency: field, so EMG and accelerometer (ACC) channels can carry different rates.
Basic Trigno Example¶
import os
from biosigio import Recording
import matplotlib.pyplot as plt
# Load data from Trigno CSV file
data_path = 'path_to_your_trigno_data.csv'
rec = Recording.from_file(data_path, importer='trigno')
# Print information about the loaded data
print(f"Number of channels: {rec.get_n_channels()}")
print(f"Number of samples: {rec.get_n_samples()}")
# Trigno recordings are often mixed-rate (EMG vs ACC/GYRO), so a single overall
# sampling frequency may not exist. get_sampling_frequency() raises ValueError in
# that case; read the per-channel rate from channels[ch]['sample_frequency'] instead.
try:
print(f"Sampling frequency: {rec.get_sampling_frequency()} Hz")
except ValueError:
print("Mixed per-channel sampling rates (see per-channel rates below)")
print(f"Recording duration: {rec.get_duration()} seconds")
# List available channels
print("\nAvailable channels:")
for ch_name, ch_info in rec.channels.items():
print(f"- {ch_name} ({ch_info['channel_type']})")
print(f" Sampling rate: {ch_info['sample_frequency']} Hz")
print(f" Dimension: {ch_info['physical_dimension']}")
# Plot EMG signals
rec.plot_signals(time_range=(0, 5), title="Raw EMG Signals")
plt.tight_layout()
plt.show()
Separating EMG and ACC Channels¶
Trigno systems often record both EMG and accelerometer data. You can separate these channels for analysis:
# Get EMG channels
emg_channels = rec.get_channels_by_type('EMG')
print(f"EMG channels: {emg_channels}")
# Create EMG-only object
emg_only = rec.select_channels(emg_channels)
# Get accelerometer channels
acc_channels = rec.get_channels_by_type('ACC')
print(f"ACC channels: {acc_channels}")
# Create ACC-only object
acc_only = rec.select_channels(acc_channels)
# Plot EMG and ACC signals separately (each call manages its own figure)
emg_only.plot_signals(time_range=(0, 5), title="EMG Signals")
acc_only.plot_signals(time_range=(0, 5), title="Accelerometer Signals")
Exporting Trigno Data to EDF/BDF¶
You can export the Trigno data to EDF or BDF format for use with other software.
EDF/BDF requires a single sampling rate across all channels, so a mixed-rate
Trigno recording (EMG vs ACC/GYRO) must be split by channel type (or resampled to
a common rate) before export; exporting a mixed-rate recording raises a
ValueError.
# Export only EMG channels (a single-rate subset)
emg_only = rec.select_channels(channel_type='EMG')
output_path = 'trigno_emg_only'
emg_only.to_edf(output_path) # Format (EDF/BDF) will be selected automatically
print(f"Exported EMG channels to: {output_path}")
# Accelerometer channels have a different rate, so export them separately
acc_only = rec.select_channels(channel_type='ACC')
acc_only.to_edf('trigno_acc_only')
print("Exported ACC channels to: trigno_acc_only")
Working with Multiple Trigno Recordings¶
If you have multiple recordings from the same experiment, you can load them separately and compare:
# Load two recordings
session1 = Recording.from_file('session1.csv', importer='trigno')
session2 = Recording.from_file('session2.csv', importer='trigno')
# Add metadata to distinguish them
session1.set_metadata('session', '1')
session1.set_metadata('condition', 'rest')
session2.set_metadata('session', '2')
session2.set_metadata('condition', 'active')
# Plot channels from both sessions (each call manages its own figure)
channel_to_compare = 'EMG1' # Replace with your channel name
session1.plot_signals([channel_to_compare], time_range=(0, 5),
title=f"Session 1: {session1.get_metadata('condition')}")
session2.plot_signals([channel_to_compare], time_range=(0, 5),
title=f"Session 2: {session2.get_metadata('condition')}")
Complete Trigno Workflow Example¶
Here's a complete workflow using Trigno data:
import os
from biosigio import Recording
import matplotlib.pyplot as plt
import numpy as np
# 1. Load the data
data_path = 'trigno_recording.csv'
rec = Recording.from_file(data_path, importer='trigno')
# 2. Add metadata
rec.set_metadata('subject', 'S001')
rec.set_metadata('condition', 'reaching')
# 3. Select only EMG channels
emg_only = rec.select_channels(channel_type='EMG')
# The EMG-only subset has a single rate, so get_sampling_frequency() is safe here
# (the full mixed-rate recording would raise ValueError).
emg_only.set_metadata('sampling_rate', emg_only.get_sampling_frequency())
# 4. Plot raw signals (plot_signals manages its own figure). Pass show=False so
# the figure stays open for savefig; plot_signals calls plt.show() by default.
emg_only.plot_signals(time_range=(0, 10),
title="Raw EMG Signals", show=False)
plt.savefig('raw_emg.png')
plt.show()
# 5. Export to EDF/BDF
output_path = 'processed_emg'
emg_only.to_edf(output_path)
print(f"Processing complete. Data exported to: {output_path}")
This example demonstrates a complete workflow from loading Trigno data to selecting channels, visualizing, and exporting to EDF/BDF format.