.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/dss/plot_04_spectral_dss.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_dss_plot_04_spectral_dss.py: Denoising Rhythms (Spectral DSS). ================================= This example demonstrates how to use DSS to isolate **oscillatory brain rhythms** (e.g., Alpha, Beta) using spectral biases. It covers bandpass-based extraction of a known frequency band, narrowband scanning to find oscillatory peaks automatically, and application to real MEG and EEG recordings. Authors: Sina Esmaeili (sina.esmaeili@umontreal.ca) Hamza Abdelhedi (hamza.abdelhedi@umontreal.ca) .. GENERATED FROM PYTHON SOURCE LINES 17-19 Imports ------- .. GENERATED FROM PYTHON SOURCE LINES 19-35 .. code-block:: Python import os import matplotlib.pyplot as plt import mne import numpy as np from mne.datasets import sample from scipy import signal from mne_denoise.dss import DSS, BandpassBias, LineNoiseBias from mne_denoise.dss.variants import narrowband_dss, narrowband_scan from mne_denoise.viz import ( plot_component_psd_comparison, plot_component_summary, plot_narrowband_score_scan, ) .. GENERATED FROM PYTHON SOURCE LINES 36-41 Part 0: Synthetic Data Demo --------------------------- We simulate a brain-like mixture with an alpha rhythm at 10 Hz in one set of channels, a beta rhythm at 22 Hz in another set, plus pink noise and a 60 Hz line component. .. GENERATED FROM PYTHON SOURCE LINES 41-98 .. code-block:: Python print("\n--- Part 0: Synthetic Data Demo ---") rng = np.random.default_rng(42) sfreq = 500 n_seconds = 20 n_times = n_seconds * sfreq n_channels = 16 times = np.arange(n_times) / sfreq # 1. Generate Noise (Pink + Line) noise = np.cumsum(rng.standard_normal((n_channels, n_times)), axis=1) # Brownian/Pink noise = signal.detrend(noise, axis=1) noise += 0.5 * np.sin(2 * np.pi * 60 * times) # Line noise # 2. Generate Rhythms # Alpha (10 Hz) - Amplitude Modulated alpha_env = np.sin(2 * np.pi * 0.5 * times) ** 2 alpha = alpha_env * np.sin(2 * np.pi * 10 * times) * 2.0 # Beta (22 Hz) - Constant beta = np.sin(2 * np.pi * 22 * times) * 1.5 # 3. Mix into data data = noise.copy() # Alpha in ch 0-2 data[0:3] += alpha * np.array([[1.0], [0.8], [0.5]]) # Beta in ch 4-6 data[4:7] += beta * np.array([[1.0], [0.8], [0.5]]) print(f"Simulated {n_channels} ch x {n_seconds} s. Peaks at 10Hz and 22Hz.") # Create MNE Raw with channel names and montage for topomap plotting ch_names = [ "Oz", "O1", "O2", "Pz", "P3", "P4", "P7", "P8", "Cz", "C3", "C4", "Fz", "F3", "F4", "F7", "F8", ] info_sim = mne.create_info(ch_names, sfreq, "eeg") montage = mne.channels.make_standard_montage("standard_1020") info_sim.set_montage(montage) raw_sim = mne.io.RawArray(data, info_sim) .. rst-class:: sphx-glr-script-out .. code-block:: none --- Part 0: Synthetic Data Demo --- Simulated 16 ch x 20 s. Peaks at 10Hz and 22Hz. Creating RawArray with float64 data, n_channels=16, n_times=10000 Range : 0 ... 9999 = 0.000 ... 19.998 secs Ready. .. GENERATED FROM PYTHON SOURCE LINES 99-103 Part 1: Narrowband Scan ----------------------- Suppose we don't know the frequencies. We can scan for them. `narrowband_scan` runs DSS at many frequencies and returns the "score" (eigenvalue). .. GENERATED FROM PYTHON SOURCE LINES 103-118 .. code-block:: Python print("\nScanning frequencies (5-30 Hz)...") # We scan 5-30 Hz with 1 Hz resolution # For each freq, it tries to find a component that is 'narrowband' at that freq. best_dss, freqs, eigenvalues = narrowband_scan( data, sfreq=sfreq, freq_range=(5, 30), freq_step=0.5, bandwidth=2.0, n_components=1 ) # Visualize the Spectrum of "Oscillatoriness" plot_narrowband_score_scan(freqs, eigenvalues, true_freqs=[10, 22], show=False) plt.show() print("Peaks clearly visible at 10 Hz and 22 Hz.") .. image-sg:: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_001.png :alt: Narrowband Score Scan :srcset: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none Scanning frequencies (5-30 Hz)... Peaks clearly visible at 10 Hz and 22 Hz. .. GENERATED FROM PYTHON SOURCE LINES 119-123 Part 1: Manual BandpassBias (10 Hz Alpha) ------------------------------------------ BandpassBias applies a bandpass filter as the bias function. Here we manually create it to understand the API. .. GENERATED FROM PYTHON SOURCE LINES 123-148 .. code-block:: Python print("\n--- Part 1a: Manual BandpassBias ---") # Create BandpassBias for 10 Hz ± 1 Hz bias_alpha = BandpassBias(freq_band=(9.0, 11.0), sfreq=sfreq, order=4) # Fit DSS manually dss_manual = DSS(n_components=4, bias=bias_alpha) dss_manual.fit(raw_sim) print(f"DSS Eigenvalues: {dss_manual.eigenvalues_[:4]}") # Visualize sources_manual = dss_manual.transform(raw_sim) plot_component_summary( dss_manual, data=raw_sim, info=raw_sim.info, picks=np.arange(len(raw_sim.ch_names)), n_components=3, show=False, ) plt.gcf().suptitle("Manual BandpassBias (9-11 Hz)") plt.show() .. image-sg:: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_002.png :alt: Manual BandpassBias (9-11 Hz), Comp 0 Pattern, Comp 0 Time Course, PSD, Comp 1 Pattern, Comp 1 Time Course, PSD, Comp 2 Pattern, Comp 2 Time Course, PSD :srcset: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none --- Part 1a: Manual BandpassBias --- DSS Eigenvalues: [0.01420774 0.01187395 0.00853639 0.00608775] .. GENERATED FROM PYTHON SOURCE LINES 149-153 Part 1b: Narrowband DSS Wrapper (Convenience) ---------------------------------------------- The narrowband_dss() wrapper simplifies the above by calculating the frequency band automatically from center freq + bandwidth. .. GENERATED FROM PYTHON SOURCE LINES 153-170 .. code-block:: Python print("\n--- Part 1b: narrowband_dss Wrapper ---") dss_alpha = narrowband_dss(sfreq=sfreq, freq=10.0, bandwidth=2.0, n_components=4) dss_alpha.fit(raw_sim) print(f"Wrapper DSS Eigenvalues: {dss_alpha.eigenvalues_[:4]}") print("(Should be similar to manual approach)") # Visualize extracted component PSD sources = dss_alpha.transform(raw_sim) comp_raw = mne.io.RawArray(sources, mne.create_info(4, sfreq, "eeg")) fig = comp_raw.compute_psd(fmax=40).plot(show=False) fig.suptitle("DSS Component Spectrum (Target: 10 Hz)") plt.show() .. image-sg:: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_003.png :alt: DSS Component Spectrum (Target: 10 Hz), EEG :srcset: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_003.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none --- Part 1b: narrowband_dss Wrapper --- Wrapper DSS Eigenvalues: [0.01420774 0.01187395 0.00853639 0.00608775] (Should be similar to manual approach) Creating RawArray with float64 data, n_channels=4, n_times=10000 Range : 0 ... 9999 = 0.000 ... 19.998 secs Ready. Effective window size : 4.096 (s) Plotting power spectral density (dB=True). /home/runner/work/mne-denoise/mne-denoise/examples/dss/plot_04_spectral_dss.py:166: RuntimeWarning: Channel locations not available. Disabling spatial colors. fig = comp_raw.compute_psd(fmax=40).plot(show=False) .. GENERATED FROM PYTHON SOURCE LINES 171-172 Compare Time Series .. GENERATED FROM PYTHON SOURCE LINES 172-195 .. code-block:: Python plt.figure(figsize=(10, 5)) plt.subplot(2, 1, 1) plt.plot(times[:500], raw_sim.get_data()[0, :500]) plt.title("Original Sensor (Noisy)") plt.subplot(2, 1, 2) # Align polarity for visual comparison src = sources[0, :500] if np.corrcoef(src, alpha[:500])[0, 1] < 0: src *= -1 plt.plot(times[:500], src, "r") plt.plot( times[:500], alpha[:500] * (np.max(np.abs(src)) / np.max(np.abs(alpha))), "k--", alpha=0.5, label="Truth", ) plt.title("DSS Component 0 (Extracted Alpha)") plt.legend() plt.tight_layout() plt.show() .. image-sg:: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_004.png :alt: Original Sensor (Noisy), DSS Component 0 (Extracted Alpha) :srcset: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_004.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 196-200 Part 3: Line Noise Removal (LineNoiseBias) =========================================== LineNoiseBias isolates narrow frequency bands for removal (e.g., 60 Hz line noise). It supports both 'iir' (notch) and 'fft' (harmonic) methods. .. GENERATED FROM PYTHON SOURCE LINES 200-217 .. code-block:: Python print("\n--- Part 2: Line Noise (NotchBias) ---") # Simulate data with 60 Hz line noise + harmonics line_freq = 60.0 # Hz line_noise = ( 0.5 * np.sin(2 * np.pi * line_freq * times) # 60 Hz + 0.3 * np.sin(2 * np.pi * 2 * line_freq * times) # 120 Hz + 0.1 * np.sin(2 * np.pi * 3 * line_freq * times) # 180 Hz ) # Add to alpha signal data_noisy = data + np.outer(np.ones(n_channels), line_noise) raw_noisy = mne.io.RawArray(data_noisy, info_sim) print(f"Added {line_freq} Hz line noise + harmonics") .. rst-class:: sphx-glr-script-out .. code-block:: none --- Part 2: Line Noise (NotchBias) --- Creating RawArray with float64 data, n_channels=16, n_times=10000 Range : 0 ... 9999 = 0.000 ... 19.998 secs Ready. Added 60.0 Hz line noise + harmonics .. GENERATED FROM PYTHON SOURCE LINES 218-220 Apply DSS with LineNoiseBias to Remove 60 Hz --------------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 220-242 .. code-block:: Python # We use method='iir' to replicate a traditional Notch filter approach notch_bias_60 = LineNoiseBias(freq=60, sfreq=sfreq, method="iir", bandwidth=2) dss_notch = DSS(n_components=None, bias=notch_bias_60) dss_notch.fit(raw_noisy) print(f"\nDSS Eigenvalues: {dss_notch.eigenvalues_[:3]}") print("Component 0 should capture 60 Hz line noise") sources_notch = dss_notch.transform(raw_noisy) # Visualize plot_component_summary( dss_notch, data=raw_noisy, info=raw_noisy.info, picks=np.arange(len(raw_noisy.ch_names)), n_components=3, show=False, ) plt.show() .. image-sg:: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_005.png :alt: Comp 0 Pattern, Comp 0 Time Course, PSD, Comp 1 Pattern, Comp 1 Time Course, PSD, Comp 2 Pattern, Comp 2 Time Course, PSD :srcset: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_005.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none DSS Eigenvalues: [0.06828558 0.00038516 0.0002469 ] Component 0 should capture 60 Hz line noise .. GENERATED FROM PYTHON SOURCE LINES 243-244 PSD comparison .. GENERATED FROM PYTHON SOURCE LINES 244-261 .. code-block:: Python plot_component_psd_comparison( raw_noisy, sources_notch, component_indices=[0], sfreq=sfreq, peak_freq=60, fmax=200, show=False, ) plt.gcf().axes[0].set_title("Line Noise: Original PSD (60 Hz + harmonics)") plt.gcf().axes[1].set_title("Line Noise: DSS Components PSD") # Mark harmonics for ax in plt.gcf().axes: for h in [2, 3]: ax.axvline(line_freq * h, color="orange", linestyle="--", alpha=0.5) plt.show() .. image-sg:: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_006.png :alt: Line Noise: Original PSD (60 Hz + harmonics), Line Noise: DSS Components PSD :srcset: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_006.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none Effective window size : 4.096 (s) .. GENERATED FROM PYTHON SOURCE LINES 262-265 Remove Line Noise and Recover Clean Signal ------------------------------------------- Project out the first component (60 Hz noise) .. GENERATED FROM PYTHON SOURCE LINES 265-293 .. code-block:: Python # Get denoised data by removing component 0 sources = dss_notch.transform(raw_noisy) sources[0] = 0 # Zero out the 60 Hz component # Reconstruct without line noise data_cleaned = dss_notch.inverse_transform(sources) # Compare PSDs from scipy.signal import welch freqs_orig, psd_orig = welch(data_noisy[0], fs=sfreq, nperseg=1024) freqs_clean, psd_clean = welch(data_cleaned[0], fs=sfreq, nperseg=1024) plt.figure(figsize=(10, 5)) plt.semilogy(freqs_orig, psd_orig, "r", alpha=0.7, label="With 60 Hz noise") plt.semilogy(freqs_clean, psd_clean, "g", alpha=0.7, label="After removal") plt.axvline(60, color="k", linestyle="--", alpha=0.5, label="60 Hz") plt.axvline(120, color="gray", linestyle="--", alpha=0.5) plt.xlabel("Frequency (Hz)") plt.ylabel("Power") plt.title("Line Noise Removal with LineNoiseBias") plt.legend() plt.xlim(0, 200) plt.grid(True, alpha=0.3) plt.show() .. image-sg:: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_007.png :alt: Line Noise Removal with LineNoiseBias :srcset: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_007.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 294-297 Part 4: Real Data (MEG Alpha) ----------------------------- We apply this to real MEG data to find spontaneous Alpha rhythms. .. GENERATED FROM PYTHON SOURCE LINES 297-334 .. code-block:: Python print("\n--- Part 3: MNE Sample Data (Alpha) ---") home = os.path.expanduser("~") mne_data_path = os.path.join(home, "mne_data") data_path = sample.data_path() raw_fname = data_path / "MEG" / "sample" / "sample_audvis_raw.fif" raw = mne.io.read_raw_fif(raw_fname, preload=True, verbose=False) raw.pick_types(meg="grad", eeg=False, eog=False, stim=False, exclude="bads") raw.crop(0, 60) # 60 seconds raw.resample(100) # Downsample for speed # Scan for natural rhythms in this dataset print("Scanning MEG data 5-20 Hz...") _, freqs_meg, eigs_meg = narrowband_scan( raw.get_data(), sfreq=raw.info["sfreq"], freq_range=(5, 20), freq_step=1.0, n_components=1, ) plot_narrowband_score_scan( freqs_meg, eigs_meg, peak_freq=freqs_meg[np.argmax(eigs_meg)], show=False ) plt.gcf().axes[0].set_title("MEG: Narrowband Scan for Alpha") plt.show() # Typically ~10-11 Hz is dominant. Let's extract it. peak_freq = freqs_meg[np.argmax(eigs_meg)] print(f"Peak detected at {peak_freq:.1f} Hz") dss_meg = narrowband_dss( sfreq=raw.info["sfreq"], freq=peak_freq, bandwidth=3.0, n_components=5 ) dss_meg.fit(raw) .. image-sg:: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_008.png :alt: MEG: Narrowband Scan for Alpha :srcset: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_008.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none --- Part 3: MNE Sample Data (Alpha) --- NOTE: pick_types() is a legacy function. New code should use inst.pick(...). Scanning MEG data 5-20 Hz... Peak detected at 8.0 Hz .. raw:: html
DSS(bias=<mne_denoise.dss.denoisers.spectral.BandpassBias object at 0x7f64589bb6e0>,
        n_components=5)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.


