def test_ButterworthFilter(self): bfilter = ButterworthFilter(time_series=self.time_series, freq_range=[10., 20.], filt_type='stop', order=2) bfilter.filter() return True
def load_eeg_from_times(df, channel_file, rel_start_ms, rel_stop_ms, buf_ms=0, noise_freq=[58., 62.], downsample_freq=1000, resample_freq=None, pass_band=None): """ Parameters ---------- df: pandas.DataFrame An dataframe with a stTime column channel_file: str Path to Ncs file from which to load eeg. rel_start_ms: int Initial time (in ms), relative to the onset of each spike rel_stop_ms: int End time (in ms), relative to the onset of each spike buf_ms: int Amount of time (in ms) of buffer to add to both the beginning and end of the time interval noise_freq: list Stop filter will be applied to the given range. Default=[58. 62] downsample_freq resample_freq pass_band Returns ------- """ # # make a df with 'stTime' column to pass to _load_eeg_timeseries # events = pd.DataFrame(data=np.stack([s_times, clust_nums], -1), columns=['stTime', 'cluster_num']) # load eeg for this channel eeg = _load_eeg_timeseries(df, rel_start_ms, rel_stop_ms, [channel_file], buf_ms, downsample_freq, resample_freq) # filter line noise if noise_freq is not None: if isinstance(noise_freq[0], float): noise_freq = [noise_freq] for this_noise_freq in noise_freq: b_filter = ButterworthFilter(eeg, this_noise_freq, filt_type='stop', order=4) eeg = b_filter.filter() # mean center the data eeg = eeg.baseline_corrected([rel_start_ms, rel_stop_ms]) # do band pass if desired. if pass_band is not None: eeg = band_pass_eeg(eeg, pass_band) return eeg
def test_ButterwothFilter(self): from xarray.testing import assert_equal b_filter = ButterworthFilter(time_series=self.base_eegs, freq_range=[58., 62.], filt_type='stop', order=4) base_eegs_filtered_1 = b_filter.filter() base_eegs_filtered_2 = self.base_eegs.filtered(freq_range=[58., 62.], filt_type='stop', order=4) assert_equal(base_eegs_filtered_1, base_eegs_filtered_2) with self.assertRaises(AssertionError): assert_equal(base_eegs_filtered_1, self.base_eegs)
def load_eeg_from_times(df, channel_file, rel_start_ms, rel_stop_ms, buf_ms=0, noise_freq=[58., 62.], downsample_freq=1000, resample_freq=None, pass_band=None): """ Parameters ---------- df: pandas.DataFrame An dataframe with a stTime column channel_file: str Path to Ncs file from which to load eeg. rel_start_ms: int Initial time (in ms), relative to the onset of each spike rel_stop_ms: int End time (in ms), relative to the onset of each spike buf_ms: int Amount of time (in ms) of buffer to add to both the beginning and end of the time interval noise_freq: list Stop filter will be applied to the given range. Default=[58. 62] downsample_freq resample_freq pass_band Returns ------- """ # # make a df with 'stTime' column to pass to _load_eeg_timeseries # events = pd.DataFrame(data=np.stack([s_times, clust_nums], -1), columns=['stTime', 'cluster_num']) # load eeg for this channel eeg = _load_eeg_timeseries(df, rel_start_ms, rel_stop_ms, [channel_file], buf_ms, downsample_freq, resample_freq) # filter line noise if noise_freq is not None: if isinstance(noise_freq[0], float): noise_freq = [noise_freq] for this_noise_freq in noise_freq: b_filter = ButterworthFilter(eeg, this_noise_freq, filt_type='stop', order=4) eeg = b_filter.filter() # mean center the data eeg = eeg.baseline_corrected([rel_start_ms, rel_stop_ms]) # do band pass if desired. if pass_band is not None: eeg = band_pass_eeg(eeg, pass_band) return eeg
def test_ButterwothFilter(self): from xarray.testing import assert_equal b_filter = ButterworthFilter(timeseries=self.base_eegs, freq_range=[58., 62.], filt_type='stop', order=4) base_eegs_filtered_1 = b_filter.filter() base_eegs_filtered_2 = self.base_eegs.filtered(freq_range=[58., 62.], filt_type='stop', order=4) assert_equal(base_eegs_filtered_1, base_eegs_filtered_2) with self.assertRaises(AssertionError): assert_equal(base_eegs_filtered_1, self.base_eegs)
def test_butterworth(self, time_series): bfilter = ButterworthFilter(timeseries=time_series, freq_range=[10., 20.], filt_type='stop', order=2) bfilter.filter()
def load_eeg_full_timeseries(task, subject, session, elec_scheme=None, noise_freq=[58., 62.], resample_freq=None, pass_band=None): """ Function for loading continuous EEG data from a full session, not based on event times. Returns a list of timeseries object. task: str The experiment name subject: str The subject number session: int The session number for this subject and task elec_scheme: pandas.DataFrame A dataframe of electrode information, returned by load_elec_info(). If the column 'contact' is in the dataframe, monopolar electrodes will be loads. If the columns 'contact_1' and 'contact_2' are in the df, bipolar will be loaded. You may pass in a subset of rows to only load data for electrodes in those rows. If you do not enter an elec_scheme, all monopolar channels will be loaded (but they will not be labeled with correct channel tags). LOADING ALL ELECTRODES AND FOR AN ENTIRE SESSION AT ONCE IS NOT REALLY RECOMMENDED. noise_freq: list Stop filter will be applied to the given range. Default=(58. 62) resample_freq: float Sampling rate to resample to after loading eeg pass_band: list If given, the eeg will be band pass filtered in the given range Returns ------- list A TimeSeries object. """ # load eeg eeg = CMLReader(subject=subject, experiment=task, session=session).load_eeg(scheme=elec_scheme).to_ptsa() # filter line noise if noise_freq is not None: if isinstance(noise_freq[0], float): noise_freq = [noise_freq] for this_noise_freq in noise_freq: b_filter = ButterworthFilter(eeg, this_noise_freq, filt_type='stop', order=4) eeg = b_filter.filter() # resample if desired. Note: can be a bit slow especially if have a lot of eeg data if resample_freq is not None: r_filter = ResampleFilter(eeg, resample_freq) eeg = r_filter.filter() # do band pass if desired. if pass_band is not None: eeg = band_pass_eeg(eeg, pass_band) return eeg
def load_eeg(events, rel_start_ms, rel_stop_ms, buf_ms=0, elec_scheme=None, noise_freq=[58., 62.], resample_freq=None, pass_band=None, use_mirror_buf=False, demean=False, do_average_ref=False): """ Returns an EEG TimeSeries object. Parameters ---------- events: pandas.DataFrame An events dataframe that contains eegoffset and eegfile fields rel_start_ms: int Initial time (in ms), relative to the onset of each event rel_stop_ms: int End time (in ms), relative to the onset of each event buf_ms: Amount of time (in ms) of buffer to add to both the begining and end of the time interval elec_scheme: pandas.DataFrame A dataframe of electrode information, returned by load_elec_info(). If the column 'contact' is in the dataframe, monopolar electrodes will be loads. If the columns 'contact_1' and 'contact_2' are in the df, bipolar will be loaded. You may pass in a subset of rows to only load data for electrodes in those rows. If you do not enter an elec_scheme, all monopolar channels will be loaded (but they will not be labeled with correct channel tags). Entering a scheme is recommended. noise_freq: list Stop filter will be applied to the given range. Default=(58. 62) resample_freq: float Sampling rate to resample to after loading eeg. pass_band: list If given, the eeg will be band pass filtered in the given range. use_mirror_buf: bool If True, the buffer will be data taken from within the rel_start_ms to rel_stop_ms interval, mirrored and prepended and appended to the timeseries. If False, data outside the rel_start_ms and rel_stop_ms interval will be read. demean: bool If True, will subject the mean voltage between rel_start_ms and rel_stop_ms from each channel do_average_ref: bool If True, will compute the average reference based on the mean voltage across channels Returns ------- TimeSeries EEG timeseries object with dimensions channels x events x time (or bipolar_pairs x events x time) NOTE: The EEG data is returned with time buffer included. If you included a buffer and want to remove it, you may use the .remove_buffer() method. EXTRA NOTE: INPUT SECONDS FOR REMOVING BUFFER, NOT MS!! """ # add buffer is using if (buf_ms is not None) and not use_mirror_buf: actual_start = rel_start_ms - buf_ms actual_stop = rel_stop_ms + buf_ms else: actual_start = rel_start_ms actual_stop = rel_stop_ms # load eeg # Should auto convert to PTSA? Any reason not to? eeg = CMLReader(subject=events.iloc[0].subject).load_eeg( events, rel_start=actual_start, rel_stop=actual_stop, scheme=elec_scheme).to_ptsa() # compute average reference by subracting the mean across channels if do_average_ref: eeg = eeg - eeg.mean(dim='channel') # baseline correct subracting the mean within the baseline time range if demean: eeg = eeg.baseline_corrected([rel_start_ms, rel_stop_ms]) # add mirror buffer if using. PTSA is expecting this to be in seconds. if use_mirror_buf: eeg = eeg.add_mirror_buffer(buf_ms / 1000.) # filter line noise if noise_freq is not None: if isinstance(noise_freq[0], float): noise_freq = [noise_freq] for this_noise_freq in noise_freq: b_filter = ButterworthFilter(eeg, this_noise_freq, filt_type='stop', order=4) eeg = b_filter.filter() # resample if desired. Note: can be a bit slow especially if have a lot of eeg data if resample_freq is not None: r_filter = ResampleFilter(eeg, resample_freq) eeg = r_filter.filter() # do band pass if desired. if pass_band is not None: eeg = band_pass_eeg(eeg, pass_band) # reorder dims to make events first eeg = make_events_first_dim(eeg) return eeg
def test_ButterworthFilter(self): bfilter = ButterworthFilter(time_series = self.time_series,freq_range = [10.,20.],filt_type='stop',order=2) bfilter.filter() return True
def load_eeg_from_event_times(events, rel_start_ms, rel_stop_ms, channel_list, buf_ms=0, noise_freq=[58., 62.], downsample_freq=1000, resample_freq=None, pass_band=None, demean=False, do_average_ref=False): """ Returns an EEG TimeSeries object. Parameters ---------- events: pandas.DataFrame An events dataframe rel_start_ms: int Initial time (in ms), relative to the onset of each event rel_stop_ms: int End time (in ms), relative to the onset of each event channel_list: list list of paths to channels (ncs files) buf_ms: int Amount of time (in ms) of buffer to add to both the begining and end of the time interval noise_freq: list Stop filter will be applied to the given range. Default=(58. 62) resample_freq: float Sampling rate to resample to after loading eeg. pass_band: list If given, the eeg will be band pass filtered in the given range. demean: bool If True, will subject the mean voltage between rel_start_ms and rel_stop_ms from each channel do_average_ref: bool If True, will compute the average reference based on the mean voltage across channels Returns ------- TimeSeries EEG timeseries object with dimensions event x time x channel """ # eeg is a PTSA timeseries eeg = _load_eeg_timeseries(events, rel_start_ms, rel_stop_ms, channel_list, buf_ms, downsample_freq) # compute average reference by subracting the mean across channels if do_average_ref: eeg = eeg - eeg.mean(dim='channel') # baseline correct subracting the mean within the baseline time range if demean: eeg = eeg.baseline_corrected([rel_start_ms, rel_stop_ms]) # filter line noise if noise_freq is not None: if isinstance(noise_freq[0], float): noise_freq = [noise_freq] for this_noise_freq in noise_freq: b_filter = ButterworthFilter(eeg, this_noise_freq, filt_type='stop', order=4) eeg = b_filter.filter() # resample if desired. Note: can be a bit slow especially if have a lot of eeg data if resample_freq is not None: r_filter = ResampleFilter(eeg, resample_freq) eeg = r_filter.filter() # do band pass if desired. if pass_band is not None: eeg = band_pass_eeg(eeg, pass_band) return eeg
def power_spectra_from_spike_times(s_times, clust_nums, channel_file, rel_start_ms, rel_stop_ms, freqs, noise_freq=[58., 62.], downsample_freq=250, mean_over_spikes=True): """ Function to compute power relative to spike times. This computes power at given frequencies for the ENTIRE session and then bins it relative to spike times. You WILL run out of memory if you don't let it downsample first. Default downsample is to 250 Hz. Parameters ---------- s_times: np.ndarray Array (or list) of timestamps of when spikes occured. EEG will be loaded relative to these times. clust_nums: s_times: np.ndarray Array (or list) of cluster IDs, same size as s_times channel_file: str Path to Ncs file from which to load eeg. rel_start_ms: int Initial time (in ms), relative to the onset of each spike rel_stop_ms: int End time (in ms), relative to the onset of each spike freqs: np.ndarray array of frequencies at which to compute power noise_freq: list Stop filter will be applied to the given range. Default=[58. 62] downsample_freq: int or float Frequency to downsample the data. Use decimate, so we will likely not reach the exact frequency. mean_over_spikes: bool After computing the spike x frequency array, do we mean over spikes and return only the mean power spectra Returns ------- dict dict of either spike x frequency array of power values or just frequencies, if mean_over_spikes. Keys are cluster numbers """ # make a df with 'stTime' column for epoching events = pd.DataFrame(data=np.stack([s_times, clust_nums], -1), columns=['stTime', 'cluster_num']) # load channel data signals, timestamps, sr = load_ncs(channel_file) # downsample the session if downsample_freq is not None: signals, timestamps, sr = _my_downsample(signals, timestamps, sr, downsample_freq) else: print( 'I HIGHLY recommend you downsample the data before computing power across the whole session...' ) print('You will probably run out of memory.') # make into timeseries eeg = TimeSeries.create(signals, samplerate=sr, dims=['time'], coords={'time': timestamps / 1e6}) # filter line noise if noise_freq is not None: if isinstance(noise_freq[0], float): noise_freq = [noise_freq] for this_noise_freq in noise_freq: b_filter = ButterworthFilter(eeg, this_noise_freq, filt_type='stop', order=4) eeg = b_filter.filter() # compute power wave_pow = MorletWaveletFilter(eeg, freqs, output='power', width=5, cpus=12, verbose=False).filter() # log the power data = wave_pow.data wave_pow.data = numexpr.evaluate('log10(data)') # get start and stop relative to the spikes epochs = _compute_epochs(events, rel_start_ms, rel_stop_ms, timestamps, sr) bad_epochs = (np.any(epochs < 0, 1)) | (np.any(epochs > len(signals), 1)) epochs = epochs[~bad_epochs] events = events[~bad_epochs].reset_index(drop=True) # mean over time within epochs spikes_x_freqs = np.stack( [np.mean(wave_pow.data[:, x[0]:x[1]], axis=1) for x in epochs]) # make dict with keys being cluster numbers. Mean over spikes if desired. pow_spect_dict = {} for this_cluster in events.cluster_num.unique(): if mean_over_spikes: pow_spect_dict[this_cluster] = spikes_x_freqs[ events.cluster_num == this_cluster].mean(axis=0) else: pow_spect_dict[this_cluster] = spikes_x_freqs[events.cluster_num == this_cluster] return pow_spect_dict
def load_eeg_from_event_times(events, rel_start_ms, rel_stop_ms, channel_list, buf_ms=0, noise_freq=[58., 62.], downsample_freq=1000, resample_freq=None, pass_band=None, demean=False, do_average_ref=False): """ Returns an EEG TimeSeries object. Parameters ---------- events: pandas.DataFrame An events dataframe rel_start_ms: int Initial time (in ms), relative to the onset of each event rel_stop_ms: int End time (in ms), relative to the onset of each event channel_list: list list of paths to channels (ncs files) buf_ms: int Amount of time (in ms) of buffer to add to both the begining and end of the time interval noise_freq: list Stop filter will be applied to the given range. Default=(58. 62) resample_freq: float Sampling rate to resample to after loading eeg. pass_band: list If given, the eeg will be band pass filtered in the given range. demean: bool If True, will subject the mean voltage between rel_start_ms and rel_stop_ms from each channel do_average_ref: bool If True, will compute the average reference based on the mean voltage across channels Returns ------- TimeSeries EEG timeseries object with dimensions event x time x channel """ # eeg is a PTSA timeseries eeg = _load_eeg_timeseries(events, rel_start_ms, rel_stop_ms, channel_list, buf_ms, downsample_freq) # compute average reference by subracting the mean across channels if do_average_ref: eeg = eeg - eeg.mean(dim='channel') # baseline correct subracting the mean within the baseline time range if demean: eeg = eeg.baseline_corrected([rel_start_ms, rel_stop_ms]) # filter line noise if noise_freq is not None: if isinstance(noise_freq[0], float): noise_freq = [noise_freq] for this_noise_freq in noise_freq: b_filter = ButterworthFilter(eeg, this_noise_freq, filt_type='stop', order=4) eeg = b_filter.filter() # resample if desired. Note: can be a bit slow especially if have a lot of eeg data if resample_freq is not None: r_filter = ResampleFilter(eeg, resample_freq) eeg = r_filter.filter() # do band pass if desired. if pass_band is not None: eeg = band_pass_eeg(eeg, pass_band) return eeg
def power_spectra_from_spike_times(s_times, clust_nums, channel_file, rel_start_ms, rel_stop_ms, freqs, noise_freq=[58., 62.], downsample_freq=250, mean_over_spikes=True): """ Function to compute power relative to spike times. This computes power at given frequencies for the ENTIRE session and then bins it relative to spike times. You WILL run out of memory if you don't let it downsample first. Default downsample is to 250 Hz. Parameters ---------- s_times: np.ndarray Array (or list) of timestamps of when spikes occured. EEG will be loaded relative to these times. clust_nums: s_times: np.ndarray Array (or list) of cluster IDs, same size as s_times channel_file: str Path to Ncs file from which to load eeg. rel_start_ms: int Initial time (in ms), relative to the onset of each spike rel_stop_ms: int End time (in ms), relative to the onset of each spike freqs: np.ndarray array of frequencies at which to compute power noise_freq: list Stop filter will be applied to the given range. Default=[58. 62] downsample_freq: int or float Frequency to downsample the data. Use decimate, so we will likely not reach the exact frequency. mean_over_spikes: bool After computing the spike x frequency array, do we mean over spikes and return only the mean power spectra Returns ------- dict dict of either spike x frequency array of power values or just frequencies, if mean_over_spikes. Keys are cluster numbers """ # make a df with 'stTime' column for epoching events = pd.DataFrame(data=np.stack([s_times, clust_nums], -1), columns=['stTime', 'cluster_num']) # load channel data signals, timestamps, sr = load_ncs(channel_file) # downsample the session if downsample_freq is not None: signals, timestamps, sr = _my_downsample(signals, timestamps, sr, downsample_freq) else: print('I HIGHLY recommend you downsample the data before computing power across the whole session...') print('You will probably run out of memory.') # make into timeseries eeg = TimeSeries.create(signals, samplerate=sr, dims=['time'], coords={'time': timestamps / 1e6}) # filter line noise if noise_freq is not None: if isinstance(noise_freq[0], float): noise_freq = [noise_freq] for this_noise_freq in noise_freq: b_filter = ButterworthFilter(eeg, this_noise_freq, filt_type='stop', order=4) eeg = b_filter.filter() # compute power wave_pow = MorletWaveletFilter(eeg, freqs, output='power', width=5, cpus=12, verbose=False).filter() # log the power data = wave_pow.data wave_pow.data = numexpr.evaluate('log10(data)') # get start and stop relative to the spikes epochs = _compute_epochs(events, rel_start_ms, rel_stop_ms, timestamps, sr) bad_epochs = (np.any(epochs < 0, 1)) | (np.any(epochs > len(signals), 1)) epochs = epochs[~bad_epochs] events = events[~bad_epochs].reset_index(drop=True) # mean over time within epochs spikes_x_freqs = np.stack([np.mean(wave_pow.data[:, x[0]:x[1]], axis=1) for x in epochs]) # make dict with keys being cluster numbers. Mean over spikes if desired. pow_spect_dict = {} for this_cluster in events.cluster_num.unique(): if mean_over_spikes: pow_spect_dict[this_cluster] = spikes_x_freqs[events.cluster_num == this_cluster].mean(axis=0) else: pow_spect_dict[this_cluster] = spikes_x_freqs[events.cluster_num == this_cluster] return pow_spect_dict
use_reref_eeg=True, common_root='data').read() words = events[events.type == 'WORD'] # select all available channels eegfile = words[0].eegfile eegfile_reref = str.split(str(eegfile), '/') day = eegfile_reref[-1] eegfile_reref = '/'.join(eegfile_reref[0:-1]) channels = glob.glob(eegfile_reref + '/' + day + "*.[0-9]*") channels = np.array([str.split(x, '.')[-1] for x in channels]) #channels = np.array(['{:03}'.format(x) for x in range(0,132)]) eeg = EEGReader(events=words, channels=channels, start_time=0.3, end_time=1.6).read() b_filter = ButterworthFilter(time_series=eeg, order=4, freq_range=[58, 62]) eeg_filtered = b_filter.filter() eeg_buffered = eeg_filtered.add_mirror_buffer(1.3) eeg_buffered.data = np.ascontiguousarray(eeg_buffered.data) import time pt = time.time() freqs = np.logspace(np.log10(3), np.log10(180), 50) pow_ev, _ = MorletWaveletFilterCpp(time_series=eeg_buffered, freqs=freqs[0:1], output='power', cpus=20, verbose=False).filter() run_time = time.time() - pt
def load_eeg(events, rel_start_ms, rel_stop_ms, buf_ms=0, elec_scheme=None, noise_freq=[58., 62.], resample_freq=None, pass_band=None, use_mirror_buf=False, demean=False, do_average_ref=False): """ Returns an EEG TimeSeries object. Parameters ---------- events: pandas.DataFrame An events dataframe that contains eegoffset and eegfile fields rel_start_ms: int Initial time (in ms), relative to the onset of each event rel_stop_ms: int End time (in ms), relative to the onset of each event buf_ms: Amount of time (in ms) of buffer to add to both the begining and end of the time interval elec_scheme: pandas.DataFrame A dataframe of electrode information, returned by load_elec_info(). If the column 'contact' is in the dataframe, monopolar electrodes will be loads. If the columns 'contact_1' and 'contact_2' are in the df, bipolar will be loaded. You may pass in a subset of rows to only load data for electrodes in those rows. If you do not enter an elec_scheme, all monopolar channels will be loaded (but they will not be labeled with correct channel tags). Entering a scheme is recommended. noise_freq: list Stop filter will be applied to the given range. Default=(58. 62) resample_freq: float Sampling rate to resample to after loading eeg. pass_band: list If given, the eeg will be band pass filtered in the given range. use_mirror_buf: bool If True, the buffer will be data taken from within the rel_start_ms to rel_stop_ms interval, mirrored and prepended and appended to the timeseries. If False, data outside the rel_start_ms and rel_stop_ms interval will be read. demean: bool If True, will subject the mean voltage between rel_start_ms and rel_stop_ms from each channel do_average_ref: bool If True, will compute the average reference based on the mean voltage across channels Returns ------- TimeSeries EEG timeseries object with dimensions channels x events x time (or bipolar_pairs x events x time) NOTE: The EEG data is returned with time buffer included. If you included a buffer and want to remove it, you may use the .remove_buffer() method. EXTRA NOTE: INPUT SECONDS FOR REMOVING BUFFER, NOT MS!! """ # check if monopolar is possible for this subject if 'contact' in elec_scheme: eegfile = np.unique(events.eegfile)[0] if os.path.splitext(eegfile)[1] == '.h5': eegfile = f'/protocols/r1/subjects/{events.iloc[0].subject}/experiments/{events.iloc[0].experiment}/sessions/{events.iloc[0].session}/ephys/current_processed/noreref/{eegfile}' with h5py.File(eegfile, 'r') as f: if not np.array(f['monopolar_possible'])[0] == 1: print('Monopolar referencing not possible for {}'.format( events.iloc[0].subject)) return # add buffer is using if (buf_ms is not None) and not use_mirror_buf: actual_start = rel_start_ms - buf_ms actual_stop = rel_stop_ms + buf_ms else: actual_start = rel_start_ms actual_stop = rel_stop_ms # load eeg eeg = CMLReader(subject=events.iloc[0].subject).load_eeg( events, rel_start=actual_start, rel_stop=actual_stop, scheme=elec_scheme).to_ptsa() # now auto cast to float32 to help with memory issues with high sample rate data eeg.data = eeg.data.astype('float32') # baseline correct subracting the mean within the baseline time range if demean: eeg = eeg.baseline_corrected([rel_start_ms, rel_stop_ms]) # compute average reference by subracting the mean across channels if do_average_ref: eeg = eeg - eeg.mean(dim='channel') # add mirror buffer if using. PTSA is expecting this to be in seconds. if use_mirror_buf: eeg = eeg.add_mirror_buffer(buf_ms / 1000.) # filter line noise if noise_freq is not None: if isinstance(noise_freq[0], float): noise_freq = [noise_freq] for this_noise_freq in noise_freq: for this_chan in range(eeg.shape[1]): b_filter = ButterworthFilter(eeg[:, this_chan:this_chan + 1], this_noise_freq, filt_type='stop', order=4) eeg[:, this_chan:this_chan + 1] = b_filter.filter() # resample if desired. Note: can be a bit slow especially if have a lot of eeg data # pdb.set_trace() # if resample_freq is not None: # for this_chan in range(eeg.shape[1]): # r_filter = ResampleFilter(eeg[:, this_chan:this_chan+1], resample_freq) # eeg[:, this_chan:this_chan + 1] = r_filter.filter() if resample_freq is not None: eeg_resamp = [] for this_chan in range(eeg.shape[1]): r_filter = ResampleFilter(eeg[:, this_chan:this_chan + 1], resample_freq) eeg_resamp.append(r_filter.filter()) coords = {x: eeg[x] for x in eeg.coords.keys()} coords['time'] = eeg_resamp[0]['time'] coords['samplerate'] = resample_freq dims = eeg.dims eeg = TimeSeries.create(np.concatenate(eeg_resamp, axis=1), resample_freq, coords=coords, dims=dims) # do band pass if desired. if pass_band is not None: eeg = band_pass_eeg(eeg, pass_band) # reorder dims to make events first eeg = make_events_first_dim(eeg) return eeg