.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_tutorials/plot_20_pipelines.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_tutorials_plot_20_pipelines.py: .. _tut-pipelines: Build and adjust a pipeline =========================== A pipeline is a list of named steps. Each step is a small scikit-learn style estimator: its parameters are set when it is created, ``fit`` learns what it needs from a recording, ``transform`` applies it, and afterwards it reports what it did (``qc_``) and draws it (``plot``). This tutorial builds the recommended MEG pipeline for a Neuromag system step by step on MNE's ``sample`` recording, looks at every step, and then changes it. .. GENERATED FROM PYTHON SOURCE LINES 16-18 .. code-block:: Python :dedent: 1 .. GENERATED FROM PYTHON SOURCE LINES 21-37 .. code-block:: Python import tempfile from pathlib import Path import mne import meeg_utils as meu from meeg_utils import steps as S mne.set_log_level("ERROR") data_path = mne.datasets.sample.data_path() raw = mne.io.read_raw_fif(data_path / "MEG" / "sample" / "sample_audvis_raw.fif") raw.pick(["meg", "eog", "stim"]).load_data() raw.info["line_freq"] = 60.0 meu.io.detect_system(raw) .. rst-class:: sphx-glr-script-out .. code-block:: none 'neuromag' .. GENERATED FROM PYTHON SOURCE LINES 38-43 The steps --------- Neuromag systems come with a cross-talk and a fine-calibration file, which SSS needs. In a BIDS dataset they are found automatically; here we pass them. .. GENERATED FROM PYTHON SOURCE LINES 43-58 .. code-block:: Python cross_talk = data_path / "SSS" / "ct_sparse_mgh.fif" calibration = data_path / "SSS" / "sss_cal_mgh.dat" pipe = meu.Pipeline( [ ("bads", S.BadChannels("maxwell", cross_talk=cross_talk, calibration=calibration)), ("sss", S.Maxwell(cross_talk=cross_talk, calibration=calibration)), ("highpass", S.Filter(0.1, None)), ("resample", S.Resample(250.0)), ("line_noise", S.LineNoise("zapline-plus")), ("ica", S.ICA(20, picks="meg", method="infomax", labeler="megnet")), ] ) pipe .. raw:: html
#StepConfiguration (changed parameters)
0badsBadChannels(calibration=PosixPath('/home/runner/mne_data/MNE-sample-data/SSS/sss_cal_mgh.dat'), cross_talk=PosixPath('/home/runner/mne_data/MNE-sample-data/SSS/ct_sparse_mgh.fif'), method='maxwell')
1sssMaxwell(calibration=PosixPath('/home/runner/mne_data/MNE-sample-data/SSS/sss_cal_mgh.dat'), cross_talk=PosixPath('/home/runner/mne_data/MNE-sample-data/SSS/ct_sparse_mgh.fif'))
2highpassFilter(h_freq=None, l_freq=0.1)
3resampleResample(sfreq=250.0)
4line_noiseLineNoise()
5icaICA(labeler='megnet', n_components=20, picks='meg')