.. GENERATED FROM PYTHON SOURCE LINES 335-345 .. code-block:: Python plot_component_summary( dss_meg, data=raw, info=raw.info, picks=np.arange(len(raw.ch_names)), n_components=3, show=False, ) plt.show() .. image-sg:: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_009.png :alt: Comp 0 Pattern, Comp 0 Time Course, PSD, Comp 1 Pattern, Comp 1 Time Course, PSD, Comp 2 Pattern, Comp 2 Time Course, PSD :srcset: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_009.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 346-347 Additional visualizations for MEG .. GENERATED FROM PYTHON SOURCE LINES 347-368 .. code-block:: Python print("Creating additional MEG visualizations...") # The high-level visualization helpers can also produce the same comparisons, # but here we keep custom plots so the intermediate quantities remain explicit. # Time series comparison: Raw sensor vs DSS component sources_meg = dss_meg.transform(raw) fig, axes = plt.subplots(2, 1, figsize=(12, 6)) t = raw.times[:1000] # First 10 seconds axes[0].plot(t, raw.get_data()[0, :1000]) axes[0].set_title("MEG: Original Sensor (Gradiometer 0)") axes[0].set_ylabel("Amplitude") axes[0].grid(True, alpha=0.3) axes[1].plot(t, sources_meg[0, :1000], color="purple") axes[1].set_title(f"MEG: Extracted Alpha Component ({peak_freq:.1f} Hz)") axes[1].set_xlabel("Time (s)") axes[1].set_ylabel("Amplitude") axes[1].grid(True, alpha=0.3) plt.tight_layout() plt.show() .. image-sg:: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_010.png :alt: MEG: Original Sensor (Gradiometer 0), MEG: Extracted Alpha Component (8.0 Hz) :srcset: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_010.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none Creating additional MEG visualizations... .. GENERATED FROM PYTHON SOURCE LINES 369-370 PSD Comparison: Before vs After .. GENERATED FROM PYTHON SOURCE LINES 370-382 .. code-block:: Python plot_component_psd_comparison( raw, sources_meg, component_indices=[0], sfreq=raw.info["sfreq"], peak_freq=peak_freq, show=False, ) plt.gcf().axes[0].set_title("MEG: Original Data PSD (Average)") plt.gcf().axes[1].set_title("MEG: DSS Components PSD") plt.show() .. image-sg:: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_011.png :alt: MEG: Original Data PSD (Average), MEG: DSS Components PSD :srcset: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_011.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none Effective window size : 20.480 (s) .. GENERATED FROM PYTHON SOURCE LINES 383-388 Part 4: Real Data (EEG Alpha - Resting State) ---------------------------------------------- For EEG, we use the EEG Motor Movement/Imagery dataset which includes resting-state recordings with eyes-open and eyes-closed conditions. Eyes-closed resting state typically shows strong alpha rhythms (8-12 Hz). .. GENERATED FROM PYTHON SOURCE LINES 388-447 .. code-block:: Python print("\n--- Part 4: EEG Resting-State Alpha (EEGBCI Dataset) ---") from mne.datasets import eegbci from mne.io import read_raw_edf # Load resting-state data (eyes closed = run 1) # Subject 1, Run 1 (eyes closed 1 minute) print("Loading EEGBCI resting-state data (eyes closed)...") raw_eeg = read_raw_edf( eegbci.load_data(subjects=[1], runs=[1], update_path=True)[0], preload=True, verbose=False, ) # Clean up annotations raw_eeg.annotations.onset[:] = 0 # Reset annotations eegbci.standardize(raw_eeg) # Apply standard channel names montage = mne.channels.make_standard_montage("standard_1005") raw_eeg.set_montage(montage, on_missing="ignore") # Pick EEG channels, exclude non-standard ones raw_eeg.pick_types(meg=False, eeg=True, stim=False, eog=False, exclude="bads") raw_eeg.crop(0, 30) # Use first 30 seconds raw_eeg.filter(1, 40, fir_design="firwin") # Bandpass for cleaner alpha raw_eeg.resample(100) # Downsample for speed # Re-reference to average raw_eeg.set_eeg_reference("average", projection=True) raw_eeg.apply_proj() print( f"EEG Data: {len(raw_eeg.ch_names)} channels, " f"{raw_eeg.times[-1]:.1f}s (eyes closed)" ) # Scan for rhythms print("Scanning EEG for alpha rhythm...") _, freqs_eeg, eigs_eeg = narrowband_scan( raw_eeg.get_data(), sfreq=raw_eeg.info["sfreq"], freq_range=(5, 20), freq_step=0.5, n_components=1, ) peak_freq_eeg = freqs_eeg[np.argmax(eigs_eeg)] plot_narrowband_score_scan(freqs_eeg, eigs_eeg, peak_freq=peak_freq_eeg, show=False) plt.gcf().axes[0].set_title("EEG: Narrowband Scan (Eyes Closed Resting State)") plt.show() print(f"EEG Peak detected at {peak_freq_eeg:.1f} Hz (alpha band)") # Extract alpha component dss_eeg = narrowband_dss( sfreq=raw_eeg.info["sfreq"], freq=peak_freq_eeg, bandwidth=3.0, n_components=5 ) dss_eeg.fit(raw_eeg) .. image-sg:: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_012.png :alt: EEG: Narrowband Scan (Eyes Closed Resting State) :srcset: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_012.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none --- Part 4: EEG Resting-State Alpha (EEGBCI Dataset) --- Loading EEGBCI resting-state data (eyes closed)... Using default location ~/mne_data for EEGBCI... Downloading EEGBCI data Download complete in 08s (1.2 MB) NOTE: pick_types() is a legacy function. New code should use inst.pick(...). Filtering raw data in 1 contiguous segment Setting up band-pass filter from 1 - 40 Hz FIR filter parameters --------------------- Designing a one-pass, zero-phase, non-causal bandpass filter: - Windowed time-domain design (firwin) method - Hamming window with 0.0194 passband ripple and 53 dB stopband attenuation - Lower passband edge: 1.00 - Lower transition bandwidth: 1.00 Hz (-6 dB cutoff frequency: 0.50 Hz) - Upper passband edge: 40.00 Hz - Upper transition bandwidth: 10.00 Hz (-6 dB cutoff frequency: 45.00 Hz) - Filter length: 529 samples (3.306 s) EEG channel type selected for re-referencing Adding average EEG reference projection. 1 projection items deactivated Average reference projection was added, but has not been applied yet. Use the apply_proj method to apply it. Created an SSP operator (subspace dimension = 1) 1 projection items activated SSP projectors applied... EEG Data: 64 channels, 30.0s (eyes closed) Scanning EEG for alpha rhythm... EEG Peak detected at 12.0 Hz (alpha band) .. raw:: html
DSS(bias=<mne_denoise.dss.denoisers.spectral.BandpassBias object at 0x7f6459338230>,
        n_components=5)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.


