Skip to main content

MNEXTEND

This package provides additional functionality for working with MNE-Python, the most popular Python package for processing electrophysiological data (EEG, MEG, ...).

Features

Reading additional file formats

MNEXTEND provides readers for the following file formats that are not natively supported by MNE-Python:

  • XDF (Extensible Data Format) – see below for more details
  • MAT (MATLAB)
  • NPY (NumPy)

In addition, MNEXTEND adds the following readers from third-party packages:

Together with the native MNE-Python readers, read_raw() and read_epochs() provide a unified interface for reading electrophysiological data from a wide range of file formats, so all you have to do is:

from mnextend import read_raw, read_epochs

raw = read_raw("my_data.xdf", streams=[1, 2], fs_new=500)
epochs = read_epochs("my_data-epochs.fif.gz")

Inspecting files before reading

Some formats require inspecting file contents before calling read_raw(), e.g. to let a user pick which stream(s) or participant(s) to load:

from mnextend.io.bvrf import read_bvrf_header
from mnextend.io.xdf import resolve_streams

streams = resolve_streams("my_data.xdf")
header = read_bvrf_header("my_data.bvrh")

Reading XDF files

XDF files usually contain several streams with different sampling rates and data types, for example EEG from an amplifier, trigger codes from a trigger box, and text markers from the experiment software. The streams argument in the example above selects the streams to load (all other streams are ignored), and fs_new resamples them to a common sampling frequency.

Let's consider a file with the following streams (as listed by resolve_streams()):

ID Type Format Sampling rate Content Possible modes (default first)
1 EEG float32 500 Hz EEG signals continuous, discrete
2 Trigger int32 1000 Hz trigger codes (0, 7, 255) discrete, continuous
3 Markers string 0 Hz text markers ("start", "stop") annotations
4 Markers int32 0 Hz event codes annotations, discrete
5 HeartRate float32 0 Hz heart rate updates annotations, discrete
6 TTL int16 1000 Hz TTL pulses (0, 1) continuous, discrete

Each stream is loaded in one of three modes:

  • Continuous ("continuous" or "c"): channels with signals such as EEG, which are filtered and resampled like any signal.
  • Discrete ("discrete" or "d"): channels with values such as trigger codes, which must not be changed. They are resampled without filtering by holding the previous value, so that they only contain values from the original data (a warning is issued if short pulses are lost due to downsampling). Discrete channels of streams with a regular sampling frequency get the channel type "stim" (unless the stream specifies a different type), so that mne.find_events() works out of the box.
  • Annotations ("annotations" or "a"): one annotation per non-empty string (string streams) or per sample with the value as its description (numeric streams).

If streams is not specified, all streams containing samples are loaded in their default modes. If streams is a list of stream IDs, only these streams are loaded in their default modes. A dict maps stream IDs to modes instead. Channels are always ordered by stream ID. Which modes are possible depends on the stream:

  • String streams (such as stream 3) can only be converted to annotations.
  • Numeric streams with a nominal sampling frequency of 0 Hz (streams 4 and 5) are converted to annotations by default. They can also be loaded as discrete channels, which makes sense for irregular measurements like heart rate (each value is held until the next one arrives).
  • Numeric streams with a regular sampling frequency (streams 1, 2, and 6) are loaded as continuous or discrete channels. The default is discrete if the stream type is "Marker(s)", "Event(s)", "Trigger(s)", or "Stim" (case-insensitive), such as stream 2, and continuous otherwise.

The stream type is just a name chosen by the software that created the stream, so the default can be wrong in both directions. Stream 6 contains discrete pulses, but its type "TTL" is not recognized. Conversely, an analog photodiode signal could be streamed with the type "Trigger". In such cases, specify the mode explicitly. The data type plays no role, because many programs stream trigger codes as floats, and amplifiers often stream continuous signals as integers. Channels with the channel type "stim" (for example, a trigger channel in an EEG stream) are always discrete, even in continuous streams.

Here are some examples for the file above:

from mnextend import read_raw

# all streams in their default modes (`fs_new` is required for multiple channel streams)
# (1, 6: continuous; 2: discrete; 3, 4, 5: annotations)
raw = read_raw("my_data.xdf", fs_new=500)

# all streams except the TTL pulses in their default modes
# (1: continuous; 2: discrete; 3, 4, 5: annotations; 6: not loaded)
raw = read_raw("my_data.xdf", streams=[1, 2, 3, 4, 5], fs_new=500)

