.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/asr/plot_10_choosing_a_variant.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_asr_plot_10_choosing_a_variant.py: Choosing an ASR variant. ======================== A runnable version of the "Choosing a variant" section of the ASR user guide. ``mne-denoise`` ships several ASR backends; this example runs the three you will most often choose between on one substrate and prints a short recommendation: - ``ASR(method="standard")`` -- the right default for most EEG; - ``ASR(method="riemannian_windowed")`` -- Riemannian-robust calibration with a working ``cutoff``; - ``JugglerASR(strategy="gev")`` -- sample-wise calibration that survives heavy contamination where the standard window selector starves. See ``plot_06`` (cutoff), ``plot_07`` (Riemannian), ``plot_08`` (adaptive) and ``plot_09`` (Juggler) for the per-variant deep dives. .. GENERATED FROM PYTHON SOURCE LINES 20-22 Synthetic substrate + helper ---------------------------- .. GENERATED FROM PYTHON SOURCE LINES 22-61 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from mne_denoise.asr import ASR, JugglerASR from mne_denoise.qa import variance_removed rng = np.random.default_rng(3) sfreq = 250.0 n_channels, n_times = 16, 10000 # 40 s t = np.arange(n_times) / sfreq brain = np.zeros((n_channels, n_times)) for ch in range(n_channels): phase = rng.uniform(0, 2 * np.pi) brain[ch] = 0.6 * np.sin(2 * np.pi * 10.0 * t + phase) + 0.05 * rng.standard_normal( n_times ) contaminated = brain.copy() for start in np.linspace(600, n_times - 600, 8).astype(int): spatial = rng.standard_normal(n_channels) spatial /= np.linalg.norm(spatial) contaminated[:, start : start + 200] += 10.0 * np.outer( spatial, rng.standard_normal(200) ) estimators = { "standard": ASR(sfreq=sfreq, cutoff=20.0, picks=None, verbose=False), "riemannian_windowed": ASR( sfreq=sfreq, cutoff=20.0, method="riemannian_windowed", picks=None, verbose=False, ), "juggler-gev": JugglerASR( sfreq=sfreq, cutoff=20.0, strategy="gev", picks=None, verbose=False ), } .. GENERATED FROM PYTHON SOURCE LINES 62-64 Run each variant and score it ----------------------------- .. GENERATED FROM PYTHON SOURCE LINES 64-74 .. code-block:: Python rows = {} for name, est in estimators.items(): cleaned = np.asarray(est.fit_transform(contaminated)) pct = variance_removed(contaminated, cleaned) corr = float(np.corrcoef(cleaned.ravel(), brain.ravel())[0, 1]) rows[name] = (pct, corr) print( f" {name:22s} variance removed={rows[name][0]:5.1f}% corr-to-clean={corr:.3f}" ) .. rst-class:: sphx-glr-script-out .. code-block:: none standard variance removed= 85.0% corr-to-clean=0.999 riemannian_windowed variance removed= 85.0% corr-to-clean=0.999 juggler-gev variance removed= 94.0% corr-to-clean=0.639 .. GENERATED FROM PYTHON SOURCE LINES 75-77 Recommendation -------------- .. GENERATED FROM PYTHON SOURCE LINES 77-83 .. code-block:: Python print("\nQuick guide:") print(" - reference-compatible start . ASR(method='standard'), then validate cutoff") print(" - robust calibration + cutoff ASR(method='riemannian_windowed')") print(" - online / streaming ......... AdaptiveASR(variant='psw' or 'psp')") print(" - extreme MoBI / dense bursts JugglerASR(strategy='gev' or 'dbscan')") .. rst-class:: sphx-glr-script-out .. code-block:: none Quick guide: - reference-compatible start . ASR(method='standard'), then validate cutoff - robust calibration + cutoff ASR(method='riemannian_windowed') - online / streaming ......... AdaptiveASR(variant='psw' or 'psp') - extreme MoBI / dense bursts JugglerASR(strategy='gev' or 'dbscan') .. GENERATED FROM PYTHON SOURCE LINES 84-86 Side-by-side scores ------------------- .. GENERATED FROM PYTHON SOURCE LINES 86-101 .. code-block:: Python names = list(rows) fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4)) ax1.bar(names, [rows[n][0] for n in names], color="C0") ax1.set_ylabel("% variance removed") ax1.set_title("Artifact suppression") ax1.tick_params(axis="x", labelrotation=20) ax2.bar(names, [rows[n][1] for n in names], color="C2") ax2.set_ylim(0, 1) ax2.set_ylabel("correlation to clean reference") ax2.set_title("Signal fidelity") ax2.tick_params(axis="x", labelrotation=20) fig.suptitle("Choosing an ASR variant (same data, three backends)") fig.tight_layout() plt.show() .. image-sg:: /auto_examples/asr/images/sphx_glr_plot_10_choosing_a_variant_001.png :alt: Choosing an ASR variant (same data, three backends), Artifact suppression, Signal fidelity :srcset: /auto_examples/asr/images/sphx_glr_plot_10_choosing_a_variant_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 2.815 seconds) .. _sphx_glr_download_auto_examples_asr_plot_10_choosing_a_variant.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_10_choosing_a_variant.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_10_choosing_a_variant.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_10_choosing_a_variant.zip `