diff --git a/mne_bids/config.py b/mne_bids/config.py index d225f02b7..e864ae265 100644 --- a/mne_bids/config.py +++ b/mne_bids/config.py @@ -13,7 +13,7 @@ DOI = """https://doi.org/10.21105/joss.01896""" -EPHY_ALLOWED_DATATYPES = ["meg", "eeg", "ieeg", "nirs"] +EPHY_ALLOWED_DATATYPES = ["meg", "eeg", "ieeg", "nirs", "emg"] ALLOWED_DATATYPES = EPHY_ALLOWED_DATATYPES + ["anat", "beh"] @@ -84,6 +84,8 @@ ".EEG": "Nihon Kohden", } +emg_manufacturers = {} # TODO + nirs_manufacturers = {".snirf": "SNIRF"} # file-extension map to mne-python readers @@ -115,6 +117,7 @@ MANUFACTURERS = dict() MANUFACTURERS.update(meg_manufacturers) MANUFACTURERS.update(eeg_manufacturers) +MANUFACTURERS.update(emg_manufacturers) MANUFACTURERS.update(ieeg_manufacturers) MANUFACTURERS.update(nirs_manufacturers) @@ -135,6 +138,10 @@ ".set", # EEGLAB, potentially accompanied by .fdt ] +allowed_extensions_emg = [ + ".edf", # European Data Format +] + allowed_extensions_ieeg = [ ".vhdr", # BrainVision, accompanied by .vmrk, .eeg ".edf", # European Data Format @@ -151,6 +158,7 @@ ALLOWED_DATATYPE_EXTENSIONS = { "meg": allowed_extensions_meg, "eeg": allowed_extensions_eeg, + "emg": allowed_extensions_emg, "ieeg": allowed_extensions_ieeg, "nirs": allowed_extensions_nirs, } @@ -169,12 +177,16 @@ # allowed suffixes (i.e. last "_" delimiter in the BIDS filenames before # the extension) ALLOWED_FILENAME_SUFFIX = [ + # datatypes: "meg", "markers", "eeg", "ieeg", + "emg", + "nirs", "T1w", - "FLASH", # datatype + "FLASH", + # sidecars: "participants", "scans", "sessions", @@ -182,13 +194,14 @@ "optodes", "channels", "coordsystem", - "events", # sidecars + "events", + # MEG-specific sidecars: "headshape", - "digitizer", # meg-specific sidecars + "digitizer", + # behavioral: "beh", "physio", - "stim", # behavioral - "nirs", + "stim", ] # converts suffix to known path modalities @@ -199,6 +212,7 @@ "markers": "meg", "eeg": "eeg", "ieeg": "ieeg", + "emg": "emg", "T1w": "anat", "FLASH": "anat", } @@ -207,9 +221,9 @@ ALLOWED_FILENAME_EXTENSIONS = ( ALLOWED_INPUT_EXTENSIONS + [".json", ".tsv", ".tsv.gz", ".nii", ".nii.gz"] - + [".pos", ".eeg", ".vmrk"] - + [".dat", ".EEG"] # extra datatype-specific metadata files. - + [".mrk"] # extra eeg extensions # KIT/Yokogawa/Ricoh marker coil + + [".pos", ".eeg", ".vmrk"] # extra datatype-specific metadata files. + + [".dat", ".EEG"] # extra eeg extensions + + [".mrk"] # KIT/Yokogawa/Ricoh marker coil ) # allowed BIDSPath entities @@ -313,6 +327,7 @@ + BIDS_EEG_COORDINATE_FRAMES ) ALLOWED_SPACES["ieeg"] = BIDS_SHARED_COORDINATE_FRAMES + BIDS_IEEG_COORDINATE_FRAMES +ALLOWED_SPACES["emg"] = None # TODO revise if we support digitization of EMG sensors ALLOWED_SPACES["anat"] = None ALLOWED_SPACES["beh"] = None @@ -486,6 +501,7 @@ "Pollonini, L. (2023). fNIRS-BIDS, the Brain Imaging Data Structure " "Extended to Functional Near-Infrared Spectroscopy. PsyArXiv. " "https://doi.org/10.31219/osf.io/7nmcp", + "emg": "In preparation", } diff --git a/mne_bids/utils.py b/mne_bids/utils.py index fe3ad5738..f61e45e21 100644 --- a/mne_bids/utils.py +++ b/mne_bids/utils.py @@ -159,11 +159,13 @@ def _handle_datatype(raw, datatype): datatypes.append("meg") if "eeg" in raw: datatypes.append("eeg") + if "emg" in raw: + datatypes.append("emg") if "fnirs_cw_amplitude" in raw: datatypes.append("nirs") if len(datatypes) == 0: raise ValueError( - "No MEG, EEG or iEEG channels found in data. " + "No MEG, EEG, iEEG, or EMG channels found in data. " "Please use raw.set_channel_types to set the " "channel types in the data." ) @@ -172,6 +174,8 @@ def _handle_datatype(raw, datatype): datatype = "meg" elif "ieeg" in datatypes and "meg" not in datatypes: datatype = "ieeg" + elif "emg" in datatypes: + datatype = "emg" else: raise ValueError( f"Multiple data types (``{datatypes}``) were " diff --git a/mne_bids/write.py b/mne_bids/write.py index 500d300ff..fede1a529 100644 --- a/mne_bids/write.py +++ b/mne_bids/write.py @@ -1008,6 +1008,13 @@ def _sidecar_json( ("Manufacturer", manufacturer), ] + ch_info_json_emg = [ + # ("EEGReference", "n/a"), + # ("EEGGround", "n/a"), + # ("EEGPlacementScheme", _infer_eeg_placement_scheme(raw)), + # ("Manufacturer", manufacturer) + ] + ch_info_json_ieeg = [ ("iEEGReference", "n/a"), ("ECOGChannelCount", n_ecogchan), @@ -1037,6 +1044,8 @@ def _sidecar_json( append_datatype_json = ch_info_json_meg elif datatype == "eeg": append_datatype_json = ch_info_json_eeg + elif datatype == "emg": + append_datatype_json = ch_info_json_emg elif datatype == "ieeg": append_datatype_json = ch_info_json_ieeg elif datatype == "nirs":