ezmsg.simbiophys.system.velocity2ecephys#

Convert 2D cursor velocity to simulated extracellular electrophysiology.

This module provides a complete system that encodes cursor velocity into realistic ecephys signals containing both spike waveforms and LFP-like background activity.

Pipeline:

velocity (x,y) -> CART2POL --+--> Velocity2Spike --> spikes --|
                             |                                +--> Add --> ecephys
                             +--> Velocity2LFP ----> lfp -----|

The coordinate transformation from Cartesian to polar is done once at the input, then shared by both spike and LFP encoding branches.

This is the top-level system for velocity-encoded neural simulation. Use this when you need full ecephys-like output suitable for testing BCI decoders.

See also

ezmsg.simbiophys.system.velocity2spike: Spike-only encoding. ezmsg.simbiophys.system.velocity2lfp: LFP-only encoding.

Classes

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

Bases: Collection

Encode cursor velocity into simulated extracellular electrophysiology.

This system combines spike and LFP encoding to produce realistic ecephys signals. It runs two parallel pipelines:

  1. Spike branch (Velocity2Spike): Generates cosine-tuned spike waveforms based on velocity direction and magnitude.

  2. LFP branch (Velocity2LFP): Generates velocity-modulated colored noise representing local field potentials.

The outputs are summed to produce the final ecephys signal.

Input:

AxisArray with shape (N, 2) containing cursor velocity in pixels/second. Dimension 0 is time, dimension 1 is [vx, vy].

Output:

AxisArray with shape (M, output_ch) containing combined spike and LFP signals at output_fs sampling rate.

Example

>>> encoder = VelocityEncoder(VelocityEncoderSettings(
...     output_fs=30_000.0,
...     output_ch=256,
...     seed=42,
... ))
Parameters:

settings (Settings | None)

SETTINGS#

alias of VelocityEncoderSettings

INPUT_SIGNAL = InputTopicStream:unlocated[AxisArray]()#
COORDS = <ezmsg.sigproc.coordinatespaces.CoordinateSpaces object>#
SPIKES = <ezmsg.simbiophys.system.velocity2spike.Velocity2Spike object>#
LFP = <ezmsg.simbiophys.system.velocity2lfp.Velocity2LFP object>#
ADD = <ezmsg.sigproc.math.add.Add object>#
LINE_NOISE = <ezmsg.simbiophys.line_noise.LineNoiseUnit object>#
OUTPUT_SIGNAL = OutputTopicStream:unlocated[AxisArray]()#
configure()[source]#

A lifecycle hook that runs when the Collection is instantiated.

This is the best place to call Unit.apply_settings() on each member Unit of the Collection. Override this method to perform collection-specific configuration of child components.

Return type:

None

network()[source]#

Override this method and have the definition return a NetworkDefinition which defines how InputStreams and OutputStreams from member Units will be connected.

The NetworkDefinition specifies the message routing between components by connecting output streams to input streams.

Returns:

Network definition specifying stream connections

Return type:

Iterable[tuple[Stream | str, Stream | str]]

class VelocityEncoderSettings(output_fs=30000.0, output_ch=256, seed=6767, baseline_rate=10, modulation_depth=0.06369426751592357, max_velocity=315, n_sources=8, drift_scale=4.0, line_noise_freq=None, line_noise_amp=10.0, line_noise_drift_rate=0.002, line_noise_drift_bound=1.5)[source]#

Bases: Settings

Settings for VelocityEncoder.

Parameters:
output_fs: float = 30000.0#

Output sampling rate in Hz.

output_ch: int = 256#

Number of output channels (simulated electrodes).

seed: int = 6767#

Random seed for reproducible spike and LFP generation.

baseline_rate: float = 10#

Baseline firing rate in Hz

modulation_depth: float = 0.06369426751592357#

Directional modulation depth in Hz per (pixel/second)

max_velocity: float = 315#

Velocity (px/s) at which LFP beta reaches full modulation.

n_sources: int = 8#

Number of cosine-encoded LFP sources.

drift_scale: float = 4.0#

Amplitude of always-on slow 1/f drift added to each LFP source before mixing (a shared low-frequency field drift across channels). Velocity- independent, so baseline wander is present even at rest. Set to 0 to disable.

line_noise_freq: float | None = None#

Mains line-noise frequency in Hz (50.0 or 60.0). None (default) disables line noise (pass-through). Added to every channel of the final signal.

line_noise_amp: float = 10.0#

Amplitude of the line-noise sinusoid (same units as the output signal).

line_noise_drift_rate: float = 0.002#

Line-noise frequency drift rate in Hz per second (recording-clock drift).

__init__(output_fs=30000.0, output_ch=256, seed=6767, baseline_rate=10, modulation_depth=0.06369426751592357, max_velocity=315, n_sources=8, drift_scale=4.0, line_noise_freq=None, line_noise_amp=10.0, line_noise_drift_rate=0.002, line_noise_drift_bound=1.5)#
Parameters:
Return type:

None

line_noise_drift_bound: float = 1.5#

Line-noise frequency is clamped to line_noise_freq +/- this Hz.