How to get indices for dropped epochs from a subset of epochs?

Dear all,

In my pipeline, I have a step where I remove some epochs based on if they have a blink in a certain place. When I do this, mne prints out indices of the dropped trials as an output. In fact, it prints two versions. One gives indices relating to only the subset of trials in this particular epochs variable and the second seems to be indices relating to all events. I would like to know how I could get a list with the first set of indices. I know that epochs.drop_log is available but makes it very difficult to identify which trials were removed from the subset of trials in the current epochs variable.

I need these indices so that I can remove the same trials from my behavioural data. I hope I didn’t miss an easy solution in the documentation!

Thanks and take care!

epochs.selection stores the indices that were kept. That might be good enough? I.e., you can do something like behavioral_trials[epochs.selection] and it will keep only the behavioral trials where the ephys data has not been dropped. But be careful to only do that once; if you have other steps where you remove behavioral trials, the indices will get out of sync.

If that’s not good enough, please provide a code snippet; it’s hard to guess exactly what your pipeline is doing based on your prose description of it.

Thanks for the quick response. I’ve inspected epochs.selection and this also gives you indices relating to all of the events in the raw data. I’ve built a minimal working example using tutorial data which will hopefully make my pipeline clearer. The indices get printed in the output, so maybe it’s just a case of looking for where this happens in the source code?

import numpy as np
import mne

sample_data_folder = mne.datasets.sample.data_path()
sample_data_raw_file = (sample_data_folder / 'MEG' / 'sample' /
                        'sample_audvis_filt-0-40_raw.fif')
raw = mne.io.read_raw_fif(sample_data_raw_file)

events = mne.find_events(raw, stim_channel='STI 014')
print(events[:5])  # show the first 5
event_dict = {'auditory/left': 1, 'auditory/right': 2, 'visual/left': 3,
              'visual/right': 4, 'smiley': 5, 'buttonpress': 32}

# First epoch using event_dict. This will create an Epoch around all triggers in event_dict.
# epochs = mne.Epochs(raw, events, event_id = event_dict, on_missing = 'ignore', baseline = None, # tmin=-0.5, tmax=1)
# Secondly, we select only the events we want. We can refer to events by the names that were defined # in the dictionary.
aud_select = epochs['auditory']
aud_select

# In this step, epochs can be marked as bad. The indices relating to the dropped epochs from this subset of epochs are
# printed in the output where it says:
# Dropped x epochs: idx.
# This is the set of indices I would like to have as a list to export and use for behavioural analysis.

aud_select.plot(block = True, events = events, n_epochs = 1, event_id = event_dict, event_color = 'red', n_channels = 32)

# epochs.selection gives indices relating to all events, not the subset of epochs in the variable aud_select
aud_select.selection

ok, now I understand. Interactive marking of bad epochs gets the annotation "USER" in the drop log. So you can do this to get the indices:

np.where(list(map(lambda x: x == ('USER',), aud_select.drop_log)))[0]

or equivalently:

[ix for ix, log in enumerate(aud_select.drop_log) if log == ('USER',)]

Thanks again for the help. I was able to use your suggestions to find a solution. I wanted the local index for only the subset of the trials so there were a couple more lines of code necessary to get to this step. I did it as follows:

import numpy as np
import mne

sample_data_folder = mne.datasets.sample.data_path()
sample_data_raw_file = (sample_data_folder / 'MEG' / 'sample' /
                        'sample_audvis_filt-0-40_raw.fif')
raw = mne.io.read_raw_fif(sample_data_raw_file)

events = mne.find_events(raw, stim_channel='STI 014')
print(events[:5])  # show the first 5
event_dict = {'auditory/left': 1, 'auditory/right': 2, 'visual/left': 3,
              'visual/right': 4, 'smiley': 5, 'buttonpress': 32}

# First epoch using event_dict. This will create an Epoch around all triggers in event_dict.
epochs = mne.Epochs(raw, events, event_id = event_dict, on_missing = 'ignore', baseline = None, tmin=-0.5, tmax=1)
# Secondly, we select only the events we want. We can refer to events by the names that were defined in the dictionary.
aud_select = epochs['auditory']
aud_select

# This variable contains indices showing auditory events in all events
og_selection = aud_select.selection

# Visually reject trials
aud_select.plot(block = True, events = events, n_epochs = 1, event_id = event_dict, event_color = 'red', n_channels = 32)

# Here we get a dictionary containing each of the global indices from all events and the local equivalent local indices of only auditory events.
key_value = [[key, value] for key, value in zip(og_selection, range(len(og_selection)))]
global_to_local = dict(key_value)

# Find the global indices of the trials that were removed.
bad_trials = np.where(list(map(lambda x: x == ('USER',), aud_select.drop_log)))[0]
bad_trials

# Find the local indices that relate to the global ones in aud_select. Now these can be exported and used to remove the same trials in behavioural data.
for global_index in bad_trials:
    print(global_to_local[global_index])