.. GENERATED FROM PYTHON SOURCE LINES 448-458 .. code-block:: Python plot_component_summary( dss_eeg, data=raw_eeg, info=raw_eeg.info, picks=np.arange(len(raw_eeg.ch_names)), n_components=3, show=False, ) plt.show() .. image-sg:: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_013.png :alt: Comp 0 Pattern, Comp 0 Time Course, PSD, Comp 1 Pattern, Comp 1 Time Course, PSD, Comp 2 Pattern, Comp 2 Time Course, PSD :srcset: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_013.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 459-460 Additional visualizations for EEG .. GENERATED FROM PYTHON SOURCE LINES 460-481 .. code-block:: Python print("Creating additional EEG visualizations...") # Note: Similar to MEG, you can use plot_psd_comparison() and # plot_channel_time_course_comparison() from mne_denoise.viz # Time series comparison: Raw sensor vs DSS component sources_eeg = dss_eeg.transform(raw_eeg) fig, axes = plt.subplots(2, 1, figsize=(12, 6)) t_eeg = raw_eeg.times[:1000] # First 10 seconds axes[0].plot(t_eeg, raw_eeg.get_data()[0, :1000]) axes[0].set_title("EEG: Original Sensor (Channel 0)") axes[0].set_ylabel("Amplitude (µV)") axes[0].grid(True, alpha=0.3) axes[1].plot(t_eeg, sources_eeg[0, :1000], color="orange") axes[1].set_title(f"EEG: Extracted Alpha Component ({peak_freq_eeg:.1f} Hz)") axes[1].set_xlabel("Time (s)") axes[1].set_ylabel("Amplitude") axes[1].grid(True, alpha=0.3) plt.tight_layout() plt.show() .. image-sg:: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_014.png :alt: EEG: Original Sensor (Channel 0), EEG: Extracted Alpha Component (12.0 Hz) :srcset: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_014.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none Creating additional EEG visualizations... .. GENERATED FROM PYTHON SOURCE LINES 482-483 PSD Comparison: Before vs After .. GENERATED FROM PYTHON SOURCE LINES 483-494 .. code-block:: Python plot_component_psd_comparison( raw_eeg, sources_eeg, component_indices=[0], sfreq=raw_eeg.info["sfreq"], peak_freq=peak_freq_eeg, show=False, ) plt.gcf().axes[0].set_title("EEG: Original Data PSD (Average)") plt.gcf().axes[1].set_title("EEG: DSS Components PSD") plt.show() .. image-sg:: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_015.png :alt: EEG: Original Data PSD (Average), EEG: DSS Components PSD :srcset: /auto_examples/dss/images/sphx_glr_plot_04_spectral_dss_015.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none Effective window size : 20.480 (s) .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 18.895 seconds) .. _sphx_glr_download_auto_examples_dss_plot_04_spectral_dss.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_04_spectral_dss.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_04_spectral_dss.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_04_spectral_dss.zip `