ezmsg.sigproc.downsample#

Integer downsampling by selecting every Nth sample along an axis.

Functions

downsample(target_rate=None, factor=None)[source]#
Parameters:
  • target_rate (float | None)

  • factor (int | None)

Return type:

DownsampleTransformer

Classes

class Downsample(*args, settings=None, **kwargs)[source]#

Bases: BaseTransformerUnit[DownsampleSettings, AxisArray, AxisArray, DownsampleTransformer]

Parameters:

settings (Settings | None)

SETTINGS#

alias of DownsampleSettings

async on_signal(message)[source]#

Skip the publish when no samples accumulated.

At factor > 1 most input chunks span less than one downsample period, so DownsampleTransformer._process returns a payload with a zero-length axis. Suppressing the broadcast in that case avoids shipping an empty AxisArray across SHM/socket every input chunk. Only emptiness along the downsampled axis is suppressed: a message that is empty along other axes (e.g. all channels sliced away upstream) still flows so downstream consumers keep its cadence.

Parameters:

message (AxisArray)

Return type:

AsyncGenerator

class DownsampleSettings(target_rate=None, factor=None)[source]#

Bases: Settings

Settings for Downsample node.

Parameters:
  • target_rate (float | None)

  • factor (int | None)

target_rate: float | None = None#

Desired rate after downsampling. The actual rate will be the nearest integer factor of the input rate that is the same or higher than the target rate.

factor: int | None = None#

Explicitly specify downsample factor. If specified, target_rate is ignored.

__init__(target_rate=None, factor=None)#
Parameters:
  • target_rate (float | None)

  • factor (int | None)

Return type:

None

class DownsampleState[source]#

Bases: object

q: int = 0#

The integer downsampling factor. It will be determined based on the target rate.

s_idx: int = 0#

Index of the next msg’s first sample into the virtual rotating ds_factor counter.

axis: str = ''#

the message’s declared stream_dim.

Type:

The dimension being downsampled

class DownsampleTransformer(*args, **kwargs)[source]#

Bases: BaseStatefulTransformer[DownsampleSettings, AxisArray, AxisArray, DownsampleState]

Downsampled data simply comprise every factor`th sample. This should only be used following appropriate lowpass filtering. If your pipeline does not already have lowpass filtering then consider using the :obj:`Decimate collection instead.

The dimension is not configurable: it is always the one messages accumulate along. The phase counter s_idx carries across messages so the kept samples form one arithmetic sequence over the whole stream rather than restarting per chunk. That is the entire point along the accumulating dimension, and it is meaningless along any other: a static axis has the same length every message, so the carried phase makes the selection itself rotate. Downsampling (time, freq) along freq by 2 alternates between bins [0, 2, 4] and [1, 3] – different frequencies, and a different output length, on alternating messages.

For a static axis use Slicer with "::2", which selects the same elements every time and holds no state to do it.

The dimension comes from the message’s stream_dim, so a Downsample placed after a windowing stage decimates windows without reconfiguration. When a producer does not declare one, STREAMING_DIMS supplies the fallback.