def test_pick_forward_seeg(): fwd = read_forward_solution(test_forward.fname_meeg) counts = channel_indices_by_type(fwd['info']) for key in counts.keys(): counts[key] = len(counts[key]) counts['meg'] = counts['mag'] + counts['grad'] fwd_ = pick_types_forward(fwd, meg=True, eeg=False, seeg=False) _check_fwd_n_chan_consistent(fwd_, counts['meg']) fwd_ = pick_types_forward(fwd, meg=False, eeg=True, seeg=False) _check_fwd_n_chan_consistent(fwd_, counts['eeg']) # should raise exception related to emptiness assert_raises(ValueError, pick_types_forward, fwd, meg=False, eeg=False, seeg=True) # change last chan from EEG to sEEG seeg_name = 'OTp1' rename_channels(fwd['info'], {'EEG 060': (seeg_name, 'seeg')}) fwd['sol']['row_names'][-1] = fwd['info']['chs'][-1]['ch_name'] counts['eeg'] -= 1 counts['seeg'] += 1 # repick & check fwd_seeg = pick_types_forward(fwd, meg=False, eeg=False, seeg=True) assert_equal(fwd_seeg['sol']['row_names'], [seeg_name]) assert_equal(fwd_seeg['info']['ch_names'], [seeg_name]) # should work fine fwd_ = pick_types_forward(fwd, meg=True, eeg=False, seeg=False) _check_fwd_n_chan_consistent(fwd_, counts['meg']) fwd_ = pick_types_forward(fwd, meg=False, eeg=True, seeg=False) _check_fwd_n_chan_consistent(fwd_, counts['eeg']) fwd_ = pick_types_forward(fwd, meg=False, eeg=False, seeg=True) _check_fwd_n_chan_consistent(fwd_, counts['seeg'])
def test_pick_forward_seeg(): """Test picking forward with SEEG """ fwd = read_forward_solution(test_forward.fname_meeg) counts = channel_indices_by_type(fwd["info"]) for key in counts.keys(): counts[key] = len(counts[key]) counts["meg"] = counts["mag"] + counts["grad"] fwd_ = pick_types_forward(fwd, meg=True, eeg=False, seeg=False) _check_fwd_n_chan_consistent(fwd_, counts["meg"]) fwd_ = pick_types_forward(fwd, meg=False, eeg=True, seeg=False) _check_fwd_n_chan_consistent(fwd_, counts["eeg"]) # should raise exception related to emptiness assert_raises(ValueError, pick_types_forward, fwd, meg=False, eeg=False, seeg=True) # change last chan from EEG to sEEG seeg_name = "OTp1" rename_channels(fwd["info"], {"EEG 060": seeg_name}) for ch in fwd["info"]["chs"]: if ch["ch_name"] == seeg_name: ch["kind"] = FIFF.FIFFV_SEEG_CH ch["coil_type"] = FIFF.FIFFV_COIL_EEG fwd["sol"]["row_names"][-1] = fwd["info"]["chs"][-1]["ch_name"] counts["eeg"] -= 1 counts["seeg"] += 1 # repick & check fwd_seeg = pick_types_forward(fwd, meg=False, eeg=False, seeg=True) assert_equal(fwd_seeg["sol"]["row_names"], [seeg_name]) assert_equal(fwd_seeg["info"]["ch_names"], [seeg_name]) # should work fine fwd_ = pick_types_forward(fwd, meg=True, eeg=False, seeg=False) _check_fwd_n_chan_consistent(fwd_, counts["meg"]) fwd_ = pick_types_forward(fwd, meg=False, eeg=True, seeg=False) _check_fwd_n_chan_consistent(fwd_, counts["eeg"]) fwd_ = pick_types_forward(fwd, meg=False, eeg=False, seeg=True) _check_fwd_n_chan_consistent(fwd_, counts["seeg"])
def channel_properties(self): info = data.current.raw.info dialog = ChannelPropertiesDialog(self, info) if dialog.exec_(): dialog.model.sort(0) bads = [] renamed = {} types = {} for i in range(dialog.model.rowCount()): new_label = dialog.model.item(i, 1).data(Qt.DisplayRole) old_label = info["ch_names"][i] if new_label != old_label: renamed[old_label] = new_label new_type = dialog.model.item(i, 2).data(Qt.DisplayRole).lower() old_type = channel_type(info, i).lower() if new_type != old_type: types[new_label] = new_type if dialog.model.item(i, 3).checkState() == Qt.Checked: bads.append(info["ch_names"][i]) info["bads"] = bads data.data[data.index].raw.info["bads"] = bads if renamed: mne.rename_channels(info, renamed) mne.rename_channels(data.data[data.index].raw.info, renamed) if types: data.current.raw.set_channel_types(types) data.data[data.index].raw.set_channel_types(types) self._update_infowidget() self._toggle_actions(True)
def set_channel_properties(self, bads=None, names=None, types=None): if bads: self.current["raw"].info["bads"] = bads if names: mne.rename_channels(self.current["raw"].info, names) if types: self.current["raw"].set_channel_types(types)
def rename_channels(inst, new_channel_names, **kwargs): """ Change the channel names of the MNE instance. Parameters ---------- inst : mne.io.Raw | mne.io.RawArray | mne.Epochs | mne.Evoked MNE instance of Raw | Epochs | Evoked. new_channel_names : list The list of the new channel names. **kwargs : Additional arguments are passed to mne.rename_channels() c.f. https://mne.tools/stable/generated/mne.rename_channels.html """ if 'mapping' in kwargs.keys(): logger.warning( 'Argument mapping should not be provided. ' 'Override with new_channel_names.') del kwargs['mapping'] if len(inst.ch_names) != len(new_channel_names): logger.error( 'The number of new channels does not match that of fif file.') raise RuntimeError mapping = {inst.info['ch_names'][k]: new_ch for k, new_ch in enumerate(new_channel_names)} mne.rename_channels(inst.info, mapping, **kwargs)
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 capitalize_chnames(info): """Convert channel names in info to upper case; operates inplace""" mne.rename_channels(info, lambda x: x.upper()) if 'projs' in info.keys(): for p in info['projs']: print(p) for i, c in enumerate(p['data']['col_names']): p['data']['col_names'][i] = c.upper()
def set_channel_properties(self, bads=None, names=None, types=None): if bads != self.current["data"].info["bads"]: self.current["data"].info["bads"] = bads self.history.append(f"data.info['bads'] = {bads}") if names: mne.rename_channels(self.current["data"].info, names) self.history.append(f"mne.rename_channels(data.info, {names})") if types: self.current["data"].set_channel_types(types) self.history.append(f"data.set_channel_types({types})")
def create_cognitive_reduce_features(data_path): preprocess = 'raw' for f in data_path.rglob("*{:}.edf".format(preprocess)): print(f.name) task = re.findall('(?<=_S[0-9]{2}_T[0-9]{2}_).+(?=_raw\.edf)', f.name)[0] uid = re.findall('.+(?=_S[0-9]+_T[0-9]+_)', f.name)[0] # Read eeg file raw = mne.io.read_raw_edf(f) # Rename Channel mne.rename_channels(raw.info, renameChannels) # Set montage (3d electrode location) raw = raw.set_montage('standard_1020') raw = raw.pick(EEG_channels) raw.crop(tmin=(raw.times[-1] - 120)) # Create events every 20 seconds reject_criteria = dict(eeg=160e-6, ) # 100 µV events_array = mne.make_fixed_length_events(raw, start=0.5, stop=None, duration=0.5) epochs = mne.Epochs(raw, events_array, tmin=-0.5, tmax=0.5, reject=reject_criteria, preload=True) epochs.drop_bad() print(epochs.get_data().shape) # epochs.plot_drop_log(show=True, subject=uid) frontal_epochs = epochs.copy().pick(frontal_ch) parietal_epochs = epochs.copy().pick(parietal_ch) frontal_bandpower = calculate_features(frontal_epochs) frontal_bandpower['area'] = 'frontal' parietal_bandpower = calculate_features(parietal_epochs) parietal_bandpower['area'] = 'parietal' final_feat = pd.concat((frontal_bandpower, parietal_bandpower)) final_feat['condition'] = task final_feat['user'] = uid final_feat.reset_index(drop=True) final_feat.to_csv(f.parent / 'eeg_features.csv') ratio = pd.DataFrame(frontal_bandpower['Theta'] / parietal_bandpower['Alpha'], columns=['ratio']) ratio['condition'] = task ratio['user'] = uid ratio.to_csv(f.parent / 'thetaf-alphap.csv')
def _set_montage(raw): mne.rename_channels( raw.info, dict( zip(raw.info["ch_names"], TruScanEEGpy.convert_to_tenfive(raw.info["ch_names"])))) montage = TruScanEEGpy.montage_mne_128( TruScanEEGpy.layout_128(names="10-5")) extra_channels = np.array(raw.info["ch_names"])[np.array( [i not in montage.ch_names for i in raw.info["ch_names"]])] raw = raw.drop_channels(extra_channels[np.array( [i not in ["EOG"] for i in extra_channels])]) raw = raw.set_montage(montage) return (raw)
def _load_raw(raw_fname, ann_fname, preload, load_eeg_only=True, crop_wake_mins=False): ch_mapping = { 'EOG horizontal': 'eog', 'Resp oro-nasal': 'misc', 'EMG submental': 'misc', 'Temp rectal': 'misc', 'Event marker': 'misc' } exclude = ch_mapping.keys() if load_eeg_only else () raw = mne.io.read_raw_edf(raw_fname, preload=preload, exclude=exclude) annots = mne.read_annotations(ann_fname) raw.set_annotations(annots, emit_warning=False) if crop_wake_mins > 0: # Find first and last sleep stages mask = [ x[-1] in ['1', '2', '3', '4', 'R'] for x in annots.description ] sleep_event_inds = np.where(mask)[0] # Crop raw tmin = annots[int( sleep_event_inds[0])]['onset'] - crop_wake_mins * 60 tmax = annots[int( sleep_event_inds[-1])]['onset'] + crop_wake_mins * 60 raw.crop(tmin=max(tmin, raw.times[0]), tmax=min(tmax, raw.times[-1])) # Rename EEG channels ch_names = { i: i.replace('EEG ', '') for i in raw.ch_names if 'EEG' in i } mne.rename_channels(raw.info, ch_names) if not load_eeg_only: raw.set_channel_types(ch_mapping) basename = os.path.basename(raw_fname) subj_nb = int(basename[3:5]) sess_nb = int(basename[5]) desc = pd.Series({'subject': subj_nb, 'recording': sess_nb}, name='') return raw, desc
def read_info(subject, data_type, run_index=0, hcp_path=op.curdir): """Read info from unprocessed data Parameters ---------- subject : str, file_map The subject data_type : str The kind of data to read. The following options are supported: 'rest' 'task_motor' 'task_story_math' 'task_working_memory' 'noise_empty_room' 'noise_subject' run_index : int The run index. For the first run, use 0, for the second, use 1. Also see HCP documentation for the number of runs for a given data type. hcp_path : str The HCP directory, defaults to op.curdir. Returns ------- info : instance of mne.io.meas_info.Info The MNE channel info object. .. note:: HCP MEG does not deliver only 3 of the 5 task packages from MRI HCP. """ raw, config = get_file_paths(subject=subject, data_type=data_type, output='raw', run_index=run_index, hcp_path=hcp_path) if not op.exists(raw): raw = None meg_info = _read_bti_info(raw, config) if raw is None: logger.info('Did not find Raw data. Guessing EMG, ECG and EOG ' 'channels') rename_channels(meg_info, dict(_label_mapping)) return meg_info
def test_pick_forward_seeg_ecog(): """Test picking forward with SEEG and ECoG """ fwd = read_forward_solution(fname_meeg) counts = channel_indices_by_type(fwd['info']) for key in counts.keys(): counts[key] = len(counts[key]) counts['meg'] = counts['mag'] + counts['grad'] fwd_ = pick_types_forward(fwd, meg=True) _check_fwd_n_chan_consistent(fwd_, counts['meg']) fwd_ = pick_types_forward(fwd, meg=False, eeg=True) _check_fwd_n_chan_consistent(fwd_, counts['eeg']) # should raise exception related to emptiness assert_raises(ValueError, pick_types_forward, fwd, meg=False, seeg=True) assert_raises(ValueError, pick_types_forward, fwd, meg=False, ecog=True) # change last chan from EEG to sEEG, second-to-last to ECoG ecog_name = 'E1' seeg_name = 'OTp1' rename_channels(fwd['info'], {'EEG 059': ecog_name}) rename_channels(fwd['info'], {'EEG 060': seeg_name}) for ch in fwd['info']['chs']: if ch['ch_name'] == seeg_name: ch['kind'] = FIFF.FIFFV_SEEG_CH ch['coil_type'] = FIFF.FIFFV_COIL_EEG elif ch['ch_name'] == ecog_name: ch['kind'] = FIFF.FIFFV_ECOG_CH ch['coil_type'] = FIFF.FIFFV_COIL_EEG fwd['sol']['row_names'][-1] = fwd['info']['chs'][-1]['ch_name'] fwd['sol']['row_names'][-2] = fwd['info']['chs'][-2]['ch_name'] counts['eeg'] -= 2 counts['seeg'] += 1 counts['ecog'] += 1 # repick & check fwd_seeg = pick_types_forward(fwd, meg=False, seeg=True) assert_equal(fwd_seeg['sol']['row_names'], [seeg_name]) assert_equal(fwd_seeg['info']['ch_names'], [seeg_name]) # should work fine fwd_ = pick_types_forward(fwd, meg=True) _check_fwd_n_chan_consistent(fwd_, counts['meg']) fwd_ = pick_types_forward(fwd, meg=False, eeg=True) _check_fwd_n_chan_consistent(fwd_, counts['eeg']) fwd_ = pick_types_forward(fwd, meg=False, seeg=True) _check_fwd_n_chan_consistent(fwd_, counts['seeg']) fwd_ = pick_types_forward(fwd, meg=False, ecog=True) _check_fwd_n_chan_consistent(fwd_, counts['ecog'])
def read_info(subject, data_type, run_index=0, hcp_path=op.curdir): """Read info from unprocessed data Parameters ---------- subject : str, file_map The subject data_type : str The kind of data to read. The following options are supported: 'rest' 'task_motor' 'task_story_math' 'task_working_memory' 'noise_empty_room' 'noise_subject' run_index : int The run index. For the first run, use 0, for the second, use 1. Also see HCP documentation for the number of runs for a given data type. hcp_path : str The HCP directory, defaults to op.curdir. Returns ------- info : instance of mne.io.meas_info.Info The MNE channel info object. .. note:: HCP MEG does not deliver only 3 of the 5 task packages from MRI HCP. """ raw, config = get_file_paths( subject=subject, data_type=data_type, output='raw', run_index=run_index, hcp_path=hcp_path) if not op.exists(raw): raw = None meg_info = _read_bti_info(raw, config) if raw is None: logger.info('Did not find Raw data. Guessing EMG, ECG and EOG ' 'channels') rename_channels(meg_info, dict(_label_mapping)) return meg_info
def create_cognitive_full_features(data_path): preprocess = 'raw' for f in data_path.rglob("*{:}.edf".format(preprocess)): print(f.name) task = re.findall('(?<=_S[0-9]{2}_T[0-9]{2}_).+(?=_raw\.edf)', f.name)[0] uid = re.findall('.+(?=_S[0-9]+_T[0-9]+_)', f.name)[0] # Read eeg file raw = mne.io.read_raw_edf(f) # Rename Channel mne.rename_channels(raw.info, renameChannels) # Set montage (3d electrode location) raw = raw.set_montage('standard_1020') raw = raw.pick(EEG_channels) # raw.crop(tmin=(raw.times[-1] - 120)) # Create events every 20 seconds reject_criteria = dict(eeg=140e-6, ) # 100 µV events_array = mne.make_fixed_length_events(raw, start=0.5, stop=None, duration=0.5) epochs = mne.Epochs(raw, events_array, tmin=-0.5, tmax=0.5, reject=reject_criteria, preload=True) epochs.drop_bad() print(epochs.get_data().shape) # epochs.plot_drop_log(show=True, subject=uid) epochs = epochs.copy().pick(EEG_channels) bandpower_df = calculate_features(epochs) bandpower_df.loc[:, ('info', 'condition')] = task bandpower_df.loc[:, ('info', 'user')] = uid bandpower_df.to_csv(f.parent / 'eeg_features_full_set.csv') bandpower_df.to_pickle(f.parent / 'eeg_features_full_set.pd')
def set_channel_properties(self, bads=None, names=None, types=None): if self.current["raw"]: if bads: self.current["raw"].info["bads"] = bads self.history.append(('raw.info["bads"]={}').format(bads)) if names: mne.rename_channels(self.current["raw"].info, names) self.history.append( 'rename_channels(raw.info, {}'.format(names)) if types: self.current["raw"].set_channel_types(types) self.history.append('raw.set_channel_types({}'.format(types)) else: if bads: self.current["epochs"].info["bads"] = bads self.history.append('epochs.info["bads"]={}'.format(bads)) if names: mne.rename_channels(self.current["epochs"].info, names) self.history.append( 'rename_channels(epochs.info, {}'.format(names)) if types: self.current["epochs"].set_channel_types(types) self.history.append( 'epochs.set_channel_types({}'.format(types))
cuelocked.resample(100) #resample to 100 hz else: print('cleaned data already exists for subject %s' % str(i)) cuelocked = mne.epochs.read_epochs( fname=param['cuelocked'].replace('cuelocked', 'cuelocked_cleaned'), preload=True) cuelocked.resample(100) #resample to 100Hz cuelocked.drop_channels(['RM']) chnames = np.asarray(cuelocked.ch_names) chnamemapping = {} for x in range(len(chnames)): chnamemapping[chnames[x]] = chnames[x].replace('Z', 'z').replace( 'FP', 'Fp') mne.rename_channels(cuelocked.info, chnamemapping) cuelocked.set_montage('easycap-M1') # set up params for TF decomp freqs = np.arange(1, 41, 1) # frequencies from 1-40Hz n_cycles = freqs * .3 # 300ms timewindow for estimation if laplacian: for stiff in [3, 4]: #get surface laplacian #the n_legendre_terms basically makes no difference here really slap = mne.preprocessing.compute_current_source_density( cuelocked, stiffness=stiff) print('\n running TF decomposition')
# Find event onset and cut event = nk.events_find(raw.copy().pick_channels(["Foto" ]).to_data_frame()["Foto"]) tmin = event["onset"][0] / 3000 raw = raw.crop(tmin=tmin, tmax=tmin + 8 * 60) # EOG eog = raw.copy().pick_channels(["124", "125"]).to_data_frame() eog = eog["124"] - eog["125"] raw = nk.eeg_add_channel(raw, eog, channel_type="eog", channel_name="EOG") raw = raw.drop_channels(["124", "125"]) # Montage mne.rename_channels( raw.info, dict( zip(raw.info["ch_names"], TruScanEEGpy.convert_to_tenfive(raw.info["ch_names"])))) montage = TruScanEEGpy.montage_mne_128(TruScanEEGpy.layout_128(names="10-5")) extra_channels = np.array(raw.info["ch_names"])[np.array( [i not in montage.ch_names for i in raw.info["ch_names"]])] raw = raw.drop_channels(extra_channels[np.array( [i not in ["EOG"] for i in extra_channels])]) raw = raw.set_montage(montage) # Save raw = raw.resample(300) raw.save("eeg_restingstate_300hz.fif", overwrite=True) ## Convert to df #df = pd.DataFrame(raw.get_data().T)
'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']) chnames = np.asarray(epochs.ch_names) chnamemapping = {} for x in range(len(chnames)): chnamemapping[chnames[x]] = chnames[x].replace('Z', 'z').replace( 'FP', 'Fp') mne.rename_channels(epochs.info, chnamemapping) epochs.set_montage('easycap-M1') if laplacian: # epochs.drop_channels(['RM', 'LM']) epochs = mne.preprocessing.compute_current_source_density( epochs, stiffness=5) #default stiffness is 4 glmdata = glm.data.TrialGLMData(data=epochs.get_data(), time_dim=2, sample_rate=500) cues = epochs.metadata.cue.to_numpy() pside = epochs.metadata.pside.to_numpy() #pside = np.where(pside == 0, 1, -1)
ssavg = {} for c in codes: ssavg[c] = list() for i in range(5): subjfile = 'garfield00{:02d}.vhdr'.format(i + 1) csvout = 'garfield00{:02d}.csv'.format(i + 1) raw = mne.io.read_raw_brainvision(subjfile, preload=True) # get the channel names and types configured mne.rename_channels( raw.info, { 'TP9': 'A1', 'TP10': 'A2', 'PO9': 'IO1', 'PO10': 'SO1', 'T7': 'LO1', 'T8': 'LO2' }) raw.set_eeg_reference(['A1', 'A2']) raw.set_channel_types({ 'IO1': 'eog', 'SO1': 'eog', 'LO1': 'eog', 'LO2': 'eog' }) raw.set_montage(montage) # zero-phase bandpass FIR filter with passband from 0.1 to 30 Hz
def load_data(self, filename): """Load the data from `filename` Parameters ---------- filename : str REQUIRED: which filename to load Returns ------- EEGData : obj An object of the EEGData class containing the EEG signal Raises ------ ValueError If there is a problem picking the channels """ eeg_start_time_of_day = helpers.parse_gt_24_hours_time( self.cfg.summary["patients"][self.cfg.neonate_id]["eeg_start_time"], time_of_day=True, ).seconds # The following logic works because measurements never last more than 24 hours. if eeg_start_time_of_day < self.current_time: self.current_day = self.current_day + 1 self.current_time = eeg_start_time_of_day eeg_start = datetime.timedelta( days=self.current_day, seconds=eeg_start_time_of_day ).total_seconds() # n_seizures = int(self.summary["edf_files"][filename]["seizure_count"]) seizures_start = [] seizures_end = [] seizures = self.cfg.summary["patients"][self.cfg.neonate_id]["seizures"] for seizure in seizures: start = seizures[seizure]["start"] + eeg_start end = seizures[seizure]["end"] + eeg_start seizures_start.append(start) seizures_end.append(end) self.seizures_time.append((start, end)) filename = path.join(self.cfg.data_path, filename) raw_edf = mne.io.read_raw_edf(filename, preload=True, stim_channel=None) # Some files' channels have -REF, some -Ref, so use the same mne.rename_channels(raw_edf.info, str.upper) # Test if bipolar data is requested if self.cfg.bipolar: raw_edf = self.get_bipolar_values(raw_edf) elif self.cfg.unipolar: raw_edf.pick_channels(self.cfg.channels_names_unipolar) if len(raw_edf[:, 1][0]) != len(self.cfg.channels_names_unipolar): print("-------------------------------") raise ValueError( f"ERROR after loading edf data." " Number of channels picked in edf data: {len(raw_edf[:, 1][0])} !=" " number of channels requested {len(self.cfg.channels_names)}" ) else: raise ValueError("Shouldn't get here. Error picking channels.") print("Number of channels:", len(raw_edf[:, 1][0])) print("Using channels: ", raw_edf.ch_names) # return the EEG signal return EEGData(raw_edf, eeg_start, seizures_start, seizures_end, self.cfg)
def _remap(self, montage_mapping): mne.rename_channels(self.mne_info, montage_mapping) for child in self._children: child.chain_initialize()
def add_eeg_info(eeg_file = None, loc = None, experiment_info = None, experimenters = None, subject_info = None, log_object = None): ''' Update the information stored in the eeg data object (accessed via raw.info) :param str OR mne.io.array.array.RawArray eegfile: The eeg data file that is edited :param str loc: The location of the eeg data file :param str experiment_info: Some information on your experiment :param str experimenters: Who conducted the experiment? :param dict subject_info: Additional information you want to store :param module log_object: A reference to the log file used to store logs :type log_object: object or None :return: The raw data object with updated values :rtype: mne.io.array.array.RawArray :raises AttributeError: (not raised) if no log file is defined :raises Exception: if no eeg data file is defined :raises TypeError: if the eeg file is not of type str or RawArray :raises ValueError: if the eeg file is of type str but extension is not .bdf :raises FileNotFoundError: if loc refers to a non-existing path ''' able_to_log = False function_name = 'add_eeg_info' if log_object is not None: try: log_object.critical('{} - STARTED'.format(function_name)) able_to_log = True except AttributeError: pass # if logging > disable verbose verbose_level = True if able_to_log: verbose_level = False if not able_to_log: print('') print(' * * * * * * * * * * * * * * * * * *') print(' * FUNCTION CALL >>> add_eeg_info *') print(' * * * * * * * * * * * * * * * * * *') print('') # file name operations if (eeg_file is None): if able_to_log: log_object.error('error in {}: check 1'.format(function_name)) raise Exception('\n!! Conflict in passed parameters !!\n' 'The filename of your EEG data should be passed') if (type(eeg_file) is not str) and (type(eeg_file) is not mne.io.array.array.RawArray): if able_to_log: log_object.error('error in {}: check 2'.format(function_name)) raise TypeError('\nFilename should be either\n\ta string\n\ta RawArray\n') if (type(eeg_file) is str) and eeg_file[-4:].lower() != '.bdf': if able_to_log: log_object.error('error in {}: check 3'.format(function_name)) raise ValueError('\nThis pipeline was written to handle .bdf files\n' 'Option 1:\n' '\tAdjust the source code to read other file formats\n' 'Option 2:\n' '\tConvert your EEG data file to the .bdf format') # declare raw = None # decision tree if type(eeg_file) is str: if loc is None: if able_to_log: log_object.error('error in {}: check 4'.format(function_name)) raise FileNotFoundError('\nNo path was provided.\nWe cannot find the data') else: if os.path.isdir(loc): path_to_file = os.path.join(loc, eeg_file) raw = mne.io.read_raw_bdf(path_to_file, verbose = verbose_level) else: if able_to_log: log_object.error('error in {}: check 5'.format(function_name)) raise FileNotFoundError("The path is faulty, please provide the exact path to the EEG file...") else: raw = eeg_file info = raw.info if able_to_log: log_object.info('{}: initial checks passed'.format(function_name)) else: print('\n* LOG *\nInitial checks passed') # add string to the description tag if experiment_info is not None: info['description'] = experiment_info if experimenters is not None: info['experimenter'] = experimenters if subject_info is not None: info['subject_info'] = subject_info # set the correct EEG channel info ch_names = ['Fp1', 'AF7', 'AF3', 'F1', 'F3', \ 'F5', 'F7', 'FT7', 'FC5', 'FC3', \ 'FC1', 'C1', 'C3', 'C5', 'T7', \ 'TP7', 'CP5', 'CP3', 'CP1', 'P1', \ 'P3', 'P5', 'P7', 'P9', 'PO7', \ 'PO3', 'O1', 'Iz', 'Oz', 'POz', \ 'Pz', 'CPz', 'Fpz', 'Fp2', 'AF8', \ 'AF4', 'AFz', 'Fz', 'F2', 'F4', \ 'F6', 'F8', 'FT8', 'FC6', 'FC4', \ 'FC2', 'FCz', 'Cz', 'C2', 'C4', \ 'C6', 'T8', 'TP8', 'CP6', 'CP4', \ 'CP2', 'P2', 'P4', 'P6', 'P8', \ 'P10', 'PO8', 'PO4', 'O2'] if 'A1' in info['ch_names']: info['ch_names'][:len(ch_names)] = ch_names ch_names += info['ch_names'][len(ch_names):] for i in range(len(info['ch_names'])): info['chs'][i]['ch_name'] = ch_names[i] # add channel types (FPPW configuration) if type(eeg_file) is str: for i in range(73): if i < 64: raw.set_channel_types(mapping={info['ch_names'][i]: 'eeg'}) elif 64 <= i < 72: raw.set_channel_types(mapping={info['ch_names'][i]: 'eog'}) else: raw.set_channel_types(mapping={info['ch_names'][i]: 'stim'}) if able_to_log: log_object.info('{}: electrode types added'.format(function_name)) else: print('\n* LOG *\nElectrode types added\n') # rename the trigger channel from Status to STI 014 try: mne.rename_channels(info, {'Status' : 'STI 014'}) except ValueError: if able_to_log: log_object.error('Error in {}: check 6'.format(function_name)) else: print('\nStatus could not be found in channel names.\nContinuing...\n') # return adjusted data if able_to_log: log_object.critical('{}: COMPLETED'.format(function_name)) else: print("\n* LOG *\n{}\n\tadd_eeg_info() completed\n".format(eeg_file)) return raw
import matplotlib.pyplot as plt def renameChannels(chName): if 'Z' in chName: chName = chName.replace('Z','z') if 'P' in chName and 'F' in chName: chName = chName.replace('P','p') return chName file = Path('./data_edf/UJing_S02_T01_Baseline_raw.edf') EEG_channels = ["FP1","FP2","AF3","AF4","F7","F3","FZ","F4", "F8","FC5","FC1","FC2","FC6","T7","C3","CZ", "C4","T8","CP5","CP1","CP2","CP6","P7","P3", "PZ","P4","P8","PO7","PO3","PO4","PO8","OZ"] sfreq = 250 #Read eeg data raw = mne.io.read_raw_edf(file) #Rename Channel mne.rename_channels(raw.info, renameChannels) #Set montage (3d electrode location) raw = raw.set_montage('standard_1020') # filtered = raw.filter(0.5,30) scalings = {'eeg': 0.00003} # Could also pass a dictionary with some value == 'auto' raw.plot(n_channels=32, scalings=scalings, title='Auto-scaled Data from arrays', show=True, block=True)
subject_files = os.listdir(subject_folder) for pieces in subject_files: if pieces[-11:] == 'tsss_mc.fif': final_path = subject_folder+pieces print(final_path) raw = mne.io.read_raw_fif(final_path, preload=False) # read preprocessed data #print(raw.info) print(raw.info['ch_names'][0:2]) # are both EOG channels here? if raw.info['ch_names'][0:2] == [u'EOG001', u'EOG002']: print('everything cool with subject ', subject) log.write(subject+ ' ' + pieces +' EOG ok\n') elif os.path.isfile(subject_folder+pieces[:-4]+'_EOG.fif'): print('this has been fixed already ', subject) log.write(subject+ ' ' + pieces +' has been fixed\n') else: print('better check EOGs of subject ', subject) log.write(subject+ ' ' + pieces +' check EOG\n') log.write(str(raw.info['ch_names'][0:2])+'\n') # the following two lines are only relevant, if the EOG # channels were not mapped correctly raw.set_channel_types({'BIO003' : 'eog'}) mne.rename_channels(raw.info, {u'BIO003' : u'EOG002'}) #print(raw.info) print(raw.info['ch_names'][0:2]) # are both EOG channels here? root, ext = os.path.splitext(final_path) raw.save(root+'_EOG'+ext) print('[done]') log.write('[done]\n') log.close()
if "chanlocs" in file ] #print(healthy_subjects[0:19]) print("total healthy_subjects available", len(healthy_subjects)) #DARAC904DMU i = 65 for each_healthy in healthy_subjects[65:73]: print("*" * 100) print(i) raw_healthy, eeg_chans_he = HBT.hbn_raw(subject=each_healthy, path_absolute=path_healthy_data) dat_evs_he = mne.find_events(raw_healthy) mne.rename_channels(raw_healthy.info, map_monstages) list_to_drop = [ each_key for each_key in raw_healthy.ch_names if each_key not in keys_1020 + ['stim'] ] raw_healthy.drop_channels(list_to_drop) # ADHD each_adhd = selected_ADHD_subjects[i] print(path_ADHD_data + each_adhd) raw_ADHD, eeg_chans = ADHD.adhd_raw(path_subject=path_ADHD_data + each_adhd, delta_between_events_s=20) #dat_evs_ADHD = mne.find_events(raw_ADHD) #raw_ADHD.set_eeg_reference(ref_channels='average',projection=True)
param['path'], 'glms', 'cue', 'epochsglm1', 'wmc_' + param['subid'] + '_cuelocked_tl_' + lapstr + name + '_tstats-ave.fif'))[0]) #%% #%% for i in range(subs.size): for contrast in contrasts: for dat in [data, data_t]: chnames = np.asarray(dat[contrast][i].ch_names) # newchnames = [x.replace('Z', 'z').replace('FP','Fp') for x in chnames] chnamemapping = {} for x in range(len(chnames)): chnamemapping[chnames[x]] = chnames[x].replace( 'z', 'Z').replace('Fp', 'FP') mne.rename_channels(dat[contrast][i].info, chnamemapping) if 'RM' in dat[contrast][i].ch_names: dat[contrast][i].drop_channels(['RM']) stat = 'beta' #choose whether you want to use the single subject tstats or betas for the analysis if stat == 'beta': dat2use = deepcopy(data) elif stat == 'tstat': dat2use = deepcopy(data_t) contrast = 'clvsr' #choose the cope you want to look at #print(contrasts) shows what there is channels = [ 'PO7', 'O1' ] #choose the channel you want to run the cluster permutation tests on for contrast in ['clvsr']: #['pright_cued', 'pleft_cued', 'clvsr']:
def run_events(subject_id): subject = "sub_%03d" % subject_id print("processing subject: %s" % subject) in_path = op.join(data_path, "Subjects") #make map yourself in cwd called 'Subjects' process_path = op.join( data_path, "EEG_Process") #make map yourself in cwd called 'EEG_Process' for run in range(1, 2): fname = op.join(in_path, 'sub_%03d.bdf' % (subject_id, )) raw = mne.io.read_raw_bdf(fname) print(" S %s - R %s" % (subject, run)) #info dataset info = raw.info #You can always print whatever info you'd like to acquire (events, bads, channel names...) #bad electrodes bads = raw.info['bads'] #raw.load_data() Uncomment this if you have bad channels #raw.interpolate_bads() #Uncomment this if you have bad channels events = mne.find_events(raw) fname_events = op.join(process_path, 'events_%03d-eve.fif' % (subject_id, )) mne.write_events(fname_events, events) #####CHANNELS##### #BDF Files have other channel names. Changing them to the wide-known names mne.rename_channels(info=info, 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', 'EXG1': 'EXVR', 'EXG2': 'EXHR', 'EXG3': 'EXHL', 'EXG5': 'M1', 'EXG6': 'M2' }) #M1&2=mastoids #Changing the channel types raw.set_channel_types({ 'EXVR': 'eog', 'EXHR': 'eog', 'EXHL': 'eog', 'EXG4': 'eog', 'M1': 'misc', 'M2': 'misc', 'GSR1': 'bio' }) #topographical maps later on; set montage! montage = mne.channels.read_montage('standard_1005', transform=True) print(montage) raw.set_montage(montage) #Drop 2 otiose channels. They were saved by accidence. Need to preload data for it raw.load_data() raw.drop_channels(['EXG7', 'EXG8']) #re-reference raw.set_eeg_reference('average', projection=True) #PSD: quite interesting to identify noisy channels #raw.plot_psd(dB=True,estimate='power') #Band-pass. Based on literature. raw.filter(l_freq=0.01, h_freq=40, picks='all', method='fir', filter_length='auto', phase='zero', fir_window='hamming', fir_design='firwin') #safe data files fname_preprocess_non_epoch = op.join( process_path, "sub_%03d_raw.fif" % (subject_id, )) raw.save(fname_preprocess_non_epoch, overwrite=True)