.. GENERATED FROM PYTHON SOURCE LINES 59-62 This is the ``meg-erp`` preset; ``meu.Pipeline.preset("meg-erp", system="neuromag")`` builds the same pipeline and finds the two files in the BIDS dataset of the recording. .. GENERATED FROM PYTHON SOURCE LINES 62-64 .. code-block:: Python clean = pipe.fit_transform(raw) .. GENERATED FROM PYTHON SOURCE LINES 65-70 Bad channels ------------ :func:`mne.preprocessing.find_bad_channels_maxwell` scores every channel against its SSS reconstruction. ``MEG 2443`` was already marked bad in the file: .. GENERATED FROM PYTHON SOURCE LINES 70-73 .. code-block:: Python print(pipe.qc_["bads"]["meg"]) figs = pipe["bads"].plot("scores") .. image-sg:: /auto_tutorials/images/sphx_glr_plot_20_pipelines_001.png :alt: Bad-channel detection scores (detected channels in red), Maxwell grad, Maxwell mag :srcset: /auto_tutorials/images/sphx_glr_plot_20_pipelines_001.png, /auto_tutorials/images/sphx_glr_plot_20_pipelines_001_2_00x.png 2.00x :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none {'bads': ['MEG 2313'], 'n_bads': 1, 'fraction': 0.0032679738562091504, 'by_criterion': {'noisy': ['MEG 2313'], 'flat': []}} .. GENERATED FROM PYTHON SOURCE LINES 74-78 SSS --- Signal-space separation keeps the fields from inside the head and rebuilds the bad channels. The spectra before and after: .. GENERATED FROM PYTHON SOURCE LINES 78-81 .. code-block:: Python print({k: pipe.qc_["sss"][k] for k in ("reconstructed", "n_basis", "power_change_db")}) figs = pipe["sss"].plot("psd") .. image-sg:: /auto_tutorials/images/sphx_glr_plot_20_pipelines_002.png :alt: Spectra before and after SSS, MAG, GRAD :srcset: /auto_tutorials/images/sphx_glr_plot_20_pipelines_002.png, /auto_tutorials/images/sphx_glr_plot_20_pipelines_002_2_00x.png 2.00x :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none {'reconstructed': ['MEG 2443', 'MEG 2313'], 'n_basis': 72, 'power_change_db': {'mag': np.float64(-9.28), 'grad': np.float64(-1.97)}} .. GENERATED FROM PYTHON SOURCE LINES 82-86 Line noise ---------- ZapLine-plus removes the 60 Hz components and their harmonics, chunk by chunk, without notching the spectrum: .. GENERATED FROM PYTHON SOURCE LINES 86-88 .. code-block:: Python figs = pipe["line_noise"].plot("psd") .. image-sg:: /auto_tutorials/images/sphx_glr_plot_20_pipelines_003.png :alt: Line noise (zapline-plus, 60 Hz), MAG, GRAD :srcset: /auto_tutorials/images/sphx_glr_plot_20_pipelines_003.png, /auto_tutorials/images/sphx_glr_plot_20_pipelines_003_2_00x.png 2.00x :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 89-94 ICA with MEGnet --------------- MEGnet labels the 20 components (it was trained on 20 Infomax components of 250 Hz data, which is why the pipeline resamples first). Components whose artifact probability is at least 0.8 are removed: .. GENERATED FROM PYTHON SOURCE LINES 94-97 .. code-block:: Python print(pipe.qc_["ica"]["labels"]) figs = pipe["ica"].plot("labels") .. image-sg:: /auto_tutorials/images/sphx_glr_plot_20_pipelines_004.png :alt: ICA labels (megnet); x = excluded :srcset: /auto_tutorials/images/sphx_glr_plot_20_pipelines_004.png, /auto_tutorials/images/sphx_glr_plot_20_pipelines_004_2_00x.png 2.00x :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none ['brain/other', 'eye blink', 'brain/other', 'brain/other', 'heart beat', 'brain/other', 'brain/other', 'brain/other', 'brain/other', 'brain/other', 'brain/other', 'brain/other', 'brain/other', 'eye movement', 'brain/other', 'brain/other', 'brain/other', 'brain/other', 'heart beat', 'brain/other'] .. GENERATED FROM PYTHON SOURCE LINES 98-100 .. code-block:: Python figs = pipe["ica"].plot("components") .. image-sg:: /auto_tutorials/images/sphx_glr_plot_20_pipelines_005.png :alt: ICA000 (mag) brain/other 1.00, ICA001 (mag) eye blink 1.00, ICA002 (mag) brain/other 1.00, ICA003 (mag) brain/other 1.00, ICA004 (mag) heart beat 1.00, ICA005 (mag) brain/other 1.00, ICA006 (mag) brain/other 1.00, ICA007 (mag) brain/other 1.00, ICA008 (mag) brain/other 1.00, ICA009 (mag) brain/other 1.00, ICA010 (mag) brain/other 1.00, ICA011 (mag) brain/other 1.00, ICA012 (mag) brain/other 1.00, ICA013 (mag) eye movement 0.65, ICA014 (mag) brain/other 1.00, ICA015 (mag) brain/other 1.00, ICA016 (mag) brain/other 1.00, ICA017 (mag) brain/other 1.00, ICA018 (mag) heart beat 0.50, ICA019 (mag) brain/other 1.00 :srcset: /auto_tutorials/images/sphx_glr_plot_20_pipelines_005.png, /auto_tutorials/images/sphx_glr_plot_20_pipelines_005_2_00x.png 2.00x :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 101-103 The excluded components, with their spectrum and time course (these figures need the data): .. GENERATED FROM PYTHON SOURCE LINES 103-105 .. code-block:: Python figs = pipe["ica"].plot("properties", inst=raw) .. rst-class:: sphx-glr-horizontal * .. image-sg:: /auto_tutorials/images/sphx_glr_plot_20_pipelines_006.png :alt: ICA001 (mag), Segment image and ERP/ERF, Spectrum, Dropped segments: 0.00 % :srcset: /auto_tutorials/images/sphx_glr_plot_20_pipelines_006.png, /auto_tutorials/images/sphx_glr_plot_20_pipelines_006_2_00x.png 2.00x :class: sphx-glr-single-img * .. image-sg:: /auto_tutorials/images/sphx_glr_plot_20_pipelines_007.png :alt: ICA004 (mag), Segment image and ERP/ERF, Spectrum, Dropped segments: 0.00 % :srcset: /auto_tutorials/images/sphx_glr_plot_20_pipelines_007.png, /auto_tutorials/images/sphx_glr_plot_20_pipelines_007_2_00x.png 2.00x :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 106-117 If you disagree with a label, correct it and transform again; the decomposition is kept: .. code-block:: python pipe["ica"].relabel({4: "brain"}) clean = pipe.transform(raw) Change the pipeline ------------------- Parameters are addressed as ``__``, as in scikit-learn: .. GENERATED FROM PYTHON SOURCE LINES 117-120 .. code-block:: Python pipe.set_params(highpass__l_freq=1.0, ica__threshold=0.9) pipe["highpass"] .. raw:: html
Filter(h_freq=None, l_freq=1.0)
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 121-123 Steps can be added, replaced and removed by name, and a pipeline can be sliced: .. GENERATED FROM PYTHON SOURCE LINES 123-127 .. code-block:: Python pipe.insert_after("line_noise", "lowpass", S.Filter(None, 40.0)) pipe.remove("resample") list(pipe.named_steps), pipe[:2] .. rst-class:: sphx-glr-script-out .. code-block:: none (['bads', 'sss', 'highpass', 'line_noise', 'lowpass', 'ica'], Pipeline(steps=[('bads', BadChannels(calibration=PosixPath('/home/runner/mne_data/MNE-sample-data/SSS/sss_cal_mgh.dat'), cross_talk=PosixPath('/home/runner/mne_data/MNE-sample-data/SSS/ct_sparse_mgh.fif'), method='maxwell')), ('sss', Maxwell(calibration=PosixPath('/home/runner/mne_data/MNE-sample-data/SSS/sss_cal_mgh.dat'), cross_talk=PosixPath('/home/runner/mne_data/MNE-sample-data/SSS/ct_sparse_mgh.fif')))])) .. GENERATED FROM PYTHON SOURCE LINES 128-129 A pipeline is saved as YAML, to rerun it or to publish it with a paper: .. GENERATED FROM PYTHON SOURCE LINES 129-133 .. code-block:: Python fname = Path(tempfile.mkdtemp()) / "pipeline.yaml" pipe.to_yaml(fname) print(fname.read_text()) .. rst-class:: sphx-glr-script-out .. code-block:: none meeg_utils_version: 0.2.0 copy: true steps: - name: bads class: meeg_utils.steps.channels:BadChannels params: calibration: /home/runner/mne_data/MNE-sample-data/SSS/sss_cal_mgh.dat cross_talk: /home/runner/mne_data/MNE-sample-data/SSS/ct_sparse_mgh.fif h_freq: 40.0 limit: 7.0 method: maxwell origin: auto psd: false random_state: 42 ransac: true reject_by_annotation: null robust_reference: true - name: sss class: meeg_utils.steps.maxwell:Maxwell params: bad_condition: error calibration: /home/runner/mne_data/MNE-sample-data/SSS/sss_cal_mgh.dat coord_frame: head cross_talk: /home/runner/mne_data/MNE-sample-data/SSS/ct_sparse_mgh.fif destination: null ext_order: 3 head_pos: null int_order: 8 origin: auto regularize: in remove_chpi: true skip_by_annotation: - edge - bad_acq_skip st_correlation: 0.98 st_duration: null - name: highpass class: meeg_utils.steps.filtering:Filter params: filter_length: auto fir_design: firwin fir_window: hamming h_freq: null h_trans_bandwidth: auto iir_params: null l_freq: 1.0 l_trans_bandwidth: auto method: fir n_jobs: null phase: zero picks: null - name: line_noise class: meeg_utils.steps.line_noise:LineNoise params: adaptive_params: null fline: null method: zapline-plus n_harmonics: null n_remove: auto nfft: 1024 - name: lowpass class: meeg_utils.steps.filtering:Filter params: filter_length: auto fir_design: firwin fir_window: hamming h_freq: 40.0 h_trans_bandwidth: auto iir_params: null l_freq: null l_trans_bandwidth: auto method: fir n_jobs: null phase: zero picks: null - name: ica class: meeg_utils.steps.ica:ICA params: decim: null exclude_labels: null fit_h_freq: 100.0 fit_l_freq: 1.0 fit_params: null labeler: megnet max_iter: auto method: infomax n_components: 20 picks: meg random_state: 42 reject_by_annotation: true threshold: 0.9 .. GENERATED FROM PYTHON SOURCE LINES 134-143 ``meu.Pipeline.from_yaml(fname)`` reads it back, and ``meu run pipeline.yaml --sources bids/ --out derivatives/`` runs it from the command line. MEG and EEG together -------------------- :class:`~meeg_utils.steps.ByChannelType` runs separate steps on each channel type and writes the results back into one recording, e.g. SSS for the MEG and PREP plus an average reference for the EEG: .. GENERATED FROM PYTHON SOURCE LINES 143-158 .. code-block:: Python combined = meu.Pipeline( [ ( "by_type", S.ByChannelType( { "meg": [("sss", S.Maxwell(cross_talk=cross_talk, calibration=calibration))], "eeg": [("bads", S.BadChannels("prep")), ("reference", S.Reference())], } ), ), ("highpass", S.Filter(0.1, None)), ] ) combined .. raw:: html
#StepConfiguration (changed parameters)
0by_typeByChannelType(branches={'eeg': [('bads', BadChannels(method='prep')), ('reference', Reference())], 'meg': [('sss', Maxwell(calibration=PosixPath('/home/runner/mne_data/MNE-sample-data/SSS/sss_cal_mgh.dat'), cross_talk=PosixPath('/home/runner/mne_data/MNE-sample-data/SSS/ct_sparse_mgh.fif')))]})
1highpassFilter(h_freq=None, l_freq=0.1)


.. rst-class:: sphx-glr-timing **Total running time of the script:** (2 minutes 13.774 seconds) .. _sphx_glr_download_auto_tutorials_plot_20_pipelines.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_20_pipelines.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_20_pipelines.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_20_pipelines.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_