yasa.spindles_detect(data, sf=None, ch_names=None, hypno=None, include=1, 2, 3, freq_sp=12, 15, freq_broad=1, 30, duration=0.5, 2, min_distance=500, thresh={'corr': 0.65, 'rel_pow': 0.2, 'rms': 1.5}, multi_only=False, remove_outliers=False, verbose=False)[source]

Spindles detection.


Single or multi-channel data. Unit must be uV and shape (n_samples) or (n_chan, n_samples). Can also be a mne.io.BaseRaw, in which case data, sf, and ch_names will be automatically extracted, and data will also be automatically converted from Volts (MNE) to micro-Volts (YASA).


Sampling frequency of the data in Hz. Can be omitted if data is a mne.io.BaseRaw.


If the detection is taking too long, make sure to downsample your data to 100 Hz (or 128 Hz). For more details, please refer to mne.filter.resample().

ch_nameslist of str

Channel names. Can be omitted if data is a mne.io.BaseRaw.


Sleep stage (hypnogram). If the hypnogram is loaded, the detection will only be applied to the value defined in include (default = N1 + N2 + N3 sleep).

The hypnogram must have the same number of samples as data. To upsample your hypnogram, please refer to yasa.hypno_upsample_to_data().


The default hypnogram format in YASA is a 1D integer vector where:

  • -2 = Unscored

  • -1 = Artefact / Movement

  • 0 = Wake

  • 1 = N1 sleep

  • 2 = N2 sleep

  • 3 = N3 sleep

  • 4 = REM sleep

includetuple, list or int

Values in hypno that will be included in the mask. The default is (1, 2, 3), meaning that the detection is applied on N1, N2 and N3 sleep. This has no effect when hypno is None.

freq_sptuple or list

Spindles frequency range. Default is 12 to 15 Hz. Please note that YASA uses a FIR filter (implemented in MNE) with a 1.5Hz transition band, which means that for freq_sp = (12, 15 Hz), the -6 dB points are located at 11.25 and 15.75 Hz.

freq_broadtuple or list

Broad band frequency range. Default is 1 to 30 Hz.

durationtuple or list

The minimum and maximum duration of the spindles. Default is 0.5 to 2 seconds.


If two spindles are closer than min_distance (in ms), they are merged into a single spindles. Default is 500 ms.


Detection thresholds:

  • 'rel_pow': Relative power (= power ratio freq_sp / freq_broad).

  • 'corr': Moving correlation between original signal and sigma-filtered signal.

  • 'rms': Number of standard deviations above the mean of a moving root mean square of sigma-filtered signal.

You can disable one or more threshold by putting None instead:

thresh = {'rel_pow': None, 'corr': 0.65, 'rms': 1.5}
thresh = {'rel_pow': None, 'corr': None, 'rms': 3}

Define the behavior of the multi-channel detection. If True, only spindles that are present on at least two channels are kept. If False, no selection is applied and the output is just a concatenation of the single-channel detection dataframe. Default is False.


If True, YASA will automatically detect and remove outliers spindles using sklearn.ensemble.IsolationForest. The outliers detection is performed on all the spindles parameters with the exception of the Start, Peak, End, Stage, and SOPhase columns. YASA uses a random seed (42) to ensure reproducible results. Note that this step will only be applied if there are more than 50 detected spindles in the first place. Default to False.

verbosebool or str

Verbose level. Default (False) will only print warning and error messages. The logging levels are ‘debug’, ‘info’, ‘warning’, ‘error’, and ‘critical’. For most users the choice is between ‘info’ (or verbose=True) and warning (verbose=False).

New in version 0.2.0.


To get the full detection dataframe, use:

>>> sp = spindles_detect(...)
>>> sp.summary()

This will give a pandas.DataFrame where each row is a detected spindle and each column is a parameter (= feature or property) of this spindle. To get the average spindles parameters per channel and sleep stage:

>>> sp.summary(grp_chan=True, grp_stage=True)


The parameters that are calculated for each spindle are:

  • 'Start': Start time of the spindle, in seconds from the beginning of data.

  • 'Peak': Time at the most prominent spindle peak (in seconds).

  • 'End' : End time (in seconds).

  • 'Duration': Duration (in seconds)

  • 'Amplitude': Peak-to-peak amplitude of the (detrended) spindle in the raw data (in µV).

  • 'RMS': Root-mean-square (in µV)

  • 'AbsPower': Median absolute power (in log10 µV^2), calculated from the Hilbert-transform of the freq_sp filtered signal.

  • 'RelPower': Median relative power of the freq_sp band in spindle calculated from a short-term fourier transform and expressed as a proportion of the total power in freq_broad.

  • 'Frequency': Median instantaneous frequency of spindle (in Hz), derived from an Hilbert transform of the freq_sp filtered signal.

  • 'Oscillations': Number of oscillations (= number of positive peaks in spindle.)

  • 'Symmetry': Location of the most prominent peak of spindle, normalized from 0 (start) to 1 (end). Ideally this value should be close to 0.5, indicating that the most prominent peak is halfway through the spindle.

  • 'Stage' : Sleep stage during which spindle occured, if hypno was provided.

    All parameters are calculated from the broadband-filtered EEG (frequency range defined in freq_broad).

For better results, apply this detection only on artefact-free NREM sleep.


A critical bug was fixed in YASA 0.6.1, in which the number of detected spindles could vary drastically depending on the sampling frequency of the data. Please make sure to check any results obtained with this function prior to the 0.6.1 release.


The sleep spindles detection algorithm is based on:


For a walkthrough of the spindles detection, please refer to the following Jupyter notebooks: