Skip to content

Conversation

@agramfort
Copy link
Member

a quick attempt to see what it would take to support EMG data for mne-bids

cc @neuromechanist @robertoostenveld

follow up on bids-standard/bids-specification#1371

@agramfort
Copy link
Member Author

here is quick script to test:

import mne
from mne.datasets import eegbci

from mne_bids import write_raw_bids, BIDSPath

subject = 1
run = 2
eegbci.load_data(subject=subject, runs=run, update_path=True)

# Load the data from "2 minutes eyes closed rest"
edf_path = eegbci.load_data(subject=subject, runs=run)[0]
raw = mne.io.read_raw_edf(edf_path, preload=False)
raw.info['line_freq'] = 50  # specify power line frequency as required by BIDS

raw.set_channel_types({ch: "emg" for ch in raw.ch_names})

# zero padding to account for >100 subjects in this dataset
subject_id = '001'

bids_root = "./test_data"
bids_path = BIDSPath(subject=subject_id, task="task", root=bids_root)
write_raw_bids(raw, bids_path, overwrite=True)

@neuromechanist
Copy link

neuromechanist commented Apr 10, 2023

Thanks for initiating this effort. I think there are quite a few distinctions between EMG and EEG (or other electrophysiology data currently in BIDS) that require more attention.

Probably, the first issue is which data files/extensions should be allowed. This may seem straightforward, but each manufacturer has quite an obscure data type for themselves. For example, Delsys (.hpf) is not a transparent data file and exclusively requires Delsys File Utility to convert to C3D, CSV etc. OT Bioelecttronica, Noarxon, and TSMi hardware also seem to handle data within their software best. EDF and BDF seem good choices (open source, reach availability across program languages, and fast read-write).

The next issue that comes to mind is the sensor placement (anatomical location, inter-electrode distance, number of electrodes, etc.). For EMG (not the high-density version), SENIAM has been the longstanding guideline. But there should also be a feature to allow the user to define custom sensor placement. This can't be handled in the BIDS guidelines for *_electrodes.tsv, *_channles.tsv, or *_coordsystem.json.

Other differences, such as signal quality metrics, make EMG more distinct from EEG. Instead of impedance from *_electrodes.tsv, EMG's signal quality is measured by SNR and/or noise floor when the muscle is inactive. Further, *_electordes.tsv may not be a good presentation of the EMG sensors as they are, in most cases, bipolar sensors, which makes them channels.

Overall, I believe EMG requires more than carrying over the EEG-BIDS specs. Also, a decision should be made on whether to include HDsEMG, iEMG, and iEMG arrays in bids-standard/bids-specification#1371. We will circulate the first draft of the arguments for 1-including all EMG modalities under one BIDS specification proposal and 2-HDsEMG metadata information that is not covered by other modalities this week.

Given the active development of EMG interfaces at Reality Labs, It would be great if folks at MRL could join the effort here and in BIDS.

@robertoostenveld
Copy link

In the development of previous BEPs we experienced that being able to jointly look at an example was very helpful. @neuromechanist can you share a HD-sEMG dataset? Data from a single subject will do. Converting that to a draft BIDS dataset will reveal the challenges to be addressed.

@agramfort
Copy link
Member Author

agramfort commented Apr 10, 2023 via email

@hoechenberger
Copy link
Member

@robertoostenveld

In the development of previous BEPs we experienced that being able to jointly look at an example was very helpful.

I agree, let's try to go this route

@neuromechanist
Copy link

neuromechanist commented Apr 11, 2023

can you share an HD-sEMG dataset?

Of course, here is the link to a sample comparative data I collected a while ago with three systems: OTB Sessantaquattro, Delsys Galelio, and g.tec Pangolin: EMG sample files. Both original files and converted files are included for convenience.
Since there is also a follow-up question about whether to have EMG and HDsEMG together, I also added an example of Delsys Trigno Mini recordings. I will add a sample of the Noraxon EMG recording later this week. Noraxon sample files are also added.

EMG is a bit different but I see a lot of similarities too. I really see the EEG standard as the building block for EMG and I would seek for concept reuse as much as possible.

I 100% agree. Signal-wise, I see not much difference in storing any electrophysiological data either. However, what those signals mean, where they are collected from, and how they could/should be analyzed or reproduced are totally different stories.

I guess that it may turn out that the main items that may require updating are the required and recommended metadata to ensure transparency, reusability, and reproducibility.

@robertoostenveld
Copy link

I have had a first pass at converting the 4 examples. See here as a shared folder on my google drive. The code directory contains the scripts that I used. The bids 1-4 are the respective datasets. The EMG data is currently in the beh folder, as that is where data2bids puts it by default. That could of course be changed into emg.

The main information that is missing to make the data FAIR (especially reusable) is documentation on the electrode placement (which muscle, which arrangement), and on the montage and/or recording reference and ground. Furthermore, task information and timing of events is missing. Other than that, my guess is that MNE-Python (or any other software) would have no difficulty reading this BIDS-converted data, i.e., the interoperability should already be quite good.

@neuromechanist
Copy link

I realized that it may be best to move the discussion about the additional information needed to describe the signals to the BIDS issue. Please feel free to share your comments there.

@agramfort
Copy link
Member Author

agramfort commented Apr 14, 2023 via email

@sappelhoff
Copy link
Member

With the new BIDS validator finally supported via #1302, this can probably be more easily be picked up again. Now that also the BIDS community review for EMG is under way bids-standard/bids-specification#2219

@drammock
Copy link
Member

With the new BIDS validator finally supported via #1302, this can probably be more easily be picked up again. Now that also the BIDS community review for EMG is under way bids-standard/bids-specification#2219

