def _to_annotation(self, bad_bool, description='BAD_'): import mne groups = group(bad_bool) if len(groups) > 0: onset = groups[:, 0] * (self.step / self.sfreq) duration = (self.window / self.sfreq ) + np.diff(groups).ravel() * (self.step / self.sfreq) return mne.Annotations(onset, duration, [description] * groups.shape[0]) else: return mne.Annotations([], [], [])
def load_eeg_data(EEG_DIR, ELECTRODE_NAMES, BADS, seizure=1, electrode_file='recon.fcsv', onset_file='onset_times.tsv'): electrode_file = os.path.join(EEG_DIR, electrode_file) electrodes = read_electrode_file(electrode_file) onset_times_file = os.path.join(EEG_DIR, onset_file) baseline_onsets, seizure_onsets = read_onsets(onset_times_file) studies = list(range(1, len(seizure_onsets)+1)) if isinstance(seizure, int): if seizure > 0: studies = [seizure] eeg_list = list() for i in studies: j = i if len(baseline_onsets) == 1: j = 1 fn = baseline_onsets.file_name[j] baseline_eeg_file = os.path.join(EEG_DIR, fn) baseline_onset_time = baseline_onsets.onset_time[j] fn = seizure_onsets.file_name[i] seizure_eeg_file = os.path.join(EEG_DIR, fn) seizure_onset_time = seizure_onsets.onset_time[i] read_eeg = read_micromed_eeg if fn[-3:] == 'edf': read_eeg = read_edf eeg = EEG(ELECTRODE_NAMES, BADS) raw, montage = read_eeg(baseline_eeg_file, electrodes, BADS) raw.set_annotations(mne.Annotations(baseline_onset_time, 0, 'Seizure')) eeg.set_baseline(raw, file_name=baseline_eeg_file) raw, montage = read_eeg(seizure_eeg_file, electrodes, BADS) raw.set_annotations(mne.Annotations(seizure_onset_time, 0, 'Seizure')) eeg.set_seizure(raw, file_name=seizure_eeg_file) eeg.montage = montage eeg.electrodes = electrodes eeg_list.append(eeg) return eeg_list
def set_the_annotations(hypnogram_filename, raw): """ set_the_annotations Parameters: ----------- hypnogram_filename : str Path to hypnogram file (in EDF format) raw : mne.io raw edf file Raw PSG recording that has been read initially beforehand Returns: -------- No return. Just sets the annotations to the raw PSG. """ # Function takes in the hypnogram/annotations (in EDF) as input. Returns the annotations as a return annot = read_edf_annotations(hypnogram_filename) # mne.Annotations takes in the onset and duration of each annotation (e.g. N1, N2, REM etc.) and their description. Return are the annotations mne_annot = mne.Annotations(annot.onset, annot.duration, annot.description) # The following line allows the annotations to be set on top of the current PSG recording, where 'raw' is the raw PSG file loaded into the worksapce via MNE. raw.set_annotations(mne_annot) print(mne_annot)
def annotate_jumps(raw, cutoff=25, allowed_before_bad=np.inf): logging.info('Annotating jump artifacts') arts, z, jumps_per_channel = detect_jumps(raw.copy(), cutoff=cutoff) # Need to check for jumps_per_channel bads = [k for k, v in jumps_per_channel.items() if v > allowed_before_bad] arts = [arts[k] for k, v in jumps_per_channel.items() if v <= allowed_before_bad] if len(bads) > 0: if 'bads' in raw.info.keys(): raw.info['bads'].extend(bads) else: raw.info['bads'] = bads a = [] for k in arts: if len(k) is not 0: a.extend(k) arts = np.array(a) annotations = None try: if len(arts) > 0: annotations = mne.Annotations(arts[:, 0], arts[:, 1], 'bad jump') except IndexError: pass return raw, annotations, z, jumps_per_channel
def annotate_cars(raw, cutoff=4.0, der_cutoff=7.): logging.info('Annotating car artifacts') arts, z, d = detect_cars(raw.copy(), cutoff=cutoff, der_cutoff=der_cutoff) annotations = None if len(arts) > 0: annotations = mne.Annotations(arts[:, 0], arts[:, 1], 'bad car') return annotations, z, d
def set_sleep_annotations(self): sleep_stages = ['Wake', 'N1', 'N2', 'N3', 'REM'] _ann = mne.Annotations( np.array([0, 0.01, 0.02, 0.03, 0.04], dtype=np.float64), np.array([0.001, 0.001, 0.001, 0.001, 0.001], dtype=np.float64), sleep_stages) self.bipolar_raw.set_annotations(_ann)
def test_events_from_annotation_orig_time_none(): """Tests events_from_annotation with orig_time None and first_sampe > 0.""" # Create fake data sfreq, duration_s = 100, 10 data = np.random.RandomState(42).randn(1, sfreq * duration_s) info = mne.create_info(ch_names=['EEG1'], ch_types=['eeg'], sfreq=sfreq) raw = mne.io.RawArray(data, info) # Add annotation toward the end onset = [8] duration = [1] description = ['0'] annots = mne.Annotations(onset, duration, description) raw = raw.set_annotations(annots) # Crop start of raw raw.crop(tmin=7) # Extract epochs events, event_ids = mne.events_from_annotations(raw) epochs = mne.Epochs(raw, events, tmin=0, tmax=1, baseline=None, on_missing='warning') # epochs is empty assert_array_equal(epochs.get_data()[0], data[:, 800:901])
def _add_markers(self, cnt): with h5py.File(self.filename, "r") as h5file: event_times_in_ms = h5file["mrk"]["time"][:].squeeze() event_classes = ( h5file["mrk"]["event"]["desc"][:].squeeze().astype(np.int64)) # Check whether class names known and correct order class_name_set = h5file["nfo"]["className"][:].squeeze() all_class_names = [ "".join(chr(c.item()) for c in h5file[obj_ref]) for obj_ref in class_name_set ] if self.check_class_names: _check_class_names(all_class_names, event_times_in_ms, event_classes) event_times_in_samples = event_times_in_ms * cnt.info["sfreq"] / 1000.0 event_times_in_samples = np.uint32(np.round(event_times_in_samples)) # Check if there are markers at the same time previous_i_sample = -1 for i_event, (i_sample, id_class) in enumerate( zip(event_times_in_samples, event_classes)): if i_sample == previous_i_sample: log.warning("Same sample has at least two markers.\n" "{:d}: ({:.0f} and {:.0f}).\n".format( i_sample, event_classes[i_event - 1], event_classes[i_event], ) + "Marker codes will be summed.") previous_i_sample = i_sample # Now create stim chan stim_chan = np.zeros_like(cnt.get_data()[0]) for i_sample, id_class in zip(event_times_in_samples, event_classes): stim_chan[i_sample] += id_class info = mne.create_info(ch_names=["STI 014"], sfreq=cnt.info["sfreq"], ch_types=["stim"]) stim_cnt = mne.io.RawArray(stim_chan[None], info, verbose="WARNING") cnt = cnt.add_channels([stim_cnt]) event_arr = [ event_times_in_samples, [0] * len(event_times_in_samples), event_classes, ] cnt.info["events"] = np.array(event_arr).T event_times_in_sec = event_times_in_ms / 1000.0 # 4 second trials durations = np.full(event_times_in_ms.shape, 4) # Label information for this dataset # have to add 1 as class labels start from 1, not 0 (due to matlab) event_desc = dict([(i + 1, c) for i, c in enumerate(all_class_names)]) descriptions = [event_desc[y] for y in event_classes] annots = mne.Annotations(event_times_in_sec, durations, descriptions) cnt.set_annotations(annots) return cnt
def epoch(file, event_dict, time_dict, indir): """ Epochs a single file filters and downsamples, removes blinks etc returns epochs object :param file: file to read :param event_dict: the dictionary of events :param time_dict: times to form epochs :param indir: filepath :return: """ # load the first file raw = mne.io.read_raw_fif(join(indir, file), preload=True) raw._first_samps[0] = 0 # Apply band-pass filter raw.filter(1, 200., fir_design='firwin', skip_by_annotation='edge') # detect blinks eog_events = mne.preprocessing.find_eog_events(raw) n_blinks = len(eog_events) # Center to cover the whole blink with full duration of 0.5s: onset = eog_events[:, 0] / raw.info['sfreq'] - 0.25 duration = np.repeat(0.5, n_blinks) raw.set_annotations(mne.Annotations(onset, duration, ['bad blink'] * n_blinks,orig_time=raw.info['meas_date'])) events = mne.find_events(raw, min_duration=0.002) epochs = mne.Epochs(raw, events, event_dict, tmin=time_dict['tmin'], tmax=time_dict['tmax'], baseline=time_dict['baseline'], preload=True, proj=True) epochs.pick_types(meg=True, exclude='bads') epochs.resample(600., npad='auto') return epochs
def ss_preproc(set_file): # read the raw file raw = mne.io.read_raw_brainvision(set_file, eog=['SO1', 'IO1', 'LO1', 'LO2'], montage='standard_1020', preload=True) # making reference-- averaging (mean of A1+A2) raw = mne.io.add_reference_channels(raw, ['A1']) raw.set_eeg_reference(['A1', 'A2']) # filtering sensitivity either 0.1 or 0.3 raw = raw.copy().filter(0.1, 30, l_trans_bandwidth='auto', h_trans_bandwidth='auto', method='fir', phase='zero', fir_window='hamming', n_jobs=2) # find eog events-- blink related eog_events = mne.preprocessing.find_eog_events(raw) n_blinks = len(eog_events) onset = eog_events[:, 0] / raw.info['sfreq'] - 0.25 duration = np.repeat(0.5, n_blinks) raw.annotations = mne.Annotations(onset, duration, ['bad blink'] * n_blinks, orig_time=raw.info['meas_date']) raw.save(set_file + '-raw.fif', overwrite=True)
def set_sw_annot(raw, path): """ Read hypno(txt file) and raw (vhdr-fif file) and Return (start, duration, description, end) """ """ Return hypnogram plus scoring """ hfiletxt = open(path, 'r') file = hfiletxt start = [] duration = [] end = [] description = [] for line in file: row = line.strip().split(',') if len(row) == 3: if row[2] == 'sw_I' or row[2] == 'sw_II' or row[ 2] == 'sw_dudosa' or row[2] == None: aux = row[0] + row[1] start.append(row[0]) duration.append(row[1]) description.append(row[2]) end.append(aux) start = np.asarray(start) start = start.astype(np.float) duration = np.asarray(duration) duration = duration.astype(np.float) description = np.asarray(description) my_annot = mne.Annotations(start, duration, description, orig_time=raw.annotations.orig_time) reraw = raw.copy().set_annotations(my_annot) return reraw, my_annot
def read_raw_data(run_index, hcp_params, lfreq=0.5, hfreq=60): raw = hcp.read_raw(run_index=run_index, **hcp_params) raw.load_data() # apply ref channel correction and drop ref channels # preproc.apply_ref_correction(raw) annots = hcp.read_annot(run_index=run_index, **hcp_params) # construct MNE annotations bad_seg = (annots['segments']['all']) / raw.info['sfreq'] annotations = mne.Annotations( bad_seg[:, 0], (bad_seg[:, 1] - bad_seg[:, 0]), description='bad') raw.annotations = annotations raw.info['bads'].extend(annots['channels']['all']) raw.pick_types(meg=True, ref_meg=False) raw.filter(lfreq, None, method='iir', iir_params=dict(order=4, ftype='butter'), n_jobs=1) raw.filter(None, hfreq, method='iir', iir_params=dict(order=4, ftype='butter'), n_jobs=1) # read ICA and remove EOG ECG # note that the HCP ICA assumes that bad channels have already been removed ica_mat = hcp.read_ica(run_index=run_index, **hcp_params) # We will select the brain ICs only exclude = annots['ica']['ecg_eog_ic'] preproc.apply_ica_hcp(raw, ica_mat=ica_mat, exclude=exclude) return raw
def _load_dataset(): """Load data and tidy it a bit""" fnirs_data_folder = mne.datasets.fnirs_motor.data_path() fnirs_raw_dir = os.path.join(fnirs_data_folder, 'Participant-1') raw_intensity = mne.io.read_raw_nirx(fnirs_raw_dir, verbose=True).load_data() raw_intensity.crop(0, raw_intensity.annotations.onset[-1]) new_des = [des for des in raw_intensity.annotations.description] new_des = ['A' if x == "1.0" else x for x in new_des] new_des = ['B' if x == "2.0" else x for x in new_des] new_des = ['C' if x == "3.0" else x for x in new_des] annot = mne.Annotations(raw_intensity.annotations.onset, raw_intensity.annotations.duration, new_des) raw_intensity.set_annotations(annot) picks = mne.pick_types(raw_intensity.info, meg=False, fnirs=True) dists = mne.preprocessing.nirs.source_detector_distances( raw_intensity.info, picks=picks) raw_intensity.pick(picks[dists > 0.01]) assert 'fnirs_cw_amplitude' in raw_intensity assert len(np.unique(raw_intensity.annotations.description)) == 4 return raw_intensity
def test_create_from_single_raw(): n_channels = 50 n_times = 500 sfreq = 100 rng = np.random.RandomState(34834) data = rng.rand(n_channels, n_times) ch_names = [f'ch{i}' for i in range(n_channels)] ch_types = ['eeg'] * n_channels info = mne.create_info(ch_names=ch_names, sfreq=sfreq, ch_types=ch_types) raw = mne.io.RawArray(data, info) n_anns = 10 inds = np.linspace(0, n_times, n_anns, endpoint=False).astype(int) onsets = raw.times[inds] durations = np.ones(n_anns) * 0.2 descriptions = ['test_trial'] * len(durations) anns = mne.Annotations(onsets, durations, descriptions) raw = raw.set_annotations(anns) windows = create_from_mne_raw([raw], 0, 0, 5, 2, False) # windows per trial: 0-5,2-7,4-9,6-11,...,14-19,15-20 assert len(windows) == 9 * n_anns for i_w, (x, y, (i_w_in_t, i_start, i_stop)) in enumerate(windows): assert i_w_in_t == i_w % 9 i_t = i_w // 9 assert i_start == inds[i_t] + i_w_in_t * 2 - (i_w_in_t == 8) assert i_stop == inds[i_t] + i_w_in_t * 2 - (i_w_in_t == 8) + 5 np.testing.assert_allclose(x, data[:, i_start:i_stop], atol=1e-5, rtol=1e-5)
def annotate_blinks(raw, threshold=10, acc_thresh=2000, Hz=1200, ch_mapping={'x': 'UADC002-3705', 'y': 'UADC003-3705', 'p': 'UADC004-3705'}): ''' Detect blinks and annotate as bad blinks Arguments: threshold : float Velocity threshold for saccade detection acc_thresh : float Acceleration threshold for saccade detection Hz: int Sampling rate of data. Returns: mne.Annotations object with blinks labeled as 'bad blinks' ''' logging.info('Annotating blinks artifacts') x, y, p = eye_voltage2gaze(raw, ch_mapping=ch_mapping) xpos, ypos = x.ravel() / ppd(), y.ravel() / ppd() sc = saccade_detection(xpos, ypos, threshold=threshold, acc_thresh=acc_thresh, Hz=Hz) blinks, scfilt = blink_detection(xpos, ypos, sc) if len(blinks) == 0: return None blink_onsets = raw.times[blinks[:, 0]] blink_durations = raw.times[blinks[:, 1]] - raw.times[blinks[:, 0]] return mne.Annotations(blink_onsets, blink_durations, 'bad blinks')
def test_apply_ica(): """Test ICA application.""" raw = hcp.read_raw(data_type='rest', verbose='error', **hcp_params) annots = hcp.read_annot(data_type='rest', **hcp_params) # construct MNE annotations bad_seg = (annots['segments']['all']) / raw.info['sfreq'] annotations = mne.Annotations(bad_seg[:, 0], (bad_seg[:, 1] - bad_seg[:, 0]), description='bad') raw.annotations = annotations raw.info['bads'].extend(annots['channels']['all']) ica_mat = hcp.read_ica(data_type='rest', **hcp_params) exclude = [ ii for ii in range(annots['ica']['total_ic_number'][0]) if ii not in annots['ica']['brain_ic_vs'] ] assert_raises(RuntimeError, apply_ica_hcp, raw, ica_mat=ica_mat, exclude=exclude) # XXX right now this is just a smoke test, should really check some # values... with warnings.catch_warnings(record=True): raw.crop(0, 1).load_data() apply_ica_hcp(raw, ica_mat=ica_mat, exclude=exclude)
def test_crop_by_annotations(meas_date, first_samp): """Test crop by annotations of raw.""" raw = read_raw_fif(raw_fname) if meas_date is None: raw.set_meas_date(None) raw = mne.io.RawArray(raw.get_data(), raw.info, first_samp=first_samp) onset = np.array([0, 1.5], float) if meas_date is not None: onset += raw.first_time annot = mne.Annotations(onset=onset, duration=[1, 0.5], description=["a", "b"], orig_time=raw.info['meas_date']) raw.set_annotations(annot) raws = raw.crop_by_annotations() assert len(raws) == 2 assert len(raws[0].annotations) == 1 assert raws[0].times[-1] == pytest.approx(annot[:1].duration[0], rel=1e-3) assert raws[0].annotations.description[0] == annot.description[0] assert len(raws[1].annotations) == 1 assert raws[1].times[-1] == pytest.approx(annot[1:2].duration[0], rel=5e-3) assert raws[1].annotations.description[0] == annot.description[1]
def _parse_events_for_description(events, events_id, description: str, sfreq, orig_time) -> mne.Annotations: """Parse events/eventsID from mne python for a specific description.""" events = np.asarray(events) # look for the exact event fitting the description event_id = None selected_event = None for event, _id in events_id.items(): if event == description: event_id = events_id[event] selected_event = event break new_events = events[np.where((events[:, -1] == event_id))] # if no events were found matching description return None if selected_event is None: return None # create new annotations data structure onsets = new_events[:, 0] / sfreq durations = np.zeros_like(onsets) # assumes instantaneous events descriptions = [selected_event] annot_from_events = mne.Annotations(onset=onsets, duration=durations, description=descriptions, orig_time=orig_time) return annot_from_events
def make_annotations_from_events(raw): events = mne.find_events( raw, stim_channel='STI101') # events: onsets by durations by description onsets = events[:, 0] / raw.info['sfreq'] # calculate onsets in seconds durations = np.zeros_like(onsets) event_ids = events[:, -1] if ~any(event_id in event_ids for event_id in [2, 3, 4]): diffs = np.diff(onsets) vid1_i = np.where((diffs < 31) & (diffs > 29))[0][ 0] + 1 # index of event after the button 'Start' pushed descriptions = [str(event_id) for event_id in event_ids] descriptions[vid1_i] = 'vid' + descriptions[vid1_i] else: descriptions = list( map( lambda event_id: 'vid' + str(event_id) if event_id != 1 else str(event_id), event_ids)) annot_from_events = mne.Annotations(onset=onsets, duration=durations, description=descriptions, orig_time=raw.info['meas_date']) raw.set_annotations(annot_from_events) return raw
def add_EMG_event(self): file = r"{}\{}".format(self.base_folder, 'EMG_onsets.csv') dt = pd.read_csv(file, index_col=0, header=None) task_name_list = ['WE_l', 'WE_r', 'IE_l', 'IE_r'] EMG_onsets_dict = dict.fromkeys(task_name_list) EMG_onsets_dict['WE_l'] = self.remove_nan_from_array(dt.values[0, :]) EMG_onsets_dict['WE_r'] = self.remove_nan_from_array(dt.values[1, :]) EMG_onsets_dict['IE_l'] = self.remove_nan_from_array(dt.values[2, :]) EMG_onsets_dict['IE_r'] = self.remove_nan_from_array(dt.values[3, :]) onsets_for_annotation = np.concatenate( (self.raw_array.annotations.onset, EMG_onsets_dict['WE_l'], EMG_onsets_dict['WE_r'], EMG_onsets_dict['IE_l'], EMG_onsets_dict['IE_r'])) durations_for_annotation = np.zeros_like(onsets_for_annotation) descriptions_for_annotation = np.concatenate( (self.raw_array.annotations.description, np.array(['EMG_WE_l'] * len(EMG_onsets_dict['WE_l'])), np.array(['EMG_WE_r'] * len(EMG_onsets_dict['WE_r'])), np.array(['EMG_IE_l'] * len(EMG_onsets_dict['IE_l'])), np.array(['EMG_IE_r'] * len(EMG_onsets_dict['IE_r'])))) annot_from_events = mne.Annotations( onset=onsets_for_annotation, duration=durations_for_annotation, description=descriptions_for_annotation) self.raw_array.set_annotations(annot_from_events)
def test_crop_more(): """Test more cropping.""" raw = mne.io.read_raw_fif(fif_fname).crop(0, 11).load_data() raw._data[:] = np.random.RandomState(0).randn(*raw._data.shape) onset = np.array([0.47058824, 2.49773765, 6.67873287, 9.15837097]) duration = np.array([0.89592767, 1.13574672, 1.09954739, 0.48868752]) annotations = mne.Annotations(onset, duration, 'BAD') raw.set_annotations(annotations) assert len(raw.annotations) == 4 delta = 1. / raw.info['sfreq'] offset = raw.first_samp * delta raw_concat = mne.concatenate_raws([ raw.copy().crop(0, 4 - delta), raw.copy().crop(4, 8 - delta), raw.copy().crop(8, None) ]) assert_allclose(raw_concat.times, raw.times) assert_allclose(raw_concat[:][0], raw[:][0]) assert raw_concat.first_samp == raw.first_samp assert_and_remove_boundary_annot(raw_concat, 2) assert len(raw_concat.annotations) == 4 assert_array_equal(raw_concat.annotations.description, raw.annotations.description) assert_allclose(raw.annotations.duration, duration) assert_allclose(raw_concat.annotations.duration, duration) assert_allclose(raw.annotations.onset, onset + offset) assert_allclose(raw_concat.annotations.onset, onset + offset, atol=1. / raw.info['sfreq'])
def remove_eof_local_detection(data): data = data.copy() event_id = 998 eog_events = mne.preprocessing.find_eog_events(data, event_id) n_blinks = len(eog_events) # Read epochs picks = mne.pick_types(data.info, meg=False, eeg=False, stim=False, eog=True, exclude='bads') tmin, tmax = -0.2, 0.2 blink_epochs = mne.Epochs(data, eog_events, event_id, tmin, tmax, picks=picks) data = blink_epochs.get_data() print("Number of detected EOG artifacts : %d" % len(blink_epochs)) # Center to cover the whole blink with full duration of 0.5s: onset = eog_events[:, 0] / data.info['sfreq'] - 0.25 duration = np.repeat(0.5, n_blinks) annot = mne.Annotations(onset, duration, ['bad blink'] * n_blinks, orig_time=data.info['meas_date']) data.set_annotations(annot) data.plot(n_channels=5, events=eog_events) return data
def clip_eeg(raw, pre=5, post=20): """ Clip EEG file Parameters ---------- raw : MNE Raw EEG data pre : float, optional how much time prior to the onset to clip, by default 5 post : float, optional how much time after to the onset to clip, by default 20 Returns ------- NME Raw """ onset = raw.annotations.onset[0] start = onset - pre if start < 0: start = 0 end = onset + post if end > raw.times[-1]: end = raw.times[-1] clipped = raw.copy().crop(start, end) clipped.set_annotations(None) clipped.set_annotations(mne.Annotations(onset-start, 0, 'Seizure')) return clipped
def test_export_mne_raw(tmpdir): """Test mne export.""" # Create a Raw object sfreq = 250.0 ch_names = ["Fp1", "Fp2", "Fz", "Cz", "Pz", "O1", "O2", "analog", "temp"] ch_types = ["eeg"] * (len(ch_names) - 2) + ["misc"] * 2 info = mne.create_info(ch_names, ch_types=ch_types, sfreq=sfreq) info.set_montage("standard_1020") data = np.random.randn(len(ch_names), int(sfreq * 100)) raw = mne.io.RawArray(data, info) # Make a fake channel in °C raw.info["chs"][-1]["unit"] = FIFF.FIFF_UNIT_CEL annots = mne.Annotations( onset=[3, 13, 30, 70, 90], # seconds duration=[1, 1, 0.5, 0.25, 9], # seconds description=[ "Stimulus/S 1", "Stimulus/S2.50", "Response/R101", "Look at this", "Comment/And at this", ], ch_names=[(), (), (), ("Fp1",), ("Fp1", "Fp2")], ) raw.set_annotations(annots) # export to BrainVision fname = tmpdir / "mne_export.vhdr" with pytest.warns(RuntimeWarning, match="'double' .* Converting to float32"): _export_mne_raw(raw=raw, fname=fname) with pytest.raises(ValueError, match="`fname` must have the '.vhdr'"): _export_mne_raw(raw=raw, fname=str(fname).replace(".vhdr", ".eeg.tar.gz")) # test overwrite with pytest.warns(): _export_mne_raw(raw=raw, fname=fname, overwrite=True) # try once more with "single" data and mne events fname = tmpdir / "mne_export_events.vhdr" raw = mne.io.RawArray(data.astype(np.single), info) raw.orig_format = "single" events = np.vstack( [ np.linspace(0, sfreq * 00, 10).astype(int), np.zeros(10).astype(int), np.arange(1, 11).astype(int), ] ).T _export_mne_raw(raw=raw, fname=fname, events=events) raw_read = mne.io.read_raw_brainvision(fname) np.testing.assert_allclose(raw_read.get_data(), raw.get_data())
def load_mne_labels() -> mne.Annotations: # https://mne.tools/stable/auto_tutorials/raw/plot_30_annotate_raw.html#sphx-glr-auto-tutorials-raw-plot-30-annotate-raw-py df = load_labels() start, stop, description = unzip([[*row] for row in df.to_records(index=False)]) duration = [(t1 - t0).total_seconds() for t0, t1 in zip(start, stop)] onset = [t.timestamp() for t in start] return mne.Annotations(onset, duration, description)
def import_annotations(self, fname): """Import annotations from a CSV file.""" if fname.endswith('.csv'): descs, onsets, durations = [], [], [] fs = self.current["raw"].info["sfreq"] with open(fname) as f: f.readline() # skip header for line in f: ann = line.split(",") if len(ann) == 3: # type, onset, duration onset = float(ann[1].strip()) duration = float(ann[2].strip()) if onset > self.current["raw"].n_times / fs: msg = ("One or more annotations are outside " "of the data range.") raise InvalidAnnotationsError(msg) else: descs.append(ann[0].strip()) onsets.append(onset) durations.append(duration) annotations = mne.Annotations(onsets, durations, descs) self.current["raw"].set_annotations(annotations) self.history.append("Import annotations from " + fname) self.history.append("raw.annotations = annotations") if fname.endswith('.mrk'): beg, end, desc = [], [], [] fs = self.current["raw"].info["sfreq"] with open(fname) as f: f.readline() for line in f: line = line.replace(' ', '') line = line.replace('"', '') line = line.replace('\n', '') b, e, d = tuple(line.split("\t")) beg.append(int(b)) end.append(int(e)) desc.append(d) beg, end = np.array(beg), np.array(end) onsets = beg / fs durations = (end - beg) / fs annotations = mne.Annotations(onsets, durations, desc) self.current["raw"].set_annotations(annotations) self.history.append("Import annotations from " + fname) self.history.append("raw.annotations = annotations")
def run_events(subject_id): subject = "sub_%03d" % subject_id print("processing subject: %s" % subject) in_path = op.join( data_path, "EEG_Process") #make map yourself in cwd called 'Subjects' process_path = op.join( data_path, "EEG_Process") #make map yourself in cwd called 'EEG_Process' raw_list = list() events_list = list() for run in range(1, 2): fname = op.join(in_path, 'sub_%03d_raw.fif' % (subject_id, )) raw = mne.io.read_raw_fif(fname, preload=True) print(" S %s - R %s" % (subject, run)) #import events and reorganize delay = int(round(0.0345 * raw.info['sfreq'])) events = mne.read_events( op.join(in_path, 'events_%03d-eve.fif' % (subject_id, ))) events[:, 0] = events[:, 0] + delay events_list.append(events) raw_list.append(raw) raw, events = mne.concatenate_raws(raw_list, events_list=events_list) ###some visualizations on the blinks in the raw data file### eog_events = mne.preprocessing.find_eog_events(raw) onsets = eog_events[:, 0] / raw.info['sfreq'] - 0.25 durations = [0.5] * len(eog_events) descriptions = ['bad blink'] * len(eog_events) blink_annot = mne.Annotations(onsets, durations, descriptions, orig_time=raw.info['meas_date']) raw.set_annotations(blink_annot) eeg_picks = mne.pick_types(raw.info, eeg=True) raw.plot(events=eog_events, order=eeg_picks) ###CONCLUSION: NOT THE BEST ALGORITHM #####ICA##### ica = ICA(random_state=97, n_components=15) picks = mne.pick_types(raw.info, eeg=True, eog=True, stim=False, exclude='bads') ica.fit(raw, picks=picks) raw.load_data() ica.plot_sources(raw) ica.plot_components() ica.plot_overlay(raw, exclude=[6], picks='eeg') #visualize the difference raw2 = raw.copy() ica.exclude = [6] ica.apply(raw2) raw2.plot() ica.plot_properties(raw, picks=[6])
def annotate_bads_auto(raw, reject_criteria, jump_criteria, reject_criteria_blink=200e-6): """ reads raw object and annotates automatically by threshold criteria - lower or higher than value. Also reject big jumps. supra-threshold areas are rejected - 50 ms to each side of event returns the annotated raw object and print times annotated :param jump_criteria: number - the minimum point to-point difference for rejection :param raw: raw object :param reject_criteria: number - threshold :param reject_criteria_blink: number, mark blinks in order to not reject them by mistake :return: annotated raw object """ data = raw.get_data(picks='eeg') # matrix size n_channels X samples del_arr = [raw.ch_names.index(i) for i in raw.info['bads']] data = np.delete(data, del_arr, 0) # don't check bad channels block_end = (raw.get_data(264).astype(np.int) & 255)[0] == 254 jumps = ((block_end[:-1]) | (abs(sum(np.diff(data))) > len(data) * jump_criteria) ) # mark large changes (mean change over jump threshold) jumps = np.append(jumps, False) # fix length for comparing # reject big jumps and threshold crossings, except the beggining and the end. rejected_times = (sum(abs(data) > reject_criteria) == 1) & \ ((raw._times > 0.1) & (raw._times < max(raw._times) - 0.1)) event_times = raw._times[ rejected_times] # collect all times of rejections except first and last 100ms plt.plot(rejected_times) extralist = [] data_eog = raw.get_data(picks='eog') eye_events = raw._times[sum(abs(data_eog) > reject_criteria_blink) > 0] plt.plot(sum(abs(data_eog) > reject_criteria_blink) > 0) plt.title( "blue-annotations before deleting eye events. orange - only eye events" ) print("loop length:", len(event_times)) for i in range( 2, len(event_times)): # don't remove adjacent time points or blinks if i % 300 == 0: print(i) if ((event_times[i] - event_times[i - 1]) < .05) | \ (np.any(abs(event_times[i] - eye_events) < .3) > 0): ## if a blink occured 300ms before or after extralist.append(i) event_times = np.delete(event_times, extralist) event_times = np.append(event_times, raw._times[jumps]) # add jumps onsets = event_times - 0.05 print("100 ms of data rejected in times:\n", onsets) durations = [0.1] * len(event_times) descriptions = ['BAD_data'] * len(event_times) annot = mne.Annotations(onsets, durations, descriptions, orig_time=raw.info['meas_date']) raw.set_annotations(annot) return raw
def add_info(raw): # DEBUG-VARIABLES # subject = 204 # fname = '/net/store/nbp/projects/hyperscanning/hyperscanning-2.0/mne_data/sourcedata/sub-{}/eeg/sub-{}-task-hyper_eeg.fif'.format(subject, subject) # raw = mne.io.read_raw_fif(fname = fname, preload = False) # CREATE EVENTS # print(mne.find_events.__doc__) try: events = mne.find_events(raw, stim_channel = 'STI 014') except ValueError as err: print("ValueError: {}".format(err)) print("--> trying to decrease length of 'shortest_event' from default(2) to 1 sample.") events = mne.find_events(raw, stim_channel = 'STI 014', shortest_event = 1) # raw.info['events'] = events --> This line does not work and gave an error ####### CHECKBLOCK if event block 12 start/end exist in dataset ######### # stim = raw.copy().load_data().pick_types(eeg=False, stim=True) # stim.plot(start=750, duration=1000) # stim.info # print(pd.DataFrame(events[:]).to_string()) # # find = pd.DataFrame(events[:]) # # Check if triggers 35 = Block 12 start, 47 = Block 12 end occur in dataset # # Sol 1 # find[find[2].isin([35, 47]) == True] # # Sol 2 # for i in range(len(find)): # if find[2][i] == 35 | 47: # print(find.index.values[i]) # # print(find.index.values.astype(int)[i]) # Create mapping dictionary of event description key = value pairs mapping = map_events() # invert the dict mapping = {v: k for k, v in mapping.items()} # for each trigger-key, map the corresponding trigger definition descriptions = np.asarray([mapping[event_id] for event_id in events[:, 2]]) # add annotations to eeg-struct srate = raw.info['sfreq'] onsets = events[:,0] / srate durations = np.zeros_like(onsets) # assuming instantaneous events # mne.Annotations input: # 1. supply the onset timestamps of each event (in sec.) # 2. the duration of event (set to 0sec.) # 3. the event description # 4. the onset of first sample annot = mne.Annotations(onsets, durations, descriptions, orig_time = None) # for idx, my_annot in enumerate(raw.annotations): # iterate on the Annotations object # # print('annot #{0}: onset={1}'.format(idx, my_annot['onset'])) # print('annot #{0}: {1}'.format(idx, my_annot['description'])) raw.set_annotations(annot) # raw.plot(start = 1103, duration = 3) return raw
def test_GLM_system_test(): fnirs_data_folder = mne.datasets.fnirs_motor.data_path() fnirs_raw_dir = os.path.join(fnirs_data_folder, 'Participant-1') raw_intensity = mne.io.read_raw_nirx(fnirs_raw_dir).load_data() raw_intensity.resample(1.0) new_des = [des for des in raw_intensity.annotations.description] new_des = ['Control' if x == "1.0" else x for x in new_des] new_des = ['Tapping/Left' if x == "2.0" else x for x in new_des] new_des = ['Tapping/Right' if x == "3.0" else x for x in new_des] annot = mne.Annotations(raw_intensity.annotations.onset, raw_intensity.annotations.duration, new_des) raw_intensity.set_annotations(annot) raw_intensity.annotations.crop(35, 2967) raw_od = mne.preprocessing.nirs.optical_density(raw_intensity) raw_haemo = mne.preprocessing.nirs.beer_lambert_law(raw_od) short_chs = get_short_channels(raw_haemo) raw_haemo = get_long_channels(raw_haemo) design_matrix = make_first_level_design_matrix(raw_intensity, hrf_model='spm', stim_dur=5.0, drift_order=3, drift_model='polynomial') design_matrix["ShortHbO"] = np.mean( short_chs.copy().pick(picks="hbo").get_data(), axis=0) design_matrix["ShortHbR"] = np.mean( short_chs.copy().pick(picks="hbr").get_data(), axis=0) glm_est = run_GLM(raw_haemo, design_matrix) df = glm_to_tidy(raw_haemo, glm_est, design_matrix) df = _tidy_long_to_wide(df) a = (df.query('condition in ["Control"]').groupby(['condition', 'Chroma' ]).agg(['mean'])) # Make sure false positive rate is less than 5% assert a["Significant"].values[0] < 0.05 assert a["Significant"].values[1] < 0.05 a = (df.query('condition in ["Tapping/Left", "Tapping/Right"]').groupby( ['condition', 'Chroma']).agg(['mean'])) # Fairly arbitrary cutoff here, but its more than 5% assert a["Significant"].values[0] > 0.7 assert a["Significant"].values[1] > 0.7 assert a["Significant"].values[2] > 0.7 assert a["Significant"].values[3] > 0.7 left = [[1, 1], [1, 2], [1, 3], [2, 1], [2, 3], [2, 4], [3, 2], [3, 3], [4, 3], [4, 4]] right = [[5, 5], [5, 6], [5, 7], [6, 5], [6, 7], [6, 8], [7, 6], [7, 7], [8, 7], [8, 8]] groups = dict(Left_ROI=picks_pair_to_idx(raw_haemo, left), Right_ROI=picks_pair_to_idx(raw_haemo, right)) df = pd.DataFrame() for idx, col in enumerate(design_matrix.columns[:3]): df = df.append(glm_region_of_interest(glm_est, groups, idx, col)) assert df.shape == (12, 8)