Butterworth

class gpype.backend.filters.base.butterworth.Butterworth[source]

Bases: IONode

Butterworth filter implementation for real-time signal processing.

Implements a Butterworth digital filter using second-order sections for numerical stability. Supports lowpass, highpass, bandpass, and bandstop filtering with configurable order and maintains state for streaming data.

DEFAULT_ORDER = 2

Default filter order for Butterworth filters

PHASE_CAUSAL = 'causal'

Filtered forwards only, carrying the filter’s group delay. The only thing a realtime pipeline can do, because the samples after the current one have not been acquired yet.

PHASE_ZERO = 'zero'

Filtered forwards and backwards, so the result has no group delay at any frequency. Needs every sample, and therefore a batch run.

PHASE_CHOICES = ('causal', 'zero')

Accepted values of phase, in the order the catalog lists them.

DEFAULT_PHASE = 'causal'

What a filter does when nothing is said, which has to stay the realtime answer: a default that changed with the execution mode would give two different results for one document.

class Configuration[source]

Bases: Configuration

Configuration class for Butterworth filter parameters.

class Keys[source]

Bases: Keys

Configuration keys for Butterworth filter settings.

FN = 'fn'

Cutoff frequencies configuration key

BTYPE = 'btype'

Filter type configuration key

ORDER = 'order'

Filter order configuration key

PHASE = 'phase'

Causal or zero-phase filtering

__init__(fn, btype, order=None, phase=None, **kwargs)[source]

Initialize the Butterworth filter with specified parameters.

Parameters:
  • fn (list) – List of cutoff frequencies in Hz. Single value for lowpass/ highpass, two values [low, high] for bandpass/bandstop.

  • btype (str) – Filter type (‘lowpass’, ‘highpass’, ‘bandpass’, ‘bandstop’).

  • order (int) – Filter order. Defaults to 2 if not specified.

  • phase (str) – causal (default) filters forwards only and carries the filter’s group delay, which is the only thing a realtime pipeline can do. zero filters forwards and backwards, leaving no group delay at any frequency – which needs every sample, so it runs in a batch pipeline and is refused in a realtime one.

  • **kwargs – Additional arguments passed to parent IONode class.

Raises:

ValueError – If fn is not a list, btype is invalid, order <= 0, or phase is not one of PHASE_CHOICES.

setup(data, port_context_in)[source]

Setup the Butterworth filter before processing begins.

Initializes filter coefficients and state based on sampling rate and channel configuration from input context.

Parameters:
  • data (dict[str, ndarray]) – Initial data dictionary (not used in setup).

  • port_context_in (dict[str, dict]) – Input port context with sampling_rate and channel_count metadata.

Return type:

dict[str, dict]

Returns:

Output port context dictionary with updated metadata.

Raises:

ValueError – If required context keys are missing.

step(data)[source]

Apply Butterworth filter to input data.

Processes input data through the filter while maintaining filter state for continuous operation.

Parameters:

data (dict[str, ndarray]) – Dictionary containing input data with key PORT_IN. Input should be 2D array (samples x channels).

Return type:

dict[str, ndarray]

Returns:

Dictionary with filtered data under key PORT_OUT.

Raises:

ValueError – If input data is not 2D array.

process(data)[source]

Filter a whole recording in one call.

Called instead of step() in a batch run. With phase='causal' this hands the block straight to step – sosfilt over N rows is the same state machine as over N frames, so a batch run and a realtime run give identical samples, which is the property that makes validating offline worth anything.

With phase='zero' it filters forwards and backwards, leaving no group delay at any frequency. That is what a realtime pipeline cannot do, and the reason this mode exists.

Parameters:

data (dict[str, ndarray]) – The complete recording, under key PORT_IN.

Return type:

dict[str, ndarray]

Returns:

The filtered recording under key PORT_OUT.

Raises:

ValueError – If the recording is too short for the filter’s edge padding.