def transform_event_id(raw, transform_dic=None, description_transform=None): """Transform the description of Raw. Parameters ---------- raw : mne.Raw Raw instance. transform_dic : None | dic Dictionary holds the new id required for conversion. Which key is the old id and the value is the new id. description_transform : None | callable Function use raw as input and return new_events and new_event_id. Returns ------- None Notes ----- """ if description_transform: all_events, all_event_id = description_transform(raw) else: all_events, all_event_id = events_from_annotations(raw) if transform_dic: new_all_event_id = _transform_from_dict(all_event_id, transform_dic) else: new_all_event_id = {v: k for k, v in all_event_id.items()} annotation_new = annotations_from_events(all_events, raw.info['sfreq'], new_all_event_id) raw.set_annotations(annotation_new)
def load_data(subject_index, index, channels): event_time, event_label, raw_data = load_file(subjects[subject_index], index) event_num = len(event_label) event_duration = np.ones(event_num, dtype=np.int) * 4 events = np.column_stack((event_time, event_duration, event_label)) print(subject_index, index, event_num) info = mne.create_info(ch_names, ch_types=ch_types, sfreq=srate) info['description'] = 'My dataset' info.set_montage('standard_1005') raw = mne.io.RawArray(raw_data, info) annotations = mne.annotations_from_events(events, srate, event_desc={ 1004: 'left', 1005: 'right' }) raw.set_annotations(annotations) raw = raw.pick_channels(channels) raw = raw.resample(resample_rate) raw.filter(l_freq, h_freq, fir_design='firwin', skip_by_annotation='edge') if raw_plot: raw.plot() events, event_id = mne.events_from_annotations(raw) reject_criteria = dict(eeg=150e-6) epochs = mne.Epochs(raw, events, tmin=-0.1, tmax=3.9 - 1. / resample_rate, event_id=event_id, reject=reject_criteria, preload=True) if epoch_plot: epochs.plot() # print(epochs) epoch_data = epochs.get_data() events = epochs.events event_num = len(events) data_label = [] for i in range(event_num): for j in range(2 * resample_rate): data_ = epoch_data[i, :, j:j + 2 * resample_rate].reshape(-1) label_ = [abs(events[i][-1] - 2), events[i][-1] - 1] data_label += [np.hstack((data_, label_))] print(len(data_label), len(data_label[0])) return data_label
def _annotations_from_moabb_stim_channel(raw, dataset): # find events from stim channel events = mne.find_events(raw) # get annotations from events event_desc = {k: v for v, k in dataset.event_id.items()} annots = mne.annotations_from_events(events, raw.info['sfreq'], event_desc) # set trial on and offset given by moabb onset, offset = dataset.interval annots.onset += onset annots.duration += offset - onset return annots
def annotations_from_events(self): """Convert events to annotations.""" mapping = self.current.get("event_mapping") annots = mne.annotations_from_events( self.current["events"], self.current["data"].info["sfreq"], event_desc=mapping) if len(annots) > 0: self.current["data"].set_annotations(annots) hist = ("annots = mne.annotations_from_events(events, " 'data.info["sfreq"]') if mapping is not None: hist += f", event_desc={mapping}" hist += ")" self.history.append(hist) self.history.append("data = data.set_annotations(annots)")
def plot_with_events(): edf = '/Users/rotemfalach/Documents/University/lab/EDFs_forRotem/402_for_tag.edf' raw = mne.io.read_raw_edf(edf) raw.pick_channels(['RAH1', 'RAH1-RAH2']) raw.crop(tmin=0, tmax=600) # raw.set_channel_types({'SEEG RAH1-REF': 'seeg', 'EOG1-REF': 'eog', 'EOG2-REF': 'eog'}) # raw.set_channel_types({x :'seeg' for x in ['RA1M', 'REC1M', 'RAH1M', 'RPSMA1M', 'ROF1M', 'RAC1M', 'LA1M', 'LEC1M', 'LAH1M', 'LPSMA1M', 'LOF1M', 'LAC1M']}) # some_events = mne.make_fixed_length_events(raw, start=5, stop=50, duration=2.) mapping = {1: 'amp', 2: 'grad', 3: 'env'} spikes_df = pd.read_csv( '/Users/rotemfalach/projects/epileptic_activity/402_RAH1_spikes.csv') some_events = np.array([[x[4], 0, get_thresh_id(x[1])] for x in spikes_df.values]) annot_from_events = mne.annotations_from_events(events=some_events, event_desc=mapping, sfreq=raw.info['sfreq']) raw.set_annotations(annot_from_events) # raw.save('406_events.fif') raw.plot(color='black', start=0, duration=30, scalings=dict(eeg=1.2e-4, eog=3e-4, seeg=2e-4)) print('finish')
def _read_events(events_data, event_id, raw, verbose=None): """Retrieve events (for use in *_events.tsv) from FIFF/array & Annotations. Parameters ---------- events_data : str | np.ndarray | None If a string, a path to an events file. If an array, an MNE events array (shape n_events, 3). If None, events will be generated from ``raw.annotations``. event_id : dict | None The event id dict used to create a 'trial_type' column in events.tsv, mapping a description key to an integer-valued event code. raw : mne.io.Raw The data as MNE-Python Raw object. verbose : bool | str | int | None If not None, override default verbose level (see :func:`mne.verbose`). Returns ------- all_events : np.ndarray, shape = (n_events, 3) The first column contains the event time in samples and the third column contains the event id. The second column is ignored for now but typically contains the value of the trigger channel either immediately before the event or immediately after. all_dur : np.ndarray, shape (n_events,) The event durations in seconds. all_desc : dict A dictionary with the keys corresponding to the event descriptions and the values to the event IDs. """ # get events from events_data if isinstance(events_data, str): events = read_events(events_data, verbose=verbose).astype(int) elif isinstance(events_data, np.ndarray): if events_data.ndim != 2: raise ValueError('Events must have two dimensions, ' f'found {events_data.ndim}') if events_data.shape[1] != 3: raise ValueError('Events must have second dimension of length 3, ' f'found {events_data.shape[1]}') events = events_data else: events = np.empty(shape=(0, 3), dtype=int) if events.size > 0: # Only keep events for which we have an ID <> description mapping. ids_without_desc = set(events[:, 2]) - set(event_id.values()) if ids_without_desc: raise ValueError( f'No description was specified for the following event(s): ' f'{", ".join([str(x) for x in sorted(ids_without_desc)])}. ' f'Please add them to the event_id dictionary, or drop them ' f'from the events_data array.') del ids_without_desc mask = [e in list(event_id.values()) for e in events[:, 2]] events = events[mask] # Append events to raw.annotations. All event onsets are relative to # measurement beginning. id_to_desc_map = dict(zip(event_id.values(), event_id.keys())) # We don't pass `first_samp`, as set_annotations() below will take # care of this shift automatically. new_annotations = mne.annotations_from_events( events=events, sfreq=raw.info['sfreq'], event_desc=id_to_desc_map, orig_time=raw.annotations.orig_time, verbose=verbose) raw = raw.copy() # Don't alter the original. annotations = raw.annotations.copy() # We use `+=` here because `Annotations.__iadd__()` does the right # thing and also performs a sanity check on `Annotations.orig_time`. annotations += new_annotations raw.set_annotations(annotations) del id_to_desc_map, annotations, new_annotations # Now convert the Annotations to events. all_events, all_desc = events_from_annotations( raw, event_id=event_id, regexp=None, # Include `BAD_` and `EDGE_` Annotations, too. verbose=verbose) all_dur = raw.annotations.duration if all_events.size == 0 and 'rest' not in raw.filenames[0]: warn('No events found or provided. Please add annotations ' 'to the raw data, or provide the events_data and ' 'event_id parameters. If this is resting state data ' 'it is recommended to name the task "rest".') return all_events, all_dur, all_desc
# system (where sample numbering starts when the acquisition system is # initiated, not when the *recording* is initiated), we also need to pass in # the ``orig_time`` parameter so that the onsets are properly aligned relative # to the start of recording: mapping = { 1: 'auditory/left', 2: 'auditory/right', 3: 'visual/left', 4: 'visual/right', 5: 'smiley', 32: 'buttonpress' } annot_from_events = mne.annotations_from_events( events=events, event_desc=mapping, sfreq=raw.info['sfreq'], orig_time=raw.info['meas_date']) raw.set_annotations(annot_from_events) ############################################################################### # Now, the annotations will appear automatically when plotting the raw data, # and will be color-coded by their label value: raw.plot(start=5, duration=5) ############################################################################### # .. _`chunk-duration`: # # Making multiple events per annotation # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
dat.info['line_freq'] = 60 # Extract trigger event data from EEG annotations try: annot = mne.read_annotations(filepath) if len(annot) > 10: dat.set_annotations(annot) events, e_id = mne.events_from_annotations(dat, event_id=event_map) orig_time = dat.annotations.orig_time else: events = mne.find_events(dat, shortest_event=1, mask=65280, mask_type="not_and") orig_time = dat.info['meas_date'] events = mne.pick_events(events, include=list(event_map.values())) annot_new = mne.annotations_from_events( events=events, sfreq=dat.info['sfreq'], orig_time=orig_time, event_desc=event_name_map, verbose=False ) dat.set_annotations(annot_new) except (ValueError, RuntimeError): print(" * Unable to find any valid triggers, skipping...\n") continue # Acutally write out BIDS data write_raw_bids(dat, bids_path, verbose=False) # Update sidecar files with correct metadata json_path = BIDSPath(subject=study_id, task=taskname, suffix='eeg', extension='.json', root=bids_root) with open(json_path.fpath, 'r') as tmp_f: sidecar_json = json.load(tmp_f) file_info = metadata.copy()
# event data raw.set_annotations(None) events = mne.find_events(raw, stim_channel='UPPT001', min_duration=2 / raw.info['sfreq']) # repair annotations events_id = { 'watch_{0}_{1}s'.format((i - 1) * 10, i * 10): int(i) for i in np.unique(events[:, -1]) if i != 255 } events_id['beginning'] = 255 annot_new = mne.annotations_from_events( events, raw.info['sfreq'], event_desc={v: k for k, v in events_id.items()}, first_samp=raw.first_samp) # raw.set_annotations(annot_new) # convert data to bids format bids_path = BIDSPath(subject=subid, session='movie', task='movie', run=runid, datatype='meg', root=bids_dir) write_raw_bids(raw, bids_path=bids_path, overwrite=True, events_data=events,
def load_5f_halt(args): """Loading and preprocessing the validation/traning data of the 5F or HaLT datasets. Parameters ---------- args : Namespace Input arguments. Returns ---------- dataset : BaseConcatDataset BaseConcatDataset of raw MNE arrays. """ import os from scipy import io import numpy as np import mne from sklearn.utils import resample from braindecode.datautil import exponential_moving_standardize from braindecode.datasets import BaseDataset, BaseConcatDataset ### Channel types ### # Rejecting channels A1, A1, X5 (see paper) ch_names = ['Fp1', 'Fp2', 'F3', 'F4', 'C3', 'C4', 'P3', 'P4', 'O1', 'O2', 'F7', 'F8', 'T3', 'T4', 'T5', 'T6', 'Fz', 'Cz', 'Pz', 'stim'] ch_types = ['eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'stim'] idx_chan = np.ones(22, dtype=bool) unused_chans = np.asarray((10, 11, 21)) idx_chan[unused_chans] = False ### Subjects ### dataset = [] if args.dataset == '5f': data_dir = os.path.join(args.project_dir, 'datasets', '5f', 'data') elif args.dataset == 'halt': data_dir = os.path.join(args.project_dir, 'datasets', 'halt', 'data') files = os.listdir(data_dir) files.sort() # Loading only one subject for intra-subject analysis if args.inter_subject == False: used_files = [] for file in files: if 'Subject'+args.test_sub in file: used_files.append(file) else: used_files = files ### Loading and preprocessing the .mat data ### for file in used_files: print('\n\nData file --> '+file+'\n\n') current_sub = file.partition('Subject')[2][0] data = io.loadmat(os.path.join(data_dir, file), chars_as_strings=True)['o'] sfreq = np.asarray(data[0][0]['sampFreq'][0]) marker = np.transpose(np.asarray(data[0][0]['marker'])) data = np.transpose(np.asarray(data[0][0]['data']))[idx_chan,:] data = exponential_moving_standardize(data) data = np.append(data, marker, 0) del marker ### Converting to MNE format and downsample ### info = mne.create_info(ch_names, sfreq, ch_types) raw_train = mne.io.RawArray(data, info) raw_train.info['highpass'] = 0.53 raw_train.info['lowpass'] = 70 del data ### Get events and downsample data ### events = mne.find_events(raw_train, stim_channel='stim', output='onset', consecutive='increasing') # Drop unused events idx = np.ones(events.shape[0], dtype=bool) for e in range(len(idx)): if events[e,2] > 6: idx[e] = False events = events[idx] # Drop stimuli channel raw_train.pick_types(eeg=True) # Downsampling the data raw_train.resample(args.sfreq) ### Dividing events into training, validation and test ### # For intra-subject decoding, 10 trials per condition are used for # validation, 10 trials for testing, and the remaining trials are used # for training. # For inter-subject decoding 75 trials per condition of the subject of # interest are used for validation and 75 for testing. All the data # from the other subjects is used for training. idx_train = np.zeros((events.shape[0],len(np.unique(events[:,2]))), dtype=bool) idx_val = np.zeros((events.shape[0],len(np.unique(events[:,2]))), dtype=bool) idx_test = np.zeros((events.shape[0],len(np.unique(events[:,2]))), dtype=bool) for e in range(len(np.unique(events[:,2]))): if args.inter_subject == False: shuf = resample(np.where(events[:,2] == e+1)[0], replace=False) idx_val[shuf[:10],e] = True idx_test[shuf[10:20],e] = True idx_train[shuf[20:],e] = True else: if args.test_sub == current_sub: idx_val[np.where(events[:,2] == e+1)[0][0:75],e] = True idx_test[np.where(events[:,2] == e+1)[0][75:150],e] = True else: idx_train[np.where(events[:,2] == e+1)[0],e] = True idx_train = np.sum(idx_train, 1, dtype=bool) idx_val = np.sum(idx_val, 1, dtype=bool) idx_test = np.sum(idx_test, 1, dtype=bool) events_train = events[idx_train,:] events_val = events[idx_val,:] events_test = events[idx_test,:] ### Creating the raw data annotations ### if args.dataset == '5f': event_desc = {1: 'thumb', 2: 'index_finger', 3: 'middle_finger', 4: 'ring_finger', 5: 'pinkie_finger'} elif args.dataset == 'halt': event_desc = {1: 'left_hand', 2: 'right_hand', 3: 'passive_neutral', 4: 'left_leg', 5: 'tongue', 6: 'right_leg'} if args.inter_subject == False: annotations_train = mne.annotations_from_events(events_train, sfreq, event_desc=event_desc) annotations_val = mne.annotations_from_events(events_val, sfreq, event_desc=event_desc) annotations_test = mne.annotations_from_events(events_test, sfreq, event_desc=event_desc) # Creating 1s trials annotations_train.duration = np.repeat(1., len(events_train)) annotations_val.duration = np.repeat(1., len(events_val)) annotations_test.duration = np.repeat(1., len(events_test)) # Adding annotations to raw data raw_val = raw_train.copy() raw_test = raw_train.copy() raw_train.set_annotations(annotations_train) raw_val.set_annotations(annotations_val) raw_test.set_annotations(annotations_test) else: if args.test_sub == current_sub: annotations_val = mne.annotations_from_events(events_val, sfreq, event_desc=event_desc) annotations_test = mne.annotations_from_events(events_test, sfreq, event_desc=event_desc) # Creating 1s trials annotations_val.duration = np.repeat(1., len(events_val)) annotations_test.duration = np.repeat(1., len(events_test)) # Adding annotations to raw data raw_val = raw_train.copy() raw_test = raw_train.copy() raw_val.set_annotations(annotations_val) raw_test.set_annotations(annotations_test) else: annotations_train = mne.annotations_from_events(events_train, sfreq, event_desc=event_desc) # Creating 1s trials annotations_train.duration = np.repeat(1., len(events_train)) # Adding annotations to raw data raw_train.set_annotations(annotations_train) ### Converting to BaseConcatDataset format ### description_train = {'subject': current_sub, 'partition': 'training'} description_val = {'subject': current_sub, 'partition': 'validation'} description_test = {'subject': current_sub, 'partition': 'test'} if args.inter_subject == False: dataset.append(BaseDataset(raw_train, description_train)) dataset.append(BaseDataset(raw_val, description_val)) dataset.append(BaseDataset(raw_test, description_test)) else: if args.test_sub == current_sub: dataset.append(BaseDataset(raw_val, description_val)) dataset.append(BaseDataset(raw_test, description_test)) else: dataset.append(BaseDataset(raw_train, description_train)) dataset = BaseConcatDataset(dataset) ### Output ### return dataset
def test_annotations_from_events(): """Test events to annotations conversion.""" raw = read_raw_fif(fif_fname) events = mne.find_events(raw) # 1. Automatic event description # ------------------------------------------------------------------------- annots = annotations_from_events(events, raw.info['sfreq'], first_samp=raw.first_samp, orig_time=None) assert len(annots) == events.shape[0] # Convert back to events raw.set_annotations(annots) events_out, _ = events_from_annotations(raw, event_id=int) assert_array_equal(events, events_out) # 2. Explicit event mapping # ------------------------------------------------------------------------- event_desc = {1: 'one', 2: 'two', 3: 'three', 32: None} annots = annotations_from_events(events, sfreq=raw.info['sfreq'], event_desc=event_desc, first_samp=raw.first_samp, orig_time=None) assert np.all([a in ['one', 'two', 'three'] for a in annots.description]) assert len(annots) == events[events[:, 2] <= 3].shape[0] # 3. Pass list # ------------------------------------------------------------------------- event_desc = [1, 2, 3] annots = annotations_from_events(events, sfreq=raw.info['sfreq'], event_desc=event_desc, first_samp=raw.first_samp, orig_time=None) assert np.all([a in ['1', '2', '3'] for a in annots.description]) assert len(annots) == events[events[:, 2] <= 3].shape[0] # 4. Try passing callable # ------------------------------------------------------------------------- event_desc = lambda d: 'event{}'.format(d) # noqa:E731 annots = annotations_from_events(events, sfreq=raw.info['sfreq'], event_desc=event_desc, first_samp=raw.first_samp, orig_time=None) assert np.all(['event' in a for a in annots.description]) assert len(annots) == events.shape[0] # 5. Pass numpy array # ------------------------------------------------------------------------- event_desc = np.array([[1, 2, 3], [1, 2, 3]]) with pytest.raises(ValueError, match='event_desc must be 1D'): annots = annotations_from_events(events, sfreq=raw.info['sfreq'], event_desc=event_desc, first_samp=raw.first_samp, orig_time=None) with pytest.raises(ValueError, match='Invalid type for event_desc'): annots = annotations_from_events(events, sfreq=raw.info['sfreq'], event_desc=1, first_samp=raw.first_samp, orig_time=None) event_desc = np.array([1, 2, 3]) annots = annotations_from_events(events, sfreq=raw.info['sfreq'], event_desc=event_desc, first_samp=raw.first_samp, orig_time=None) assert np.all([a in ['1', '2', '3'] for a in annots.description]) assert len(annots) == events[events[:, 2] <= 3].shape[0]
lfp_dict[array_label] = item # create mevent annotations event_df = lfp_dict["event"] events = np.zeros([len(event_df.index), 3]) stimulus_mapping = {"GoStimulus": 1, "StopStimulus": 2, "Response": 3} for i, event in event_df.iterrows(): events[i, 0] = round(event["latency"][0][0]) events[i, 2] = stimulus_mapping.get(event["type"][0]) event_mapping = {1: "GoStimulus", 2: "StopSimulus", 3: "Response"} annot_from_events = mne.annotations_from_events( events=events, event_desc=event_mapping, sfreq=lfp_dict["srate"][0], ) # SG = subgaleal channel_locs = [ loc[0][0].replace("subgaleal", "SG") for loc in lfp_dict["chanlocs"] ] info = mne.create_info(ch_names=channel_locs, sfreq=lfp_dict["srate"][0]) data = lfp_dict["data"] channels = mne.io.RawArray(np.array(data), info) channels.set_annotations(annot_from_events) channels.plot(start=0, duration=5) plt.show()
cleaned_epochs_AR[1].set_eeg_reference('average') cleaned_epochs_AR[0].save('epochs_a_short.fif', overwrite=True) cleaned_epochs_AR[1].save('epochs_b_short.fif', overwrite=True) #%% Get timings of bad segments Epoch_no = [ 381, 382, 554, 555, 557, 586, 587, 663, 678, 683, 967, 1126, 1146, 1303, 1351, 1378, 1408, 1439, 1661, 1662, 1663 ] ev1 = ev_list[ev_list[:, 2] != 101] ev2 = ev1[ev1[:, 2] != 104] ev3 = ev2[ev2[:, 2] != 106] ev4 = ev3[ev3[:, 2] != 1] ev5 = ev4[Epoch_no, :] # Creating annotations dictionary events_to_bad = {102: 'Bad', 103: 'Bad', 105: 'Bad', 107: 'Bad', 108: 'Bad'} An = mne.annotations_from_events(ev5, 2048, events_to_bad) # Set annotation duration An.duration = np.ones(len(Epoch_no)) # Save annotations An.save('bad_segments_pair003-annot.fif')
# set event type to 1 or 2 for congruent and incongruent trials for event_index in np.arange(events.shape[0]): trial_type = behavorial_df.iloc[event_index]["trial_type"] if trial_type == "con": events[event_index, 2] = 1 elif trial_type == "incon": events[event_index, 2] = 2 else: raise ValueError("trial type must be con or incon") # create mevent annotations mapping = {1: "con", 2: "incon"} annot_from_events = mne.annotations_from_events( events=events, event_desc=mapping, sfreq=raw_trig.info["sfreq"], ) # load lfps lfp_list = glob.glob("LFP*.ncs") for index in range(len(lfp_list)): lfp_list[index] = load_ncs(lfp_list[index]) lfp_list.sort(key=lambda x: x["channel"]) channels = [str(file["channel"]) for file in lfp_list] # ensure sampling freq is the same for all lfps sampling_freq = lfp_list[0]["sampling_freq"] if any(file["sampling_freq"] != sampling_freq for file in lfp_list): warnings.warn("Sample frequency does not match for all LFP files.")