def test_simulate_raw_chpi(): """Test simulation of raw data with cHPI""" with warnings.catch_warnings(record=True): # MaxShield raw = Raw(raw_chpi_fname, allow_maxshield=True) sphere = make_sphere_model('auto', 'auto', raw.info) # make sparse spherical source space sphere_vol = tuple(sphere['r0'] * 1000.) + (sphere.radius * 1000.,) src = setup_volume_source_space('sample', sphere=sphere_vol, pos=70.) stc = _make_stc(raw, src) # simulate data with cHPI on raw_sim = simulate_raw(raw, stc, None, src, sphere, cov=None, chpi=False) # need to trim extra samples off this one raw_chpi = simulate_raw(raw, stc, None, src, sphere, cov=None, chpi=True, head_pos=pos_fname) # test that the cHPI signals make some reasonable values psd_sim, freqs_sim = compute_raw_psd(raw_sim) psd_chpi, freqs_chpi = compute_raw_psd(raw_chpi) assert_array_equal(freqs_sim, freqs_chpi) hpi_freqs = _get_hpi_info(raw.info)[0] freq_idx = np.sort([np.argmin(np.abs(freqs_sim - f)) for f in hpi_freqs]) picks_meg = pick_types(raw.info, meg=True, eeg=False) picks_eeg = pick_types(raw.info, meg=False, eeg=True) assert_allclose(psd_sim[picks_eeg], psd_chpi[picks_eeg], atol=1e-20) assert_true((psd_chpi[picks_meg][:, freq_idx] > 100 * psd_sim[picks_meg][:, freq_idx]).all()) # test localization based on cHPI information trans_sim, rot_sim, t_sim = _calculate_chpi_positions(raw_chpi) trans, rot, t = get_chpi_positions(pos_fname) t -= raw.first_samp / raw.info['sfreq'] _compare_positions((trans, rot, t), (trans_sim, rot_sim, t_sim), max_dist=0.005)
def test_psd(): """Test PSD estimation """ raw = io.Raw(raw_fname) exclude = raw.info['bads'] + ['MEG 2443', 'EEG 053'] # bads + 2 more # picks MEG gradiometers picks = pick_types(raw.info, meg='mag', eeg=False, stim=False, exclude=exclude) picks = picks[:2] tmin, tmax = 0, 10 # use the first 60s of data fmin, fmax = 2, 70 # look at frequencies between 5 and 70Hz n_fft = 128 # the FFT size (n_fft). Ideally a power of 2 psds, freqs = compute_raw_psd(raw, tmin=tmin, tmax=tmax, picks=picks, fmin=fmin, fmax=fmax, n_fft=n_fft, n_jobs=1, proj=False) psds_proj, freqs = compute_raw_psd(raw, tmin=tmin, tmax=tmax, picks=picks, fmin=fmin, fmax=fmax, n_fft=n_fft, n_jobs=1, proj=True) assert_array_almost_equal(psds, psds_proj) assert_true(psds.shape == (len(picks), len(freqs))) assert_true(np.sum(freqs < 0) == 0) assert_true(np.sum(psds < 0) == 0)
def test_simulate_raw_chpi(): """Test simulation of raw data with cHPI""" with warnings.catch_warnings(record=True): # MaxShield raw = Raw(raw_chpi_fname, allow_maxshield=True) sphere = make_sphere_model('auto', 'auto', raw.info) # make sparse spherical source space sphere_vol = tuple(sphere['r0'] * 1000.) + (sphere.radius * 1000.,) src = setup_volume_source_space('sample', sphere=sphere_vol, pos=70.) stc = _make_stc(raw, src) # simulate data with cHPI on raw_sim = simulate_raw(raw, stc, None, src, sphere, cov=None, chpi=False) raw_chpi = simulate_raw(raw, stc, None, src, sphere, cov=None, chpi=True) # XXX we need to test that the cHPI signals are actually in the correct # place, but that should be a subsequent enhancement (not trivial to do so) psd_sim, freqs_sim = compute_raw_psd(raw_sim) psd_chpi, freqs_chpi = compute_raw_psd(raw_chpi) assert_array_equal(freqs_sim, freqs_chpi) hpi_freqs = np.array([x['custom_ref'][0] for x in raw.info['hpi_meas'][0]['hpi_coils']]) freq_idx = np.sort([np.argmin(np.abs(freqs_sim - f)) for f in hpi_freqs]) picks_meg = pick_types(raw.info, meg=True, eeg=False) picks_eeg = pick_types(raw.info, meg=False, eeg=True) assert_allclose(psd_sim[picks_eeg], psd_chpi[picks_eeg]) assert_true((psd_chpi[picks_meg][:, freq_idx] > 100 * psd_sim[picks_meg][:, freq_idx]).all())
def test_simulate_raw_chpi(): """Test simulation of raw data with cHPI""" with warnings.catch_warnings(record=True): # MaxShield raw = Raw(raw_chpi_fname, allow_maxshield=True) sphere = make_sphere_model('auto', 'auto', raw.info) # make sparse spherical source space sphere_vol = tuple(sphere['r0'] * 1000.) + (sphere.radius * 1000., ) src = setup_volume_source_space('sample', sphere=sphere_vol, pos=70.) stc = _make_stc(raw, src) # simulate data with cHPI on raw_sim = simulate_raw(raw, stc, None, src, sphere, cov=None, chpi=False) # need to trim extra samples off this one raw_chpi = simulate_raw(raw, stc, None, src, sphere, cov=None, chpi=True, head_pos=pos_fname) # test cHPI indication hpi_freqs, _, hpi_pick, hpi_on, _ = _get_hpi_info(raw.info) assert_allclose(raw_sim[hpi_pick][0], 0.) assert_allclose(raw_chpi[hpi_pick][0], hpi_on) # test that the cHPI signals make some reasonable values psd_sim, freqs_sim = compute_raw_psd(raw_sim) psd_chpi, freqs_chpi = compute_raw_psd(raw_chpi) assert_array_equal(freqs_sim, freqs_chpi) freq_idx = np.sort([np.argmin(np.abs(freqs_sim - f)) for f in hpi_freqs]) picks_meg = pick_types(raw.info, meg=True, eeg=False) picks_eeg = pick_types(raw.info, meg=False, eeg=True) assert_allclose(psd_sim[picks_eeg], psd_chpi[picks_eeg], atol=1e-20) assert_true((psd_chpi[picks_meg][:, freq_idx] > 100 * psd_sim[picks_meg][:, freq_idx]).all()) # test localization based on cHPI information trans_sim, rot_sim, t_sim = _calculate_chpi_positions(raw_chpi) trans, rot, t = get_chpi_positions(pos_fname) t -= raw.first_samp / raw.info['sfreq'] _compare_positions((trans, rot, t), (trans_sim, rot_sim, t_sim), max_dist=0.005)
def test_compares_psd(): """Test PSD estimation on raw for plt.psd and scipy.signal.welch """ raw = io.Raw(raw_fname) exclude = raw.info['bads'] + ['MEG 2443', 'EEG 053'] # bads + 2 more # picks MEG gradiometers picks = pick_types(raw.info, meg='grad', eeg=False, stim=False, exclude=exclude)[:2] tmin, tmax = 0, 10 # use the first 60s of data fmin, fmax = 2, 70 # look at frequencies between 5 and 70Hz n_fft = 2048 # Compute psds with the new implementation using Welch psds_welch, freqs_welch = compute_raw_psd(raw, tmin=tmin, tmax=tmax, fmin=fmin, fmax=fmax, proj=False, picks=picks, n_fft=n_fft, n_jobs=1) # Compute psds with plt.psd start, stop = raw.time_as_index([tmin, tmax]) data, times = raw[picks, start:(stop + 1)] from matplotlib.pyplot import psd out = [psd(d, Fs=raw.info['sfreq'], NFFT=n_fft) for d in data] freqs_mpl = out[0][1] psds_mpl = np.array([o[0] for o in out]) mask = (freqs_mpl >= fmin) & (freqs_mpl <= fmax) freqs_mpl = freqs_mpl[mask] psds_mpl = psds_mpl[:, mask] assert_array_almost_equal(psds_welch, psds_mpl) assert_array_almost_equal(freqs_welch, freqs_mpl) assert_true(psds_welch.shape == (len(picks), len(freqs_welch))) assert_true(psds_mpl.shape == (len(picks), len(freqs_mpl))) assert_true(np.sum(freqs_welch < 0) == 0) assert_true(np.sum(freqs_mpl < 0) == 0) assert_true(np.sum(psds_welch < 0) == 0) assert_true(np.sum(psds_mpl < 0) == 0)
def computePowerSpectrum(self, times, fmin, fmax, nfft, logarithm=True): """ Computes power spectral densities for given data. Parameters: times - A list of tuples indicating the start and end points for the trial. fmin - Lower limit for the frequencies. fmax - Higher limit for the frequencies. n_fft - Length of the tapers (ie. windows). logarithm - A boolean to indicate if logarithmic scale is to be used. """ picks = mne.pick_types(self.raw.info, meg=False, eeg=True, exclude=[]) # If no eeg channels found, use all channels. if picks == []: picks = None psdList = [] for time in times: try: self.e2.clear() psds, freqs = compute_raw_psd(self.raw, tmin=time[0], tmax=time[1], fmin=fmin, fmax=fmax, n_fft=nfft, picks=picks, proj=True, verbose=True) self.e2.set() except Exception as e: self.e2.set() print str(e) return if logarithm: psds = 10 * np.log10(psds) psdList.append((psds, freqs)) return psdList
def plot_denoising(fname_raw, fmin=0, fmax=300, tmin=0.0, tmax=60.0, proj=False, n_fft=4096, color='blue', stim_name=None, event_id=1, tmin_stim=-0.2, tmax_stim=0.5, area_mode='range', area_alpha=0.33, n_jobs=1, title1='before denoising', title2='after denoising', info=None, show=True, fnout=None): """Plot the power spectral density across channels Parameters ---------- raw : instance of io.Raw The raw instance to use. tmin : float Start time for calculations. tmax : float End time for calculations. fmin : float Start frequency to consider. fmax : float End frequency to consider. proj : bool Apply projection. n_fft : int Number of points to use in Welch FFT calculations. picks : array-like of int | None List of channels to use. Cannot be None if `ax` is supplied. If both `picks` and `ax` are None, separate subplots will be created for each standard channel type (`mag`, `grad`, and `eeg`). ax : instance of matplotlib Axes | None Axes to plot into. If None, axes will be created. color : str | tuple A matplotlib-compatible color to use. area_mode : str | None Mode for plotting area. If 'std', the mean +/- 1 STD (across channels) will be plotted. If 'range', the min and max (across channels) will be plotted. Bad channels will be excluded from these calculations. If None, no area will be plotted. area_alpha : float Alpha for the area. n_jobs : int Number of jobs to run in parallel. verbose : bool, str, int, or None If not None, override default verbose level (see mne.verbose). """ from matplotlib import gridspec as grd import matplotlib.pyplot as plt from mne.time_frequency import compute_raw_psd if isinstance(fname_raw, list): fnraw = fname_raw else: if isinstance(fname_raw, str): fnraw = list([fname_raw]) else: fnraw = list(fname_raw) # --------------------------------- # estimate power spectrum # --------------------------------- psds_all = [] freqs_all = [] # loop across all filenames for fname in fnraw: # read in data raw = mne.io.Raw(fname, preload=True) picks = mne.pick_types(raw.info, meg='mag', eeg=False, stim=False, eog=False, exclude='bads') if area_mode not in [None, 'std', 'range']: raise ValueError('"area_mode" must be "std", "range", or None') psds, freqs = compute_raw_psd(raw, picks=picks, fmin=fmin, fmax=fmax, tmin=tmin, tmax=tmax, n_fft=n_fft, n_jobs=n_jobs, plot=False, proj=proj) psds_all.append(psds) freqs_all.append(freqs) if stim_name: n_xplots = 2 # get some infos events = mne.find_events(raw, stim_channel=stim_name, consecutive=True) else: n_xplots = 1 fig = plt.figure('denoising', figsize=(16, 6 * n_xplots)) gs = grd.GridSpec(n_xplots, int(len(psds_all))) # loop across all filenames for idx in range(int(len(psds_all))): # --------------------------------- # plot power spectrum # --------------------------------- p1 = plt.subplot(gs[0, idx]) # Convert PSDs to dB psds = 10 * np.log10(psds_all[idx]) psd_mean = np.mean(psds, axis=0) if area_mode == 'std': psd_std = np.std(psds, axis=0) hyp_limits = (psd_mean - psd_std, psd_mean + psd_std) elif area_mode == 'range': hyp_limits = (np.min(psds, axis=0), np.max(psds, axis=0)) else: # area_mode is None hyp_limits = None p1.plot(freqs_all[idx], psd_mean, color=color) if hyp_limits is not None: p1.fill_between(freqs_all[idx], hyp_limits[0], y2=hyp_limits[1], color=color, alpha=area_alpha) if idx == 0: p1.set_title(title1) ylim = [np.min(psd_mean) - 10, np.max(psd_mean) + 10] else: p1.set_title(title2) p1.set_xlabel('Freq (Hz)') p1.set_ylabel('Power Spectral Density (dB/Hz)') p1.set_xlim(freqs_all[idx][0], freqs_all[idx][-1]) p1.set_ylim(ylim[0], ylim[1]) # --------------------------------- # plot signal around stimulus # onset # --------------------------------- if stim_name: raw = mne.io.Raw(fname_raw[idx], preload=True) epochs = mne.Epochs(raw, events, event_id, proj=False, tmin=tmin_stim, tmax=tmax_stim, picks=picks, preload=True, baseline=(None, None)) evoked = epochs.average() if idx == 0: ymin = np.min(evoked.data) ymax = np.max(evoked.data) times = evoked.times * 1e3 p2 = plt.subplot(gs[1, idx]) p2.plot(times, evoked.data.T, 'blue', linewidth=0.5) p2.set_xlim(times[0], times[len(times) - 1]) p2.set_ylim(1.1 * ymin, 1.1 * ymax) if (idx == 1) and info: plt.text(times[0], 0.9 * ymax, ' ICs: ' + str(info)) # save image if fnout: fig.savefig(fnout + '.png', format='png') # show image if requested if show: plt.show() plt.close('denoising') plt.ion()
import matplotlib.pyplot as plt from mne.datasets import sample data_path = sample.data_path() raw_fname = data_path + "/MEG/sample/sample_audvis_filt-0-40_raw.fif" raw = fiff.Raw(raw_fname, preload=True) raw.filter(1, 20) picks = fiff.pick_types(raw.info, meg=True, exclude=[]) tmin, tmax = 0, 120 # use the first 120s of data fmin, fmax = 2, 20 # look at frequencies between 2 and 20Hz n_fft = 2048 # the FFT size (NFFT). Ideally a power of 2 psds, freqs = compute_raw_psd(raw, picks=picks, tmin=tmin, tmax=tmax, fmin=fmin, fmax=fmax) psds = 10 * np.log10(psds) # scale to dB def my_callback(ax, ch_idx): """ This block of code is executed once you click on one of the channel axes in the plot. To work with the viz internals this function should only take two parameters, the axis and the channel or data index. """ ax.plot(freqs, psds[ch_idx], color="yellow") ax.set_xlabel = "Frequency (Hz)" ax.set_ylabel = "Power (dB)" for ax, idx in iter_topography(raw.info, on_pick=my_callback):
# Set parameters data_path = sample.data_path('..') raw_fname = data_path + '/MEG/sample/sample_audvis_raw.fif' # Setup for reading the raw data raw = fiff.Raw(raw_fname) exclude = raw.info['bads'] + ['MEG 2443', 'EEG 053'] # bads + 2 more # picks MEG gradiometers picks = fiff.pick_types(raw.info, meg='grad', eeg=False, eog=False, stim=False, exclude=exclude) tmin, tmax = 0, 60 # use the first 60s of data fmin, fmax = 2, 70 # look at frequencies between 5 and 70Hz NFFT = 2048 # the FFT size (NFFT). Ideally a power of 2 psds, freqs = compute_raw_psd(raw, tmin=tmin, tmax=tmax, picks=picks, fmin=fmin, fmax=fmax, NFFT=NFFT, n_jobs=1) ############################################################################### # Compute mean and standard deviation accross channels and then plot psd_mean = np.mean(psds, axis=0) psd_std = np.std(psds, axis=0) hyp_limits = (psd_mean - psd_std, psd_mean + psd_std) import pylab as pl pl.close('all') pl.plot(freqs, psd_mean) pl.fill_between(freqs, hyp_limits[0], y2=hyp_limits[1], color=(1, 0, 0, .3), alpha=0.5) pl.xlabel('Freq (Hz)') pl.ylabel('PSD')
eog=False, stim=False, exclude='bads', selection=selection) # Let's just look at the first few channels for demonstration purposes picks = picks[:4] tmin, tmax = 0, 60 # use the first 60s of data fmin, fmax = 2, 300 # look at frequencies between 2 and 300Hz NFFT = 2048 # the FFT size (NFFT). Ideally a power of 2 psds, freqs = compute_raw_psd(raw, tmin=tmin, tmax=tmax, picks=picks, fmin=fmin, fmax=fmax, NFFT=NFFT, n_jobs=1, plot=False, proj=False) # And now do the same with SSP applied psds_ssp, freqs = compute_raw_psd(raw, tmin=tmin, tmax=tmax, picks=picks, fmin=fmin, fmax=fmax, NFFT=NFFT, n_jobs=1, plot=False,
tmin, tmax = 10, 130 # use the first 2min of data after the first 10s fmin, fmax = 1, 228 # look at frequencies between 1 and 228 NFFT = 2048 # the FFT size (NFFT). Ideally a power of 2 subjs = get_subjects_from_excel() # let's do one subject to get the dimensions subj = subjs.keys()[0] raw_fname = data_path + subj + '_rest_LP100_HP0.6_CP3_DS300_raw.fif' raw = fiff.Raw(raw_fname) picks = fiff.pick_channels_regexp(raw.info['ch_names'], 'M..-*') tmp, freqs = compute_raw_psd(raw, tmin=tmin, tmax=tmax, picks=picks, fmin=fmin, fmax=fmax, NFFT=NFFT, n_jobs=1, plot=False, proj=False) psds = np.zeros_like(np.tile(tmp, [len(subjs), 1, 1])) # Loop through all the subjects we find. Calculate the power in all channels for idx, subj in enumerate(subjs): raw_fname = data_path + subj + '_rest_LP100_HP0.6_CP3_DS300_raw.fif' # Setup for reading the raw data raw = fiff.Raw(raw_fname) psds[idx], freqs = compute_raw_psd(raw, tmin=tmin,
from mne.datasets import sample data_path = sample.data_path() raw_fname = data_path + '/MEG/sample/sample_audvis_filt-0-40_raw.fif' raw = fiff.Raw(raw_fname, preload=True) raw.filter(1, 20) picks = fiff.pick_types(raw.info, meg=True, exclude=[]) tmin, tmax = 0, 120 # use the first 120s of data fmin, fmax = 2, 20 # look at frequencies between 2 and 20Hz n_fft = 2048 # the FFT size (NFFT). Ideally a power of 2 psds, freqs = compute_raw_psd(raw, picks=picks, tmin=tmin, tmax=tmax, fmin=fmin, fmax=fmax) psds = 10 * np.log10(psds) # scale to dB def my_callback(ax, ch_idx): """ This block of code is executed once you click on one of the channel axes in the plot. To work with the viz internals this function should only take two parameters, the axis and the channel or data index. """ ax.plot(freqs, psds[ch_idx], color='yellow') ax.set_xlabel = 'Frequency (Hz)' ax.set_ylabel = 'Power (dB)'
def plot_denoising_4raw_data(fname_raw, fmin=0, fmax=300, tmin=0.0, tmax=60.0, proj=False, n_fft=4096, color='blue', stim_name=None, event_id=1, tmin_stim=-0.2, tmax_stim=0.5, area_mode='range', area_alpha=0.33, n_jobs=1, title1='before denoising', title2='after denoising', info=None, show=True, fnout=None): """Plot the power spectral density across channels to show denoising. Parameters ---------- fname_raw : list or str List of raw files, without denoising and with for comparison. tmin : float Start time for calculations. tmax : float End time for calculations. fmin : float Start frequency to consider. fmax : float End frequency to consider. proj : bool Apply projection. n_fft : int Number of points to use in Welch FFT calculations. color : str | tuple A matplotlib-compatible color to use. area_mode : str | None Mode for plotting area. If 'std', the mean +/- 1 STD (across channels) will be plotted. If 'range', the min and max (across channels) will be plotted. Bad channels will be excluded from these calculations. If None, no area will be plotted. area_alpha : float Alpha for the area. info : bool Display information in the figure. show : bool Show figure. fnout : str Name of the saved output figure. If none, no figure will be saved. title1, title2 : str Title for two psd plots. n_jobs : int Number of jobs to use for parallel computation. stim_name : str Name of the stim channel. If stim_name is set, the plot of epochs average is also shown alongside the PSD plots. event_id : int ID of the stim event. (only when stim_name is set) Example Usage ------------- plot_denoising(['orig-raw.fif', 'orig,nr-raw.fif', fnout='example') """ from matplotlib import gridspec as grd import matplotlib.pyplot as plt from mne.time_frequency import compute_raw_psd fnraw = get_files_from_list(fname_raw) # --------------------------------- # estimate power spectrum # --------------------------------- psds_all = [] freqs_all = [] # loop across all filenames for fname in fnraw: # read in data raw = mne.io.Raw(fname, preload=True) picks = mne.pick_types(raw.info, meg='mag', eeg=False, stim=False, eog=False, exclude='bads') if area_mode not in [None, 'std', 'range']: raise ValueError('"area_mode" must be "std", "range", or None') psds, freqs = compute_raw_psd(raw, picks=picks, fmin=fmin, fmax=fmax, tmin=tmin, tmax=tmax, n_fft=n_fft, n_jobs=n_jobs, proj=proj) psds_all.append(psds) freqs_all.append(freqs) if stim_name: n_xplots = 2 # get some infos events = mne.find_events(raw, stim_channel=stim_name, consecutive=True) else: n_xplots = 1 fig = plt.figure('denoising', figsize=(16, 6 * n_xplots)) gs = grd.GridSpec(n_xplots, int(len(psds_all))) # loop across all filenames for idx in range(int(len(psds_all))): # --------------------------------- # plot power spectrum # --------------------------------- p1 = plt.subplot(gs[0, idx]) # Convert PSDs to dB psds = 10 * np.log10(psds_all[idx]) psd_mean = np.mean(psds, axis=0) if area_mode == 'std': psd_std = np.std(psds, axis=0) hyp_limits = (psd_mean - psd_std, psd_mean + psd_std) elif area_mode == 'range': hyp_limits = (np.min(psds, axis=0), np.max(psds, axis=0)) else: # area_mode is None hyp_limits = None p1.plot(freqs_all[idx], psd_mean, color=color) if hyp_limits is not None: p1.fill_between(freqs_all[idx], hyp_limits[0], y2=hyp_limits[1], color=color, alpha=area_alpha) if idx == 0: p1.set_title(title1) ylim = [np.min(psd_mean) - 10, np.max(psd_mean) + 10] else: p1.set_title(title2) p1.set_xlabel('Freq (Hz)') p1.set_ylabel('Power Spectral Density (dB/Hz)') p1.set_xlim(freqs_all[idx][0], freqs_all[idx][-1]) p1.set_ylim(ylim[0], ylim[1]) # --------------------------------- # plot signal around stimulus # onset # --------------------------------- if stim_name: raw = mne.io.Raw(fnraw[idx], preload=True) epochs = mne.Epochs(raw, events, event_id, proj=False, tmin=tmin_stim, tmax=tmax_stim, picks=picks, preload=True, baseline=(None, None)) evoked = epochs.average() if idx == 0: ymin = np.min(evoked.data) ymax = np.max(evoked.data) times = evoked.times * 1e3 p2 = plt.subplot(gs[1, idx]) p2.plot(times, evoked.data.T, 'blue', linewidth=0.5) p2.set_xlim(times[0], times[len(times) - 1]) p2.set_ylim(1.1 * ymin, 1.1 * ymax) if (idx == 1) and info: plt.text(times[0], 0.9 * ymax, ' ICs: ' + str(info)) # save image if fnout: fig.savefig(fnout + '.png', format='png') # show image if requested if show: plt.show() plt.close('denoising') plt.ion()
raw = fiff.Raw(raw_fname) exclude = raw.info["bads"] + ["MEG 2443", "EEG 053"] # bads + 2 more # Add SSP projection vectors to reduce EOG and ECG artifacts projs = read_proj(proj_fname) raw.add_proj(projs, remove_existing=True) # Pick MEG magnetometers in the Left-temporal region selection = read_selection("Left-temporal") picks = fiff.pick_types(raw.info, meg="mag", eeg=False, eog=False, stim=False, exclude=exclude, selection=selection) tmin, tmax = 0, 60 # use the first 60s of data fmin, fmax = 2, 300 # look at frequencies between 2 and 300Hz NFFT = 2048 # the FFT size (NFFT). Ideally a power of 2 psds, freqs = compute_raw_psd( raw, tmin=tmin, tmax=tmax, picks=picks, fmin=fmin, fmax=fmax, NFFT=NFFT, n_jobs=1, plot=False, proj=False ) # And now do the same with SSP applied psds_ssp, freqs = compute_raw_psd( raw, tmin=tmin, tmax=tmax, picks=picks, fmin=fmin, fmax=fmax, NFFT=NFFT, n_jobs=1, plot=False, proj=True ) # Convert PSDs to dB psds = 10 * np.log10(psds) psds_ssp = 10 * np.log10(psds_ssp) ############################################################################### # Compute mean and standard deviation accross channels and then plot def plot_psds(freqs, psds, fill_color): psd_mean = np.mean(psds, axis=0)
def plot_denoising(fname_raw, fmin=0, fmax=300, tmin=0.0, tmax=60.0, proj=False, n_fft=4096, color='blue', stim_name=None, event_id=1, tmin_stim=-0.2, tmax_stim=0.5, area_mode='range', area_alpha=0.33, n_jobs=1, title1='before denoising', title2='after denoising', info=None, show=True, fnout=None): """Plot the power spectral density across channels Parameters ---------- raw : instance of io.Raw The raw instance to use. tmin : float Start time for calculations. tmax : float End time for calculations. fmin : float Start frequency to consider. fmax : float End frequency to consider. proj : bool Apply projection. n_fft : int Number of points to use in Welch FFT calculations. picks : array-like of int | None List of channels to use. Cannot be None if `ax` is supplied. If both `picks` and `ax` are None, separate subplots will be created for each standard channel type (`mag`, `grad`, and `eeg`). ax : instance of matplotlib Axes | None Axes to plot into. If None, axes will be created. color : str | tuple A matplotlib-compatible color to use. area_mode : str | None Mode for plotting area. If 'std', the mean +/- 1 STD (across channels) will be plotted. If 'range', the min and max (across channels) will be plotted. Bad channels will be excluded from these calculations. If None, no area will be plotted. area_alpha : float Alpha for the area. n_jobs : int Number of jobs to run in parallel. verbose : bool, str, int, or None If not None, override default verbose level (see mne.verbose). """ from matplotlib import gridspec as grd import matplotlib.pyplot as plt from mne.time_frequency import compute_raw_psd if isinstance(fname_raw, list): fnraw = fname_raw else: if isinstance(fname_raw, str): fnraw = list([fname_raw]) else: fnraw = list(fname_raw) # --------------------------------- # estimate power spectrum # --------------------------------- psds_all = [] freqs_all = [] # loop across all filenames for fname in fnraw: # read in data raw = mne.io.Raw(fname, preload=True) picks = mne.pick_types(raw.info, meg='mag', eeg=False, stim=False, eog=False, exclude='bads') if area_mode not in [None, 'std', 'range']: raise ValueError('"area_mode" must be "std", "range", or None') psds, freqs = compute_raw_psd(raw, picks=picks, fmin=fmin, fmax=fmax, tmin=tmin, tmax=tmax, n_fft=n_fft, n_jobs=n_jobs, plot=False, proj=proj) psds_all.append(psds) freqs_all.append(freqs) if stim_name: n_xplots = 2 # get some infos events = mne.find_events(raw, stim_channel=stim_name, consecutive=True) else: n_xplots = 1 fig = plt.figure('denoising', figsize=(16, 6*n_xplots)) gs = grd.GridSpec(n_xplots, int(len(psds_all))) # loop across all filenames for idx in range(int(len(psds_all))): # --------------------------------- # plot power spectrum # --------------------------------- p1 = plt.subplot(gs[0, idx]) # Convert PSDs to dB psds = 10 * np.log10(psds_all[idx]) psd_mean = np.mean(psds, axis=0) if area_mode == 'std': psd_std = np.std(psds, axis=0) hyp_limits = (psd_mean - psd_std, psd_mean + psd_std) elif area_mode == 'range': hyp_limits = (np.min(psds, axis=0), np.max(psds, axis=0)) else: # area_mode is None hyp_limits = None p1.plot(freqs_all[idx], psd_mean, color=color) if hyp_limits is not None: p1.fill_between(freqs_all[idx], hyp_limits[0], y2=hyp_limits[1], color=color, alpha=area_alpha) if idx == 0: p1.set_title(title1) ylim = [np.min(psd_mean)-10, np.max(psd_mean)+10] else: p1.set_title(title2) p1.set_xlabel('Freq (Hz)') p1.set_ylabel('Power Spectral Density (dB/Hz)') p1.set_xlim(freqs_all[idx][0], freqs_all[idx][-1]) p1.set_ylim(ylim[0], ylim[1]) # --------------------------------- # plot signal around stimulus # onset # --------------------------------- if stim_name: raw = mne.io.Raw(fname_raw[idx], preload=True) epochs = mne.Epochs(raw, events, event_id, proj=False, tmin=tmin_stim, tmax=tmax_stim, picks=picks, preload=True, baseline=(None, None)) evoked = epochs.average() if idx == 0: ymin = np.min(evoked.data) ymax = np.max(evoked.data) times = evoked.times * 1e3 p2 = plt.subplot(gs[1, idx]) p2.plot(times, evoked.data.T, 'blue', linewidth=0.5) p2.set_xlim(times[0], times[len(times) - 1]) p2.set_ylim(1.1 * ymin, 1.1 * ymax) if (idx == 1) and info: plt.text(times[0], 0.9*ymax, ' ICs: ' + str(info)) # save image if fnout: fig.savefig(fnout + '.png', format='png') # show image if requested if show: plt.show() plt.close('denoising') plt.ion()