rejecting selected BAD labels in mne.Epochs

Hello,

In mne.epochs reject_by_annotation takes in a boolean to reject all BAD_*
Is there a way to reject only “BAD_manual” (for example) and leave the other BAD_*?

Thank you!

Ana

1 Like

Hello,

I had to look through the code, I was expecting reject_by_annotation="BAD_manual" to do this but it does not seem to be the case. Maybe that behavior could be added.
In the meantime, I think the best next idea is to rename the other annotations to something else, at least temporary. The annotations are stored in raw.annotations, and each of them is a dictionary (I think?).

Mathieu

1 Like

Dear Mathiew,

Thank you for your reply.
I am running into some obstacles while implementing your suggestion, and thought to ask if you have any suggestions.

My goal is to rename the annotations with the decription ‘BAD-iti’ just to ‘iti’ so that they are not rejected when I use the rejection argument in mne.Epochs. To do this I have tried two strategies.

  1. I have tried to directly change the values of the annotation ordered dictionaries, but this doesn’t seem to work.
dct_annot=data_in.annotations
#<Annotations | 2029 segments: BAD_ (9), BAD_action_nonsel (384), ...>
# As a example I chose the 5th ordered dictionairy 
dct_annot[5]
#Out[130]: 
#OrderedDict([('onset', 154.442993),
#             ('duration', 2.86199951171875),
#             ('description', 'BAD_iti'),
#             ('orig_time',
#              datetime.datetime(2020, 11, 11, 11, 53, 8, 60174, tzinfo=datetime.timezone.utc))])

dct_annot[5]['description'] 
#Out[131]: 'BAD_iti'

#Then I have tried to change the 'description' value to 'iti'
dct_annot[5]['description'] = 'iti'

#But when I test it, it has not changed (no error output)
dct_annot[5]['description'] 
#Out[133]: 'BAD_iti'


  1. Next, I tried getting the annotations out as a list of ordered dictionaries and renaming the ‘descriptions’ inside the ordered dictionaries. In this approach I am able to change the values of the ordered dictionaries. But I am not able to transform the list of updated ordered dictionaries back into an mne.annotations object in order to be able to use mne.set_annotations.
import mne
from typing import List
from collections import OrderedDict

def update_descriptions(ordered_dicts: List[OrderedDict]) -> List[OrderedDict]:
    """
    Update the value of the 'description' key in each ordered dictionary in the list if it is 'BAD_iti'
    :param ordered_dicts: a list of ordered dictionaries with a 'description' key
    :return: an updated list of ordered dictionaries with the new 'description' values
    """
    ordered_dicts=list(ordered_dicts)
    for od in ordered_dicts:
        if od['description'] == 'BAD_iti':
            od['description'] = 'iti'
    return ordered_dicts


dct_annot=data_in.annotations
#<Annotations | 2029 segments: BAD_ (9), BAD_action_nonsel (384), ...>

# Update the descriptions so that all 'BAD_iti' are updated to 'iti' (Works!)
updated_ordered_dicts = update_descriptions(dct_annot)

# updated_ordered_dicts[5]
# Out[145]: 
# OrderedDict([('onset', 154.442993),
#              ('duration', 2.86199951171875),
#              ('description', 'iti'),
#              ('orig_time',
#               datetime.datetime(2020, 11, 11, 11, 53, 8, 60174, tzinfo=datetime.timezone.utc))])

# But, how to use the updated list to create a new annotation object?
#mne.Annotations(onset, duration, description)

Thank you for your input!

Ana

Hello,

It turns out the Annotation object has a rename method. Here is a MWE code example:

import numpy as np
from mne import Annotations
from mne.datasets import sample
from mne.io import read_raw_fif


directory = sample.data_path() / "MEG" / "sample"
fname = directory / "sample_audvis_raw.fif"
raw = read_raw_fif(fname, preload=True)

# create fake annotations
annotations1 = Annotations(
    onset=np.arange(0, 200, 10), duration=1, description="BAD_iti"
)
annotations2 = Annotations(
    onset=np.arange(5, 205, 10), duration=1, description="BAD_else"
)
raw.set_annotations(annotations1 + annotations2)

# rename "BAD_iti" annotations
raw.annotations.rename({"BAD_iti": "iti"})

Mathieu

1 Like