I've been working on it. Aiming to have this mergeable within a few weeks.

@drammock drammock marked this pull request as ready for review October 27, 2025 21:47
@drammock drammock changed the title WIP : add support for EMG data add support for EMG data Oct 27, 2025
Copy link
Member

@drammock drammock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@agramfort @sappelhoff I'll plan to test this more thoroughly with a few proper datasets soon, but in the meantime I think this one is ready for another couple pairs of eyes. I've left some inline comments to hopefully speed along your reviews.

"markers",
"eeg",
"ieeg",
"emg",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the only new line here; the rest of the changes to this list are just un-doing some bad comment placement arising from a past autoformatter snafu

Comment on lines +245 to +247
+ [".pos", ".eeg", ".vmrk"] # extra datatype-specific metadata files.
+ [".dat", ".EEG"] # extra eeg extensions
+ [".mrk"] # KIT/Yokogawa/Ricoh marker coil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another unrelated-to-EMG fix of bad autoformatter comment placement

Comment on lines +347 to +356
# EMG allows arbitrary (user-defined) coord frames
class EmgCoordFrames(list):
"""Container for arbitrary (user-defined) coordinate frames (spaces)."""

def __contains__(self, item):
"""Pretends to contain any non-empty string."""
return isinstance(item, str) and len(item)


BIDS_EMG_COORDINATE_FRAMES = EmgCoordFrames()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this may be a bit too clever; EMG-BIDS allows coordsys spaces to have arbitrary (user-defined) names, and this is a way to make that possible (avoid "space entity is not valid for datatype EMG" errors) without disabling the existing checking mechanisms. Open to other approaches if this doesn't sit well with somebody.

Comment on lines +505 to +506
" released in 2009). It comes in three different flavours "
"each in symmetric or asymmetric version."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another unrelated autoformatter snafu fix

Comment on lines +1943 to +1952
"anat",
"beh",
"dwi",
"eeg",
"emg",
"fmap",
"func",
"ieeg",
"meg",
"nirs",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added EMG and also sorted the entries

Comment on lines +2151 to +2159
elif bids_path.datatype == "emg":
# TODO EMG: Handle EMG coordsystem if it's not in `raw.info["dig"]`.
# In theory we could make a helper func for creating a `DigMontage` from
# EMG electrode location info, and users could pass that into
# `write_raw_bids`...
warn(
"No electrode location info found in raw file, so not writing "
"coordinate system info for EMG data. Please add `coordsystem.json` "
"file manually."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the only part (I think?) that is "undone". My hunch is that for many users, the easiest thing to do is going to be writing their coordsys.json files by hand, because it's hard for us to know/guess anything based on the files. That said, 2 other options are:

  1. do something like _write_empty_ieeg_positions does
  2. do what the comment above suggests (write a helper function that users must call first, to create a digmontage instance they can pass in to write_raw_bids).

Neither of those options will handle all possible user cases (due to the support for "nested" coordinate systems, which require multiple coordsys.json files with different space entities) --- possibly not even the majority of use cases.

@drammock drammock mentioned this pull request Nov 5, 2025
@drammock
Copy link
Member

drammock commented Nov 5, 2025

@bruAristimunha FWIW the test_lock_refcount_multiprocess failed here (https://github.com/mne-tools/mne-bids/actions/runs/19111819345/job/54610627372?pr=1129) but passed in the few CI runs before it. Would be good to either mark it as @flaky or figure out the source of the non-determinism.

@bruAristimunha
Copy link
Contributor

I think I know the root cause... we basically need to wait a little while to check if the system removes all the lock files. I will open some PR to try to treat this.

@bruAristimunha
Copy link
Contributor

bruAristimunha commented Nov 6, 2025

should be fine now @drammock

@drammock drammock mentioned this pull request Nov 6, 2025
7 tasks
@drammock
Copy link
Member

@agramfort
Copy link
Member Author

@drammock yeah I pushed this cause I started to play with https://nemar.org/dataexplorer/detail?dataset_id=nm000104 cf NB in https://github.com/agramfort/nemar_emg_datasets_notebooks

without this patch I could not load the data.

I have no visibility on how https://nemar.org/dataexplorer/detail?dataset_id=nm000104 was produced. I assume it was not produced using mne-bids. I am waiting to hear by from @neuromechanist @arnodelorme on these data as there some remaining things to fix AFAIK.

sorry about this

@bruAristimunha
Copy link
Contributor

I think the dataset should be fix now, can we finish the PR? I would like to use the EMG support on EEGDash :)

@drammock
Copy link
Member

I think the dataset should be fix now, can we finish the PR? I would like to use the EMG support on EEGDash :)

This is a high priority for me, but won't happen until early-mid December as I'm on holiday now for about 2 weeks

@neuromechanist
Copy link

neuromechanist commented Nov 22, 2025

The EMG datasets should be fixed as of v1.1.0 (for example, see nemarDatasets/nm000104). The problem was how I interpreted the timestamps when ingesting the data from HDF5. Hopefully, it is now ok.

Failure of importing coordsystem.json might be due to adding the space-<label> entity to the files to distinguish multiple coordsystem.json files within a dataset (for nm000104, this would be the left and right forearms)

The conversion was done using EEGLAB's eeg-bids plugin, which is now extended for emg as well.

Datasets originally (v1.0) passed the pre-release BIDS validator (using the validator as bids-standard/bids-examples#480). The mods in v1.1.0 did not change dataset metadata or structure. I will test all datasets one more time once the EMG-PRs are merged.

@agramfort
Copy link
Member Author

agramfort commented Nov 22, 2025 via email

@neuromechanist
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants