CoolFace
Apppublic

Aluode/PerceptionLabPortable

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
_lof.py99 linesDownload Raw Back to preprocessing
1"""Bad channel detection using Local Outlier Factor (LOF)."""2 3# Authors: The MNE-Python contributors.4# License: BSD-3-Clause5# Copyright the MNE-Python contributors.6 7import numpy as np8 9from .._fiff.pick import _picks_to_idx10from ..io.base import BaseRaw11from ..utils import _soft_import, _validate_type, logger, verbose12 13 14@verbose15def find_bad_channels_lof(16    raw,17    n_neighbors=20,18    *,19    picks=None,20    metric="euclidean",21    threshold=1.5,22    return_scores=False,23    verbose=None,24):25    """Find bad channels using Local Outlier Factor (LOF) algorithm.26 27    Parameters28    ----------29    raw : instance of Raw30        Raw data to process.31    n_neighbors : int32        Number of neighbors defining the local neighborhood (default is 20).33        Smaller values will lead to higher LOF scores.34    %(picks_good_data)s35    metric : str36        Metric to use for distance computation. Default is “euclidean”,37        see :func:`sklearn.metrics.pairwise.distance_metrics` for details.38    threshold : float39        Threshold to define outliers. Theoretical threshold ranges anywhere40        between 1.0 and any positive integer. Default: 1.541        It is recommended to consider this as an hyperparameter to optimize.42    return_scores : bool43        If ``True``, return a dictionary with LOF scores for each44        evaluated channel. Default is ``False``.45    %(verbose)s46 47    Returns48    -------49    noisy_chs : list50        List of bad M/EEG channels that were automatically detected.51    scores : ndarray, shape (n_picks,)52        Only returned when ``return_scores`` is ``True``. It contains the53        LOF outlier score for each channel in ``picks``.54 55    See Also56    --------57    maxwell_filter58    annotate_amplitude59 60    Notes61    -----62    See :footcite:`KumaravelEtAl2022` and :footcite:`BreunigEtAl2000` for background on63    choosing ``threshold``.64 65    .. versionadded:: 1.766 67    References68    ----------69    .. footbibliography::70    """  # noqa: E50171    _soft_import("sklearn", "using LOF detection", strict=True)72    from sklearn.neighbors import LocalOutlierFactor73 74    _validate_type(raw, BaseRaw, "raw")75    # Get the channel types76    channel_types = raw.get_channel_types()77    picks = _picks_to_idx(raw.info, picks=picks, none="data", exclude="bads")78    picked_ch_types = set(channel_types[p] for p in picks)79 80    # Check if there are different channel types81    if len(picked_ch_types) != 1:82        raise ValueError(83            f"Need exactly one channel type in picks, got {sorted(picked_ch_types)}"84        )85    ch_names = [raw.ch_names[pick] for pick in picks]86    data = raw.get_data(picks=picks)87    clf = LocalOutlierFactor(n_neighbors=n_neighbors, metric=metric)88    clf.fit_predict(data)89    scores_lof = clf.negative_outlier_factor_90    bad_channel_indices = [91        i for i, v in enumerate(np.abs(scores_lof)) if v >= threshold92    ]93    bads = [ch_names[idx] for idx in bad_channel_indices]94    logger.info(f"LOF: Detected bad channel(s): {bads}")95    if return_scores:96        return bads, scores_lof97    else:98        return bads99 
Aluode/PerceptionLabPortable · CoolFace