File naming with multiple simultaneous EEG devices

Might anyone be able to recommend file naming suggestions for a longitudinal design including (sometimes) simultaneous continuous EEG from multiple devices? And how to handle the electrodes, channels and event tsv files for this situation?

design:

  • longitudinal (multiple sessions)

  • during each session, simultaneous recordings from one or multiple EEG devices (+ physiological signals) were acquired, all converted into edf. Here, “simultaneous” means recordings overlap greatly in time, but aren’t yet perfectly synchronized (i.e., different start/end times for each device’s recording)

  • each device has its own electrode and channel tsv files

  • recordings from different devices typically have different associated event files

  • [there can even be multiple tasks and runs]

Using “ses” to accommodate the longitudinal design is straightforward, but not sure how to optimally choose among/combine from “acq”, “recording”, “desc” (or even other entities?) to best name/distinguish the edf files originating from different devices. In addition, from the documentation it appears that the electrodes/channels/events files each have different rules regarding which entities are allowed to be present (but I could be wrong), further complicating things.

Any suggestions welcome!

  • recording is not allowed for eeg files (only allowed for physio files): so not possible
  • desc is only allowed for derivative data: so not possible
  • acq: seems to be the one to go with.

So I would do something like this (I used acq-apparatus

(the following assumes the same channels, electrodes, coordsystem is kept constant across the runs of a given task for a given apparatus

sub-<label>/
    ses-<label>/
        eeg/
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-1_eeg.edf
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-1_eeg.json
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-1_events.json
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-1_events.tsv
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-2_eeg.edf
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-2_eeg.json
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-2_events.json
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-2_events.tsv
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_channels.json
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_channels.tsv
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_electrodes.json
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_electrodes.tsv
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_coordsystem.json

            sub-<label>_ses-<label>_task-foo_acq-apparatus2_run-1_eeg.edf
            sub-<label>_ses-<label>_task-foo_acq-apparatus2_run-1_eeg.json
            sub-<label>_ses-<label>_task-foo_acq-apparatus2_run-1_events.json
            sub-<label>_ses-<label>_task-foo_acq-apparatus2_run-1_events.tsv
            sub-<label>_ses-<label>_task-foo_acq-apparatus2_run-2_eeg.edf
            sub-<label>_ses-<label>_task-foo_acq-apparatus2_run-2_eeg.json
            sub-<label>_ses-<label>_task-foo_acq-apparatus2_run-2_events.json
            sub-<label>_ses-<label>_task-foo_acq-apparatus2_run-2_events.tsv
            sub-<label>_ses-<label>_task-foo_acq-apparatus2_channels.json
            sub-<label>_ses-<label>_task-foo_acq-apparatus2_channels.tsv
            sub-<label>_ses-<label>_task-foo_acq-apparatus2_electrodes.json
            sub-<label>_ses-<label>_task-foo_acq-apparatus2_electrodes.tsv
            sub-<label>_ses-<label>_task-foo_acq-apparatus2_coordsystem.json

I suspect that the triggers are sent to all recording eeg devices so you may not need to need to keep track of the timing offset between each device, right?

hope this helps

many thanks, very helpful!

  • being able to only use “acq” for distinguising between devices simplifies things

  • didn’t realize that the file names of the *_events tsv/json can match the entire edf file name, so that nicely allows keeping different events files associated with their own device

  • I see you included “task” in the electrodes tsv/json and coordsystem json. from the specs I got the impression that “task” should not be included here. but if it is allowed (or at least “permissible”) that would be even better as it makes for more consistent (and unambiguous) file naming

  • timing offsets are an entirely different issue, as unfortumately the same triggers don’t end up in every device. assuming we find a robust way of determining offsets, I was thinking of keeping these offsets in the scans.tsv (since the acquisition times are also kept there). makes sense?

  • and to add a final question: is there any way to accommodate multiple *.events.tsv files belonging to the same edf? we often have an “initial” events file (e.g., triggers), followed later by manual annotations, and again later we might have events from some detector. if only a single events file is allowed, the only way to deal with this is to have an iterative approach that reads in existing events, merges it with the new events, and writes out the combined events. this is both cumbersome and risky (might delete old events). would it be possible to store multiple *_events-[mytag].tsv files or something along those lines?

if you look at the filename template in this section, it is pretty clear that task is allowed

https://bids-specification.readthedocs.io/en/latest/modality-specific-files/electroencephalography.html#electrodes-description-_electrodestsv

YES!!! pretty much the best way to do this!

agree that in general, once acquired and converted a raw dataset should “almost” never be touched (and if you do use some data version control like datalad)

so in this case, your new events are based on annotation (like sleep staging score of your raw data), so I think that in this case the approach is to treat those events as derivatives of the raw BIDS data.

so I would add a derivatives folder where you have a lot more freedom and can rely on the desc entity to differentiate different event file

for example

derivatives
    sleep_scoring
        sub-<label>/
            ses-<label>/
                eeg/
                    sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-1_desc-sleepscore_events.json
                    sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-2_desc-sleepscore__events.tsv
sub-<label>/
    ses-<label>/
        eeg/
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-1_eeg.edf
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-1_eeg.json
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-1_events.json
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-1_events.tsv
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-2_eeg.edf
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-2_eeg.json
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-2_events.json
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-2_events.tsv
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_channels.json
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_channels.tsv
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_electrodes.json
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_electrodes.tsv
            sub-<label>_ses-<label>_task-foo_acq-apparatus1_coordsystem.json

pinging @robert who may have some better ideas about this

hope that helps

many thanks for the clarifications and suggestions.

regarding events: I suspected the answer might lie in the derivatives. given that desc is available here, I should be able to accommodate multiple event types in the following way, right?

derivatives
    sleep_annotations
        sub-<label>/
            ses-<label>/
                eeg/
                    sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-1_desc-sleepscore_events.json
                    sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-1_desc-sleepscore_events.tsv
                    sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-1_desc-sleepdetector1_events.json
                    sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-1_desc-sleepdetector1_events.tsv
                    sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-1_desc-sleepdetector2_events.json
                    sub-<label>_ses-<label>_task-foo_acq-apparatus1_run-1_desc-sleepdetector2_events.tsv
                    ...
sub-<label>/

yup that would be the way to do it