mne_denoise.icanclean.ICanClean#

class mne_denoise.icanclean.ICanClean(sfreq: float, ref_channels: list[str] | list[int] | None = None, primary_channels: list[str] | list[int] | None = None, mode: str = 'sliding', clean_with: str = 'X', segment_len: float = 2.0, overlap: float = 0.0, threshold: float | str = 0.7, max_reject_fraction: float = 0.5, reref_primary: bool | str = False, reref_ref: bool | str = False, stats_segment_len: float | None = None, global_threshold: float | str | None = None, global_clean_with: str | None = None, global_max_reject_fraction: float | None = None, verbose: bool = True)[source]#

ICanClean Transformer for reference-based artifact removal.

Implements the iCanClean algorithm [1] [2] [3] using canonical correlation analysis (CCA) between primary channels and reference channels to identify and remove artifact-dominated subspaces.

The estimator supports four operating modes:

mode='global'

Estimate one CCA decomposition on the full recording and subtract the selected artifact basis once.

mode='sliding'

Estimate a fresh CCA decomposition in each clean window and combine the cleaned windows with overlap-add.

mode='calibrated'

Estimate one global CCA decomposition, then reuse that fixed basis for window-local scoring and subtraction.

mode='hybrid'

Run an explicit global cleaning pass first, then run the standard sliding-window cleaner on the globally cleaned output.

Parameters:
  • sfreq (float) – Sampling frequency in Hz.

  • ref_channels (list of str | list of int) – Explicit reference noise channels. For MNE objects, provide channel names or integer channel indices. For NumPy arrays, provide integer channel indices.

  • primary_channels (list of str | list of int | None, default=None) – Explicit primary (scalp) channels to clean. If None, all channels not listed in ref_channels are used.

  • mode ({'sliding', 'global', 'calibrated', 'hybrid'}, default='sliding') – Cleaning mode. Use 'global' for a single full-recording pass, 'sliding' for the standard windowed cleaner, 'calibrated' for a global CCA calibration with local window scoring, or 'hybrid' to run an explicit global pass followed by the sliding pass.

  • clean_with ({'X', 'Y', 'both'}, default='X') – Canonical variates used as the noise basis. 'X' uses the data-side variates U, 'Y' uses the reference-side variates V, and 'both' concatenates both sets.

  • segment_len (float, default=2.0) – Sliding window duration in seconds (the “clean window”).

  • overlap (float, default=0.0) – Overlap between consecutive windows as a fraction in [0, 1).

  • threshold (float | 'auto', default=0.7) – \(R^2\) threshold for component rejection. If 'auto', uses an adaptive threshold based on the 95th percentile of the running correlation distribution.

  • max_reject_fraction (float, default=0.5) – Safety cap: at most this fraction of canonical components can be removed per window.

  • reref_primary (bool | str, default=False) – Apply average re-referencing to primary channels for CCA only (the original data is used for cleaning). True or 'fullrank' uses a full-rank average reference that preserves rank; 'loserank' uses a standard average reference that reduces rank by one.

  • reref_ref (bool | str, default=False) – Same as reref_primary but for reference channels.

  • stats_segment_len (float | None, default=None) – Duration (seconds) of the broader “stats window” for CCA computation. If None or equal to segment_len, the same window is used for CCA and cleaning. When larger, CCA is computed on the broader window but only the inner segment_len portion is cleaned. This is only valid for 'sliding' and 'hybrid' modes and must be greater than or equal to segment_len.

  • global_threshold (float | 'auto' | None, default=None) – Threshold for the explicit global pass in mode='hybrid'.

  • global_clean_with ({'X', 'Y', 'both'} | None, default=None) – Noise basis for the explicit global pass in mode='hybrid'.

  • global_max_reject_fraction (float | None, default=None) – Reject cap for the explicit global pass in mode='hybrid'.

  • verbose (bool, default=True) – Whether to log progress information.

correlations_#

Squared canonical correlations per window. d = min(rank(primary), rank(reference)).

Type:

ndarray, shape (n_windows, d)

n_removed_#

Number of components removed per window.

Type:

ndarray, shape (n_windows,)

removed_idx_#

