def make_bipolar(data_fname, montage_filename): raw = mne.io.read_raw_edf(data_fname, preload=False, verbose=False) mne.rename_channels(raw.info, lambda name: re.sub(r'(POL|SEEG)\s+', '', name).strip()) channel_types = dict() for ch in raw.ch_names: result = re.match(r'^[A-Z][\']?\d+', ch) if result: channel_types[ch] = 'seeg' raw.set_channel_types(channel_types) montage = pd.read_csv(montage_filename, delimiter='\t') montage.drop_duplicates(subset='name', inplace=True) anode,cathode = clean_montage(raw.ch_names, montage.anode.tolist(), montage.cathode.tolist()) raw.load_data() bipo = mne.set_bipolar_reference(raw, list(anode), list(cathode), copy=True, verbose=False) bipo = drop_monopolar_channels(bipo) bipo.drop_channels(bipo.info['bads']) picks_seeg = mne.pick_types(bipo.info, meg=False, seeg=True) non_seeg_chans = [ch_name for ch_idx, ch_name in enumerate(bipo.ch_names) if not(ch_idx in picks_seeg) or len(ch_name.split('-')) == 1] bipo.drop_channels(non_seeg_chans) bipo.notch_filter(np.arange(50, bipo.info['sfreq']//2, 50)) return bipo
def for_firas_37(crop_start=None, file_name=None): edf = 'C:\\Matlab\\D037_28_01_21a.edf' raw = mne.io.read_raw_edf(edf) channels_list_original = [ 'RA 01', 'RA 02', 'RH 01', 'RH 02', 'LAH 01', 'LAH 02' ] channels_list_bipolar_original = [ x[:-1] + str(int(x[-1]) + 1) for x in channels_list_original ] channels_list = [x.replace(' 0', '') for x in channels_list_original] channels_list_bipolar = [ x.replace(' 0', '') for x in channels_list_bipolar_original ] raw.pick_channels( list( set(channels_list_original) | set(channels_list_bipolar_original))) channels_mapping = {x: x.replace(' 0', '') for x in raw.ch_names} raw.rename_channels(channels_mapping) if crop_start is not None: raw.crop(tmin=crop_start * 60, tmax=crop_start * 60 + 16 * 60) raw.resample(250) raw.load_data() raw_bi = mne.set_bipolar_reference(raw, anode=channels_list, cathode=channels_list_bipolar, drop_refs=False) rotem_write_edf(raw_bi, '416_bipolar.edf' if file_name is None else file_name)
def create_bipolar(raw, electrodes): """ create EEG data in a bipolar montage Parameters ---------- raw : MNE Raw EEG data electrodes : list of strings names of electrodes Returns ------- bipolar : MNE Raw EEG data in a bipolar montage """ anodes = list() cathodes = list() ch_names = list() for name in electrodes: temp = setup_bipolar(name, raw.ch_names, raw.info['bads']) anodes.extend(temp[0]) cathodes.extend(temp[1]) ch_names.extend(temp[2]) bipolar = mne.set_bipolar_reference(raw, anodes, cathodes, ch_names, verbose=False) bipolar = bipolar.pick_channels(ch_names) bipolar = bipolar.reorder_channels(ch_names) return bipolar
def test_bipolar_combinations(): """Test bipolar channel generation.""" ch_names = ['CH' + str(ni + 1) for ni in range(10)] info = create_info(ch_names=ch_names, sfreq=1000., ch_types=['eeg'] * len(ch_names)) raw_data = np.random.randn(len(ch_names), 1000) raw = RawArray(raw_data, info) def _check_bipolar(raw_test, ch_a, ch_b): picks = [raw_test.ch_names.index(ch_a + '-' + ch_b)] get_data_res = raw_test.get_data(picks=picks)[0, :] manual_a = raw_data[ch_names.index(ch_a), :] manual_b = raw_data[ch_names.index(ch_b), :] assert_array_equal(get_data_res, manual_a - manual_b) # test classic EOG/ECG bipolar reference (only two channels per pair). raw_test = set_bipolar_reference(raw, ['CH2'], ['CH1'], copy=True) _check_bipolar(raw_test, 'CH2', 'CH1') # test all combinations. a_channels, b_channels = zip(*itertools.combinations(ch_names, 2)) a_channels, b_channels = list(a_channels), list(b_channels) raw_test = set_bipolar_reference(raw, a_channels, b_channels, copy=True) for ch_a, ch_b in zip(a_channels, b_channels): _check_bipolar(raw_test, ch_a, ch_b) # check if reference channels have been dropped. assert (len(raw_test.ch_names) == len(a_channels)) raw_test = set_bipolar_reference(raw, a_channels, b_channels, drop_refs=False, copy=True) # check if reference channels have been kept correctly. assert (len(raw_test.ch_names) == len(a_channels) + len(ch_names)) for idx, ch_label in enumerate(ch_names): manual_ch = raw_data[idx, :] assert_array_equal( raw_test._data[raw_test.ch_names.index(ch_label), :], manual_ch) # test bipolars with a channel in both list (anode & cathode). raw_test = set_bipolar_reference(raw, ['CH2', 'CH1'], ['CH1', 'CH2'], copy=True) _check_bipolar(raw_test, 'CH2', 'CH1') _check_bipolar(raw_test, 'CH1', 'CH2')
def add_bipolar_derivation(raw, ch_1, ch_2): """ adds a channel to the given raw instance that is ch_1-ch_2 :param raw: raw object to derive channel from :param ch_1: anode :param ch_2: cathode """ raw = mne.set_bipolar_reference(raw, ch_1, ch_2, drop_refs=False) return raw
def test_bipolar_combinations(): """Test bipolar channel generation.""" ch_names = ['CH' + str(ni + 1) for ni in range(10)] info = create_info( ch_names=ch_names, sfreq=1000., ch_types=['eeg'] * len(ch_names)) raw_data = np.random.randn(len(ch_names), 1000) raw = RawArray(raw_data, info) def _check_bipolar(raw_test, ch_a, ch_b): picks = [raw_test.ch_names.index(ch_a + '-' + ch_b)] get_data_res = raw_test.get_data(picks=picks)[0, :] manual_a = raw_data[ch_names.index(ch_a), :] manual_b = raw_data[ch_names.index(ch_b), :] assert_array_equal(get_data_res, manual_a - manual_b) # test classic EOG/ECG bipolar reference (only two channels per pair). raw_test = set_bipolar_reference(raw, ['CH2'], ['CH1'], copy=True) _check_bipolar(raw_test, 'CH2', 'CH1') # test all combinations. a_channels, b_channels = zip(*itertools.combinations(ch_names, 2)) a_channels, b_channels = list(a_channels), list(b_channels) raw_test = set_bipolar_reference(raw, a_channels, b_channels, copy=True) for ch_a, ch_b in zip(a_channels, b_channels): _check_bipolar(raw_test, ch_a, ch_b) # check if reference channels have been dropped. assert (len(raw_test.ch_names) == len(a_channels)) raw_test = set_bipolar_reference( raw, a_channels, b_channels, drop_refs=False, copy=True) # check if reference channels have been kept correctly. assert (len(raw_test.ch_names) == len(a_channels) + len(ch_names)) for idx, ch_label in enumerate(ch_names): manual_ch = raw_data[idx, :] assert_array_equal( raw_test._data[raw_test.ch_names.index(ch_label), :], manual_ch) # test bipolars with a channel in both list (anode & cathode). raw_test = set_bipolar_reference( raw, ['CH2', 'CH1'], ['CH1', 'CH2'], copy=True) _check_bipolar(raw_test, 'CH2', 'CH1') _check_bipolar(raw_test, 'CH1', 'CH2')
def write_events_fif_bipolar(): edf = '/Users/rotemfalach/projects/epileptic_activity/results/406/406_overnightData.edf' channels_list = [ 'SEEG LA1-REF', 'SEEG LA2-REF', 'SEEG LAH1-REF', 'SEEG LAH2-REF', 'SEEG RA1-REF', 'SEEG RA2-REF', 'SEEG RAH1-REF', 'SEEG RAH2-REF' ] channels_list_bipolar = [ x[:-5] + str(int(x[-5]) + 1) + '-REF' for x in channels_list ] # channels_list = ['LA 02', 'LH 01', 'LH 02', 'RA 02', 'RMH 01', 'RMH 02'] # 036 # channels_list_bipolar = [x[:-1] + str(int(x[-1]) + 1) for x in channels_list] spikes_files = '_'.join(edf.split('_')[0:2]) original_raw = mne.io.read_raw_edf(edf) original_raw.pick_channels( list(set(channels_list) | set(channels_list_bipolar))) original_raw.load_data() raw = original_raw for chan in channels_list: # original_raw.rename_channels({chan: chan.replace('SEEG ', '').replace('-REF', '')}) original_raw = mne.set_bipolar_reference( original_raw, anode=[chan], cathode=chan[:-5] + str(int(chan[-5]) + 1) + '-REF', drop_refs=False, ch_name=chan + '_bi') stim_amp, stim_grad, stim_env = np.zeros((1, raw.n_times)), np.zeros( (1, raw.n_times)), np.zeros((1, raw.n_times)) # chan_alias = chan.replace(' 0', '') chan_alias = chan.replace('SEEG ', '').replace('-REF', '') spikes_df = pd.read_csv(spikes_files + '_' + chan_alias + '_biplor_spikes.csv') for evt in spikes_df.values: if evt[1] == 'amp': stim_amp[0][evt[4]] = 1 elif evt[1] == 'grad': stim_grad[0][evt[4]] = 1 else: stim_env[0][evt[4]] = 1 info_amp = mne.create_info([chan_alias + '_AMP_bi'], raw.info['sfreq'], ['stim']) info_grad = mne.create_info([chan_alias + '_GRAD_bi'], raw.info['sfreq'], ['stim']) info_env = mne.create_info([chan_alias + '_ENV_bi'], raw.info['sfreq'], ['stim']) amp_raw = mne.io.RawArray(stim_amp, info_amp) grad_raw = mne.io.RawArray(stim_grad, info_grad) env_raw = mne.io.RawArray(stim_env, info_env) original_raw.add_channels([amp_raw, grad_raw, env_raw], force_update_info=True) original_raw.drop_channels( list(set(channels_list) | set(channels_list_bipolar))) original_raw.resample(500).save('406_bi.fif')
def bipolar_ref(raw, anode, cathode, new_ch=None, copy=False, ch_info=None): """ Sets bipolar montage. """ from mne import set_bipolar_reference cathode = utilsfunc.in_list(cathode) if len(cathode) == 1: cathode = cathode * len(utilsfunc.in_list(anode)) if new_ch is None: new_ch = utilsfunc.in_list(anode) if copy is False: set_bipolar_reference(raw,anode=anode,\ cathode=cathode,ch_name=new_ch,\ copy=False, ch_info=ch_info) else: return set_bipolar_reference(raw,anode=anode,\ cathode=cathode,ch_name=new_ch,\ copy=True, ch_info=ch_info)
def for_firas_398(crop_start=None, file_name=None): edf = 'C:\\UCLA\\P398_overnightData.edf' raw = mne.io.read_raw_edf(edf) channels_list_original = [ 'SEEG R' 'A1-REF', 'SEEG RA2-REF', 'SEEG REC1-REF', 'SEEG REC2-REF', 'SEEG RAH1-REF', 'SEEG RAH2-REF', 'SEEG LA1-REF', 'SEEG LA2-REF', 'SEEG LAH1-REF', 'SEEG LAH2-REF' ] channels_list_bipolar_original = [ x[:-5] + str(int(x[-5]) + 1) + '-REF' for x in channels_list_original ] channels_list = [ x.replace('SEEG ', '').replace('-REF', '') for x in channels_list_original ] channels_list_bipolar = [ x.replace('SEEG ', '').replace('-REF', '') for x in channels_list_bipolar_original ] raw.pick_channels( list( set(channels_list_original) | set(channels_list_bipolar_original))) channels_mapping = { x: x.replace('SEEG ', '').replace('-REF', '') for x in raw.ch_names } raw.rename_channels(channels_mapping) if crop_start is not None: raw.crop(tmin=crop_start * 60, tmax=crop_start * 60 + 16 * 60) raw.resample(250) raw.load_data() raw_bi = mne.set_bipolar_reference(raw, anode=channels_list, cathode=channels_list_bipolar, drop_refs=False) # raw_bi.plot() write_edf('398_bipolar.edf' if file_name is None else file_name, raw_bi)
def test_set_bipolar_reference(inst_type): """Test bipolar referencing.""" raw = read_raw_fif(fif_fname, preload=True) raw.apply_proj() if inst_type == 'raw': inst = raw del raw elif inst_type in ['epochs', 'evoked']: events = find_events(raw, stim_channel='STI 014') epochs = Epochs(raw, events, tmin=-0.3, tmax=0.7, preload=True) inst = epochs if inst_type == 'evoked': inst = epochs.average() del epochs ch_info = {'kind': FIFF.FIFFV_EOG_CH, 'extra': 'some extra value'} with pytest.raises(KeyError, match='key errantly present'): set_bipolar_reference(inst, 'EEG 001', 'EEG 002', 'bipolar', ch_info) ch_info.pop('extra') reref = set_bipolar_reference(inst, 'EEG 001', 'EEG 002', 'bipolar', ch_info) assert (reref.info['custom_ref_applied']) # Compare result to a manual calculation a = inst.copy().pick_channels(['EEG 001', 'EEG 002']) a = a._data[..., 0, :] - a._data[..., 1, :] b = reref.copy().pick_channels(['bipolar'])._data[..., 0, :] assert_allclose(a, b) # Original channels should be replaced by a virtual one assert ('EEG 001' not in reref.ch_names) assert ('EEG 002' not in reref.ch_names) assert ('bipolar' in reref.ch_names) # Check channel information bp_info = reref.info['chs'][reref.ch_names.index('bipolar')] an_info = reref.info['chs'][inst.ch_names.index('EEG 001')] for key in bp_info: if key == 'loc': assert_array_equal(bp_info[key], 0) elif key == 'coil_type': assert_equal(bp_info[key], FIFF.FIFFV_COIL_EEG_BIPOLAR) elif key == 'kind': assert_equal(bp_info[key], FIFF.FIFFV_EOG_CH) else: assert_equal(bp_info[key], an_info[key]) # Minimalist call reref = set_bipolar_reference(inst, 'EEG 001', 'EEG 002') assert ('EEG 001-EEG 002' in reref.ch_names) # Minimalist call with twice the same anode reref = set_bipolar_reference(inst, ['EEG 001', 'EEG 001', 'EEG 002'], ['EEG 002', 'EEG 003', 'EEG 003']) assert ('EEG 001-EEG 002' in reref.ch_names) assert ('EEG 001-EEG 003' in reref.ch_names) # Set multiple references at once reref = set_bipolar_reference( inst, ['EEG 001', 'EEG 003'], ['EEG 002', 'EEG 004'], ['bipolar1', 'bipolar2'], [{ 'kind': FIFF.FIFFV_EOG_CH }, { 'kind': FIFF.FIFFV_EOG_CH }], ) a = inst.copy().pick_channels(['EEG 001', 'EEG 002', 'EEG 003', 'EEG 004']) a = np.concatenate([ a._data[..., :1, :] - a._data[..., 1:2, :], a._data[..., 2:3, :] - a._data[..., 3:4, :] ], axis=-2) b = reref.copy().pick_channels(['bipolar1', 'bipolar2'])._data assert_allclose(a, b) # Test creating a bipolar reference that doesn't involve EEG channels: # it should not set the custom_ref_applied flag reref = set_bipolar_reference(inst, 'MEG 0111', 'MEG 0112', ch_info={'kind': FIFF.FIFFV_MEG_CH}, verbose='error') assert (not reref.info['custom_ref_applied']) assert ('MEG 0111-MEG 0112' in reref.ch_names) # Test a battery of invalid inputs pytest.raises(ValueError, set_bipolar_reference, inst, 'EEG 001', ['EEG 002', 'EEG 003'], 'bipolar') pytest.raises(ValueError, set_bipolar_reference, inst, ['EEG 001', 'EEG 002'], 'EEG 003', 'bipolar') pytest.raises(ValueError, set_bipolar_reference, inst, 'EEG 001', 'EEG 002', ['bipolar1', 'bipolar2']) pytest.raises(ValueError, set_bipolar_reference, inst, 'EEG 001', 'EEG 002', 'bipolar', ch_info=[{ 'foo': 'bar' }, { 'foo': 'bar' }]) pytest.raises(ValueError, set_bipolar_reference, inst, 'EEG 001', 'EEG 002', ch_name='EEG 003')
# edf = 'C:\\UCLA\\P406_staging_PSG_and_intracranial_Mref_correct.txt.edf' # edf = 'C:\\Users\\user\\PycharmProjects\\pythonProject\\results\\402\\402_for_tag.edf' # edf = "C:ֿֿֿֿ\\analysis\\396\\396_LAH1_100_samples.fif" subj = '406' edf = f'C:\\UCLA\\P{subj}_overnightData.edf' depth_epochs = pd.read_csv( f'C:\\repos\\spikes_notebooks\\spike_index_{subj}.csv') scalp_epochs = pd.read_csv( f'C:\\repos\\spikes_notebooks\\scalp_index_{subj}.csv') raw = mne.io.read_raw_edf(edf).pick_channels( ['EOG1', 'EOG2', 'C3', 'C4', 'PZ', 'RAH1', 'RAH2', 'LAH1', 'LAH2']).resample(1000) raw = mne.set_bipolar_reference(raw, 'RAH1', 'RAH2', ch_name='RAH1-RAH2', drop_refs=False) raw = mne.set_bipolar_reference(raw, 'LAH1', 'LAH2', ch_name='LAH1-LAH2', drop_refs=False) depth = np.zeros((1, raw.n_times)) for evt in depth_epochs.values: depth[0][250 * evt[0]:250 * evt[0] + 250] = 1 scalp = np.zeros((1, raw.n_times)) for evt in scalp_epochs.values: scalp[0][250 * evt[0]:250 * evt[0] + 250] = 1
def load_data(bids_path): # read_raw_bids automatically # - populates bad channels using the BIDS channels.tsv # - sets channels types according to BIDS channels.tsv `type` column # - sets raw.annotations using the BIDS events.tsv subject = bids_path.subject session = bids_path.session extra_params = dict() if config.allow_maxshield: extra_params['allow_maxshield'] = config.allow_maxshield raw = read_raw_bids(bids_path=bids_path, extra_params=extra_params) if subject != 'emptyroom': # Crop the data. if config.crop is not None: raw.crop(*config.crop) # Rename events. if config.rename_events: rename_events(raw=raw, subject=subject, session=session) raw.load_data() if hasattr(raw, 'fix_mag_coil_types'): raw.fix_mag_coil_types() montage_name = config.eeg_template_montage if config.get_datatype() == 'eeg' and montage_name: msg = (f'Setting EEG channel locatiions to template montage: ' f'{montage_name}.') logger.info( gen_log_message(message=msg, step=1, subject=subject, session=session)) montage = mne.channels.make_standard_montage(montage_name) raw.set_montage(montage, match_case=False, on_missing='warn') if config.ch_types == ['eeg'] and config.eeg_bipolar_channels: msg = 'Creating bipolar channels …' logger.info( gen_log_message(message=msg, step=1, subject=subject, session=session)) raw.load_data() for ch_name, (anode, cathode) in config.eeg_bipolar_channels.items(): msg = f' {anode} – {cathode} -> {ch_name}' logger.info( gen_log_message(message=msg, step=1, subject=subject, session=session)) mne.set_bipolar_reference(raw, anode=anode, cathode=cathode, ch_name=ch_name, drop_refs=False, copy=False) # If we created a new bipolar channel that the user wishes to # use as an EOG channel, it is probably a good idea to set its channel # type to 'eog'. Bipolar channels, by default, don't have a location, # so one might get unexpected results otherwise, as the channel would # influence e.g. in GFP calculations, but not appear on topographic # maps. if any([ eog_ch_name in config.eeg_bipolar_channels for eog_ch_name in config.eog_channels ]): msg = 'Setting channel type of new bipolar EOG channel(s) …' logger.info( gen_log_message(message=msg, step=1, subject=subject, session=session)) for eog_ch_name in config.eog_channels: if eog_ch_name in config.eeg_bipolar_channels: msg = f' {eog_ch_name} -> eog' logger.info( gen_log_message(message=msg, step=1, subject=subject, session=session)) raw.set_channel_types({eog_ch_name: 'eog'}) if config.drop_channels: msg = f'Dropping channels: {", ".join(config.drop_channels)}' logger.info( gen_log_message(message=msg, step=1, subject=subject, session=session)) raw.drop_channels(config.drop_channels) return raw
def test_set_bipolar_reference(): """Test bipolar referencing.""" raw = read_raw_fif(fif_fname, preload=True) raw.apply_proj() reref = set_bipolar_reference(raw, 'EEG 001', 'EEG 002', 'bipolar', {'kind': FIFF.FIFFV_EOG_CH, 'extra': 'some extra value'}) assert (reref.info['custom_ref_applied']) # Compare result to a manual calculation a = raw.copy().pick_channels(['EEG 001', 'EEG 002']) a = a._data[0, :] - a._data[1, :] b = reref.copy().pick_channels(['bipolar'])._data[0, :] assert_allclose(a, b) # Original channels should be replaced by a virtual one assert ('EEG 001' not in reref.ch_names) assert ('EEG 002' not in reref.ch_names) assert ('bipolar' in reref.ch_names) # Check channel information bp_info = reref.info['chs'][reref.ch_names.index('bipolar')] an_info = reref.info['chs'][raw.ch_names.index('EEG 001')] for key in bp_info: if key == 'loc': assert_array_equal(bp_info[key], 0) elif key == 'coil_type': assert_equal(bp_info[key], FIFF.FIFFV_COIL_EEG_BIPOLAR) elif key == 'kind': assert_equal(bp_info[key], FIFF.FIFFV_EOG_CH) else: assert_equal(bp_info[key], an_info[key]) assert_equal(bp_info['extra'], 'some extra value') # Minimalist call reref = set_bipolar_reference(raw, 'EEG 001', 'EEG 002') assert ('EEG 001-EEG 002' in reref.ch_names) # Minimalist call with twice the same anode reref = set_bipolar_reference(raw, ['EEG 001', 'EEG 001', 'EEG 002'], ['EEG 002', 'EEG 003', 'EEG 003']) assert ('EEG 001-EEG 002' in reref.ch_names) assert ('EEG 001-EEG 003' in reref.ch_names) # Set multiple references at once reref = set_bipolar_reference( raw, ['EEG 001', 'EEG 003'], ['EEG 002', 'EEG 004'], ['bipolar1', 'bipolar2'], [{'kind': FIFF.FIFFV_EOG_CH, 'extra': 'some extra value'}, {'kind': FIFF.FIFFV_EOG_CH, 'extra': 'some extra value'}], ) a = raw.copy().pick_channels(['EEG 001', 'EEG 002', 'EEG 003', 'EEG 004']) a = np.array([a._data[0, :] - a._data[1, :], a._data[2, :] - a._data[3, :]]) b = reref.copy().pick_channels(['bipolar1', 'bipolar2'])._data assert_allclose(a, b) # Test creating a bipolar reference that doesn't involve EEG channels: # it should not set the custom_ref_applied flag reref = set_bipolar_reference(raw, 'MEG 0111', 'MEG 0112', ch_info={'kind': FIFF.FIFFV_MEG_CH}, verbose='error') assert (not reref.info['custom_ref_applied']) assert ('MEG 0111-MEG 0112'[:15] in reref.ch_names) # Test a battery of invalid inputs pytest.raises(ValueError, set_bipolar_reference, raw, 'EEG 001', ['EEG 002', 'EEG 003'], 'bipolar') pytest.raises(ValueError, set_bipolar_reference, raw, ['EEG 001', 'EEG 002'], 'EEG 003', 'bipolar') pytest.raises(ValueError, set_bipolar_reference, raw, 'EEG 001', 'EEG 002', ['bipolar1', 'bipolar2']) pytest.raises(ValueError, set_bipolar_reference, raw, 'EEG 001', 'EEG 002', 'bipolar', ch_info=[{'foo': 'bar'}, {'foo': 'bar'}]) pytest.raises(ValueError, set_bipolar_reference, raw, 'EEG 001', 'EEG 002', ch_name='EEG 003')
'C32', 'EXG1', 'EXG2', 'EXG3', 'EXG4', 'EXG5', 'EXG6', 'EXG7', 'EXG8', 'GSR1', 'GSR2', 'Erg1', 'Erg2', 'Resp', 'Plet', 'Temp']) Data_rawEEG.rename_channels(mapping={'A1':'Fp1', 'A2':'AF7', 'A3':'AF3', 'A4':'F1', 'A5':'F3', 'A6':'F5', 'A7':'F7', 'A8':'FT7', 'A9':'FC5', 'A10':'FC3', 'A11':'FC1', 'A12':'C1', 'A13':'C3', 'A14':'C5', 'A15':'T7', 'A16':'TP7', 'A17':'CP5', 'A18':'CP3', 'A19':'CP1', 'A20':'P1', 'A21':'P3', 'A22':'P5', 'A23':'P7', 'A24':'P9', 'A25':'PO7', 'A26':'PO3', 'A27':'O1', 'A28':'Iz', 'A29':'Oz', 'A30':'POz', 'A31':'Pz', 'A32':'CPz', 'B1':'Fpz', 'B2':'Fp2', 'B3':'AF8', 'B4':'AF4', 'B5':'AFz', 'B6':'Fz', 'B7':'F2', 'B8':'F4', 'B9':'F6', 'B10':'F8', 'B11':'FT8', 'B12':'FC6', 'B13':'FC4', 'B14':'FC2', 'B15':'FCz', 'B16':'Cz', 'B17':'C2', 'B18':'C4', 'B19':'C6', 'B20':'T8', 'B21':'TP8', 'B22':'CP6', 'B23':'CP4', 'B24':'CP2', 'B25':'P2', 'B26':'P4', 'B27':'P6', 'B28':'P8', 'B29':'P10', 'B30':'PO8', 'B31':'PO4', 'B32':'O2','C1':'mastoidleft', 'C2':'mastoidright', 'C3':'HEOGleft','C4':'HEOGright', 'C5':'VEOGup', 'C6':'VEOGdown','Status':'triggers'}) #VEOG< HEOG setup Data_rawEEG = mne.set_bipolar_reference(Data_rawEEG,anode='VEOGup',cathode='VEOGdown',ch_name='VEOG') Data_rawEEG = mne.set_bipolar_reference(Data_rawEEG,anode='HEOGleft',cathode='HEOGright',ch_name='HEOG') Data_rawEEG.set_channel_types({'VEOG':'eog','HEOG':'eog'}) ## Setting EEG reference Data_rawEEG.set_eeg_reference(['mastoidleft','mastoidright']) Data_rawEEG.drop_channels(['mastoidleft','mastoidright']) ## Filter on data low_f = 0.1 #Low edge of the high-pass filter high_f = 30 #High edge of the low-pass filter picks_eeg_eog = mne.pick_types(Data_rawEEG.info, meg=False, eeg=True, eog=True) #select the eeg and the eog channels for filtering
raw = mne.io.read_raw_bdf(data_fname, preload=True) raw = raw.pick(picks=[ 'EXG1', 'EXG2', 'EXG3', 'EXG4', 'EXG5', 'EXG6', 'EXG7', 'EXG8', 'Erg1', 'Erg2', 'Status' ]) mne_events = mne.find_events(raw) if name_subj == "S3": #removes incpmleted trail for S3 mne_events = mne_events[:-5] mne_events[:, 2] = mne_events[:, 2] - mne_events[:, 1] mne_events = np.array( [list(x) for x in mne_events if x[2] in initial_expctd_events]) mne.set_bipolar_reference(raw,anode=['EXG1','EXG3'], cathode=['EXG2','EXG4'],ch_name=['EMG_L','EMG_R'],\ copy=False) raw.pick_channels(['EMG_L', 'EMG_R', 'Erg1', 'Erg2']) raw.set_channel_types({ 'EMG_L': 'emg', 'EMG_R': 'emg', 'Erg1': 'misc', 'Erg2': 'misc' }) emg_channels_idx = {0: 'EMG_L', 1: 'EMG_R'} force_channels_idx = {2: 'Erg1', 3: 'Erg2'} channel_names = list(emg_channels_idx.values()) + list( force_channels_idx.values()) #Filtering raw = dbt.use_mne.apply_filter(raw, ch_names=['EMG_L', 'EMG_R'], low_cutoff=10)
nameBDF = f Trigger = [11, 21, 31, 41] #65314 fname = os.path.join(pathBDF, nameBDF) # raw = mne.io.read_raw_edf(fname,preload=True, verbose=True) raw = mne.io.read_raw_brainvision(fname, montage=None, eog=('HEOG_m', 'HEOG_p', 'VEOG_m', 'VEOG_p'), misc='auto', scale=1.0, preload=True, verbose=True) raw mne.set_bipolar_reference(raw,anode=['EMGg_m','EMGd_m'],\ cathode=['EMGg_p','EMGd_p'],ch_name=['EMG_L','EMG_R'],\ copy=False) # events = mne.find_events(raw, stim_channel = 'STI 014', min_duration=0.002, mask=2**24-64) events = mne.find_events(raw) raw.pick_channels(['EMG_L', 'EMG_R']) raw.set_channel_types({ 'EMG_L': 'emg', 'EMG_R': 'emg', # 'EXG5' :'eog', # 'EXG6' :'eog', # 'Erg1' :'misc', # 'Erg2': 'misc', # 'STI 014': 'stim' })
'C1': 'M1', 'C2': 'M2', 'C3': 'HEOGleft', 'C4': 'HEOGright', 'C5': 'VEOGup', 'C6': 'VEOGdown', 'Status': 'triggers' }) # Setting channel montage montage = mne.channels.read_montage('biosemi64') raw.set_montage(montage) # Creating EOG channels raw = mne.set_bipolar_reference(raw, anode='VEOGup', cathode='VEOGdown', ch_name='VEOG') raw = mne.set_bipolar_reference(raw, anode='HEOGleft', cathode='HEOGright', ch_name='HEOG') raw.set_channel_types({'VEOG': 'eog', 'HEOG': 'eog'}) # Setting reference (mastoids, but given different name for better electrode location) raw.set_eeg_reference(['M1', 'M2']) raw.drop_channels(['M1', 'M2']) # raw.set_eeg_reference(ref_channels='average') # # Investigating raw data (Identify bad channels and add to list above) # raw.plot() # raw.plot_psd(fmax=70)
def rereference(edf: mne.io.RawArray, desired_ref: str, current_ref: str = None, pick_chans: list = None) -> Tuple[mne.io.RawArray, str]: """ reference an edf. M1 and M2 should be included, but NOT as eeg stype in the mne.io.RawArray. contra_mastoid reref will be undone if needed but this requires M1 and M2 PRIOR to any referencing. :param edf: edf to re-ref :param current_ref: current reference type, can be "contra_mastoid",'linked_ear' or a channel name :param desired_ref: current reference type, can be "contra_mastoid",'linked_ear' or a channel name. If None, assumed it is a common channels :return: """ if pick_chans is None: chans = edf.ch_names else: chans = pick_chans if current_ref == desired_ref: return edf, current_ref if desired_ref in ['linked_ear' ] and 'M1' not in chans or 'M2' not in chans: warnings.warn( 'Trying to reference to linked ear, but missing M1 and M2 channels. EEG file will not be re-referenced', EEGWarning) return edf, current_ref if current_ref == 'contra_mastoid': to_reref = [ch for ch in chans if ch not in ['M1', 'M2']] left = [ ch for ch in to_reref if len([n for n in ['1', '3', '5', '7', '9'] if n in ch]) > 0 ] right = [ ch for ch in to_reref if len([n for n in ['2', '4', '6', '8', '10'] if n in ch]) > 0 ] if len(left) > 0 and 'M2' not in chans: warnings.warn( 'Trying to reference to left channels to M2 ear, but missing M2 channel. left channels cannot be unreferenced' ) left_ref = [] left = [] else: left_ref = ['M2'] * len(left) if len(right) > 0 and 'M1' not in chans: warnings.warn( 'Trying to reference to right channels to M1 ear, but missing M1 channel. right channels cannot be unreferenced' ) right_ref = [] right = [] else: right_ref = ['M1'] * len(right) edf = edf.apply_function(lambda x: -x, picks=['M1', 'M2']) edf = mne.set_bipolar_reference(edf, left + right, left_ref + right_ref, drop_refs=False, verbose=False) edf = edf.drop_channels(left + right) edf.rename_channels({ch: ch.split('-')[0] for ch in edf.ch_names}) edf = edf.apply_function(lambda x: -x, picks=['M1', 'M2']) ref_type = desired_ref if desired_ref == 'contra_mastoid': if current_ref == 'linked_ear': edf = edf.apply_function(lambda x: -x, picks=['M1', 'M2']) edf, _ = mne.set_eeg_reference(edf, ref_channels=['M1', 'M2'], verbose=False) edf = edf.apply_function(lambda x: -x, picks=['M1', 'M2']) to_reref = [ch for ch in chans if ch not in ['M1', 'M2']] left = [ ch for ch in to_reref if len([n for n in ['1', '3', '5', '7', '9', 'z'] if n in ch]) > 0 ] right = [ ch for ch in to_reref if len([n for n in ['2', '4', '6', '8', '10'] if n in ch]) > 0 ] if len(left) > 0 and 'M2' not in chans: warnings.warn( 'Trying to reference to left channels to M2 ear, but missing M2 channel. left channels will not be re-referenced' ) left_ref = [] left = [] ref_type = 'contra_right_only' else: left_ref = ['M2'] * len(left) if len(right) > 0 and 'M1' not in chans: warnings.warn( 'Trying to reference to right channels to M1 ear, but missing M1 channel. right channels will not be re-referenced' ) right_ref = [] right = [] ref_type = 'contra_left_only' else: right_ref = ['M1'] * len(right) edf = mne.set_bipolar_reference(edf, left + right, left_ref + right_ref, drop_refs=False, verbose=False) edf = edf.drop_channels(left + right) edf.rename_channels({ch: ch.split('-')[0] for ch in edf.ch_names}) elif desired_ref == 'linked_ear': edf, _ = mne.set_eeg_reference(edf, ref_channels=['M1', 'M2'], verbose=False) else: edf, _ = mne.set_eeg_reference(edf, ref_channels=desired_ref, verbose=False) return edf, ref_type
# %% # Using a bipolar reference # ^^^^^^^^^^^^^^^^^^^^^^^^^ # # To create a bipolar reference, you can use :meth:`~mne.set_bipolar_reference` # along with the respective channel names for ``anode`` and ``cathode`` which # creates a new virtual channel that takes the difference between two # specified channels (anode and cathode) and drops the original channels by # default. The new virtual channel will be annotated with the channel info of # the anode with location set to ``(0, 0, 0)`` and coil type set to # ``EEG_BIPOLAR`` by default. Here we use a contralateral/transverse bipolar # reference between channels ``EEG 054`` and ``EEG 055`` as described in # :footcite:`YaoEtAl2019` which creates a new virtual channel # named ``EEG 054-EEG 055``. raw_bip_ref = mne.set_bipolar_reference(raw, anode=['EEG 054'], cathode=['EEG 055']) raw_bip_ref.plot() # %% # EEG reference and source modeling # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # # If you plan to perform source modeling (either with EEG or combined EEG/MEG # data), it is **strongly recommended** to use the # average-reference-as-projection approach. It is important to use an average # reference because using a specific # reference sensor (or even an average of a few sensors) spreads the forward # model error from the reference sensor(s) into all sensors, effectively # amplifying the importance of the reference sensor(s) when computing source # estimates. In contrast, using the average of all EEG channels as reference # spreads the forward modeling error evenly across channels, so no one channel
anodes = [ 'T1', 'Fp1', 'F7', 'T3', 'T5', 'F3', 'T3', 'Fz', 'Cz', 'F4', 'T4', 'Fp2', 'F8', 'T4', 'T6', 'T2' ] cathodes = [ 'A1', 'F7', 'T3', 'T5', 'O1', 'T3', 'P3', 'Cz', 'Pz', 'T4', 'P4', 'F8', 'T4', 'T6', 'O2', 'A2' ] #Read and set original montage montage = mne.channels.make_standard_montage('standard_postfixed') epochs.set_montage(montage, raise_if_subset=False) # Set bipolar montage epochs_bipolar = mne.set_bipolar_reference(epochs, anodes, cathodes, drop_refs=False) # Removing old channels (keeping only biploar) epochs_bipolar.picks = None epochs_bipolar.drop_channels(epochs.info['ch_names']) #Print info for bipolar (double banana) reference raw data print(epochs_bipolar) print(epochs_bipolar.info['ch_names']) # ============================================================================= # # reordering bipolar channels (given original setup of channels) # ch_order = ['Fp1-F7', 'F7-T3', 'T3-T5', 'T5-O1', # 'Fp1-F3', 'F3-C3', 'C3-P3', 'P3-O1', # 'Fz-Cz', 'Cz-Pz',
def preprocess(raw): ## Input Variables ############################## trialLen = 1 # Number of seconds per trial #cutoff = 0.5 # Cut first/last .5 seconds from each downsample_fs = 1500 # What frequency to downsample to ################################################## # Filter raw.filter(0.1, 200) # data resample raw.resample(downsample_fs) # Cut data into trials (epochs) mne.EpochsArray picks = mne.pick_types(raw.info, eeg=True) data, times = raw[:] events = mne.find_events(raw) # Make trial events trialSamps = downsample_fs * trialLen dataShape = data.shape overflow = dataShape[1] % trialSamps # MNE forces you to use events to set timing for trials # Create events with event_id=9 for trial start timings (after our 1-8 ttls) trialEvents = [] n = int(raw.first_time) + 1 while n <= dataShape[1] - overflow + 1: trialEvents.append([n, 0, 9]) # [timestamp, N/A, event_id] n += trialSamps raw.add_events(np.array(trialEvents), stim_channel='TTL') # adding our trial events events = mne.find_events(raw) # Split into trials based on trial events processedObj = mne.Epochs(raw, events, event_id=9, tmin = 0.0, tmax = trialLen, baseline = None, preload=True) scalings = {'eeg':2000} # Plot to look for bad trials/channesl processedObj.plot(scalings = scalings, n_epochs = 2, show=True, block=True) print(processedObj) # Bipolar ref bi1 = [] bi2 = [] for n in range(0,16, 2): if 'CH'+str(n) not in processedObj.info['bads']: bi1.append(processedObj.ch_names[n]) if 'CH'+str(n+1) not in processedObj.info['bads']: bi2.append(processedObj.ch_names[n+1]) print(bi1, bi2) if len(processedObj.info['bads']) > 0: print('Some bad channels') print(processedObj.ch_names) # Bipolar based upon channel names processedObj = mne.set_bipolar_reference(processedObj, bi1, bi2) return processedObj
def load_data(bids_path): # read_raw_bids automatically # - populates bad channels using the BIDS channels.tsv # - sets channels types according to BIDS channels.tsv `type` column # - sets raw.annotations using the BIDS events.tsv subject = bids_path.subject session = bids_path.session extra_params = dict() if config.allow_maxshield: extra_params['allow_maxshield'] = config.allow_maxshield raw = read_raw_bids(bids_path=bids_path, extra_params=extra_params) if subject != 'emptyroom': # Crop the data. if config.crop is not None: raw.crop(*config.crop) # Rename events. if config.rename_events: rename_events(raw=raw, subject=subject, session=session) raw.load_data() if hasattr(raw, 'fix_mag_coil_types'): raw.fix_mag_coil_types() montage_name = config.eeg_template_montage if config.get_datatype() == 'eeg' and montage_name: msg = (f'Setting EEG channel locatiions to template montage: ' f'{montage_name}.') logger.info( gen_log_message(message=msg, step=1, subject=subject, session=session)) montage = mne.channels.make_standard_montage(montage_name) raw.set_montage(montage, match_case=False, on_missing='warn') if config.ch_types == ['eeg'] and config.eeg_bipolar_channels: msg = 'Creating bipolar channels …' logger.info( gen_log_message(message=msg, step=1, subject=subject, session=session)) raw.load_data() for ch_name, (anode, cathode) in config.eeg_bipolar_channels.items(): msg = f' {anode} – {cathode} -> {ch_name}' logger.info( gen_log_message(message=msg, step=1, subject=subject, session=session)) mne.set_bipolar_reference(raw, anode=anode, cathode=cathode, ch_name=ch_name, drop_refs=False, copy=False) if config.drop_channels: msg = f'Dropping channels: {", ".join(config.drop_channels)}' logger.info( gen_log_message(message=msg, step=1, subject=subject, session=session)) raw.drop_channels(config.drop_channels) return raw
def sync_matlab_and_eeg_events(edf_filename: str, timing_filename: str, event_filename: str = None, init_slice: int = None) -> object: """Syncs the matlab events with times in the EEG data, returns imported eeg raw eeg and events""" sample_rate = 128 channels_to_exclude = [ 'COUNTER', 'INTERPOLATED', 'RAW_CQ', 'GYROX', 'GYROY', 'MARKER', 'MARKER_HARDWARE', 'SYNC', 'TIME_STAMP_s', 'TIME_STAMP_ms' ] impedance_channel_map = { 'CQ_AF3': 'im_F8', 'CQ_F7': 'im_F5', 'CQ_F3': 'im_Cz', 'CQ_FC5': 'im_C3', 'CQ_T7': 'im_Fz', 'CQ_P7': 'im_Sync1', 'CQ_O1': 'im_F7', 'CQ_O2': 'im_Sync2', 'CQ_P8': 'im_P7', 'CQ_T8': 'im_P3', 'CQ_FC6': 'im_P8', 'CQ_F4': 'im_Oz', 'CQ_F8': 'im_Pz', 'CQ_AF4': 'im_P4', 'CQ_CMS': 'im_CMS', 'CQ_DRL': 'im_DRL' } channel_map = { 'O1': 'F7', 'P7': 'Sync1', 'T7': 'Fz', 'F7': 'F5', 'AF3': 'F8', 'FC5': 'C3', 'F3': 'Cz', 'O2': 'Sync2', 'P8': 'P7', 'T8': 'P3', 'F8': 'Pz', 'AF4': 'P4', 'FC6': 'P8', 'F4': 'Oz' } data_channels = [value for key, value in channel_map.items()] immedence_channels = [ value for key, value in impedance_channel_map.items() ] channel_map.update(impedance_channel_map) raw_edf = mne.io.read_raw_edf(edf_filename, stim_channel=None, exclude=channels_to_exclude) try: raw_edf.load_data() except IndexError: warnings.warn("Failed to load data, skipping subject") return raw_edf.rename_channels(channel_map) raw_edf = mne.set_bipolar_reference(raw_edf, "Sync1", "Sync2", "SyncRR") sync_channel0 = raw_edf.copy().pick_channels(["SyncRR"]) raw_im = raw_edf.copy().pick_channels(immedence_channels) raw_edf.pick_channels(data_channels) ##Process sync channels data, times = sync_channel0[:] # Extract data data = data.transpose() data = zscore(data) # normalize times -= init_slice data = data[times > 0] times = times[times > 0] # plt.plot(np.asarray(times), data) # plt.show() diff_data_raw = np.insert(np.diff(data, axis=0), 0, 0) diff_data = diff_data_raw.copy() threshold_moving = window_stdev( diff_data, 5000) * 3.5 # Calculate a moving threshold by diff_data[np.where((diff_data > -threshold_moving) & (diff_data < threshold_moving))] = 0 # Threshold diff_data[np.where( diff_data < 0)] = -diff_data[np.where(diff_data < 0)] # Rectify # plt.plot(np.asarray(times), diff_data) eeg_times = detect_peaks(diff_data, mph=0.2) eeg_times_edge = np.where(diff_data_raw[eeg_times] > 0, 1, 0) # rising edge is 1 rising = eeg_times[eeg_times_edge == 1] falling = eeg_times[eeg_times_edge == 0] # plt.plot(rising / sample_rate, np.ones(rising.shape), '*') # plt.plot(falling / sample_rate, np.ones(falling.shape), '*') eeg_times_secs = eeg_times / sample_rate event_data = pd.read_excel(timing_filename) event_data = event_data[['label', 'getSecsLogTime', 'realTime']] event_data.columns = ["label", "matlab_time", 'datetime'] event_data['matlab_time'] -= event_data['matlab_time'][0] # Start at zero event_data['eeg_time'] = np.nan recogRespTimes = event_data.label.apply( lambda lab: 'recogRespTime' not in lab) event_data_working = add_expected_transitions(event_data[recogRespTimes]) max_expected_lag = 5 # Initial Differences between matlab and eeg should not be more than 5 event_data_working['label_generic'] = event_data_working['label'].apply( lambda lab: lab[0:lab.rfind("_")]) # from collections import defaultdict # time_testing_dict = defaultdict(list) event_data.set_index('label', inplace=True, drop=False) matlab_labels = event_data_working['label_generic'].unique() for label in matlab_labels: timing_data_slice = event_data_working[ label == event_data_working['label_generic']] print("For", label, "attempting to find", len(timing_data_slice.matlab_time), "events") # plt.figure() # plt.plot(timing_data_slice.matlab_time, np.ones(len(timing_data_slice.matlab_time)), '*') # a = eeg_times_secs[(eeg_times_secs < (timing_data_slice.matlab_time.iloc[-1] + max_expected_lag)) & ( # eeg_times_secs > (timing_data_slice.matlab_time.iloc[0] - max_expected_lag))] # plt.plot(a, np.ones(len(a)), '*') # plt.show() expected_diff = np.diff(timing_data_slice.matlab_time) if label in ['syncDataLight_BeforeInter_flipTime']: sync_idx, sync_lag = find_template_in_sequence( eeg_times_secs, eeg_times_edge, expected_diff, timing_data_slice.trans_bool, 0, eeg_times_secs[-1] / 4) if sync_idx is None: warnings.warn('Did not fine sync signal. Terminating....') return eeg_times_secs = eeg_times_secs[sync_idx[0]:] - sync_lag eeg_times_edge = eeg_times_edge[sync_idx[0]:] lag_eeg_to_matlab = sync_lag print('Found start at', sync_lag) sync_idx = range(0, len(sync_idx)) else: sync_idx, sync_lag = find_template_in_sequence( eeg_times_secs, eeg_times_edge, expected_diff, timing_data_slice.trans_bool, timing_data_slice.matlab_time.iloc[0] - max_expected_lag, timing_data_slice.matlab_time.iloc[-1] + max_expected_lag) # Linearly increasing lag max_expected_lag = 5 + 0.01 * timing_data_slice.matlab_time.iloc[-1] if sync_idx is None: print('Did not find all points for', label) continue # for key, val in time_testing.items(): # time_testing_dict[key].extend(val) # print("Found", len(sync_idx), "events at", sync_lag) for lab, val in zip(timing_data_slice.label, eeg_times_secs[sync_idx]): event_data.set_value(lab, 'eeg_time', val) event_data = add_event_data_missing_sync(event_data) event_data.sort_values('matlab_time', inplace=True) events = interpolate_missing(event_data) events['type'] = events['label'].apply(lambda lab: lab[0:lab.rfind("_")]) events['eeg_samples'] = events['eeg_time'] * sample_rate events.set_index('type', inplace=True, drop=False) events.lag_eeg_to_matlab = lag_eeg_to_matlab events.to_csv(event_filename) # times -= lag_eeg_to_matlab # data = data[times > 0] # times = times[times > 0] # plot_sync_times(data, times, event_data) eeg = DotDict({}) eeg.raw = raw_edf eeg.impedance = raw_im slice_and_add_eeg_montage(eeg, lag_eeg_to_matlab) #Modifies inplace return eeg, events