Metadata Handling¶
EMGIO provides comprehensive metadata management capabilities, allowing you to work with recording session information, subject details, and other contextual data. Proper metadata handling is particularly important when working with research data that needs to be shared or archived.
The EMG
object stores various pieces of metadata loaded from the source file or added manually.
Accessing Metadata¶
When you load data into EMGIO, any available metadata from the source file is automatically imported:
# Load data
emg = EMG.from_file('data.set', importer='eeglab')
# Access all metadata
all_metadata = emg.metadata
print(all_metadata)
# Access specific metadata field
subject = emg.get_metadata('subject')
print(f"Subject: {subject}")
# Check if a metadata field exists
if emg.has_metadata('condition'):
condition = emg.get_metadata('condition')
print(f"Condition: {condition}")
You can access the general metadata dictionary directly or use helper methods:
# Access the entire metadata dictionary
all_metadata = emg.metadata
print(all_metadata)
# Get a specific metadata value
subject_id = emg.get_metadata('subject')
fs = emg.get_metadata('sampling_frequency')
print(f"Subject: {subject_id}, Fs: {fs}")
# Set or update a metadata value
emg.set_metadata('task', 'Isometric Contraction')
The specific keys available in emg.metadata
depend on the data format and the information present in the source file header. Common keys might include sampling_frequency
, subject_id
, recording_date
, device information, etc.
Channel-Specific Information¶
Information specific to each channel (like its type, physical dimension/unit, or prefiltering details) is stored within the emg.channels
dictionary, keyed by the channel label:
for channel_name, channel_info in emg.channels.items():
print(f"Channel: {channel_name}")
print(f" Type: {channel_info.get('channel_type', 'N/A')}")
print(f" Unit: {channel_info.get('physical_dimension', 'N/A')}")
print(f" Sampling Freq: {channel_info.get('sample_frequency', 'N/A')}")
print(f" Prefilter: {channel_info.get('prefilter', 'N/A')}")
# Access info for a specific channel
emg1_info = emg.channels['EMG1']
print(f"EMG1 Unit: {emg1_info['physical_dimension']}")
Annotations / Events¶
Time-stamped annotations or events associated with the recording are stored in the emg.events
attribute as a pandas DataFrame.
This DataFrame has the following standard columns:
onset
: The start time of the event in seconds, relative to the beginning of the recording.duration
: The duration of the event in seconds.description
: A string describing the event.
Loading Annotations:
- EDF/BDF: Annotations stored in the EDF+/BDF+ annotation channel are automatically loaded into
emg.events
by theEDFImporter
. - WFDB: Annotations stored in a corresponding
.atr
(or similar) file are automatically loaded intoemg.events
by theWFDBImporter
when loading the.hea
file. - Other Formats: For formats that don't have standardized annotation support within the file (like CSV, Trigno, OTB, EEGLAB
.set
), annotations are typically not loaded automatically. You may need to load them from a separate file and add them manually.
Accessing Annotations:
# Check if any events were loaded
if emg.events is not None and not emg.events.empty:
print(f"Loaded {len(emg.events)} events.")
print("First 5 events:")
print(emg.events.head())
# Filter events by description
marker_events = emg.events[emg.events['description'].str.contains('Marker')]
print("\nMarker Events:")
print(marker_events)
else:
print("No events/annotations loaded.")
Adding Annotations Manually:
You can add events programmatically using the emg.add_event()
method:
emg.add_event(onset=10.5, duration=5.0, description="Rest Period")
emg.add_event(onset=15.5, duration=0.0, description="Stimulus Onset")
print("\nEvents after adding manually:")
print(emg.events)
Exporting Annotations:
When exporting data using emg.to_edf()
, the events stored in emg.events
are automatically written to the EDF+/BDF+ annotation channel.
Setting Metadata¶
You can add or modify metadata fields:
# Set a single metadata field
emg.set_metadata('subject', 'S001')
# Set multiple metadata fields at once
emg.set_metadata_dict({
'subject': 'S001',
'condition': 'resting',
'experimenter': 'John Doe',
'recording_date': '2023-01-15'
})
Common Metadata Fields¶
While EMGIO is flexible about what metadata you can store, some common fields include:
Field | Description | Example |
---|---|---|
subject |
Subject identifier | "S001" |
session |
Session identifier | "1" |
condition |
Experimental condition | "rest" |
recording_date |
Date of recording | "2023-01-15" |
device |
Recording device | "Trigno Wireless" |
srate |
Sampling rate in Hz | 2000 |
Metadata in Exported Files¶
When exporting to EDF/BDF, EMGIO automatically includes metadata in the file header and generates a sidecar channels.tsv file with channel-specific metadata following BIDS conventions:
# Export to EDF with metadata
emg.to_edf('output')
# This will create:
# - output.edf or output.bdf (depending on format selection)
# - output.channels.tsv (channel metadata in tab-separated format)
The channels.tsv file will include information like:
name type units sampling_frequency ...
EMG1 EMG µV 2000 ...
EMG2 EMG µV 2000 ...
ACC1 ACC g 2000 ...
Copying Metadata Between EMG Objects¶
When working with multiple EMG objects, you can copy metadata between them:
# Create a subset with only EMG channels
emg_only = emg.select_channels(channel_type='EMG')
# Copy all metadata from original to subset
emg_only.metadata = emg.metadata.copy()
# Or selectively copy metadata
emg_only.set_metadata('subject', emg.get_metadata('subject'))
Best Practices for Metadata¶
- Consistency: Establish conventions for metadata fields and stick to them
- Completeness: Include all relevant information about the recording context
- Standardization: Use standard units and nomenclature
- Validation: Verify metadata accuracy before export
- Documentation: Document your metadata structure for collaborators
By maintaining good metadata practices, you ensure that your EMG data remains interpretable and useful for future analysis.