Indices of rejected components per window.

Type:

list of ndarray

filters_#

CCA coefficient matrices A (primary) per window.

Type:

list of ndarray

patterns_#

CCA coefficient matrices B (reference) per window.

Type:

list of ndarray

n_windows_#

Total number of windows processed.

Type:

int

primary_channels_#

Primary channel names used during cleaning.

Type:

list of str

ref_channels_#

Reference channel names used during cleaning.

Type:

list of str

See also

mne_denoise.DSS

Denoising Source Separation.

mne_denoise.ZapLine

DSS-based line noise removal.

Notes

Note

A public U.S. patent application has been filed for the iCanClean method: US20230363718A1, “Removing latent noise components from data signals” (Application 18/245,496). Patent applications, and any resulting patents, may affect commercial use. Consult lawyer if necessary.

When threshold='auto', the adaptive threshold is computed as the 95th percentile of all \(R^2\) values accumulated so far. For the first 10 windows (insufficient statistics), a conservative default of 0.95 is used.

The max_reject_fraction parameter prevents the algorithm from removing too many components in a single window, which would distort the signal. This is especially important for short windows or noisy reference sensors.

Examples

Basic usage with MNE Raw object (explicit reference channels):

>>> from mne_denoise.icanclean import ICanClean
>>> icanclean = ICanClean(
...     sfreq=raw.info["sfreq"],
...     ref_channels=["EOG1", "EOG2", "EMG1"],
... )
>>> raw_clean = icanclean.fit_transform(raw)

Dual-layer EEG with explicit channel names:

>>> icanclean = ICanClean(
...     sfreq=256.0,
...     primary_channels=["1-EEG0", "1-EEG1", "1-EEG2"],
...     ref_channels=["2-NSE0", "2-NSE1"],
...     segment_len=2.0,
...     overlap=0.5,
...     threshold=0.85,
... )
>>> raw_clean = icanclean.fit_transform(raw)
>>> print(f"Removed {icanclean.n_removed_.mean():.1f} components on average")

NumPy array interface:

>>> import numpy as np
>>> primary = np.random.randn(32, 5000)  # (n_primary, n_times)
>>> reference = np.random.randn(4, 5000)  # (n_ref, n_times)
>>> data = np.vstack([primary, reference])
>>> icanclean = ICanClean(
...     sfreq=250.0,
...     ref_channels=list(range(32, 36)),  # last 4 channels
... )
>>> cleaned = icanclean.fit_transform(data)

References

[1]

Downey, R. J., & Ferris, D. P. (2022). The iCanClean Algorithm: How to Remove Artifacts using Reference Noise Recordings. arXiv:2201.11798.

[2]

Downey, R. J., & Ferris, D. P. (2023). iCanClean Removes Motion, Muscle, Eye, and Line-Noise Artifacts from Phantom EEG. Sensors, 23(19), 8214. https://doi.org/10.3390/s23198214

[3]

Gonsisko, C. B., Ferris, D. P., & Downey, R. J. (2023). iCanClean Improves ICA of Mobile Brain Imaging with EEG. Sensors, 23(2), 928. https://doi.org/10.3390/s23020928

__init__(sfreq: float, ref_channels: list[str] | list[int] | None = None, primary_channels: list[str] | list[int] | None = None, mode: str = 'sliding', clean_with: str = 'X', segment_len: float = 2.0, overlap: float = 0.0, threshold: float | str = 0.7, max_reject_fraction: float = 0.5, reref_primary: bool | str = False, reref_ref: bool | str = False, stats_segment_len: float | None = None, global_threshold: float | str | None = None, global_clean_with: str | None = None, global_max_reject_fraction: float | None = None, verbose: bool = True)[source]#

Methods

__init__(sfreq[, ref_channels, ...])

fit(X[, y])

Fit is a no-op; included for sklearn compatibility.

fit_transform(X[, y])

Fit and apply ICanClean in one step.

get_metadata_routing()

Get metadata routing of this object.

get_params([deep])

Get parameters for this estimator.

set_output(*[, transform])

Set output container.

set_params(**params)

Set the parameters of this estimator.

transform(X[, y])

Apply ICanClean artifact removal.