$npx -y skills add neuromechanist/research-skills --skill bids-conversionUse this skill for \"convert to BIDS\", \"BIDS format\", \"create BIDS dataset\", \"BIDS sidecar\", \"participants.tsv\", \"events.tsv\", \"EEG BIDS\", \"EMG BIDS\", \"MEG BIDS\", \"fMRI BIDS\", \"BIDS validator\", \"channel locations\", \"electrode positions\", \"BIDS metadata\"
| 1 | # BIDS Conversion |
| 2 | |
| 3 | Convert neuroscience datasets to Brain Imaging Data Structure (BIDS) format. Supports EEG, EMG, MEG, fMRI, and behavioral data with proper file naming, JSON sidecars, and metadata. |
| 4 | |
| 5 | ## When to Use |
| 6 | |
| 7 | - Converting raw data files to BIDS format |
| 8 | - Creating or fixing BIDS metadata (JSON sidecars, TSV files) |
| 9 | - Validating BIDS compliance |
| 10 | - Setting up a new BIDS dataset from scratch |
| 11 | - Converting between data formats (e.g., .set to .edf, .vhdr to .bdf) |
| 12 | |
| 13 | ## BIDS Directory Structure |
| 14 | |
| 15 | ``` |
| 16 | dataset/ |
| 17 | dataset_description.json |
| 18 | participants.tsv |
| 19 | participants.json |
| 20 | README |
| 21 | CHANGES |
| 22 | sub-01/ |
| 23 | sub-01_scans.tsv |
| 24 | eeg/ |
| 25 | sub-01_task-rest_eeg.set |
| 26 | sub-01_task-rest_eeg.json |
| 27 | sub-01_task-rest_channels.tsv |
| 28 | sub-01_task-rest_electrodes.tsv |
| 29 | sub-01_task-rest_coordsystem.json |
| 30 | sub-01_task-rest_events.tsv |
| 31 | emg/ |
| 32 | sub-01_task-grasp_emg.edf |
| 33 | sub-01_task-grasp_emg.json |
| 34 | sub-01_task-grasp_channels.tsv |
| 35 | sub-01_task-grasp_events.tsv |
| 36 | anat/ |
| 37 | sub-01_T1w.nii.gz |
| 38 | sub-01_T1w.json |
| 39 | derivatives/ |
| 40 | pipeline-name/ |
| 41 | sub-01/ |
| 42 | ``` |
| 43 | |
| 44 | ## File Naming Convention |
| 45 | |
| 46 | ``` |
| 47 | sub-<label>[_ses-<label>]_task-<label>[_acq-<label>][_run-<index>]_<suffix>.<extension> |
| 48 | ``` |
| 49 | |
| 50 | - **sub**: subject identifier (required, alphanumeric, no special chars) |
| 51 | - **ses**: session (optional, for longitudinal studies) |
| 52 | - **task**: task name (required for functional data) |
| 53 | - **acq**: acquisition parameters (optional) |
| 54 | - **run**: run index (optional, for repeated acquisitions) |
| 55 | - **suffix**: data type (eeg, emg, meg, bold, T1w, events, channels, electrodes) |
| 56 | |
| 57 | ## Conversion Workflow |
| 58 | |
| 59 | ### Step 1: Inventory Source Data |
| 60 | |
| 61 | Identify: |
| 62 | - Data format (BrainVision .vhdr, EEGLAB .set, EDF .edf, BDF .bdf, NIfTI .nii.gz) |
| 63 | - Number of subjects and sessions |
| 64 | - Task names and conditions |
| 65 | - Channel types (EEG, EMG, EOG, ECG, misc) |
| 66 | - Events/markers in the data |
| 67 | - Coordinate system for electrode positions |
| 68 | |
| 69 | ### Step 2: Create Dataset Scaffold |
| 70 | |
| 71 | ```python |
| 72 | import json |
| 73 | from pathlib import Path |
| 74 | |
| 75 | def create_bids_scaffold(root: str, subjects: list[str], tasks: list[str], modality: str = "eeg"): |
| 76 | root = Path(root) |
| 77 | root.mkdir(exist_ok=True) |
| 78 | |
| 79 | # dataset_description.json |
| 80 | desc = { |
| 81 | "Name": "Dataset Name", |
| 82 | "BIDSVersion": "1.9.0", |
| 83 | "DatasetType": "raw", |
| 84 | "License": "CC0", |
| 85 | "Authors": ["Last, First"], |
| 86 | "DatasetDOI": "", |
| 87 | "GeneratedBy": [{"Name": "Manual conversion"}] |
| 88 | } |
| 89 | (root / "dataset_description.json").write_text(json.dumps(desc, indent=2)) |
| 90 | |
| 91 | # participants.tsv |
| 92 | with open(root / "participants.tsv", "w") as f: |
| 93 | f.write("participant_id\tage\tsex\thand\n") |
| 94 | for sub in subjects: |
| 95 | f.write(f"sub-{sub}\tn/a\tn/a\tn/a\n") |
| 96 | |
| 97 | # Create subject directories |
| 98 | for sub in subjects: |
| 99 | for task in tasks: |
| 100 | (root / f"sub-{sub}" / modality).mkdir(parents=True, exist_ok=True) |
| 101 | ``` |
| 102 | |
| 103 | ### Step 3: Convert Data Files |
| 104 | |
| 105 | #### EEG (EEGLAB .set) |
| 106 | |
| 107 | EEGLAB .set files are BIDS-compatible as-is. Copy and rename: |
| 108 | ```bash |
| 109 | cp source.set sub-01/eeg/sub-01_task-rest_eeg.set |
| 110 | cp source.fdt sub-01/eeg/sub-01_task-rest_eeg.fdt # if separate .fdt file |
| 111 | ``` |
| 112 | |
| 113 | #### EEG (BrainVision .vhdr) |
| 114 | |
| 115 | BrainVision files come in triplets (.vhdr, .vmrk, .eeg). All three must be renamed consistently: |
| 116 | ```bash |
| 117 | cp source.vhdr sub-01/eeg/sub-01_task-rest_eeg.vhdr |
| 118 | cp source.vmrk sub-01/eeg/sub-01_task-rest_eeg.vmrk |
| 119 | cp source.eeg sub-01/eeg/sub-01_task-rest_eeg.eeg |
| 120 | ``` |
| 121 | Update internal references in .vhdr and .vmrk to point to renamed files. |
| 122 | |
| 123 | #### EEG (EDF/BDF) |
| 124 | |
| 125 | Copy and rename: |
| 126 | ```bash |
| 127 | cp source.edf sub-01/eeg/sub-01_task-rest_eeg.edf |
| 128 | ``` |
| 129 | |
| 130 | #### EMG |
| 131 | |
| 132 | EMG follows the same pattern but uses the `emg` directory and suffix: |
| 133 | ```bash |
| 134 | cp source.edf sub-01/emg/sub-01_task-grasp_emg.edf |
| 135 | ``` |
| 136 | |
| 137 | ### Step 4: Create JSON Sidecars |
| 138 | |
| 139 | #### EEG sidecar (required fields) |
| 140 | |
| 141 | ```json |
| 142 | { |
| 143 | "TaskName": "rest", |
| 144 | "TaskDescription": "Eyes-open resting state recording", |
| 145 | "InstitutionName": "University Name", |
| 146 | "InstitutionAddress": "Address", |
| 147 | "Manufacturer": "BioSemi", |
| 148 | "ManufacturersModelName": "ActiveTwo", |
| 149 | "SamplingFrequency": 512, |
| 150 | "EEGChannelCount": 64, |
| 151 | "EOGChannelCount": 2, |
| 152 | "EMGChannelCount": 0, |
| 153 | "ECGChannelCount": 0, |
| 154 | "MiscChannelCount": 0, |
| 155 | "TriggerChannelCount": 1, |
| 156 | "PowerLineFrequency": 60, |
| 157 | "EEGPlacementScheme": "10-20", |
| 158 | "EEGReference": "CMS/DRL", |
| 159 | "EEGGround": "n/a", |
| 160 | "SoftwareFilters": "n/a", |
| 161 | "HardwareFilters": {"Highpass": {"HalfAmplitudeCutoffHz": 0.01}}, |
| 162 | "RecordingType": "continuous", |
| 163 | "RecordingDuration": 300 |
| 164 | } |
| 165 | ``` |