| Title: | Preprocessing Functions for PhysioExperiment Objects |
|---|---|
| Description: | Provides preprocessing functions for physiological signal data stored in 'SummarizedExperiment'-derived objects, including digital filters ('Butterworth' and notch), resampling, re-referencing, artifact detection, independent component analysis ('ICA') based artifact removal, and composable preprocessing pipelines. |
| Authors: | Yusuke Matsui [aut, cre] |
| Maintainer: | Yusuke Matsui <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.4.1 |
| Built: | 2026-10-03 13:41:35 UTC |
| Source: | https://github.com/x-biosignal/PhysioPreprocess |
Applies a preprocessing pipeline to a PhysioExperiment object.
applyPipeline(pe, pipeline, verbose = FALSE)applyPipeline(pe, pipeline, verbose = FALSE)
pe |
A PhysioExperiment object. |
pipeline |
A pipeline object created with createPipeline(). |
verbose |
Logical. If TRUE, prints progress messages. |
PhysioExperiment with all pipeline steps applied.
Oppenheim AV, Willsky AS, Nawab SH (1997). "Signals and Systems." 2nd ed. Prentice Hall.
createPipeline() for defining the pipeline steps,
butterworthFilter() and resample() for common preprocessing
operations used within pipelines.
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(1000), nrow = 100, ncol = 10)), colData = S4Vectors::DataFrame(label = paste0("Ch", 1:10)), samplingRate = 256 ) pipeline <- createPipeline( detrend = list(fn = "detrendSignals", method = "linear") ) pe_processed <- applyPipeline(pe, pipeline)pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(1000), nrow = 100, ncol = 10)), colData = S4Vectors::DataFrame(label = paste0("Ch", 1:10)), samplingRate = 256 ) pipeline <- createPipeline( detrend = list(fn = "detrendSignals", method = "linear") ) pe_processed <- applyPipeline(pe, pipeline)
Learns the clean-baseline channel covariance and the per-component RMS
thresholds that asrProcess uses to detect and reconstruct
artifact subspaces (Mullen et al., 2015). Calibration data should be a
relatively clean segment; supply calib_window to restrict it.
asrCalibrate( x, cutoff = 20, calib_window = NULL, window_len = 0.5, assay_name = NULL )asrCalibrate( x, cutoff = 20, calib_window = NULL, window_len = 0.5, assay_name = NULL )
x |
A PhysioExperiment object with a 2D (time x channels) assay. |
cutoff |
Rejection cutoff in robust standard deviations; a principal
direction whose window RMS exceeds |
calib_window |
Optional numeric |
window_len |
Sliding-window length in seconds (default: 0.5). |
assay_name |
Input assay (default: |
An object of class "asr_calibration": a list with the clean
covariance M, its square-root mixing matrix, the threshold matrix,
per-component thresholds, and settings.
Mullen, T. R., et al. (2015). "Real-time neuroimaging and cognitive monitoring using wearable dry EEG." IEEE Transactions on Biomedical Engineering, 62(11), 2553-2567. doi:10.1109/TBME.2015.2481482
Cleans a signal with a calibrated ASR model (asrCalibrate). For
each overlapping sliding window it eigendecomposes the window covariance,
flags principal directions whose RMS exceeds the calibrated threshold, and
reconstructs those directions from the retained ones via the clean-covariance
mixing matrix; windows are recombined by Hann-weighted overlap-add.
asrProcess( x, calibration, window_len = NULL, step = NULL, assay_name = NULL, output_assay = "asr" )asrProcess( x, calibration, window_len = NULL, step = NULL, assay_name = NULL, output_assay = "asr" )
x |
A PhysioExperiment object with a 2D (time x channels) assay. |
calibration |
An |
window_len |
Sliding-window length in seconds (default: the calibration value). |
step |
Window step in seconds (default: half the window length). |
assay_name |
Input assay (default: |
output_assay |
Name for the cleaned assay (default: "asr"). |
The PhysioExperiment with the cleaned signal in output_assay;
the removed-variance fraction and rejected-component fraction are stored in
metadata(x)$asr and logged in provenance.
Deprecated: these accessors now live in PhysioExperiment. The
version here delegates to PhysioExperiment::assaySamplingRates() for
backward compatibility; new code should call the PhysioExperiment function
directly, or use the canonical multi-rate container
PhysioExperiment::MultiPhysioExperiment() when streams differ in length.
assaySamplingRates(x)assaySamplingRates(x)
x |
A PhysioExperiment object. |
A named numeric vector of per-assay sampling rates (Hz).
assaySamplingRates,
MultiPhysioExperiment
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(100 * 2), nrow = 100, ncol = 2)), samplingRate = 100 ) assaySamplingRates(pe)pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(100 * 2), nrow = 100, ncol = 2)), samplingRate = 100 ) assaySamplingRates(pe)
Subtracts baseline from epochs.
baselineCorrect( x, baseline = c(-0.2, 0), method = c("mean", "median"), output_assay = "baseline_corrected" )baselineCorrect( x, baseline = c(-0.2, 0), method = c("mean", "median"), output_assay = "baseline_corrected" )
x |
An epoched PhysioExperiment object. |
baseline |
Numeric vector of length 2 (tmin, tmax) for baseline period. |
method |
Correction method: "mean" or "median". |
output_assay |
Name for the output assay. |
Modified PhysioExperiment with baseline-corrected data.
Applies a Butterworth filter (lowpass, highpass, bandpass, or bandstop) along the time axis of the specified assay.
butterworthFilter( x, low = NULL, high = NULL, order = 4L, type = c("pass", "low", "high", "stop"), use_sos = TRUE, causal = FALSE, output_assay = "filtered" )butterworthFilter( x, low = NULL, high = NULL, order = 4L, type = c("pass", "low", "high", "stop"), use_sos = TRUE, causal = FALSE, output_assay = "filtered" )
x |
A |
low |
Lower cutoff frequency in Hz. Required for highpass and bandpass. |
high |
Upper cutoff frequency in Hz. Required for lowpass and bandpass. |
order |
Filter order. Default is 4. |
type |
Filter type: "low", "high", "pass" (bandpass), or "stop" (bandstop). |
use_sos |
Logical. If TRUE (default), use second-order sections (SOS) form for improved numerical stability, especially for high filter orders. If FALSE, use the traditional transfer function (ba) form. |
causal |
Logical. If FALSE (default), apply zero-phase forward-backward
filtering ( |
output_assay |
Name for the output assay. Default is "filtered". |
By default, second-order sections (SOS) form is used for filtering, which
provides numerical stability for higher filter orders (> 8). The traditional
transfer function (ba) form can exhibit coefficient quantization errors at
high orders, leading to unstable filters. Set use_sos = FALSE to
revert to the legacy ba-form behavior.
The input object with a new assay containing filtered data.
sosfilt(), StreamFilter() for the underlying causal/stateful
filtering primitives.
# Create example EEG data pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(1000 * 4), nrow = 1000)), samplingRate = 250 ) # Bandpass filter (1-40 Hz) - common for EEG pe <- butterworthFilter(pe, low = 1, high = 40, type = "pass") # Lowpass filter (30 Hz) pe <- butterworthFilter(pe, high = 30, type = "low", output_assay = "lowpass") # Highpass filter (0.5 Hz) to remove DC drift pe <- butterworthFilter(pe, low = 0.5, type = "high", output_assay = "highpass") # High-order filter with SOS (numerically stable) pe <- butterworthFilter(pe, low = 1, high = 40, type = "pass", order = 10) # Legacy ba-form filtering pe <- butterworthFilter(pe, low = 1, high = 40, type = "pass", use_sos = FALSE, output_assay = "filtered_ba")# Create example EEG data pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(1000 * 4), nrow = 1000)), samplingRate = 250 ) # Bandpass filter (1-40 Hz) - common for EEG pe <- butterworthFilter(pe, low = 1, high = 40, type = "pass") # Lowpass filter (30 Hz) pe <- butterworthFilter(pe, high = 30, type = "low", output_assay = "lowpass") # Highpass filter (0.5 Hz) to remove DC drift pe <- butterworthFilter(pe, low = 0.5, type = "high", output_assay = "highpass") # High-order filter with SOS (numerically stable) pe <- butterworthFilter(pe, low = 1, high = 40, type = "pass", order = 10) # Legacy ba-form filtering pe <- butterworthFilter(pe, low = 1, high = 40, type = "pass", use_sos = FALSE, output_assay = "filtered_ba")
Automatically identifies artifact ICA components using statistical criteria.
classifyICAComponents( x, method = c("autocorrelation", "kurtosis", "frequency"), eog_channels = NULL, threshold = NULL )classifyICAComponents( x, method = c("autocorrelation", "kurtosis", "frequency"), eog_channels = NULL, threshold = NULL )
x |
A PhysioExperiment object with ICA decomposition
(from |
method |
Classification method: "autocorrelation", "kurtosis", or "frequency". |
eog_channels |
Integer vector of EOG channel indices for correlation-based detection. If provided, also computes EOG correlation scores. |
threshold |
Classification threshold. If NULL, uses method-specific defaults: autocorrelation=0.9, kurtosis=3.0, frequency=0.5. |
A list with:
artifact_indices: Integer vector of artifact component indices
scores: Named numeric vector of scores per component
threshold: The threshold used
method: The method used
Runs a configurable sequence of artifact removal steps.
cleanData( x, steps = c("bad_channels", "ica"), bad_channel_method = "zscore", bad_channel_threshold = NULL, interpolation_method = "average", ica_method = "fastica", ica_classify_method = "kurtosis", output_assay = "cleaned" )cleanData( x, steps = c("bad_channels", "ica"), bad_channel_method = "zscore", bad_channel_threshold = NULL, interpolation_method = "average", ica_method = "fastica", ica_classify_method = "kurtosis", output_assay = "cleaned" )
x |
A PhysioExperiment object. |
steps |
Character vector of steps to run. Options: "bad_channels", "ica". |
bad_channel_method |
Method for |
bad_channel_threshold |
Threshold for bad channel detection. |
interpolation_method |
Method for |
ica_method |
Method for |
ica_classify_method |
Method for |
output_assay |
Name for the output assay. |
Modified PhysioExperiment with cleaned data.
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(300 * 3), nrow = 300, ncol = 3)), samplingRate = 100 ) # Bad-channel detection/interpolation only (ICA needs the fastICA package) pe <- cleanData(pe, steps = "bad_channels")pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(300 * 3), nrow = 300, ncol = 3)), samplingRate = 100 ) # Bad-channel detection/interpolation only (ICA needs the fastICA package) pe <- cleanData(pe, steps = "bad_channels")
Removes power-line noise (and optional harmonics) by sliding-window
sinusoidal regression with a Thomson F-test (the CleanLine / Chronux
approach; Mitra & Bokil, 2008). In each Hann-overlapped window each channel is
regressed onto the line sine/cosine pair; when the fit is significant
(p < p_thresh) the fitted sinusoid is subtracted. This attenuates the
line deeply without a wide spectral notch and works on any number of channels.
cleanLine( x, line_freq = 50, bandwidth = 2, harmonics = 1, p_thresh = 0.01, window_sec = 4, assay_name = NULL, output_assay = "cleanline" )cleanLine( x, line_freq = 50, bandwidth = 2, harmonics = 1, p_thresh = 0.01, window_sec = 4, assay_name = NULL, output_assay = "cleanline" )
x |
A PhysioExperiment object with a 2D (time x channels) assay. |
line_freq |
Line frequency in Hz (default: 50). |
bandwidth |
Reserved spectral bandwidth in Hz around the line (default: 2). |
harmonics |
Number of harmonics to remove, including the fundamental
(default: 1, i.e. |
p_thresh |
F-test significance threshold for subtracting the line (default: 0.01). |
window_sec |
Sliding-window length in seconds (default: 4). |
assay_name |
Input assay (default: |
output_assay |
Name for the cleaned assay (default: "cleanline"). |
The PhysioExperiment with the cleaned signal in output_assay;
the removed line-power fraction is stored in metadata(x)$line_noise
and logged in provenance.
Mitra, P., & Bokil, H. (2008). Observed Brain Dynamics. Oxford University Press.
zapLine, notchFilter (the fast fixed
notch)
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(400 * 3), nrow = 400, ncol = 3)), samplingRate = 200 ) pe <- cleanLine(pe, line_freq = 50, window_sec = 1)pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(400 * 3), nrow = 400, ncol = 3)), samplingRate = 200 ) pe <- cleanLine(pe, line_freq = 50, window_sec = 1)
Orchestrates a standard cleaning pipeline mirroring EEGLAB's
clean_rawdata: flat-channel removal, high-pass drift removal,
correlation-based bad-channel interpolation, and Artifact Subspace
Reconstruction. The removed-variance fraction and any repaired channels are
recorded in provenance.
cleanRawdata( x, flatline = TRUE, highpass = c(0.25, 0.75), channel_crit = 0.8, asr_cutoff = 20, window_len = 0.5, calib_window = NULL, assay_name = NULL, output_assay = "clean" )cleanRawdata( x, flatline = TRUE, highpass = c(0.25, 0.75), channel_crit = 0.8, asr_cutoff = 20, window_len = 0.5, calib_window = NULL, assay_name = NULL, output_assay = "clean" )
x |
A PhysioExperiment object with a 2D (time x channels) assay. |
flatline |
Logical; detect and interpolate (near-)flat channels
(default: |
highpass |
Numeric |
channel_crit |
Minimum mean absolute correlation with the other channels
for a channel to be kept; channels below this are interpolated
(default: 0.8). |
asr_cutoff |
ASR rejection cutoff in robust SDs (default: 20). |
window_len |
ASR sliding-window length in seconds (default: 0.5). |
calib_window |
Optional |
assay_name |
Input assay (default: |
output_assay |
Name for the cleaned assay (default: "clean"). |
The PhysioExperiment with the cleaned signal in output_assay;
metadata(x)$clean_rawdata records the interpolated channels and the
removed-variance fraction, also logged in provenance.
Mullen, T. R., et al. (2015). "Real-time neuroimaging and cognitive monitoring using wearable dry EEG." IEEE Transactions on Biomedical Engineering, 62(11), 2553-2567. doi:10.1109/TBME.2015.2481482
Functions for creating and applying preprocessing pipelines. Create preprocessing pipeline
createPipeline(...)createPipeline(...)
... |
Preprocessing steps as named function calls. |
Creates a preprocessing pipeline specification that can be applied to data.
A preprocessing pipeline object (list).
Oppenheim AV, Willsky AS, Nawab SH (1997). "Signals and Systems." 2nd ed. Prentice Hall.
applyPipeline() for executing a pipeline on data,
filterSignals() and detrendSignals() for individual preprocessing
steps that can be included in a pipeline.
pipeline <- createPipeline( filter = list(fn = "filterSignals", lowcut = 1, highcut = 40), detrend = list(fn = "detrendSignals", method = "linear") )pipeline <- createPipeline( filter = list(fn = "filterSignals", lowcut = 1, highcut = 40), detrend = list(fn = "detrendSignals", method = "linear") )
Downsamples by an integer factor with anti-aliasing filter. An 80%-Nyquist lowpass Butterworth filter is applied before decimation to prevent aliasing.
decimate(x, factor, filter_order = 8L, output_assay = "decimated")decimate(x, factor, filter_order = 8L, output_assay = "decimated")
x |
A PhysioExperiment object. |
factor |
Integer decimation factor. |
filter_order |
Order of the anti-aliasing lowpass filter. |
output_assay |
Name for the output assay. |
A new PhysioExperiment object with sampling rate equal to the
original rate divided by factor. The time dimension is reduced
accordingly. Column data and metadata are carried over.
Crochiere, R.E. & Rabiner, L.R. (1983). "Multirate Digital Signal Processing." Prentice Hall.
resample() for arbitrary-rate resampling,
interpolate() for integer-factor upsampling,
butterworthFilter() for the anti-aliasing filter used internally.
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(400 * 2), nrow = 400, ncol = 2)), samplingRate = 100 ) pe_dec <- decimate(pe, factor = 2) samplingRate(pe_dec)pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(400 * 2), nrow = 400, ncol = 2)), samplingRate = 100 ) pe_dec <- decimate(pe, factor = 2) samplingRate(pe_dec)
Scans continuous data for artifacts using amplitude or gradient criteria.
detectArtifacts( x, method = c("amplitude", "gradient", "joint"), threshold = NULL, window_sec = 1 )detectArtifacts( x, method = c("amplitude", "gradient", "joint"), threshold = NULL, window_sec = 1 )
x |
A PhysioExperiment object. |
method |
Detection method: "amplitude", "gradient", or "joint". |
threshold |
Detection threshold. If NULL, computed as median + 5 * MAD. |
window_sec |
Detection window in seconds (default: 1.0). |
A data.frame with columns: onset (seconds), offset (seconds), channel (index), type (detection method).
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(500 * 2), nrow = 500, ncol = 2)), samplingRate = 100 ) arts <- detectArtifacts(pe, method = "amplitude") head(arts)pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(500 * 2), nrow = 500, ncol = 2)), samplingRate = 100 ) arts <- detectArtifacts(pe, method = "amplitude") head(arts)
Identifies channels with abnormal characteristics.
detectBadChannels( x, method = c("zscore", "correlation", "flatline"), threshold = NULL )detectBadChannels( x, method = c("zscore", "correlation", "flatline"), threshold = NULL )
x |
A PhysioExperiment object. |
method |
Detection method: "zscore", "correlation", or "flatline". |
threshold |
Threshold for detection (depends on method). |
Integer vector of bad channel indices.
m <- matrix(rnorm(300 * 3), nrow = 300, ncol = 3) m[, 2] <- m[, 2] * 10 # channel 2 is an amplitude outlier pe <- PhysioExperiment(assays = list(raw = m), samplingRate = 100) detectBadChannels(pe, method = "zscore")m <- matrix(rnorm(300 * 3), nrow = 300, ncol = 3) m[, 2] <- m[, 2] * 10 # channel 2 is an amplitude outlier pe <- PhysioExperiment(assays = list(raw = m), samplingRate = 100) detectBadChannels(pe, method = "zscore")
Removes linear or polynomial trends from the signal.
detrendSignal(x, type = c("linear", "constant"), output_assay = "detrended")detrendSignal(x, type = c("linear", "constant"), output_assay = "detrended")
x |
A |
type |
Type of detrending: "linear" or "constant" (mean removal). |
output_assay |
Name for the output assay. Default is "detrended". |
A PhysioExperiment object with a new assay named output_assay
containing detrended data. For "constant" type, the channel mean is
subtracted. For "linear" type, a least-squares linear fit is removed.
Oppenheim, A.V. & Willsky, A.S. (1997). "Signals and Systems." 2nd ed. Prentice Hall.
detrendSignals() for the alternative detrending implementation
with polynomial support, butterworthFilter() for highpass filtering
as an alternative to detrending.
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(200 * 2) + seq_len(200) / 50, nrow = 200, ncol = 2)), samplingRate = 100 ) pe <- detrendSignal(pe, type = "linear")pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(200 * 2) + seq_len(200) / 50, nrow = 200, ncol = 2)), samplingRate = 100 ) pe <- detrendSignal(pe, type = "linear")
Functions for removing trends from physiological signals. Detrend signals
detrendSignals( pe, method = c("linear", "mean", "polynomial"), order = 2, assay_name = NULL, output_assay = "detrended" )detrendSignals( pe, method = c("linear", "mean", "polynomial"), order = 2, assay_name = NULL, output_assay = "detrended" )
pe |
A PhysioExperiment object. |
method |
Detrending method: "linear", "mean", or "polynomial". |
order |
Polynomial order for method="polynomial". |
assay_name |
Name of the assay to detrend. |
output_assay |
Name for the detrended output assay. |
Removes linear or polynomial trends from signals.
PhysioExperiment with detrended data in output_assay.
Oppenheim AV, Willsky AS, Nawab SH (1997). "Signals and Systems." 2nd ed. Prentice Hall.
removeBaseline() for baseline subtraction over a time window,
detrendSignal() for the alternative linear/constant detrending
implementation, butterworthFilter() for highpass filtering as an
alternative to detrending.
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(1000) + 1:100/10, nrow = 100, ncol = 10)), colData = S4Vectors::DataFrame(label = paste0("Ch", 1:10)), samplingRate = 256 ) pe_detrended <- detrendSignals(pe, method = "linear")pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(1000) + 1:100/10, nrow = 100, ncol = 10)), colData = S4Vectors::DataFrame(label = paste0("Ch", 1:10)), samplingRate = 256 ) pe_detrended <- detrendSignals(pe, method = "linear")
This file provides one-pass, causal, state-carrying IIR filtering that
mirrors scipy.signal (lfilter, lfilter_zi,
sosfilt, sosfilt_zi, sosfiltfilt). Unlike the zero-phase
butterworthFilter default (which uses forward-backward
filtfilt and is inherently non-causal), these functions process a
signal strictly forward in time and can carry filter state across
consecutive chunks. This is the numerical core that a real-time streaming
backend (e.g. a future PhysioStream) reuses so that offline and
online filtering produce identical results.
All recursions use the Direct-Form-II-Transposed (DF2T) structure, which is
the same structure scipy.signal and signal::filter use, so the
outputs agree to machine precision.
Oppenheim, A.V. & Schafer, R.W. (2010). Discrete-Time Signal Processing, 3rd ed. Prentice Hall.
Virtanen, P. et al. (2020). SciPy 1.0. Nature Methods 17, 261-272.
(reference implementation: scipy.signal.sosfilt /
lfilter / lfilter_zi / sosfilt_zi).
Applies a moving average filter along the first dimension (time axis) of the default assay.
filterSignals(x, window = 5L, na.rm = FALSE, output_assay = "filtered")filterSignals(x, window = 5L, na.rm = FALSE, output_assay = "filtered")
x |
A |
window |
Integer window length for the moving average. |
na.rm |
Logical. If TRUE, NA values are ignored in the filter computation. |
output_assay |
Name for the output assay. Default is "filtered". |
A PhysioExperiment object with a new assay named output_assay
containing the moving-average-filtered data. Dimensions match the input
assay. Edge values where the full window cannot be applied are set to NA.
Oppenheim, A.V. & Willsky, A.S. (1997). "Signals and Systems." 2nd ed. Prentice Hall.
butterworthFilter() for IIR filtering, firFilter() for FIR
filtering, notchFilter() for power line noise removal,
detrendSignal() for trend removal.
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(300 * 3), nrow = 300, ncol = 3)), samplingRate = 100 ) pe <- filterSignals(pe, window = 5)pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(300 * 3), nrow = 300, ncol = 3)), samplingRate = 100 ) pe <- filterSignals(pe, window = 5)
Applies a Finite Impulse Response (FIR) filter along the time axis.
Uses zero-phase forward-backward filtering via signal::filtfilt() to
avoid phase distortion.
firFilter( x, low = NULL, high = NULL, order = 100L, type = c("pass", "low", "high", "stop"), window = "hamming", causal = FALSE, output_assay = "filtered" )firFilter( x, low = NULL, high = NULL, order = 100L, type = c("pass", "low", "high", "stop"), window = "hamming", causal = FALSE, output_assay = "filtered" )
x |
A |
low |
Lower cutoff frequency in Hz. |
high |
Upper cutoff frequency in Hz. |
order |
Filter order (number of taps - 1). Default is 100. |
type |
Filter type: "low", "high", "pass" (bandpass), or "stop" (bandstop). |
window |
Window function for FIR design. Default is "hamming". |
causal |
Logical. If FALSE (default), apply zero-phase forward-backward
filtering ( |
output_assay |
Name for the output assay. Default is "filtered". |
A PhysioExperiment object with a new assay named output_assay
containing the FIR-filtered data. Dimensions match the input assay.
Oppenheim, A.V. & Willsky, A.S. (1997). "Signals and Systems." 2nd ed. Prentice Hall.
butterworthFilter() for IIR filtering, notchFilter() for power
line noise removal, filterSignals() for moving average filtering,
lfilter() for the underlying causal filtering primitive.
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(600 * 2), nrow = 600, ncol = 2)), samplingRate = 100 ) # Linear-phase FIR bandpass (1-20 Hz); modest order keeps the example quick pe <- firFilter(pe, low = 1, high = 20, order = 20, type = "pass")pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(600 * 2), nrow = 600, ncol = 2)), samplingRate = 100 ) # Linear-phase FIR bandpass (1-20 Hz); modest order keeps the example quick pe <- firFilter(pe, low = 1, high = 20, order = 20, type = "pass")
Returns the current reference electrode information.
getCurrentReference(x)getCurrentReference(x)
x |
A PhysioExperiment object. |
A character string describing the current reference (e.g., "average",
"Cz", "M1+M2"), or NULL if no reference has been set.
Nunez, P.L. & Srinivasan, R. (2006). "Electric Fields of the Brain." 2nd ed. Oxford University Press.
rereference() for changing the reference,
isAverageReferenced() for checking average reference status.
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(100), nrow = 10, ncol = 10)), samplingRate = 100 ) pe <- setReference(pe, "Cz") getCurrentReference(pe) # "Cz"pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(100), nrow = 10, ncol = 10)), samplingRate = 100 ) pe <- setReference(pe, "Cz") getCurrentReference(pe) # "Cz"
Functions for Independent Component Analysis (ICA) and artifact removal from physiological signals.
icaDecompose( x, n_components = NULL, method = c("fastica", "jade"), max_iter = 200L, tol = 1e-04 )icaDecompose( x, n_components = NULL, method = c("fastica", "jade"), max_iter = 200L, tol = 1e-04 )
x |
A PhysioExperiment object. |
n_components |
Number of components to extract. If NULL, uses number of channels. |
method |
ICA method: "fastica" (default) or "jade". |
max_iter |
Maximum iterations for convergence. |
tol |
Tolerance for convergence. |
A list with four elements:
The independent components as a matrix or 3D array (time by component by samples for 3D data).
The mixing matrix (channels x components).
The unmixing matrix (components x channels).
The input PhysioExperiment with the ICA decomposition
(components, mixing/unmixing matrices, column means) stored in
metadata(x)$ica. The components are held in metadata rather than as an
assay because their column count is n_components, which need not equal
the object's channel count.
Hyvarinen, A. & Oja, E. (2000). "Independent component analysis: algorithms and applications." Neural Networks, 13(4-5), 411-430. doi:10.1016/S0893-6080(00)00026-5 Perform ICA decomposition
Decomposes the signal into independent components using FastICA algorithm.
Hyvarinen, A. & Oja, E. (2000). "Independent component analysis: algorithms and applications." Neural Networks, 13(4-5), 411-430. doi:10.1016/S0893-6080(00)00026-5
icaRemove() for removing specific components after decomposition,
runICA() for an alternative ICA implementation using the fastICA package,
detectBadChannels() for channel-level artifact detection.
Removes specified ICA components and reconstructs the signal.
icaRemove(x, components, output_assay = "ica_cleaned")icaRemove(x, components, output_assay = "ica_cleaned")
x |
A PhysioExperiment object with ICA decomposition. |
components |
Integer vector of component indices to remove. |
output_assay |
Name for the output assay. |
Modified PhysioExperiment with cleaned signal.
Upsamples by an integer factor with interpolation. This is a convenience
wrapper around resample() with target_rate = sr * factor.
interpolate( x, factor, method = c("linear", "spline"), output_assay = "interpolated" )interpolate( x, factor, method = c("linear", "spline"), output_assay = "interpolated" )
x |
A PhysioExperiment object. |
factor |
Integer interpolation factor. |
method |
Interpolation method: "linear" or "spline". |
output_assay |
Name for the output assay. |
A new PhysioExperiment object with sampling rate equal to the
original rate multiplied by factor. The time dimension is increased
accordingly.
Crochiere, R.E. & Rabiner, L.R. (1983). "Multirate Digital Signal Processing." Prentice Hall.
resample() for arbitrary-rate resampling,
decimate() for integer-factor downsampling.
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(200 * 2), nrow = 200, ncol = 2)), samplingRate = 100 ) pe_up <- interpolate(pe, factor = 2) samplingRate(pe_up)pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(200 * 2), nrow = 200, ncol = 2)), samplingRate = 100 ) pe_up <- interpolate(pe, factor = 2) samplingRate(pe_up)
Replaces bad channels with interpolated values from neighboring channels.
interpolateBadChannels( x, bad_channels, method = c("average", "spline"), output_assay = "interpolated" )interpolateBadChannels( x, bad_channels, method = c("average", "spline"), output_assay = "interpolated" )
x |
A PhysioExperiment object. |
bad_channels |
Integer vector of channel indices to interpolate. |
method |
Interpolation method: "average" or "spline". |
output_assay |
Name for the output assay. |
Modified PhysioExperiment with interpolated channels.
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(300 * 3), nrow = 300, ncol = 3)), samplingRate = 100 ) pe <- interpolateBadChannels(pe, bad_channels = 2, method = "average")pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(300 * 3), nrow = 300, ncol = 3)), samplingRate = 100 ) pe <- interpolateBadChannels(pe, bad_channels = 2, method = "average")
Check if data is average referenced
isAverageReferenced(x)isAverageReferenced(x)
x |
A PhysioExperiment object. |
A logical scalar: TRUE if the reference metadata is set to
"average", FALSE otherwise.
Nunez, P.L. & Srinivasan, R. (2006). "Electric Fields of the Brain." 2nd ed. Oxford University Press.
rereference() for changing the reference,
getCurrentReference() for querying the current reference.
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(100), nrow = 10, ncol = 10)), samplingRate = 100 ) pe <- rereference(pe, ref_type = "average") isAverageReferenced(pe) # TRUEpe <- PhysioExperiment( assays = list(raw = matrix(rnorm(100), nrow = 10, ncol = 10)), samplingRate = 100 ) pe <- rereference(pe, ref_type = "average") isAverageReferenced(pe) # TRUE
Applies a rational transfer function defined by numerator b and
denominator a to x, forward in time, mirroring
scipy.signal.lfilter. Optionally carries the delay-line state so a
signal can be filtered in consecutive chunks with a result identical to
filtering it whole.
lfilter(b, a, x, zi = NULL)lfilter(b, a, x, zi = NULL)
b |
Numerator (feed-forward) coefficients. |
a |
Denominator (feedback) coefficients ( |
x |
Numeric input vector. |
zi |
Optional initial delay-line state, length
|
If zi is NULL, the filtered numeric vector. Otherwise a
list with y (filtered vector) and zi (final state).
ba <- signal::butter(4, 0.2, "low") # single call y <- lfilter(ba$b, ba$a, rnorm(500)) # streamed in two chunks with carried state x <- rnorm(500) r1 <- lfilter(ba$b, ba$a, x[1:250], zi = numeric(4)) r2 <- lfilter(ba$b, ba$a, x[251:500], zi = r1$zi) identical(length(c(r1$y, r2$y)), length(x))ba <- signal::butter(4, 0.2, "low") # single call y <- lfilter(ba$b, ba$a, rnorm(500)) # streamed in two chunks with carried state x <- rnorm(500) r1 <- lfilter(ba$b, ba$a, x[1:250], zi = numeric(4)) r2 <- lfilter(ba$b, ba$a, x[251:500], zi = r1$zi) identical(length(c(r1$y, r2$y)), length(x))
Computes the filter delay-line state that, when scaled by the first input
sample and passed to lfilter, makes the filter's step response
start already in steady state (no start-up transient). This is the direct
analogue of scipy.signal.lfilter_zi.
lfilterInit(b, a)lfilterInit(b, a)
b |
Numerator (feed-forward) coefficients. |
a |
Denominator (feedback) coefficients; |
A numeric vector of length max(length(a), length(b)) - 1, the
initial delay-line state (unscaled; multiply by the first sample level).
ba <- signal::butter(2, 0.2, "low") zi <- lfilterInit(ba$b, ba$a)ba <- signal::butter(2, 0.2, "low") zi <- lfilterInit(ba$b, ba$a)
Applies a notch filter to remove power line noise (50 Hz or 60 Hz) and optionally its harmonics. Implemented as a Butterworth bandstop filter with zero-phase filtering.
notchFilter( x, freq = 50, bandwidth = 2, harmonics = 1L, output_assay = "filtered" )notchFilter( x, freq = 50, bandwidth = 2, harmonics = 1L, output_assay = "filtered" )
x |
A |
freq |
Center frequency to remove in Hz. Default is 50 (European power line). |
bandwidth |
Bandwidth of the notch in Hz. Default is 2. |
harmonics |
Number of harmonics to remove. Default is 1 (only fundamental). |
output_assay |
Name for the output assay. Default is "filtered". |
A PhysioExperiment object with a new assay named output_assay
containing the notch-filtered data. Harmonics above the Nyquist frequency
are skipped with a warning.
Oppenheim, A.V. & Willsky, A.S. (1997). "Signals and Systems." 2nd ed. Prentice Hall.
butterworthFilter() for general Butterworth filtering,
firFilter() for FIR filtering, filterSignals() for moving average
filtering.
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(1000 * 4), nrow = 1000)), samplingRate = 250 ) # Remove 50 Hz power line noise (Europe/Asia) pe <- notchFilter(pe, freq = 50) # Remove 60 Hz and harmonics (Americas) pe <- notchFilter(pe, freq = 60, harmonics = 2)pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(1000 * 4), nrow = 1000)), samplingRate = 250 ) # Remove 50 Hz power line noise (Europe/Asia) pe <- notchFilter(pe, freq = 50) # Remove 60 Hz and harmonics (Americas) pe <- notchFilter(pe, freq = 60, harmonics = 2)
Print pipeline summary
## S3 method for class 'PhysioPipeline' print(x, ...)## S3 method for class 'PhysioPipeline' print(x, ...)
x |
A PhysioPipeline object. |
... |
Additional arguments (ignored). |
Invisible x.
createPipeline() for creating pipelines,
applyPipeline() for executing pipelines.
Identifies and optionally removes epochs with artifacts.
rejectBadEpochs( x, threshold = 100, method = c("amplitude", "gradient", "variance"), remove = TRUE )rejectBadEpochs( x, threshold = 100, method = c("amplitude", "gradient", "variance"), remove = TRUE )
x |
An epoched PhysioExperiment object. |
threshold |
Amplitude threshold for rejection. |
method |
Detection method: "amplitude", "gradient", or "variance". |
remove |
If TRUE, removes bad epochs. If FALSE, returns indices only. |
If remove=TRUE, modified object. If remove=FALSE, indices of bad epochs.
Subtracts baseline from a specified time window.
removeBaseline( pe, baseline_start, baseline_end, assay_name = NULL, output_assay = "baseline_corrected" )removeBaseline( pe, baseline_start, baseline_end, assay_name = NULL, output_assay = "baseline_corrected" )
pe |
A PhysioExperiment object. |
baseline_start |
Start time of baseline window in seconds. |
baseline_end |
End time of baseline window in seconds. |
assay_name |
Name of the assay to baseline correct. |
output_assay |
Name for the baseline-corrected output assay. |
PhysioExperiment with baseline-corrected data.
Oppenheim AV, Willsky AS, Nawab SH (1997). "Signals and Systems." 2nd ed. Prentice Hall.
detrendSignals() for trend removal, baselineCorrect() for
epoch-based baseline correction, filterSignals() for moving average
smoothing.
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(1000) + 5, nrow = 100, ncol = 10)), colData = S4Vectors::DataFrame(label = paste0("Ch", 1:10)), samplingRate = 100 ) pe_corrected <- removeBaseline(pe, baseline_start = 0, baseline_end = 0.2)pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(1000) + 5, nrow = 100, ncol = 10)), colData = S4Vectors::DataFrame(label = paste0("Ch", 1:10)), samplingRate = 100 ) pe_corrected <- removeBaseline(pe, baseline_start = 0, baseline_end = 0.2)
Reconstructs signals after removing specified ICA components (e.g., artifacts).
removeICAComponents( pe, ica_result, remove_components, assay_name = NULL, output_assay = "ica_cleaned" )removeICAComponents( pe, ica_result, remove_components, assay_name = NULL, output_assay = "ica_cleaned" )
pe |
A PhysioExperiment object. |
ica_result |
Result from runICA(). |
remove_components |
Integer vector of component indices to remove. |
assay_name |
Name of the assay to reconstruct. |
output_assay |
Name for the cleaned output assay. |
PhysioExperiment with cleaned data in output_assay.
Hyvarinen A, Oja E (2000). "Independent component analysis: algorithms and applications." Neural Networks, 13(4-5), 411-430.
runICA() for performing the ICA decomposition,
icaRemove() for the alternative component removal implementation,
detectBadChannels() for channel-level artifact detection.
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(1000), nrow = 100, ncol = 10)), colData = S4Vectors::DataFrame(label = paste0("Ch", 1:10)), samplingRate = 256 ) if (requireNamespace("fastICA", quietly = TRUE)) { ica_result <- runICA(pe, n_components = 5) pe_clean <- removeICAComponents(pe, ica_result, remove_components = c(1, 3)) }pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(1000), nrow = 100, ncol = 10)), colData = S4Vectors::DataFrame(label = paste0("Ch", 1:10)), samplingRate = 256 ) if (requireNamespace("fastICA", quietly = TRUE)) { ica_result <- runICA(pe, n_components = 5) pe_clean <- removeICAComponents(pe, ica_result, remove_components = c(1, 3)) }
Functions for changing the reference electrode in EEG recordings. Re-referencing is a common preprocessing step that affects the spatial distribution of the signal.
rereference( x, ref_type = c("average", "robust", "median", "channel", "channels", "REST"), ref_channels = NULL, exclude = NULL, input_assay = NULL, output_assay = "rereferenced", keep_ref = TRUE, robust_noise_sd = 4, robust_max_iter = 5 )rereference( x, ref_type = c("average", "robust", "median", "channel", "channels", "REST"), ref_channels = NULL, exclude = NULL, input_assay = NULL, output_assay = "rereferenced", keep_ref = TRUE, robust_noise_sd = 4, robust_max_iter = 5 )
x |
A PhysioExperiment object. |
ref_type |
Type of re-referencing: "average" (common average reference), "robust" (PREP robust average reference: iteratively detect and exclude high-variance bad channels from the average; Bigdely-Shamlo et al., 2015), "median" (channel-wise median reference, robust to outlier channels), "channel" (single channel), "channels" (average of specified channels), or "REST" (Reference Electrode Standardization Technique). |
ref_channels |
For "channel" or "channels" type, the channel name(s) or index/indices to use as reference. |
exclude |
Channels to exclude from average reference calculation (e.g., non-EEG channels like EOG, EMG). |
input_assay |
Input assay name. If NULL, uses default assay. |
output_assay |
Output assay name. Default is "rereferenced". |
keep_ref |
Logical. If TRUE, keeps the original reference channel(s) in the output (zeroed). If FALSE, removes them. |
robust_noise_sd |
For "robust", the threshold (robust SDs above the median channel variance) for flagging a bad channel (default: 4). |
robust_max_iter |
For "robust", the maximum number of PREP iterations (default: 5). |
Re-referencing transforms the data by subtracting a reference signal from each channel. The choice of reference affects the spatial distribution and interpretation of the signal.
Average reference ("average"): Subtracts the mean of all channels at each time point. This is commonly used for high-density EEG and provides a reference-independent measure, but requires good spatial sampling.
Single channel reference ("channel"): Subtracts the signal from a specified electrode. Common choices include Cz, linked mastoids (A1+A2)/2, or nose reference.
Multi-channel reference ("channels"): Subtracts the average of multiple specified channels. Useful for linked mastoids or other custom references.
A PhysioExperiment object with re-referenced data stored in a new
assay named output_assay. The reference and previous_reference
metadata fields are updated. When keep_ref = FALSE and using channel-based
reference, the reference channel(s) are removed and a new object with
reduced channel count is returned.
Nunez, P.L. & Srinivasan, R. (2006). "Electric Fields of the Brain." 2nd ed. Oxford University Press. Re-reference EEG data
Changes the reference electrode for EEG recordings. Supports common re-referencing schemes including average reference, linked mastoids, and single electrode reference.
Nunez, P.L. & Srinivasan, R. (2006). "Electric Fields of the Brain." 2nd ed. Oxford University Press.
getCurrentReference() for querying the current reference,
isAverageReferenced() for checking average reference status,
butterworthFilter() for frequency-domain preprocessing.
# Create example EEG data set.seed(123) pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(1000), nrow = 100, ncol = 10)), colData = S4Vectors::DataFrame( label = c("Fp1", "Fp2", "F3", "F4", "C3", "C4", "P3", "P4", "O1", "O2"), type = rep("EEG", 10) ), samplingRate = 256 ) # Apply average reference pe_avg <- rereference(pe, ref_type = "average") # Re-reference to a single channel (Cz) pe_cz <- rereference(pe, ref_type = "channel", ref_channels = "C3") # Re-reference to linked mastoids (if available) # pe_linked <- rereference(pe, ref_type = "channels", # ref_channels = c("M1", "M2"))# Create example EEG data set.seed(123) pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(1000), nrow = 100, ncol = 10)), colData = S4Vectors::DataFrame( label = c("Fp1", "Fp2", "F3", "F4", "C3", "C4", "P3", "P4", "O1", "O2"), type = rep("EEG", 10) ), samplingRate = 256 ) # Apply average reference pe_avg <- rereference(pe, ref_type = "average") # Re-reference to a single channel (Cz) pe_cz <- rereference(pe, ref_type = "channel", ref_channels = "C3") # Re-reference to linked mastoids (if available) # pe_linked <- rereference(pe, ref_type = "channels", # ref_channels = c("M1", "M2"))
Functions for resampling signal data to different sampling rates. Resample signal data
resample( x, target_rate, method = c("linear", "spline", "fft"), assay_name = NULL, output_assay = "resampled" )resample( x, target_rate, method = c("linear", "spline", "fft"), assay_name = NULL, output_assay = "resampled" )
x |
A PhysioExperiment object. |
target_rate |
Target sampling rate in Hz. |
method |
Resampling method: "linear" (default), "spline", or "fft". |
assay_name |
Optional assay name. If NULL, uses the default assay. |
output_assay |
Name for the output assay. Default is "resampled". |
Resamples the signal data to a target sampling rate using interpolation. Supports linear interpolation, spline interpolation, and FFT-based resampling (zero-padding or truncation in the frequency domain).
A new PhysioExperiment object with sampling rate set to
target_rate. The time dimension is adjusted to match the new rate
while preserving the signal duration. Column data and metadata are
carried over from the input.
Crochiere, R.E. & Rabiner, L.R. (1983). "Multirate Digital Signal Processing." Prentice Hall.
decimate() for integer-factor downsampling with anti-aliasing,
interpolate() for integer-factor upsampling,
setAssaySamplingRate() for per-assay rate tracking.
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(500 * 2), nrow = 500, ncol = 2)), samplingRate = 100 ) pe_50 <- resample(pe, target_rate = 50) samplingRate(pe_50)pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(500 * 2), nrow = 500, ncol = 2)), samplingRate = 100 ) pe_50 <- resample(pe, target_rate = 50) samplingRate(pe_50)
Functions for Independent Component Analysis (ICA) decomposition and artifact removal using the fastICA algorithm. Perform ICA decomposition
runICA( pe, n_components = NULL, assay_name = NULL, method = "fastica", max_iter = 200, ... )runICA( pe, n_components = NULL, assay_name = NULL, method = "fastica", max_iter = 200, ... )
pe |
A PhysioExperiment object. |
n_components |
Number of components to extract. If NULL, uses all channels. |
assay_name |
Name of the assay to decompose. |
method |
ICA algorithm: "fastica" (default). |
max_iter |
Maximum number of iterations. |
... |
Additional arguments passed to fastICA::fastICA. |
Decomposes signals into independent components using the fastICA algorithm.
A list with components:
S |
Source matrix (time x components) |
A |
Mixing matrix (channels x components) |
W |
Unmixing matrix (components x channels) |
Hyvarinen A, Oja E (2000). "Independent component analysis: algorithms and applications." Neural Networks, 13(4-5), 411-430.
removeICAComponents() for reconstructing signals after removing
artifact components, icaDecompose() for the built-in ICA implementation,
detectBadChannels() for channel-level artifact detection.
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(1000), nrow = 100, ncol = 10)), colData = S4Vectors::DataFrame(label = paste0("Ch", 1:10)), samplingRate = 256 ) if (requireNamespace("fastICA", quietly = TRUE)) { ica_result <- runICA(pe, n_components = 5) }pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(1000), nrow = 100, ncol = 10)), colData = S4Vectors::DataFrame(label = paste0("Ch", 1:10)), samplingRate = 256 ) if (requireNamespace("fastICA", quietly = TRUE)) { ica_result <- runICA(pe, n_components = 5) }
Deprecated: delegates to PhysioExperiment::setAssaySamplingRate().
New code should use PhysioExperiment directly.
setAssaySamplingRate(x, assay_name, rate)setAssaySamplingRate(x, assay_name, rate)
x |
A PhysioExperiment object. |
assay_name |
Name of the assay. |
rate |
Sampling rate for the assay in Hz. |
The updated PhysioExperiment.
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(100 * 2), nrow = 100, ncol = 2)), samplingRate = 100 ) pe <- setAssaySamplingRate(pe, "raw", 100) assaySamplingRates(pe)pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(100 * 2), nrow = 100, ncol = 2)), samplingRate = 100 ) pe <- setAssaySamplingRate(pe, "raw", 100) assaySamplingRates(pe)
Builds the cascaded second-order-sections representation of a Butterworth
filter directly from the analog prototype poles (bilinear transform), which
is numerically stable for all orders. This is the design entry point for the
causal / stateful filtering functions (sosfilt,
sosfiltfilt, StreamFilter).
sosDesign( low = NULL, high = NULL, order = 4L, type = c("pass", "low", "high", "stop"), sr )sosDesign( low = NULL, high = NULL, order = 4L, type = c("pass", "low", "high", "stop"), sr )
low |
Lower cutoff frequency in Hz. Required for |
high |
Upper cutoff frequency in Hz. Required for |
order |
Filter order (per band). Default |
type |
Filter type: |
sr |
Sampling rate in Hz. |
A numeric matrix with one second-order section per row and six
columns c(b0, b1, b2, a0, a1, a2).
sosfilt, sosfiltfilt,
StreamFilter
sos <- sosDesign(high = 40, type = "low", sr = 250, order = 4) y <- sosfilt(sos, rnorm(1000))sos <- sosDesign(high = 40, type = "low", sr = 250, order = 4) y <- sosfilt(sos, rnorm(1000))
Filters x through a cascade of second-order sections, forward in time,
mirroring scipy.signal.sosfilt. Each section uses the DF2T biquad
recursion. Optionally carries the two-sample-per-section state so a signal
can be processed in consecutive chunks identically to processing it whole.
sosfilt(sos, x, zi = NULL)sosfilt(sos, x, zi = NULL)
sos |
SOS matrix ( |
x |
Numeric input vector. |
zi |
Optional initial state, a matrix |
If zi is NULL, the filtered numeric vector. Otherwise a
list with y (filtered vector) and zi (final
n_sections x 2 state matrix).
sosDesign, sosfiltInit,
sosfiltfilt
sos <- sosDesign(high = 40, type = "low", sr = 250, order = 4) y <- sosfilt(sos, rnorm(1000)) # chunked with carried state == whole-signal filtering x <- rnorm(1000) zi0 <- matrix(0, nrow(sos), 2) r1 <- sosfilt(sos, x[1:500], zi = zi0) r2 <- sosfilt(sos, x[501:1000], zi = r1$zi) max(abs(c(r1$y, r2$y) - sosfilt(sos, x)))sos <- sosDesign(high = 40, type = "low", sr = 250, order = 4) y <- sosfilt(sos, rnorm(1000)) # chunked with carried state == whole-signal filtering x <- rnorm(1000) zi0 <- matrix(0, nrow(sos), 2) r1 <- sosfilt(sos, x[1:500], zi = zi0) r2 <- sosfilt(sos, x[501:1000], zi = r1$zi) max(abs(c(r1$y, r2$y) - sosfilt(sos, x)))
Forward-backward (zero-phase) SOS filtering that mirrors
scipy.signal.sosfiltfilt: it odd-reflects the signal at both edges,
initialises the delay-line to steady state (scaled by the boundary sample) to
suppress start-up transients, filters forward and then backward. The result
has zero phase distortion but is non-causal (both directions are used). For
strictly causal / real-time-equivalent filtering, use sosfilt
or butterworthFilter with causal = TRUE.
sosfiltfilt(sos, x, padlen = NULL)sosfiltfilt(sos, x, padlen = NULL)
sos |
SOS matrix ( |
x |
Numeric input vector. |
padlen |
Number of samples of odd reflection padding at each edge.
Defaults to |
The zero-phase filtered numeric vector, same length as x.
sos <- sosDesign(high = 40, type = "low", sr = 250, order = 4) y <- sosfiltfilt(sos, rnorm(1000))sos <- sosDesign(high = 40, type = "low", sr = 250, order = 4) y <- sosfiltfilt(sos, rnorm(1000))
Per-section analogue of lfilterInit for second-order-sections
form; equivalent to scipy.signal.sosfilt_zi. Each section's steady
state is scaled by the DC gain of all preceding sections so that the whole
cascade starts in steady state when the returned matrix (scaled by the first
sample) is handed to sosfilt.
sosfiltInit(sos)sosfiltInit(sos)
sos |
SOS matrix ( |
A numeric matrix (n_sections x 2) of per-section initial
states (unscaled).
sos <- sosDesign(high = 40, type = "low", sr = 250) zi <- sosfiltInit(sos)sos <- sosDesign(high = 40, type = "low", sr = 250) zi <- sosfiltInit(sos)
Constructs a mutable filter object that carries its delay-line state across
successive $apply() calls, so a signal fed in arbitrary chunks
produces exactly the same output as filtering it whole. The identical math is
used offline and online, which lets a real-time streaming backend reuse this
object without re-deriving coefficients.
StreamFilter(sos = NULL, b = NULL, a = NULL, warmup = TRUE)StreamFilter(sos = NULL, b = NULL, a = NULL, warmup = TRUE)
sos |
SOS matrix ( |
b, a
|
Transfer-function coefficients (converted to a single SOS section
only when they describe a biquad; otherwise supply |
warmup |
Logical; if |
The returned object is an environment (reference semantics) with methods:
$apply(x)Filter numeric vector x, advancing and
storing the internal state; returns the filtered vector.
$reset()Clear the carried state so the next $apply()
starts fresh (cold or warm start per warmup).
$state()Return the current internal state matrix.
An object of class "StreamFilter" (an environment).
sos <- sosDesign(high = 30, type = "low", sr = 250, order = 4) sf <- StreamFilter(sos) x <- rnorm(1000) y_chunked <- c(sf$apply(x[1:400]), sf$apply(x[401:1000])) sf$reset() y_whole <- sf$apply(x) max(abs(y_chunked - y_whole))sos <- sosDesign(high = 30, type = "low", sr = 250, order = 4) sf <- StreamFilter(sos) x <- rnorm(1000) y_chunked <- c(sf$apply(x[1:400]), sf$apply(x[401:1000])) sf$reset() y_whole <- sf$apply(x) max(abs(y_chunked - y_whole))
Removes power-line noise while preserving the broadband spectrum using
ZapLine (de Cheveigne, 2020): the line is first suppressed by a comb-notch
smoother, then a DSS/PCA of the notched-out residual isolates the line-noise
spatial subspace, and only its top nremove components are removed from
the data. This avoids the wide spectral notch of a fixed filter and needs at
least two channels (line noise is treated as a spatial component).
zapLine( x, line_freq = 50, nremove = 1, nfft = NULL, assay_name = NULL, output_assay = "zapline" )zapLine( x, line_freq = 50, nremove = 1, nfft = NULL, assay_name = NULL, output_assay = "zapline" )
x |
A PhysioExperiment object with a 2D (time x channels) assay. |
line_freq |
Line frequency in Hz (default: 50). |
nremove |
Number of line-noise components to remove (default: 1). |
nfft |
Optional analysis FFT length controlling the line-band width for
the DSS bias (default: |
assay_name |
Input assay (default: |
output_assay |
Name for the cleaned assay (default: "zapline"). |
The PhysioExperiment with the cleaned signal in output_assay;
the removed line-power fraction is stored in metadata(x)$line_noise
and logged in provenance.
de Cheveigne, A. (2020). "ZapLine: A simple and effective method to remove power line artifacts." NeuroImage, 207, 116356. doi:10.1016/j.neuroimage.2019.116356
cleanLine, notchFilter (the fast fixed
notch)
pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(400 * 3), nrow = 400, ncol = 3)), samplingRate = 200 ) pe <- zapLine(pe, line_freq = 50)pe <- PhysioExperiment( assays = list(raw = matrix(rnorm(400 * 3), nrow = 400, ncol = 3)), samplingRate = 200 ) pe <- zapLine(pe, line_freq = 50)