def set_eeg_reference(inst, ref_channels, ref_old=None, **kwargs): """ Reference to new channels. MNE raw object is modified in-place for efficiency. Parameters ---------- inst : mne.io.Raw | mne.io.RawArray | mne.Epochs | mne.Evoked MNE instance of Raw | Epochs | Evoked. Assumes the 'eeg' type is correctly set for EEG channels. ref_channels : list of str | str Can be: - The name(s) of the channel(s) used to construct the reference. - 'average' to apply an average reference (CAR) - 'REST' to use the reference electrode standardization technique infinity reference (requires instance with montage forward kwarg). ref_old : list of str | str Channel(s) to recover. **kwargs : Additional arguments are passed to mne.set_eeg_reference() c.f. https://mne.tools/dev/generated/mne.set_eeg_reference.html """ if not (all(isinstance(ref_ch, str) for ref_ch in ref_channels) or isinstance(ref_channels, str)): logger.error("The new reference channel must be a list of strings " "or 'average' or 'REST'.") raise ValueError if ref_old is not None: mne.add_reference_channels(inst, ref_old, copy=False) mne.set_eeg_reference(inst, ref_channels, copy=False, **kwargs)
def set_reference(self, ref): self.current["reference"] = ref if ref == "average": self.current["name"] += " (average ref)" self.current["data"].set_eeg_reference(ref) self.history.append('data.set_eeg_reference("average")') else: self.current["name"] += " (" + ",".join(ref) + ")" if set(ref) - set(self.current["data"].info["ch_names"]): # add new reference channel(s) to data try: mne.add_reference_channels(self.current["data"], ref, copy=False) except RuntimeError: raise AddReferenceError( "Cannot add reference channels to average " "reference signals.") else: self.history.append( f"mne.add_reference_channels(data, {ref}, " f"copy=False)") else: # re-reference to existing channel(s) self.current["data"].set_eeg_reference(ref) self.history.append(f"data.set_eeg_reference({ref})")
def test_add_reorder(n_ref): """Test that a reference channel can be added and then data reordered.""" # gh-8300 raw = read_raw_fif(raw_fname).crop(0, 0.1).del_proj().pick('eeg') assert len(raw.ch_names) == 60 chs = ['EEG %03d' % (60 + ii) for ii in range(1, n_ref)] + ['EEG 000'] with pytest.raises(RuntimeError, match='preload'): with pytest.warns(None): # ignore multiple warning add_reference_channels(raw, chs, copy=False) raw.load_data() if n_ref == 1: ctx = nullcontext() else: assert n_ref == 2 ctx = pytest.warns(RuntimeWarning, match='locations of multiple') with ctx: add_reference_channels(raw, chs, copy=False) data = raw.get_data() assert_array_equal(data[-1], 0.) assert raw.ch_names[-n_ref:] == chs raw.reorder_channels(raw.ch_names[-1:] + raw.ch_names[:-1]) assert raw.ch_names == ['EEG %03d' % ii for ii in range(60 + n_ref)] data_new = raw.get_data() data_new = np.concatenate([data_new[1:], data_new[:1]]) assert_allclose(data, data_new)
def get_raw(filename): r = mne.io.read_raw_brainvision(filename, eog=["TVEOG", "BVEOG", "LHEOG", "RHEOG"], preload=True) if not 'TP10' in r.info['ch_names']: mne.add_reference_channels(r, 'TP10', copy=False) r.set_eeg_reference(['TP9', 'TP10']) return r
def set_reference(self): """Set reference. """ dialog = ReferenceDialog(self) if dialog.exec_(): if dialog.average.isChecked(): tmp, _ = mne.set_eeg_reference(self.all.current.raw, None) tmp.apply_proj() name = self.all.current.name + " (average ref)" new = DataSet(raw=tmp, name=name, reference="average", events=self.all.current.events) else: ref = [c.strip() for c in dialog.channellist.text().split(",")] refstr = ",".join(ref) if set(ref) - set(self.all.current.raw.info["ch_names"]): # add new reference channel(s) to data try: tmp = mne.add_reference_channels(self.all.current.raw, ref) except RuntimeError: QMessageBox.critical(self, "Cannot add new channels", "Cannot add new channels to " "average referenced data.") return else: # re-reference to existing channel(s) tmp, _ = mne.set_eeg_reference(self.all.current.raw, ref) name = self.all.current.name + " (ref {})".format(refstr) new = DataSet(raw=tmp, name=name, reference=refstr, events=self.all.current.events) self._update_datasets(new)
def _make(self, subject, recording): raw = self.source.load(subject, recording, preload=True) if self.add: raw = mne.add_reference_channels(raw, self.add, copy=False) raw.set_eeg_reference(self.reference) if self.drop: raw = raw.drop_channels(self.drop) return raw
def test_add_reorder(): """Test that a reference channel can be added and then data reordered.""" # gh-8300 raw = read_raw_fif(raw_fname).crop(0, 0.1).del_proj().pick('eeg') assert len(raw.ch_names) == 60 with pytest.raises(RuntimeError, match='preload'): add_reference_channels(raw, ['EEG 000'], copy=False) raw.load_data() add_reference_channels(raw, ['EEG 000'], copy=False) data = raw.get_data() assert_array_equal(data[-1], 0.) assert raw.ch_names[-1] == 'EEG 000' raw.reorder_channels(raw.ch_names[-1:] + raw.ch_names[:-1]) assert raw.ch_names == ['EEG %03d' % ii for ii in range(61)] data_new = raw.get_data() data_new = np.concatenate([data_new[1:], data_new[:1]]) assert_allclose(data, data_new)
def set_reference(self, ref): self.current["reference"] = ref if ref == "average": self.current["name"] += " (average ref)" self.current["raw"].set_eeg_reference(ref, projection=False) else: self.current["name"] += " (" + ",".join(ref) + ")" if set(ref) - set(self.current["raw"].info["ch_names"]): # add new reference channel(s) to data try: mne.add_reference_channels(self.current["raw"], ref, copy=False) except RuntimeError: raise AddReferenceError("Cannot add reference channels " "to average reference signals.") else: # re-reference to existing channel(s) self.current["raw"].set_eeg_reference(ref, projection=False)
def rereference(raw, ref_new, ref_old=None, **kwargs): """ Apply rereferencing. """ # For numpy array if isinstance(raw, np.ndarray): # Check if isinstance(ref_new, int): ref_new = [ref_new] if not (all(isinstance(ref_ch, int) for ref_ch in ref_new) and all(0 <= ref_ch <= raw.shape[0] for ref_ch in ref_new)): raise ValueError( 'The new reference channel indices {} are not in raw.shape {}.' .format(ref_new, raw.shape[0])) if ref_old is not None: # Number of channel to recover if isinstance(ref_old, (list, tuple, np.ndarray)): ref_old = len(ref_old) # Add blank (zero-valued) channel(s) refs = np.zeros((ref_old, raw.shape[1])) raw = np.vstack((raw, refs)) # this can not be done in-place # Re-reference raw -= np.mean(raw[ref_new], axis=0) # For MNE raw else: # Check if not (all(isinstance(ref_ch, str) for ref_ch in ref_new) or isinstance(ref_new, str)): raise ValueError( "The new reference channel must be a list of strings or 'average' or 'REST'." ) if ref_old is not None: # Add blank (zero-valued) channel(s) mne.add_reference_channels(raw, ref_old, copy=False) # Re-reference mne.set_eeg_reference(raw, ref_new, copy=False, **kwargs) return raw
def re_reference(self): # tutorial: https://github.com/mne-tools/mne-python/blob/master/tutorials/preprocessing/ # plot_55_setting_eeg_reference.py # get rid of the default average reference raw_no_ref, _ = mne.set_eeg_reference(self.raw, []) # add new reference channel (all zero) (because A1 is not saved in the recording - this will be flat) raw_new_ref = mne.add_reference_channels(self.raw, ref_channels=['ch99_A1']) # raw_new_ref.plot(block=True, scalings=dict(eeg=50, grad=1e13, mag=1e15, eog=50), n_channels=31) # set reference to average of A1 and A2 raw_new_ref.set_eeg_reference(ref_channels=['ch4_A2'])
def reref_raw(raw, ref_channels=None): """Re-reference the data to the average of all electrodes Parameters ---------- raw: mne.io.Raw raw object of EEG data ref_channels: list list of reference channels Throws ---------- TypeError: returns if raw is improper type Exception: returns if unexpected error is encountered Returns ---------- raw_filtered: mne.io.Raw instance of rereferenced data output_dict_reference: dictionary dictionary with relevant information on re-ref """ try: raw.load_data() # add back reference channel (all zero) if ref_channels is None: raw_new_ref = raw else: raw_new_ref = mne.add_reference_channels(raw, ref_channels=ref_channels) ref_type = "average" raw_new_ref = raw_new_ref.set_eeg_reference(ref_channels=ref_type) ref_details = { "Reference Type": ref_type } # return average reference return raw_new_ref, {"Reference": ref_details} except TypeError: error = 'Type Error' except Exception: error = 'Unknown Error' print(error) reref_details = {"ERROR": error} return raw, {"Reference": reref_details}
def rereference(raw): '''Rereference data to linked left and right mastoid electrodes.''' print('add empty reference channel LM and use reference function to use \ average of LM and TP10_RM (average of mastoids)') # adds an empty channel (all zeros, for the left mastiod r = mne.add_reference_channels(raw, 'LM', True) # rereference to the mean of the LM and RM r.set_eeg_reference(ref_channels=['LM', 'TP10_RM']) # I visually (plot) checked that the RM value is half of what is was before #to be able to set montage (electrode locations) reference electrodes # (and eog) should not be of type eeg r.set_channel_types({'TP10_RM': 'misc', 'LM': 'misc'}) return r
def mushu2bva(filepath, outdir, manual_amp_ref=['Cz'], save_event_id=True): #------ filedir, filenametype = os.path.split(filepath) filename, filetype = os.path.splitext(filenametype) #load mushu data to mne raw, event_id = my.mushu_to_mne(filepath, ch_names=None, montage=None) #TODO:add manually the ref raw = mne.add_reference_channels(raw, manual_amp_ref) #Save in bva vhdr format nfilename = filename + ".vhdr" out_filepath = os.path.join(outdir, nfilename) print('saving eeg fif', nfilename) write_raw_brainvision(raw, out_filepath, events=True) if save_event_id: #WARNING: EVENT ID points not well reconstructed add better #save in mat event_id or in json # event_id_filepath = os.path.join(outdir, filename+"_event_id.mat") # print ('saving event_id', event_id_filepath) # scipy.io.savemat(event_id_filepath, event_id, oned_as='row') #save in json event id event_id_filepath = os.path.join(outdir, filename + "_event_id.txt") print('saving event_id json', event_id_filepath) my.save_obj_json(event_id_filepath, event_id)
def test_silent_mne(): from packaging import version has_new_mne = version.parse(mne.__version__) >= version.parse('0.19.0') raw = create_fake_raw(n_channels=2, n_samples=10, sfreq=10.) pos = np.random.random((2, 3)) if has_new_mne: ch_pos = {'a': pos[0, :], 'b': pos[1, :]} mntg = mne.channels.make_dig_montage(ch_pos=ch_pos, coord_frame='head') else: mntg = mne.channels.Montage(pos, ['a', 'b'], 'eeg', 'fake') raw.set_montage(mntg) # adding new reference channel without position gives a warning: with pytest.warns(Warning): mne.add_reference_channels(raw.copy(), ['nose']) # ... but not when using silent_mne() context manager: with pytest.warns(None) as record: with silent_mne(): mne.add_reference_channels(raw.copy(), ['nose']) # new numpy (>= 1.20) raises warnings on older mne (<= 0.20) mne_version = version.parse(mne.__version__) if mne_version >= version.parse('0.21'): assert len(record) == 0 # with `full_silence` no warnings are raised # (irrespective of mne and numpy) with pytest.warns(None) as record: with silent_mne(full_silence=True): mne.add_reference_channels(raw.copy(), ['nose']) warn('annoying warning!', DeprecationWarning) assert len(record) == 0
# the signal at* ``Fp1``. In this situation, you can add back ``Fp1`` as a flat # channel prior to re-referencing using :func:`~mne.add_reference_channels`. # (Since our example data doesn't use the `10-20 electrode naming system`_, the # example below adds ``EEG 999`` as the missing reference, then sets the # reference to ``EEG 050``.) Here's how the data looks in its original state: raw.plot() ############################################################################### # By default, :func:`~mne.add_reference_channels` returns a copy, so we can go # back to our original ``raw`` object later. If you wanted to alter the # existing :class:`~mne.io.Raw` object in-place you could specify # ``copy=False``. # add new reference channel (all zero) raw_new_ref = mne.add_reference_channels(raw, ref_channels=['EEG 999']) raw_new_ref.plot() ############################################################################### # .. KEEP THESE BLOCKS SEPARATE SO FIGURES ARE BIG ENOUGH TO READ # set reference to `EEG 050` raw_new_ref.set_eeg_reference(ref_channels=['EEG 050']) raw_new_ref.plot() ############################################################################### # Notice that the new reference (``EEG 050``) is now flat, while the original # reference channel that we added back to the data (``EEG 999``) has a non-zero # signal. Notice also that ``EEG 053`` (which is marked as "bad" in # ``raw.info['bads']``) is not affected by the re-referencing. #
tmin=preprocess_options['tmin'], tmax=preprocess_options['tmax'], metadata=metadata, baseline=(None, None), reject=None, preload=True) # Apply ICA (in place) ica.apply(epochs) # Interpolate channels if needed, and set new montage to bv_montage if len(epochs.info['bads']) > 0: epochs.interpolate_bads() else: print('No channels were interpolated') mne.add_reference_channels(epochs, 'FCz', copy=False) epochs.set_channel_types(mapping=dict(FCz='eeg')) epochs.set_montage(bv_montage, on_missing='ignore') # Add FCz and reference to average and set montage to standard_1005 epochs.set_eeg_reference(ref_channels='average') # Baseline to -200 to 0 epochs.apply_baseline((-.2, 0)) # Save epochs epochs_fif_file = deriv_path / \ f'{sub}_task-{task}_ref-avg_desc-removedICs_epo.fif.gz' epochs.save(epochs_fif_file, overwrite=True) # Make JSON
import argparse parser = argparse.ArgumentParser(description='Plot events and blinks.') parser.add_argument('vhdr_file', help='vhdr file name') args = parser.parse_args() import os.path as op import numpy as np import mne try: raw = mne.io.read_raw_brainvision(args.vhdr_file, preload=True) except: raise OSError('Failed to read file: {}'.format(args.vhdr_file)) mne.add_reference_channels(raw, 'LiRef', copy=False) raw.set_eeg_reference(['ReRef', 'LiRef']) raw.filter(0.1, 30, method='fir', picks=[27, 28, 29, 30]) event_id = { 'sem-yes-x': 203, 'sem-no-x': 208, 'world-yes-x': 213, 'world-no-x': 218, 'rel-yes-x': 223, 'rel-no-x': 228, 'abs—min-yes-x': 233, 'abs—min-no-x': 238, 'abs—max-yes-x': 243, 'abs—max-no-x': 248 }
# Visualize raw data with events # define time periods you want to plot tmin = events[1, 0] / raw.info['sfreq'] - 2 tmax = events[18, 0] / raw.info['sfreq'] + 5 # plot the raw data raw_show = raw.copy().crop(tmin=tmin, tmax=tmax) raw_show.plot(events=events, duration=6) # check the whole data using the follows # but be careful, since it may make your computer stuck # raw.plot(start=event_start_time, duration=6) # -------------------------Rereference------------------------- # # Re-reference the algebraic average of the left(TP9) and right(TP10) mastoids # add reference channels to data that consists of all zeros raw_new_ref = mne.add_reference_channels(raw, ref_channels=['TP10']) # set reference to average of ['TP9', 'TP10'] raw_new_ref.set_eeg_reference(ref_channels=['TP9', 'TP10']) # drop referenced channels raw_new_ref.drop_channels(['TP9', 'TP10']) # save re-referenced data raw_new_ref.save(datapath + str(subID) + '_newRef_raw.fif', overwrite=True) # raw_new_ref = mne.io.read_raw_fif(datapath + str(subID) + '_newRef_raw.fif', preload=True) print('channel numbers: {}'.format(raw_new_ref.info['nchan'])) print('channel names: {}'.format(raw_new_ref.info['ch_names'])) # visualize re-referenced data raw_new_ref_show = raw_new_ref.copy().crop(tmin=tmin, tmax=tmax) raw_new_ref_show.plot(events=events, duration=6)
def test_add_reference(): """Test adding a reference.""" raw = read_raw_fif(fif_fname, preload=True) picks_eeg = pick_types(raw.info, meg=False, eeg=True) # check if channel already exists pytest.raises(ValueError, add_reference_channels, raw, raw.info['ch_names'][0]) # add reference channel to Raw raw_ref = add_reference_channels(raw, 'Ref', copy=True) assert_equal(raw_ref._data.shape[0], raw._data.shape[0] + 1) assert_array_equal(raw._data[picks_eeg, :], raw_ref._data[picks_eeg, :]) _check_channel_names(raw_ref, 'Ref') orig_nchan = raw.info['nchan'] raw = add_reference_channels(raw, 'Ref', copy=False) assert_array_equal(raw._data, raw_ref._data) assert_equal(raw.info['nchan'], orig_nchan + 1) _check_channel_names(raw, 'Ref') # for Neuromag fif's, the reference electrode location is placed in # elements [3:6] of each "data" electrode location assert_allclose(raw.info['chs'][-1]['loc'][:3], raw.info['chs'][picks_eeg[0]]['loc'][3:6], 1e-6) ref_idx = raw.ch_names.index('Ref') ref_data, _ = raw[ref_idx] assert_array_equal(ref_data, 0) # add reference channel to Raw when no digitization points exist raw = read_raw_fif(fif_fname).crop(0, 1).load_data() picks_eeg = pick_types(raw.info, meg=False, eeg=True) del raw.info['dig'] raw_ref = add_reference_channels(raw, 'Ref', copy=True) assert_equal(raw_ref._data.shape[0], raw._data.shape[0] + 1) assert_array_equal(raw._data[picks_eeg, :], raw_ref._data[picks_eeg, :]) _check_channel_names(raw_ref, 'Ref') orig_nchan = raw.info['nchan'] raw = add_reference_channels(raw, 'Ref', copy=False) assert_array_equal(raw._data, raw_ref._data) assert_equal(raw.info['nchan'], orig_nchan + 1) _check_channel_names(raw, 'Ref') # Test adding an existing channel as reference channel pytest.raises(ValueError, add_reference_channels, raw, raw.info['ch_names'][0]) # add two reference channels to Raw raw_ref = add_reference_channels(raw, ['M1', 'M2'], copy=True) _check_channel_names(raw_ref, ['M1', 'M2']) assert_equal(raw_ref._data.shape[0], raw._data.shape[0] + 2) assert_array_equal(raw._data[picks_eeg, :], raw_ref._data[picks_eeg, :]) assert_array_equal(raw_ref._data[-2:, :], 0) raw = add_reference_channels(raw, ['M1', 'M2'], copy=False) _check_channel_names(raw, ['M1', 'M2']) ref_idx = raw.ch_names.index('M1') ref_idy = raw.ch_names.index('M2') ref_data, _ = raw[[ref_idx, ref_idy]] assert_array_equal(ref_data, 0) # add reference channel to epochs raw = read_raw_fif(fif_fname, preload=True) events = read_events(eve_fname) picks_eeg = pick_types(raw.info, meg=False, eeg=True) epochs = Epochs(raw, events=events, event_id=1, tmin=-0.2, tmax=0.5, picks=picks_eeg, preload=True) # default: proj=True, after which adding a Ref channel is prohibited pytest.raises(RuntimeError, add_reference_channels, epochs, 'Ref') # create epochs in delayed mode, allowing removal of CAR when re-reffing epochs = Epochs(raw, events=events, event_id=1, tmin=-0.2, tmax=0.5, picks=picks_eeg, preload=True, proj='delayed') epochs_ref = add_reference_channels(epochs, 'Ref', copy=True) assert_equal(epochs_ref._data.shape[1], epochs._data.shape[1] + 1) _check_channel_names(epochs_ref, 'Ref') ref_idx = epochs_ref.ch_names.index('Ref') ref_data = epochs_ref.get_data()[:, ref_idx, :] assert_array_equal(ref_data, 0) picks_eeg = pick_types(epochs.info, meg=False, eeg=True) assert_array_equal(epochs.get_data()[:, picks_eeg, :], epochs_ref.get_data()[:, picks_eeg, :]) # add two reference channels to epochs raw = read_raw_fif(fif_fname, preload=True) events = read_events(eve_fname) picks_eeg = pick_types(raw.info, meg=False, eeg=True) # create epochs in delayed mode, allowing removal of CAR when re-reffing epochs = Epochs(raw, events=events, event_id=1, tmin=-0.2, tmax=0.5, picks=picks_eeg, preload=True, proj='delayed') with pytest.warns(RuntimeWarning, match='ignored .set to zero.'): epochs_ref = add_reference_channels(epochs, ['M1', 'M2'], copy=True) assert_equal(epochs_ref._data.shape[1], epochs._data.shape[1] + 2) _check_channel_names(epochs_ref, ['M1', 'M2']) ref_idx = epochs_ref.ch_names.index('M1') ref_idy = epochs_ref.ch_names.index('M2') assert_equal(epochs_ref.info['chs'][ref_idx]['ch_name'], 'M1') assert_equal(epochs_ref.info['chs'][ref_idy]['ch_name'], 'M2') ref_data = epochs_ref.get_data()[:, [ref_idx, ref_idy], :] assert_array_equal(ref_data, 0) picks_eeg = pick_types(epochs.info, meg=False, eeg=True) assert_array_equal(epochs.get_data()[:, picks_eeg, :], epochs_ref.get_data()[:, picks_eeg, :]) # add reference channel to evoked raw = read_raw_fif(fif_fname, preload=True) events = read_events(eve_fname) picks_eeg = pick_types(raw.info, meg=False, eeg=True) # create epochs in delayed mode, allowing removal of CAR when re-reffing epochs = Epochs(raw, events=events, event_id=1, tmin=-0.2, tmax=0.5, picks=picks_eeg, preload=True, proj='delayed') evoked = epochs.average() evoked_ref = add_reference_channels(evoked, 'Ref', copy=True) assert_equal(evoked_ref.data.shape[0], evoked.data.shape[0] + 1) _check_channel_names(evoked_ref, 'Ref') ref_idx = evoked_ref.ch_names.index('Ref') ref_data = evoked_ref.data[ref_idx, :] assert_array_equal(ref_data, 0) picks_eeg = pick_types(evoked.info, meg=False, eeg=True) assert_array_equal(evoked.data[picks_eeg, :], evoked_ref.data[picks_eeg, :]) # add two reference channels to evoked raw = read_raw_fif(fif_fname, preload=True) events = read_events(eve_fname) picks_eeg = pick_types(raw.info, meg=False, eeg=True) # create epochs in delayed mode, allowing removal of CAR when re-reffing epochs = Epochs(raw, events=events, event_id=1, tmin=-0.2, tmax=0.5, picks=picks_eeg, preload=True, proj='delayed') evoked = epochs.average() with pytest.warns(RuntimeWarning, match='ignored .set to zero.'): evoked_ref = add_reference_channels(evoked, ['M1', 'M2'], copy=True) assert_equal(evoked_ref.data.shape[0], evoked.data.shape[0] + 2) _check_channel_names(evoked_ref, ['M1', 'M2']) ref_idx = evoked_ref.ch_names.index('M1') ref_idy = evoked_ref.ch_names.index('M2') ref_data = evoked_ref.data[[ref_idx, ref_idy], :] assert_array_equal(ref_data, 0) picks_eeg = pick_types(evoked.info, meg=False, eeg=True) assert_array_equal(evoked.data[picks_eeg, :], evoked_ref.data[picks_eeg, :]) # Test invalid inputs raw = read_raw_fif(fif_fname, preload=False) with pytest.raises(RuntimeError, match='loaded'): add_reference_channels(raw, ['Ref']) raw.load_data() with pytest.raises(ValueError, match='Channel.*already.*'): add_reference_channels(raw, raw.ch_names[:1]) with pytest.raises(TypeError, match='instance of'): add_reference_channels(raw, 1)
raw.rename_channels({ 'EOGli': 'LO1', 'EOGre': 'LO2', 'EOGobre': 'SO2', 'EOGunre': 'IO2', 'ReRef': 'A1' }) #which channels are EOG channels? raw.set_channel_types({ 'IO2': 'eog', 'SO2': 'eog', 'LO1': 'eog', 'LO2': 'eog' }) #add missing reference channel A2 raw = mne.add_reference_channels(raw, 'A2', copy=True) #set the channel montage to the file named above raw.set_montage(montage) #re-reference to linked mastoids raw.set_eeg_reference(['A1', 'A2']) #extract events from raw file [lists all events in the data] events = mne.find_events( raw ) #extract events from raw, this returns an array of the type [time, 0, trigger] #make a copy of the events array, just in case, then... old_events = events.copy() #...loop through the events for ev in range(len(events[:, 2])): if events[ev, 2] in codes.values(): events[ev, 1] = events[
#%% set montage #raw.set_montage('standard_1005') #%% High-pass filter raw.filter(0.5, 45, fir_design='firwin') #0.1 #raw.plot() print(raw.info) #%% Clean raw data - noisy channels, interpolate #in tutorial they say that I shall pick them by hand, mark as bad and then exclude and interpolate them # https://mne.tools/0.15/auto_tutorials/plot_artifacts_correction_rejection.html # https://mne.tools/stable/auto_tutorials/preprocessing/plot_15_handling_bad_channels.html#sphx-glr-auto-tutorials-preprocessing-plot-15-handling-bad-channels-py #%% re-reference #raw.set_eeg_reference(ref_channels = ['FCz']) raw_new_ref = mne.add_reference_channels( raw, ref_channels=['Fp2'] ) #add the online reference electrode back to the data as flat channel = Fp2 is the REFERNCE! raw_new_ref.set_eeg_reference(ref_channels=['TP9', 'TP10' ]) #average of 'mastoid'electrodes #raw_new_ref.plot() #plots print(raw_new_ref.info) #%% Overview of artifact detection # low frequ drifts # ocular artifacts # https://mne.tools/stable/auto_tutorials/preprocessing/plot_40_artifact_correction_ica.html#tut-artifact-ica #%% ica #default = fastica, newer and more robust = picard ica = mne.preprocessing.ICA(n_components=20, random_state=97, max_iter=800) ica.fit(raw_new_ref)
for i in range(len(subs)): isub = subs[i] if op.exists(op.join(wd, 'data', 'decoding', 'arraylocked', 'orientation', 's%02d_orientationdecoding_preds_data.npy'%(isub))): print('decoding already run for subject %d'%isub) if not op.exists(op.join(wd, 'data', 'decoding', 'arraylocked', 'orientation', 's%02d_orientationdecoding_preds_data.npy'%(isub))): print('\n\nworking on subject ' + str(isub) + ' (%d/%d)\n\n'%(i+1, len(subs))) sub = dict(loc = 'workstation', id = isub) param = get_subject_info_wmConfidence(sub) epochs = mne.epochs.read_epochs(fname = param['arraylocked'].replace('arraylocked', 'arraylocked_cleaned'), preload=True) #read raw data epochs.set_channel_types(dict(RM='eeg')) if 'VEOG' in epochs.ch_names: #drop eog channels if present epochs.pick_types(eeg = True) epochs = mne.add_reference_channels(epochs, ref_channels = 'LM') epochs.set_eeg_reference(ref_channels = ['LM','RM']) #re-reference average of the left and right mastoid now epochs.apply_baseline((-.25, 0)) #baseline 250ms prior to array onset epochs.resample(srate) #resample epochs.drop_channels(['RM', 'LM']) #drop these reference channels now, we don't need them ntrials = len(epochs) print('\n\n %d trials in the data\n\n'%ntrials) #can't easily equalise counts of the orientation categories because they arent event_ids... #epochs = epochs.equalize_event_counts(event_ids = ['neutral_left', 'neutral_right', 'cued_left', 'cued_right'])[0] #angles are between 0 and 179 degrees, so lets generate some 15 degree bins to categorise these orientations
''' events = raw_events.copy()[1:] events[:, 2] = raw_events[1:, 2] - 10000 #make events last col stays simple as 1,2,3,4 event_id = { m.split('/')[1]: n - 10000 for m, n in raw_event_id.items() if m != 'New Segment/' } #make event_id clean print(event_id) ################################################################################################################# #preprocessing eeg data ################################################################################################################# raw = mne.add_reference_channels(raw, 'Cz') # add Cz as the reference channel raw.set_channel_types(mapping={'AF3': 'eog', 'AF7': 'eog'}) # set eog channel raw.set_montage(mne.channels.read_montage('standard_1020')) # set montage(the standard 10-20 headset) --for topography raw.pick_types(meg=False, eeg=True, eog=True) # set pick types, when use eeg and eog # print(raw.info) # show raw data information raw.filter(0.1, 30, n_jobs=2, fir_design='firwin')
"response/4":4, "response/5":5, "response/space":6} music_trg_id = { ("music/"+k):trg_id[k] for k in trg_id} lang_trg_id = { ("lang/"+k):trg_id[k] for k in trg_id} # layout = mne.find_layout(raw.info) conditions = ("music","language")#,"decoding") raw = dict() for c in conditions: raw[c] = mne.io.read_raw_brainvision("Raw_data/01_{}.vhdr".format(c),preload=True) raw[c].rename_channels({'LEOG':'LO1','LBEOG':'IO1','REOG':'LO2','C64':'SO1','RM':'A2'}) raw[c].set_eeg_reference([]) raw[c] = mne.add_reference_channels(raw[c],"A1") raw[c].set_eeg_reference(['A1','A2']) raw[c].set_channel_types({'LO1':'eog','IO1':'eog','LO2':'eog','SO1':'eog',"A1":'misc',"A2":'misc'}) raw[c].filter(0.15,30,method='fir',phase='zero',n_jobs=2,fir_window='hamming',fir_design='firwin') # peak-to-peak rejection criteria peak_to_peak = dict(eeg=150e-6,eog=250e-6) # flatline rejection criteria flatline = dict(eeg=5e-6) # absolute threshold rejection criteria threshold = 75e-6 epochs = dict() for c in conditions: events = mne.find_events(raw[c])
def preprocess(subjname): # import the data fname = op.join(config.raw_path, subjname + '.vhdr') raw = mne.io.read_raw_brainvision(fname) raw.load_data() # remove the first 15-seconds as this typically has filter artifacts raw.crop(15, None) # remove channels we don't care about raw.drop_channels(['HEOGR', 'HEOGL', 'VEOGU', 'VEOGL', 'M1', 'M2']) # get and import electrode locations raw.set_montage('standard_1005') # create copy for use in ICA raw_4_ica = raw.copy() # filter the raw copy for ICA hi_pass, lo_pass = 1, 40 # we hardcode these params for better ICA decomp raw_4_ica.filter(hi_pass, None) raw_4_ica.filter(None, lo_pass) # create fake epochs of the raw copy for ICA so we can reject big artifacts before decomp fake_event_time = np.arange(0, raw.n_times, raw.info['sfreq']) # fake event every 1-second fake_event_ids = np.tile( np.array([0, 1]), (fake_event_time.size, 1)) # mimic the last two columns of events fake_events = np.column_stack((fake_event_time, fake_event_ids)) fake_events = fake_events.astype(int) # needs to be an array of integers tmin, tmax = 0, (raw_4_ica.info['sfreq'] - 1) / raw_4_ica.info['sfreq'] epochs_4_ica = mne.Epochs(raw_4_ica, events=fake_events, tmin=tmin, tmax=tmax, baseline=(tmin, tmax)) # identify bad data before running ICA epochs_4_ica.load_data() epochs_4_ica.resample(100) # auto reject big bad stuff before ICA epoch_data = epochs_4_ica.get_data() bad_chans, bad_trials = find_bad_data(epoch_data) epochs_4_ica.info['bads'] = [ epochs_4_ica.info['ch_names'][i] for i in bad_chans ] epochs_4_ica.drop(bad_trials, 'AUTO') # run ICA on the copy from mne.preprocessing import ICA method = 'fastica' decim = 3 # make it faster... random_state = 666 # ensures same ICA each time ica = ICA(method=method, random_state=random_state).fit(epochs_4_ica, decim=decim) # visually identify bad components ica.plot_components(range(0, 9)) # plot only first 10 as have most variance comps2check = input( "Indices of components to check, separated by commas [leave blank if none]:" ) if comps2check: comps2check_idx = list(map(int, comps2check.split(","))) ica.plot_properties(raw_4_ica, comps2check_idx) bad_comps_str = input( "Indices of components to REJECT, separated by commas [leave blank if none]:" ) if bad_comps_str: bad_comps_idx = list(map(int, bad_comps_str.split(","))) ica.exclude.extend(bad_comps_idx) print('Removing components {}'.format(bad_comps_idx)) # now we create the true epoch set before applying the ica to that # filter the raw data raw.filter(config.preproc_params['hi_pass'], None) raw.filter(None, config.preproc_params['lo_pass']) # extract events - BV data has markers as annotations events, event_id = mne.events_from_annotations(raw) # AWFUL HACK TO FIX TIMING PROBLEMS OF EMBODIMENT TRIGGERS events[:, 0] = events[:, 0] - round(raw.info['sfreq'] * .117) # END OF HACK # # rename the events to something more useful evt_keys = list(config.event_info.keys()) new_event_id = {} for evt in evt_keys: new_event_id[config.event_info[evt]] = event_id[evt] # ANT data sometimes has duplicate triggers at exactly the same time so here we fix this nondup_evts = np.where(np.diff(events[:, 0]) != 0) events = events[nondup_evts[0], :] # create epochs picks = mne.pick_types(raw.info, eeg=True, stim=False, eog=False) tmin, tmax = config.preproc_params['epoch_win'] baseline = config.preproc_params['base_win'] epochs = mne.Epochs(raw, events=events, tmin=tmin, event_id=new_event_id, tmax=tmax, baseline=baseline, picks=picks) # remove the bad channels identified earlier epochs.info['bads'] = epochs_4_ica.info['bads'] # apply the ICA from the raw copy to the epoched data epochs.load_data() ica.apply(epochs) # final pass of potential bad data epoch_data = epochs.get_data() bad_chans, bad_trials = find_bad_data(epoch_data) epochs.info['bads'] = [epochs.info['ch_names'][i] for i in bad_chans] epochs.drop(bad_trials, 'AUTO') # baseline correct again as ICA will have affected epochs.apply_baseline() # with no arguments this defaults to (None,0) # would be good to plot and check here, but can at least plot it epochs.plot(scalings=dict(eeg=20e-5), n_epochs=5, n_channels=len(epochs.info['chs']), block=True) # deal with any new bad channels or trials identified by user epochs.interpolate_bads(reset_bads=False) epochs.drop_bad() # put the reference channel back in epochs = mne.add_reference_channels(epochs, 'CPz', copy=False) # convert to average reference and update channel locations epochs.set_eeg_reference(ref_channels='average', projection=False) epochs.set_montage('standard_1005') # save the data fname = op.join(config.epoch_path, subjname + '-epo.fif') epochs.save(fname, overwrite=True)
print(raw.info) #print(raw.info.keys()) #print(raw.info['ch_names']) #%% add ref channel print(raw.info['ch_names']) print(len(raw.info['ch_names'])) l1 = raw.info['ch_names'] if 'FCz' not in l1: print('FCz is not in the list') else: print('FCz is in the list') raw_new_ref = mne.add_reference_channels(raw, ref_channels =['FCz']) #add the online reference electrode back to the data as flat channel #raw_new_ref.plot() #raw.set_montage('standard_1005', on_missing = 'ignore') #need the montage! change the on_missing parameter here #%% montage #put the .bvef file in the path where the script is stored montage_path = path + 'CACS-128_NO_REF.bvef' #if use REF .bvef file then it does not work montage = mne.channels.read_custom_montage(montage_path, head_size = 0.54) #.bvef is supported, head_size in meters (we have 54 cm) print(raw.info) print(raw.info['ch_names']) #print(raw.info['chs']) print(len(raw.info['ch_names'])) montage.plot() raw_new_ref.set_montage(montage) #%% change channel types
[4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 24, 25, 26]) laplacian = True #%% only needs running if cuelocked TFR glms not already present for i in subs: print('\n\nworking on subject ' + str(i) + '\n\n') sub = dict(loc='workstation', id=i) param = get_subject_info_wmConfidence(sub) #get the epoched data epochs = mne.epochs.read_epochs(fname=param['cuelocked'].replace( 'cuelocked', 'cuelocked_cleaned'), preload=True) epochs.crop(tmin=-0.5, tmax=1) epochs = mne.add_reference_channels( epochs, ref_channels='LM' ) #adds a channel of zeros for the left mastoid (as ref to itself in theory) # deepcopy(epochs['cued_left']).apply_baseline((-.25,0)).average().plot_joint(title = 'cued left, no re-ref', times = np.arange(.1,.7,.1)) # deepcopy(epochs['cued_left']).set_eeg_reference(['RM']).apply_baseline((-.25,0)).average().plot_joint(title='cued_left, RM re-ref', times = np.arange(.1,.7,.1)) # deepcopy(epochs['cued_left']).set_eeg_reference(['LM', 'RM']).apply_baseline((-.25,0)).average().plot_joint(title = 'cued left, ave mast ref', times = np.arange(.1,.7,.1)) epochs.set_eeg_reference(ref_channels=[ 'LM', 'RM' ]) #re-reference average of the left and right mastoid now # epochs.set_eeg_reference('average') epochs.apply_baseline((-.25, 0)) #baseline 250ms prior to feedback epochs.resample(500) #resample to 500Hz if 'VEOG' in epochs.ch_names: epochs = epochs.drop_channels(['VEOG', 'HEOG']) ntrials = len(epochs) epochs.drop_channels(['RM', 'LM'])
]) subs = np.array( [4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 24, 25, 26]) #subs = np.array([24,25]) for i in subs: print('\n\nworking on subject ' + str(i) + '\n\n') sub = dict(loc='workstation', id=i) param = get_subject_info_wmConfidence(sub) arraylocked = mne.epochs.read_epochs(fname=param['arraylocked'].replace( 'arraylocked', 'arraylocked_cleaned'), preload=True) #read raw data arraylocked.resample( 100) #downsample to 100Hz so don't overwork the workstation arraylocked = mne.add_reference_channels(arraylocked, ref_channels='LM') arraylocked.set_eeg_reference(ref_channels=[ 'LM', 'RM' ]) #re-reference average of the left and right mastoid now # #will do an automated process of looking for trials with heightened variance (noise) and output which trials to keep # _, keeps = plot_AR(arraylocked, method = 'gesd', zthreshold = 1.5, p_out=.1, alpha = .05, outlier_side = 1) # keeps = keeps.flatten() # # discards = np.ones(len(arraylocked), dtype = 'bool') # discards[keeps] = False # arraylocked = arraylocked.drop(discards) #first we'll drop trials with excessive noise in the EEG arraylocked = arraylocked[ 'arraycueblink == 0'] #also exclude trials where blinks happened in the array or cue period
ica.plot_components(inst=raw) ica.exclude.extend(eog_inds) ica.apply(inst=raw) raw.save(fname=param['rawcleaned'], fmt='double') elif i in [3, 10, 19]: raw = mne.io.read_raw_eeglab(input_fname=param['rawset_sess1'], montage='easycap-M1', eog=['VEOG', 'HEOG'], preload=True) #raw.set_montage('easycap-M1') #left mastoid was online reference #right mastoid recorded for offline re-referencing #add in channel of zeros for left mastoid, and rename left and right raw = mne.add_reference_channels(raw, ref_channels='LM') raw.rename_channels({'RM': 'M2', 'LM': 'M1'}) chnames = np.asarray(raw.ch_names) chnamemapping = {} for x in range(len(chnames)): chnamemapping[chnames[x]] = chnames[x].replace('Z', 'z').replace( 'FP', 'Fp') raw.rename_channels(chnamemapping) raw.set_montage('easycap-M1', raise_if_subset=False) raw.filter(1, 40) #filter raw data ica = mne.preprocessing.ICA(n_components=60, method='infomax').fit(raw) eog_epochs = mne.preprocessing.create_eog_epochs(raw) eog_inds, eog_scores = ica.find_bads_eog(eog_epochs)
# additional erroneous triggers in block 1 of participant 39 if (obs_i == 39) & (block_i == 1): block_temp.crop(tmin=0, tmax=570) events_block.append( mne.events_from_annotations(block_temp, verbose=50)[0]) raws.append(block_temp) raw_all = mne.concatenate_raws(raws) ########################################################################################################## #################### RE-REFERENCING AND GETTING Cz back ########################## ########################################################################################################## # get Cz back by adding it as a empty channel (will be useful when rereferencing) raw_all2 = mne.add_reference_channels(raw_all, ref_channels='Cz', copy=True) ## some specific stuff to this dataset because we use a channel location file that doesn't specify the channel type types = list(np.repeat(['eeg'], 67)) # change elements in that list that aren't 'EEG' channels types[-2] = 'eog' types[-3] = 'eog' types[-4] = 'ecg' # create a dictionnary of channel names and types chtypes_dict = dict(zip(raw_all2.ch_names, types)) raw_all2.set_channel_types(chtypes_dict) # apply a average reference raw_all2 = raw_all2.set_eeg_reference('average', verbose=None)