# EEG, triggers, and only the text markers
# (1: continuous; 2: discrete; 3: annotations; 4, 5, 6: not loaded)
raw = read_raw("my_data.xdf", streams=[1, 2, 3], fs_new=500)

# heart rate as a channel instead of annotations
# (1: continuous; 5: discrete; 3, 4: annotations; 2, 6: not loaded)
raw = read_raw("my_data.xdf", streams={1: "c", 3: "a", 4: "a", 5: "d"}, fs_new=500)

# TTL pulses as a discrete channel
# (1: continuous; 2, 6: discrete; 3: annotations; 4, 5: not loaded)
raw = read_raw("my_data.xdf", streams={1: "c", 2: "d", 3: "a", 6: "d"}, fs_new=500)

If streams is not specified and several streams would be loaded as channels without fs_new, the error message lists all streams with their possible modes. To get this information programmatically, use stream_modes():

from mnextend.io.xdf import resolve_streams, stream_modes

for stream in resolve_streams("my_data.xdf"):
    print(stream["stream_id"], stream["name"], stream_modes(stream))

Streams rarely start and end at exactly the same time, so channels contain NaN wherever their stream has no data (as well as in gaps detected with gap_threshold), except for "stim" channels, which contain 0 instead. Time spans in which data channels such as EEG contain NaN are annotated as "BAD_ACQ_SKIP". MNE skips these spans when filtering (where NaN would otherwise spread to neighboring samples), and functions that reject bad segments also skip them.

Writing raw data

Writing raw data is supported via write_raw(), which does not implement any new file formats, but provides a unified interface for writing raw data to the file formats that are natively supported by MNE-Python:

from mnextend import write_raw

write_raw("my_data-raw.fif.gz", raw)

ICLabel classification

MNEXTEND includes ICLabel, a pre-trained classifier that labels ICA components as one of seven types: brain, muscle, eye, heart, line noise, channel noise, or other. In contrast to MNE-ICALabel, the classifier is implemented in pure NumPy and does not depend on ONNX Runtime.

run_iclabel() takes a fitted ICA object and the corresponding Raw or Epochs instance (which must have a montage set), and returns an array of class probabilities:

from mnextend import plot_ica_components, run_iclabel

probs = run_iclabel(raw, ica)
figs = plot_ica_components(raw, ica, probs)

Adaptive line-noise removal

Inspired by Raw.notch_filter(method="spectrum_fit") in MNE-Python, this implementation removes known line frequencies from a preloaded Raw object much faster (roughly 30× in our tests). It fits sinusoids in overlapping windows, accommodating gradual amplitude and phase changes without suppressing nearby frequencies. Because the actual mains frequency deviates slightly from its nominal value, the frequency is estimated in each window (within freq_tolerance Hz of line_freq). Like MNE filters, it cleans segments separated by annotations such as "BAD_ACQ_SKIP" or "EDGE" independently.

from mnextend import remove_line_noise

raw.load_data()
remove_line_noise(
    raw,
    line_freq=50,
    picks="eeg",
    include_harmonics=True,
    window_length=10,
    overlap=0.5,
    freq_tolerance=0.1,
    skip_by_annotation=("edge", "bad_acq_skip"),
)

Metadata

Release files for mnextend 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mnextend 0.5.0
File Size Uploaded
mnextend-0.5.0.tar.gz 10.8 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for mnextend 0.5.0
File Interpreter ABI Platform
mnextend-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 21.6 MB

Release files / mnextend-0.5.0.tar.gz

Download URL mnextend-0.5.0.tar.gz
Size 10.8 MB
Tags Source
SHA-256 checksum
How to use checksums
9ff2220cb5dfa56449d34d1bd50c60943512ad922a3cd69323f96ef03f724a9e
BLAKE2b-256 checksum
How to use checksums
691e6e80d4319567adffad621c42fae60cdd25a1ea01bcbca4f3f996fd7e9cec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / mnextend-0.5.0-py3-none-any.whl

Download URL mnextend-0.5.0-py3-none-any.whl
Size 10.8 MB
Tags Python 3
SHA-256 checksum
How to use checksums
02be8b4953234f8cc4783736b0dc097fccf35b2405d3234eaa6963fb7d95b49e
BLAKE2b-256 checksum
How to use checksums
e8d66c8c89cac87b6e5bd3ef0c6329efef6b539ca2924d0032253630b0275266
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.5.1

2 release files

This release

0.5.0 This release

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page