MNE-Python

Your closest
collaborator is
you six months ago
but you don’t reply to email.

  • Karl Broman

Why Code?

Why Code?

  • Adaptability

  • Flexibility

  • Integration

  • Repeatability

  • Reusability

  • Sharability

Where to Code?

  • Laptop / Desktop

Where to Code?

  • Laptop / Desktop
  • Remote Environments

Where to Code?

  • Laptop / Desktop
  • Remote Environments
  • Hipergator Cluster

Not limited by intellectual property licensing

Code, How?

  • Adapt example code directly from MNE documentation
  • Flexibly accommodate new datatypes & formats
  • Integrate extensive python libraries & solutions from others
  • Repeat analysis with additional data or with changes to initial steps for reanalyzing the same data
  • Reuse with minor modifications for similar data
  • Share with others so they can modify, repeat, reuse, and build on code

Return on Investment

Advantages Limitations
High Customization Increased User Knowledge Dependence
High Composability Reduced Usability
Graphical Resource Independence Explicit Command Requirement
Integration & Modularity
Utility of Scale
Searchability

MNE-Python Overview

MNE-Python Design Philosophy

  • Interactive versus Scripted Analysis

  • Integration with the Scientific Python Stack

  • Submodule-based Organization

  • Unified Application Program Interface (API)

  • In-place Operation

MNE: Modes of analysis

Interactive-mode

  • GUI-like interactive
    plotting & exploration
  • Raw and Derived Data Browsing
    • Click to mark bad channels
    • Click-and-dragging to annotate bad temporal spans

Scripted-mode

  • Analysis pipeline composed of Python script(s).
  • Scripts act as a record of everything in analysis
    • Facilitates informed adjustment of analysis

    • Facilitates refactoring, reuse, and sharing

MNE: Scientific Python Stack Integration

  • MNE-Python data objects as NumPy arrays facilitates:
    • Making custom algorithms
    • Moving data to scikit-learn’s machine learning pipelines
  • Customization of MNE-Python plots
    • matplotlib
    • PyVista’s plotting commands

Matplotlib

python

For a demonstration of a line plot on a polar axis, see Figure 1.

import numpy as np
import matplotlib.pyplot as plt

r = np.arange(0, 2, 0.01)
theta = 2 * np.pi * r
fig, ax = plt.subplots(
  subplot_kw = {'projection': 'polar'} 
)
ax.plot(theta, r)
ax.set_rticks([0.5, 1, 1.5, 2])
ax.grid(True)
plt.show()

MNE: Submodule-based organization

Organizing principles:

  • Sub-module groupings of objects and functions

  • Import sub-modules directly

  • Use sub-module name to access its functions

  • Instances of object classes can:

    • be passed between functions within sub-module
    • be passed to functions from other sub-modules that will receive the data object

MNE: Unified API

(Application Program Interface)

…context allowing a program to exchange information

  • APIs expose and receive only certain information.
  • There isn’t a difference between whether the information is received from or shared with a human-user or another program.

MNE-Python: API Reference

MNE-Python: In-place operation

  • MNE functions avoid loading data until necessary - speeding up analyses.
  • MNE workflows that utilize method chaining have a low in-memory footprint.
line = "switchport trunk allowed vlan 10,20,30"

words = line.split()
vlans_str = words[-1]
vlans = vlans_str.split(",")
print(vlans)

vlans = line.split()[-1].split(",")
print(vlans)
['10', '20', '30']
['10', '20', '30']
  • NumPy has extensive referencing and
    broadcasting routines that are optimized
    to conserve memory.
  • Operations are performed directly on
    variables without need for explicit copying.

MNE-Python Website

Migrating: EEGLAB to MNE-Python

Input - Output

Installing MNE-Python

Preprocessing Examples

Raw: Working wth Continuous Data

Epochs: Segmenting Data

Evoked: Averaging

Preprocessing Tutorials

MNE-Python: Introductory Tutorials

MNE-Python

  • classes (CamelCase names)
  • functions (underscore_case names)
import mne
import inspect

mne.io.Raw.__dict__
mappingproxy({'__module__': 'mne.io.fiff.raw',
              '__doc__': 'Raw data in FIF format.\n\n    Parameters\n    ----------\n    fname : str | file-like\n        The raw filename to load. For files that have automatically been split,\n        the split part will be automatically loaded. Filenames not ending with\n        ``raw.fif``, ``raw_sss.fif``, ``raw_tsss.fif``, ``_meg.fif``,\n        ``_eeg.fif``,  or ``_ieeg.fif`` (with or without an optional additional\n        ``.gz`` extension) will generate a warning. If a file-like object is\n        provided, preloading must be used.\n\n        .. versionchanged:: 0.18\n           Support for file-like objects.\n    allow_maxshield : bool | str (default False)\n        If True, allow loading of data that has been recorded with internal\n        active compensation (MaxShield). Data recorded with MaxShield should\n        generally not be loaded directly, but should first be processed using\n        SSS/tSSS to remove the compensation signals that may also affect brain\n        activity. Can also be "yes" to load without eliciting a warning.\n    \n    preload : bool or str (default False)\n        Preload data into memory for data manipulation and faster indexing.\n        If True, the data will be preloaded into memory (fast, requires\n        large amount of memory). If preload is a string, preload is the\n        file name of a memory-mapped file which is used to store the data\n        on the hard drive (slower, requires less memory).\n    \n    on_split_missing : str\n        Can be ``\'raise\'`` (default) to raise an error, ``\'warn\'`` to emit a\n        warning, or ``\'ignore\'`` to ignore when split file is missing.\n    \n        .. versionadded:: 0.22\n    \n    verbose : bool | str | int | None\n        Control verbosity of the logging output. If ``None``, use the default\n        verbosity level. See the :ref:`logging documentation <tut-logging>` and\n        :func:`mne.verbose` for details. Should only be passed as a keyword\n        argument.\n\n    Attributes\n    ----------\n    \n    info : mne.Info\n        The :class:`mne.Info` object with information about the sensors and methods of measurement.\n    ch_names : list of string\n        List of channels\' names.\n    n_times : int\n        Total number of time points in the raw file.\n    times :  ndarray\n        Time vector in seconds. Starts from 0, independently of `first_samp`\n        value. Time interval between consecutive time samples is equal to the\n        inverse of the sampling frequency.\n    preload : bool\n        Indicates whether raw data are in memory.\n    \n    verbose : bool | str | int | None\n        Control verbosity of the logging output. If ``None``, use the default\n        verbosity level. See the :ref:`logging documentation <tut-logging>` and\n        :func:`mne.verbose` for details. Should only be passed as a keyword\n        argument.\n    ',
              '__init__': <function mne.io.fiff.raw.__init__(self, fname, allow_maxshield=False, preload=False, on_split_missing='raise', verbose=None)>,
              '_read_raw_file': <function mne.io.fiff.raw._read_raw_file(self, fname, allow_maxshield, preload, do_check_ext=True, verbose=None)>,
              '_dtype': <property at 0x1b18fd3a0>,
              '_read_segment_file': <function mne.io.fiff.raw.Raw._read_segment_file(self, data, idx, fi, start, stop, cals, mult)>,
              'fix_mag_coil_types': <function mne.io.fiff.raw.Raw.fix_mag_coil_types(self)>,
              'acqparser': <property at 0x1b18fd4e0>})

Order of Operations

  1. Filter
  2. Artifact correction
  3. Re-reference
  4. Epoch
  5. Artifact rejection
  6. Average
  7. Plot ERP waveforms
  8. Difference waves
  9. Plot waveforms from each step
  10. Grand averages
  11. Dependent Variables