← Về thư mục
📄 / / profiles / r-and-d / raw_evidence / scientific-agent-skills / skills / neurokit2 / references / signal_processing.md

General signal processing

Checked 2026-07-23 against NeuroKit2 0.2.13, its stable wheel, tagged source, and the live signal API page (0.2.13.dev214).

Start with a signal contract

For every channel retain:

signal_sanitize() does not clean artifacts or interpolate missing values. In 0.2.13 it resets an indexed pandas Series to a default index.

Safe preprocessing order

  1. Preserve the original samples and time axis.
  2. Check timestamp order, rate, clipping, flatlines, non-finite values, and gaps.
  3. Split at long gaps. Interpolate only short, prespecified gaps and retain a mask.
  4. Remove offsets/trends only when justified.
  5. Apply a modality/method-specific filter at the native rate.
  6. Trim or flag filter transients.
  7. Detect/correct peaks or derive features.
  8. Resample continuous outputs only when alignment or modeling requires it.

Do not use a filter to “fix” clipping, sensor detachment, dropped packets, or motion. Do not interpolate event markers, quality flags, or peak indicator vectors as continuous amplitudes.

Verified 0.2.13 interfaces

Function Stable behavior relevant to schemas
signal_filter() Returns one array. Default is order-2 Butterworth; available behavior depends on method, cutoffs, and sampling rate.
signal_sanitize() Resets pandas Series indexing; it is not a NaN/artifact cleaner.
signal_fillmissing() Forward, backward, or both-direction fill only (method="forward", "backward", or "both").
signal_resample() Returns one array; accepts target length or source/target rates. Methods include interpolation, FFT, polyphase, NumPy, and pandas paths.
signal_interpolate() Returns interpolated values; explicitly provide source and target coordinates for irregular time.
signal_findpeaks() Returns a dict. The pinned default synthetic probe observed Peaks, Height, Distance, Onsets, Offsets, and Width; keys can change with input/method.
signal_fixpeaks() Returns (info, corrected_peaks) in stable source. Default Kubios info includes artifact categories and diagnostics.
signal_period() Takes peak locations and returns period in seconds, optionally interpolated to a requested sample length.
signal_rate() Takes peak locations and returns events/minute, optionally interpolated.
signal_psd() Returns a DataFrame; the pinned Welch probe observed Frequency and Power.
signal_power() Returns a one-row DataFrame with band-derived names such as Hz_0.5_2; names depend on requested bands.
signal_timefrequency() Returns (frequency, time, representation); frequency is the first object.
signal_synchrony() Returns an array; supported methods are Hilbert phase synchrony and rolling correlation.
signal_decompose() Returns a component array; stable methods are EMD and SSA, not a component dictionary.
signal_changepoints() Implements PELT and returns change-point sample indices.

Never unpack signal_psd() into (psd, frequencies) in 0.2.13:

psd = nk.signal_psd(
    signal,
    sampling_rate=250,
    method="welch",
    normalize=False,
    show=False,
)
frequency_hz = psd["Frequency"]
power = psd["Power"]

normalize=True scales by maximum PSD power. It is not physical calibration. Use normalize=False when absolute spectral units are required and derive those units from the acquisition and estimator.

Filtering and resampling

Cutoffs are in Hz and must lie below Nyquist. Report:

Example:

filtered = nk.signal_filter(
    signal,
    sampling_rate=250,
    lowcut=0.5,
    highcut=40,
    method="butterworth",
    order=2,
)
resampled = nk.signal_resample(
    filtered,
    sampling_rate=250,
    desired_sampling_rate=100,
    method="poly",
)

Downsampling requires anti-alias filtering. Resampling cannot recover timing precision or bandwidth absent from the acquisition. For multimodal data, preserve native processing and timestamps first; choose a common grid only after clock alignment.

Missing data

Forward/backward fill can create artificial constant segments. Generic interpolation can create smooth but fictional morphology and peaks. Record:

Most modality pipelines may warn and internally forward-fill some missing samples. That convenience is not a study-level missing-data policy.

Peak correction

info, corrected = nk.signal_fixpeaks(
    peaks,
    sampling_rate=250,
    method="Kubios",
    iterative=True,
)

The Kubios/Lipponen–Tarvainen path is intended for ECG/PPG beats. method="neurokit" supports explicit interval limits and can be used more generically. Always retain raw and corrected peaks, counts by artifact category, affected time ranges, and results with and without correction. Do not call corrected beat intervals “normal-to-normal” unless the study actually identifies non-sinus/ectopic beats.

Quality and reproducibility

Useful QC is multimodal and method-specific:

The bundled inspector is dependency-free:

python skills/neurokit2/scripts/inspect_signal.py \
  --input signal.csv --root . --deidentified \
  --columns ECG --time-column time_s --units ECG=mV

Sources checked 2026-07-23